Kernel-Classes.st 24 KB

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