Kernel-Classes.st 25 KB

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