Kernel-Classes.st 28 KB

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