Kernel-Classes.st 28 KB

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