Kernel-Classes.st 28 KB

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