Kernel-Classes.st 24 KB

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