Kernel-Classes.st 25 KB

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