Kernel-Classes.st 24 KB

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