Kernel-Classes.st 25 KB

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