Kernel-Classes.st 28 KB

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