Kernel-Classes.st 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119
  1. Smalltalk createPackage: 'Kernel-Classes'!
  2. Object subclass: #Behavior
  3. slots: {#organization. #slots. #fn. #superclass}
  4. package: 'Kernel-Classes'!
  5. !Behavior commentStamp!
  6. I am the superclass of all class objects.
  7. In addition to BehaviorBody, I define superclass/subclass relationships and instantiation.
  8. I define the protocol for creating instances of a class with `#basicNew` and `#new` (see `boot.js` for class constructors details).
  9. My instances know about the subclass/superclass relationships between classes and contain the description that instances are created from.
  10. I also provide iterating over the class hierarchy.!
  11. !Behavior methodsFor: 'accessing'!
  12. allInstanceVariableNames
  13. | result |
  14. result := self instanceVariableNames copy.
  15. self superclass ifNotNil: [
  16. result addAll: self superclass allInstanceVariableNames ].
  17. ^ result
  18. !
  19. allSelectors
  20. ^ self allSuperclasses
  21. inject: self selectors
  22. into: [ :acc :each | acc addAll: each selectors; yourself ]
  23. !
  24. allSubclasses
  25. "Answer an collection of the receiver's and the receiver's descendent's subclasses. "
  26. ^ Array streamContents: [ :str | self allSubclassesDo: [ :each | str nextPut: each ] ]
  27. !
  28. allSuperclasses
  29. self superclass ifNil: [ ^ #() ].
  30. ^ (OrderedCollection with: self superclass)
  31. addAll: self superclass allSuperclasses;
  32. yourself
  33. !
  34. basicOrganization
  35. ^ organization
  36. !
  37. basicOrganization: aClassOrganizer
  38. organization := aClassOrganizer
  39. !
  40. beJavaScriptSubclassOf: aJavaScriptFunction
  41. "Set the JS constructor to subclass of aJavaScriptFunction.
  42. That way I stay part of (simulated) Smalltalk hierarchy,
  43. but my instances will physically be instanceof aJavaScriptFunction."
  44. self javaScriptConstructor:
  45. (ClassBuilder new javaScriptSubclassOf: aJavaScriptFunction)
  46. !
  47. instanceVariableNames
  48. ^ slots
  49. !
  50. javaScriptConstructor
  51. "Answer the JS constructor used to instantiate. See kernel-language.js"
  52. ^ fn
  53. !
  54. javaScriptConstructor: aJavaScriptFunction
  55. "Set the JS constructor used to instantiate.
  56. See the JS counter-part in boot.js `$core.setClassConstructor'"
  57. Smalltalk core setClassConstructor: self to: aJavaScriptFunction
  58. !
  59. javascriptConstructor
  60. self deprecatedAPI: 'Use #javaScriptConstructor instead.'.
  61. ^ self javaScriptConstructor
  62. !
  63. javascriptConstructor: aJavaScriptFunction
  64. self deprecatedAPI: 'Use #javaScriptConstructor: instead.'.
  65. ^ self javaScriptConstructor: aJavaScriptFunction
  66. !
  67. lookupSelector: selector
  68. "Look up the given selector in my methodDictionary.
  69. Return the corresponding method if found.
  70. Otherwise chase the superclass chain and try again.
  71. Return nil if no method is found."
  72. | lookupClass |
  73. lookupClass := self.
  74. [ lookupClass = nil ] whileFalse: [
  75. (lookupClass includesSelector: selector)
  76. ifTrue: [ ^ lookupClass methodAt: selector ].
  77. lookupClass := lookupClass superclass ].
  78. ^ nil
  79. !
  80. prototype
  81. ^ self javaScriptConstructor prototype
  82. !
  83. subclasses
  84. self subclassResponsibility
  85. !
  86. superclass
  87. ^ superclass
  88. !
  89. theMetaClass
  90. self subclassResponsibility
  91. !
  92. theNonMetaClass
  93. self subclassResponsibility
  94. !
  95. withAllSubclasses
  96. ^ (Array with: self) addAll: self allSubclasses; yourself
  97. ! !
  98. !Behavior methodsFor: 'enumerating'!
  99. allSubclassesDo: aBlock
  100. "Evaluate the argument, aBlock, for each of the receiver's subclasses."
  101. <inlineJS: '$core.traverseClassTree(self, function(subclass) {
  102. if (subclass !!== self) aBlock._value_(subclass);
  103. })'>
  104. ! !
  105. !Behavior methodsFor: 'instance creation'!
  106. basicNew
  107. <inlineJS: 'return new self.fn()'>
  108. !
  109. new
  110. ^ self basicNew initialize
  111. ! !
  112. !Behavior methodsFor: 'testing'!
  113. canUnderstand: aSelector
  114. ^ (self includesSelector: aSelector asString) or: [
  115. self superclass notNil and: [ self superclass canUnderstand: aSelector ]]
  116. !
  117. includesBehavior: aClass
  118. ^ self == aClass or: [
  119. self inheritsFrom: aClass ]
  120. !
  121. inheritsFrom: aClass
  122. self superclass ifNil: [ ^ false ].
  123. ^ aClass == self superclass or: [
  124. self superclass inheritsFrom: aClass ]
  125. !
  126. isBehavior
  127. ^ true
  128. ! !
  129. Behavior subclass: #Class
  130. slots: {#package. #subclasses}
  131. package: 'Kernel-Classes'!
  132. !Class commentStamp!
  133. I am __the__ class object.
  134. My instances are the classes of the system.
  135. Class creation is done throught a `ClassBuilder` instance.!
  136. !Class methodsFor: 'accessing'!
  137. basicPackage: aPackage
  138. package := aPackage
  139. !
  140. classTag
  141. "Returns a tag or general category for this class.
  142. Typically used to help tools do some reflection.
  143. Helios, for example, uses this to decide what icon the class should display."
  144. ^ 'class'
  145. !
  146. definition
  147. ^ String streamContents: [ :stream | stream
  148. print: self superclass; write: ' subclass: '; printSymbol: self name; lf;
  149. write: (self traitCompositionDefinition ifNotEmpty: [ :tcd | { String tab. 'uses: '. tcd. String lf }]);
  150. tab; write: {'slots: {'. ('. ' join: (self instanceVariableNames collect: #symbolPrintString)). '}'}; lf;
  151. tab; write: 'package: '; print: self category ]
  152. !
  153. package
  154. ^ package
  155. !
  156. rename: aString
  157. ClassBuilder new renameClass: self to: aString
  158. !
  159. subclasses
  160. ^ subclasses copy
  161. !
  162. theMetaClass
  163. ^ self class
  164. ! !
  165. !Class methodsFor: 'converting'!
  166. provided
  167. "Returns JS proxy that allows to access 'static API', as in
  168. Number provided EPSILON
  169. that forwards to (wrapped JS) constructor function."
  170. ^ self javaScriptConstructor provided
  171. ! !
  172. !Class methodsFor: 'enumerating'!
  173. includingPossibleMetaDo: aBlock
  174. aBlock value: self.
  175. aBlock value: self theMetaClass
  176. ! !
  177. !Class methodsFor: 'testing'!
  178. isClass
  179. ^ true
  180. ! !
  181. Behavior subclass: #Metaclass
  182. slots: {#instanceClass}
  183. package: 'Kernel-Classes'!
  184. !Metaclass commentStamp!
  185. I am the root of the class hierarchy.
  186. My instances are metaclasses, one for each real class, and have a single instance, which they hold onto: the class that they are the metaclass of.!
  187. !Metaclass methodsFor: 'accessing'!
  188. definition
  189. ^ String streamContents: [ :stream | stream
  190. print: self;
  191. write: (self traitCompositionDefinition
  192. ifEmpty: [' ']
  193. ifNotEmpty: [ :tcd | { String lf. String tab. 'uses: '. tcd. String lf. String tab }]);
  194. write: {'slots: {'. ('. ' join: (self instanceVariableNames collect: #symbolPrintString)). '}'} ]
  195. !
  196. instanceClass
  197. ^ instanceClass
  198. !
  199. instanceVariableNames: aString
  200. "Kept for file-in compatibility."
  201. ^ self slots: aString instanceVariablesStringAsSlotList
  202. !
  203. name
  204. ^ self instanceClass name, ' class'
  205. !
  206. package
  207. ^ self instanceClass package
  208. !
  209. slots: aCollection
  210. ClassBuilder new
  211. class: self slots: aCollection.
  212. ^ self
  213. !
  214. subclasses
  215. ^ Smalltalk core metaSubclasses: self
  216. !
  217. theMetaClass
  218. ^ self
  219. !
  220. theNonMetaClass
  221. ^ self instanceClass
  222. !
  223. uses: aTraitCompositionDescription instanceVariableNames: aString
  224. "Kept for file-in compatibility."
  225. ^ self uses: aTraitCompositionDescription slots: aString instanceVariablesStringAsSlotList
  226. !
  227. uses: aTraitCompositionDescription slots: aCollection
  228. self
  229. slots: aCollection;
  230. setTraitComposition: aTraitCompositionDescription asTraitComposition.
  231. ^ self
  232. ! !
  233. !Metaclass methodsFor: 'converting'!
  234. asJavaScriptSource
  235. ^ '$globals.', self instanceClass name, '.a$cls'
  236. ! !
  237. !Metaclass methodsFor: 'testing'!
  238. isMetaclass
  239. ^ true
  240. ! !
  241. Object subclass: #ClassBuilder
  242. slots: {}
  243. package: 'Kernel-Classes'!
  244. !ClassBuilder commentStamp!
  245. I am responsible for compiling new classes or modifying existing classes in the system.
  246. Rather than using me directly to compile a class, use `Class >> subclass:instanceVariableNames:package:`.!
  247. !ClassBuilder methodsFor: 'class definition'!
  248. addSubclassOf: aClass named: className instanceVariableNames: aCollection package: packageName
  249. | theClass thePackage |
  250. theClass := Smalltalk globals at: className.
  251. thePackage := Package named: packageName.
  252. theClass ifNotNil: [
  253. theClass package: thePackage.
  254. theClass superclass == aClass
  255. ifFalse: [ ^ self
  256. migrateClassNamed: className
  257. superclass: aClass
  258. instanceVariableNames: aCollection
  259. package: packageName ] ].
  260. ^ (self
  261. basicAddSubclassOf: aClass
  262. named: className
  263. instanceVariableNames: aCollection
  264. package: packageName) recompile; yourself
  265. !
  266. addTraitNamed: traitName package: packageName
  267. | theTrait thePackage |
  268. theTrait := Smalltalk globals at: traitName.
  269. thePackage := Package named: packageName.
  270. theTrait ifNotNil: [ ^ theTrait package: thePackage; recompile; yourself ].
  271. ^ self
  272. basicAddTraitNamed: traitName
  273. package: packageName
  274. !
  275. class: aClass slots: aCollection
  276. self basicClass: aClass instanceVariables: aCollection.
  277. SystemAnnouncer current
  278. announce: (ClassDefinitionChanged new
  279. theClass: aClass;
  280. yourself)
  281. !
  282. javaScriptSubclassOf: javaScriptClass
  283. <inlineJS: '
  284. var subclass = function () {};
  285. subclass.prototype = Object.create(javaScriptClass.prototype);
  286. return subclass;'>
  287. !
  288. superclass: aClass subclass: className
  289. ^ self superclass: aClass subclass: className slots: #() package: nil
  290. !
  291. superclass: aClass subclass: className slots: aCollection package: packageName
  292. | newClass |
  293. newClass := self addSubclassOf: aClass
  294. named: className instanceVariableNames: aCollection
  295. package: (packageName ifNil: [ 'unclassified' ]).
  296. SystemAnnouncer current
  297. announce: (ClassAdded new
  298. theClass: newClass;
  299. yourself).
  300. ^ newClass
  301. ! !
  302. !ClassBuilder methodsFor: 'class migration'!
  303. migrateClass: aClass superclass: anotherClass
  304. ^ self
  305. migrateClassNamed: aClass name
  306. superclass: anotherClass
  307. instanceVariableNames: aClass instanceVariableNames
  308. package: aClass package name
  309. !
  310. migrateClassNamed: className superclass: aClass instanceVariableNames: aCollection package: packageName
  311. | oldClass newClass tmp |
  312. tmp := 'new*', className.
  313. oldClass := Smalltalk globals at: className.
  314. newClass := self
  315. addSubclassOf: aClass
  316. named: tmp
  317. instanceVariableNames: aCollection
  318. package: packageName.
  319. self basicSwapClassNames: oldClass with: newClass.
  320. [ self copyClass: oldClass to: newClass ]
  321. on: Error
  322. do: [ :exception |
  323. self
  324. basicSwapClassNames: oldClass with: newClass;
  325. basicRemoveClass: newClass.
  326. exception pass ].
  327. self
  328. rawRenameClass: oldClass to: tmp;
  329. rawRenameClass: newClass to: className.
  330. oldClass subclasses
  331. do: [ :each | self migrateClass: each superclass: newClass ].
  332. self basicRemoveClass: oldClass.
  333. SystemAnnouncer current announce: (ClassMigrated new
  334. theClass: newClass;
  335. oldClass: oldClass;
  336. yourself).
  337. ^ newClass
  338. !
  339. renameClass: aClass to: className
  340. self basicRenameClass: aClass to: className.
  341. "Recompile the class to fix potential issues with super sends"
  342. aClass recompile.
  343. SystemAnnouncer current
  344. announce: (ClassRenamed new
  345. theClass: aClass;
  346. yourself)
  347. ! !
  348. !ClassBuilder methodsFor: 'copying'!
  349. copyClass: aClass named: className
  350. | newClass |
  351. newClass := self
  352. addSubclassOf: aClass superclass
  353. named: className
  354. instanceVariableNames: aClass instanceVariableNames
  355. package: aClass package name.
  356. self copyClass: aClass to: newClass.
  357. SystemAnnouncer current
  358. announce: (ClassAdded new
  359. theClass: newClass;
  360. yourself).
  361. ^ newClass
  362. !
  363. copyClass: aClass to: anotherClass
  364. anotherClass comment: aClass comment.
  365. aClass methodDictionary valuesDo: [ :each |
  366. each origin = aClass ifTrue: [
  367. Compiler new install: each source forClass: anotherClass protocol: each protocol ] ].
  368. anotherClass setTraitComposition: aClass traitComposition.
  369. self basicClass: anotherClass class instanceVariables: aClass class instanceVariableNames.
  370. aClass class methodDictionary valuesDo: [ :each |
  371. each origin = aClass class ifTrue: [
  372. Compiler new install: each source forClass: anotherClass class protocol: each protocol ] ].
  373. anotherClass class setTraitComposition: aClass class traitComposition
  374. ! !
  375. !ClassBuilder methodsFor: 'private'!
  376. basicAddSubclassOf: aClass named: aString instanceVariableNames: aCollection package: packageName
  377. <inlineJS: '
  378. return $core.addClass(aString, aClass, aCollection, packageName);
  379. '>
  380. !
  381. basicAddTraitNamed: aString package: anotherString
  382. <inlineJS: 'return $core.addTrait(aString, anotherString)'>
  383. !
  384. basicClass: aClass instanceVariables: aCollection
  385. aClass isMetaclass ifFalse: [ self error: aClass name, ' is not a metaclass' ].
  386. Smalltalk core setSlots: aClass to: aCollection
  387. !
  388. basicRemoveClass: aClass
  389. <inlineJS: '$core.removeClass(aClass)'>
  390. !
  391. basicRenameClass: aClass to: aString
  392. <inlineJS: '
  393. $globals[aString] = aClass;
  394. delete $globals[aClass.name];
  395. aClass.name = aString;
  396. '>
  397. !
  398. basicSwapClassNames: aClass with: anotherClass
  399. <inlineJS: '
  400. var tmp = aClass.name;
  401. aClass.name = anotherClass.name;
  402. anotherClass.name = tmp;
  403. '>
  404. !
  405. rawRenameClass: aClass to: aString
  406. <inlineJS: '
  407. $globals[aString] = aClass;
  408. '>
  409. ! !
  410. !ClassBuilder class methodsFor: 'as yet unclassified'!
  411. sortClasses: aCollection
  412. | root members |
  413. root := {nil. {}}.
  414. members := HashedCollection new.
  415. aCollection do: [ :each | members at: each name put: {each. {}} ].
  416. (aCollection asArray sorted: [ :a :b | a name <= b name ]) do: [ :each |
  417. | target |
  418. target := members
  419. at: (each superclass ifNotNil: [ :superklass | superklass name ])
  420. ifAbsent: [ root ].
  421. target second add: (members at: each name) ].
  422. ^ root second
  423. ! !
  424. Trait named: #TBehaviorDefaults
  425. package: 'Kernel-Classes'!
  426. !TBehaviorDefaults methodsFor: 'accessing'!
  427. allInstanceVariableNames
  428. "Default for non-classes; to be able to send #allInstanceVariableNames to any class / trait."
  429. ^ #()
  430. !
  431. name
  432. ^ nil
  433. !
  434. superclass
  435. "Default for non-classes; to be able to send #superclass to any class / trait."
  436. ^ nil
  437. !
  438. traitUsers
  439. "Default for non-traits; to be able to send #traitUsers to any class / trait"
  440. ^ #()
  441. ! !
  442. !TBehaviorDefaults methodsFor: 'enumerating'!
  443. allSubclassesDo: aBlock
  444. "Default for non-classes; to be able to send #allSubclassesDo: to any class / trait."
  445. !
  446. includingPossibleMetaDo: aBlock
  447. "Default for non-classes."
  448. aBlock value: self
  449. ! !
  450. !TBehaviorDefaults methodsFor: 'printing'!
  451. printOn: aStream
  452. self name
  453. ifNil: [ super printOn: aStream ]
  454. ifNotNil: [ :name | aStream nextPutAll: name ]
  455. ! !
  456. Trait named: #TBehaviorProvider
  457. package: 'Kernel-Classes'!
  458. !TBehaviorProvider commentStamp!
  459. I have method dictionary and organization.!
  460. !TBehaviorProvider methodsFor: 'accessing'!
  461. >> aString
  462. ^ self methodAt: aString
  463. !
  464. methodAt: aString
  465. ^ self methodDictionary at: aString
  466. !
  467. methodDictionary
  468. <inlineJS: 'var dict = $globals.HashedCollection._new();
  469. var methods = self.methods;
  470. Object.keys(methods).forEach(function(i) {
  471. if(methods[i].selector) {
  472. dict._at_put_(methods[i].selector, methods[i]);
  473. }
  474. });
  475. return dict'>
  476. !
  477. methodOrganizationEnter: aMethod andLeave: oldMethod
  478. aMethod ifNotNil: [
  479. self organization addElement: aMethod protocol ].
  480. oldMethod ifNotNil: [
  481. self removeProtocolIfEmpty: oldMethod protocol ]
  482. !
  483. methodTemplate
  484. ^ String streamContents: [ :stream | stream
  485. write: 'messageSelectorAndArgumentNames'; lf;
  486. tab; write: '"comment stating purpose of message"'; lf;
  487. lf;
  488. tab; write: '| temporary variable names |'; lf;
  489. tab; write: 'statements' ]
  490. !
  491. methods
  492. ^ self methodDictionary values
  493. !
  494. methodsInProtocol: aString
  495. ^ self methods select: [ :each | each protocol = aString ]
  496. !
  497. organization
  498. ^ self basicOrganization ifNil: [
  499. self basicOrganization: (ClassOrganizer on: self).
  500. self basicOrganization ]
  501. !
  502. ownMethods
  503. "Answer the methods of the receiver that are not package extensions
  504. nor obtained via trait composition"
  505. ^ (self ownProtocols
  506. inject: OrderedCollection new
  507. into: [ :acc :each | acc, (self ownMethodsInProtocol: each) ])
  508. sorted: [ :a :b | a selector <= b selector ]
  509. !
  510. ownMethodsInProtocol: aString
  511. ^ (self methodsInProtocol: aString) select: [ :each | each origin = self ]
  512. !
  513. ownProtocols
  514. "Answer the protocols of the receiver that are not package extensions"
  515. ^ self protocols reject: [ :each |
  516. each match: '^\*' ]
  517. !
  518. packageOfProtocol: aString
  519. "Answer the package the method of receiver belongs to:
  520. - if it is an extension method, answer the corresponding package
  521. - else answer the receiver's package"
  522. (aString beginsWith: '*') ifFalse: [
  523. ^ self package ].
  524. ^ Package
  525. named: aString allButFirst
  526. ifAbsent: [ nil ]
  527. !
  528. protocols
  529. ^ self organization elements asArray sorted
  530. !
  531. removeProtocolIfEmpty: aString
  532. self methods
  533. detect: [ :each | each protocol = aString ]
  534. ifNone: [ self organization removeElement: aString ]
  535. !
  536. selectors
  537. ^ self methodDictionary keys
  538. !
  539. traitComposition
  540. ^ (self basicAt: 'traitComposition')
  541. ifNil: [ #() ]
  542. ifNotNil: [ :aCollection | aCollection collect: [ :each | TraitTransformation fromJSON: each ] ]
  543. !
  544. traitCompositionDefinition
  545. ^ self traitComposition ifNotEmpty: [ :traitComposition |
  546. String streamContents: [ :str |
  547. str write: '{'.
  548. traitComposition
  549. do: [ :each | str write: each definition ]
  550. separatedBy: [ str write: '. ' ].
  551. str write: '}' ] ]
  552. ! !
  553. !TBehaviorProvider methodsFor: 'compiling'!
  554. addCompiledMethod: aMethod
  555. | oldMethod announcement |
  556. oldMethod := self methodDictionary
  557. at: aMethod selector
  558. ifAbsent: [ nil ].
  559. self basicAddCompiledMethod: aMethod.
  560. announcement := oldMethod
  561. ifNil: [
  562. MethodAdded new
  563. method: aMethod;
  564. yourself ]
  565. ifNotNil: [
  566. MethodModified new
  567. oldMethod: oldMethod;
  568. method: aMethod;
  569. yourself ].
  570. SystemAnnouncer current
  571. announce: announcement
  572. !
  573. compile: aString protocol: anotherString
  574. ^ Compiler new
  575. install: aString
  576. forClass: self
  577. protocol: anotherString
  578. !
  579. recompile
  580. ^ Compiler new recompile: self
  581. !
  582. removeCompiledMethod: aMethod
  583. self basicRemoveCompiledMethod: aMethod.
  584. SystemAnnouncer current
  585. announce: (MethodRemoved new
  586. method: aMethod;
  587. yourself)
  588. !
  589. setTraitComposition: aTraitComposition
  590. <inlineJS: '$core.setTraitComposition(aTraitComposition._asJavaScriptObject(), self)'>
  591. ! !
  592. !TBehaviorProvider methodsFor: 'enumerating'!
  593. protocolsDo: aBlock
  594. "Execute aBlock for each method protocol with
  595. its collection of methods in the sort order of protocol name."
  596. | methodsByProtocol |
  597. methodsByProtocol := HashedCollection new.
  598. self methodDictionary valuesDo: [ :m |
  599. (methodsByProtocol at: m protocol ifAbsentPut: [ Array new ])
  600. add: m ].
  601. self protocols do: [ :protocol |
  602. aBlock value: protocol value: (methodsByProtocol at: protocol) ]
  603. ! !
  604. !TBehaviorProvider methodsFor: 'private'!
  605. basicAddCompiledMethod: aMethod
  606. <inlineJS: '$core.addMethod(aMethod, self)'>
  607. !
  608. basicRemoveCompiledMethod: aMethod
  609. <inlineJS: '$core.removeMethod(aMethod,self)'>
  610. ! !
  611. !TBehaviorProvider methodsFor: 'testing'!
  612. includesSelector: aString
  613. ^ self methodDictionary includesKey: aString
  614. ! !
  615. Trait named: #TMasterBehavior
  616. package: 'Kernel-Classes'!
  617. !TMasterBehavior commentStamp!
  618. I am the behavior on the instance-side of the browser.
  619. I define things like package, category, name, comment etc.
  620. as opposed to derived behaviors (metaclass, class trait, ...)
  621. that relate to me.!
  622. !TMasterBehavior methodsFor: 'accessing'!
  623. category
  624. ^ self package ifNil: [ 'Unclassified' ] ifNotNil: [ self package name ]
  625. !
  626. classTag
  627. "Every master behavior should define a class tag."
  628. ^ self subclassResponsibility
  629. !
  630. comment
  631. ^ (self basicAt: 'comment') ifNil: [ '' ]
  632. !
  633. comment: aString
  634. self basicAt: 'comment' put: aString.
  635. SystemAnnouncer current
  636. announce: (ClassCommentChanged new
  637. theClass: self;
  638. yourself)
  639. !
  640. definedMethods
  641. "Answers methods of me and derived 'meta' part if present"
  642. | methods |
  643. methods := self methods.
  644. self theMetaClass
  645. ifNil: [ ^ methods ]
  646. ifNotNil: [ :meta | ^ methods, meta methods ]
  647. !
  648. enterOrganization
  649. Smalltalk ifNotNil: [
  650. (self basicAt: 'category')
  651. ifNil: [ self basicPackage: nil ]
  652. ifNotNil: [ :category |
  653. "Amber has 1-1 correspondence between cat and pkg, atm"
  654. self basicPackage: (Package named: category).
  655. self package organization addElement: self ] ]
  656. !
  657. leaveOrganization
  658. Smalltalk ifNotNil: [
  659. self package organization removeElement: self ]
  660. !
  661. name
  662. <inlineJS: 'return self.name'>
  663. !
  664. package: aPackage
  665. | oldPackage |
  666. self package = aPackage ifTrue: [ ^ self ].
  667. oldPackage := self package.
  668. self
  669. leaveOrganization;
  670. basicAt: 'category' put: aPackage name;
  671. enterOrganization.
  672. SystemAnnouncer current announce: (ClassMoved new
  673. theClass: self;
  674. oldPackage: oldPackage;
  675. yourself)
  676. !
  677. theNonMetaClass
  678. ^ self
  679. ! !
  680. !TMasterBehavior methodsFor: 'browsing'!
  681. browse
  682. Finder findClass: self
  683. ! !
  684. !TMasterBehavior methodsFor: 'converting'!
  685. asJavaScriptSource
  686. ^ '$globals.', self name
  687. ! !
  688. Object subclass: #Trait
  689. slots: {#organization. #package. #traitUsers}
  690. package: 'Kernel-Classes'!
  691. !Trait methodsFor: 'accessing'!
  692. basicOrganization
  693. ^ organization
  694. !
  695. basicOrganization: aClassOrganizer
  696. organization := aClassOrganizer
  697. !
  698. basicPackage: aPackage
  699. package := aPackage
  700. !
  701. classTag
  702. ^ 'trait'
  703. !
  704. definition
  705. ^ String streamContents: [ :stream | stream
  706. write: 'Trait named: '; printSymbol: self name; lf;
  707. write: (self traitCompositionDefinition ifNotEmpty: [ :tcd | { String tab. 'uses: '. tcd. String lf }]);
  708. tab; write: 'package: '; print: self category ]
  709. !
  710. package
  711. ^ package
  712. !
  713. theMetaClass
  714. ^ nil
  715. !
  716. traitUsers
  717. ^ traitUsers copy
  718. ! !
  719. !Trait methodsFor: 'composition'!
  720. - anArray
  721. ^ self asTraitTransformation - anArray
  722. !
  723. @ anArrayOfAssociations
  724. ^ self asTraitTransformation @ anArrayOfAssociations
  725. ! !
  726. !Trait methodsFor: 'converting'!
  727. asTraitComposition
  728. ^ self asTraitTransformation asTraitComposition
  729. !
  730. asTraitTransformation
  731. ^ TraitTransformation on: self
  732. ! !
  733. !Trait class methodsFor: 'instance creation'!
  734. named: aString package: anotherString
  735. ^ ClassBuilder new addTraitNamed: aString package: anotherString
  736. !
  737. named: aString uses: aTraitCompositionDescription package: anotherString
  738. | trait |
  739. trait := self named: aString package: anotherString.
  740. trait setTraitComposition: aTraitCompositionDescription asTraitComposition.
  741. ^ trait
  742. ! !
  743. Object subclass: #TraitTransformation
  744. slots: {#trait. #aliases. #exclusions}
  745. package: 'Kernel-Classes'!
  746. !TraitTransformation commentStamp!
  747. I am a single step in trait composition.
  748. I represent one trait including its aliases and exclusions.!
  749. !TraitTransformation methodsFor: 'accessing'!
  750. addAliases: anArrayOfAssociations
  751. anArrayOfAssociations do: [ :each |
  752. | key |
  753. key := each key.
  754. aliases at: key
  755. ifPresent: [ self error: 'Cannot use same alias name twice.' ]
  756. ifAbsent: [ aliases at: key put: each value ] ].
  757. ^ anArrayOfAssociations
  758. !
  759. addExclusions: anArray
  760. exclusions addAll: anArray.
  761. ^ anArray
  762. !
  763. aliases
  764. ^ aliases
  765. !
  766. definition
  767. ^ String streamContents: [ :str |
  768. str print: self trait.
  769. self aliases ifNotEmpty: [ :al |
  770. str write: ' @ {'.
  771. al associations
  772. do: [ :each | str printSymbol: each key; write: ' -> '; printSymbol: each value ]
  773. separatedBy: [ str write: '. ' ].
  774. str write: '}' ].
  775. self exclusions ifNotEmpty: [ :ex |
  776. str write: ' - #('.
  777. ex asArray sorted
  778. do: [ :each | str write: each symbolPrintString allButFirst ]
  779. separatedBy: [ str space ].
  780. str write: ')' ] ]
  781. !
  782. exclusions
  783. ^ exclusions
  784. !
  785. trait
  786. ^ trait
  787. !
  788. trait: anObject
  789. trait := anObject
  790. ! !
  791. !TraitTransformation methodsFor: 'composition'!
  792. - anArray
  793. ^ self copy addExclusions: anArray; yourself
  794. !
  795. @ anArrayOfAssociations
  796. ^ self copy addAliases: anArrayOfAssociations; yourself
  797. ! !
  798. !TraitTransformation methodsFor: 'converting'!
  799. asJavaScriptObject
  800. ^ #{
  801. 'trait' -> self trait.
  802. 'aliases' -> self aliases.
  803. 'exclusions' -> self exclusions asArray sorted }
  804. !
  805. asJavaScriptSource
  806. ^ String streamContents: [ :str | str write: {
  807. '{trait: '. self trait asJavaScriptSource.
  808. self aliases ifNotEmpty: [ :al |
  809. {', aliases: '. al asJSONString} ].
  810. self exclusions ifNotEmpty: [ :ex |
  811. {', exclusions: '. ex asArray sorted asJavaScriptSource} ].
  812. '}' } ]
  813. !
  814. asTraitComposition
  815. ^ { self }
  816. !
  817. asTraitTransformation
  818. ^ self
  819. ! !
  820. !TraitTransformation methodsFor: 'copying'!
  821. postCopy
  822. aliases := aliases copy.
  823. exclusions := exclusions copy
  824. ! !
  825. !TraitTransformation methodsFor: 'initialization'!
  826. initialize
  827. super initialize.
  828. aliases := #{}.
  829. exclusions := Set new.
  830. trait := nil
  831. ! !
  832. !TraitTransformation class methodsFor: 'instance creation'!
  833. fromJSON: aJSObject
  834. ^ super new
  835. trait: (aJSObject at: #trait);
  836. addAliases: (Smalltalk readJSObject: (aJSObject at: #aliases ifAbsent: [#{}])) associations;
  837. addExclusions: (aJSObject at: #exclusions ifAbsent: [#()]);
  838. yourself
  839. !
  840. on: aTrait
  841. ^ super new trait: aTrait; yourself
  842. ! !
  843. Behavior setTraitComposition: {TBehaviorDefaults. TBehaviorProvider} asTraitComposition!
  844. Class setTraitComposition: {TMasterBehavior. TSubclassable} asTraitComposition!
  845. Trait setTraitComposition: {TBehaviorDefaults. TBehaviorProvider. TMasterBehavior} asTraitComposition!
  846. ! !
  847. !Array methodsFor: '*Kernel-Classes'!
  848. asTraitComposition
  849. "not implemented yet, noop atm"
  850. ^ self collect: [ :each | each asTraitTransformation ]
  851. ! !
  852. !String methodsFor: '*Kernel-Classes'!
  853. instanceVariablesStringAsSlotList
  854. ^ (self tokenize: ' ') reject: [ :each | each isEmpty ]
  855. ! !