Kernel-Objects.st 36 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949
  1. Smalltalk current createPackage: 'Kernel-Objects'!
  2. nil subclass: #Object
  3. instanceVariableNames: ''
  4. package: 'Kernel-Objects'!
  5. !Object commentStamp!
  6. **I am the root of the Smalltalk class system**. All classes in the system are subclasses of me.
  7. I provide default behavior common to all normal objects, such as:
  8. - accessing
  9. - copying
  10. - comparison
  11. - error handling
  12. - message sending
  13. - reflection
  14. Also utility messages that all objects should respond to are defined here.
  15. I have no instance variable.
  16. ##Access
  17. Instance variables can be accessed with `#instVarAt:` and `#instVarAt:put:`. `#instanceVariableNames` answers a collection of all instance variable names.
  18. Accessing JavaScript properties of an object is done through `#basicAt:`, `#basicAt:put:` and `basicDelete:`.
  19. ##Copying
  20. Copying an object is handled by `#copy` and `#deepCopy`. The first one performs a shallow copy of the receiver, while the second one performs a deep copy.
  21. The hook method `#postCopy` can be overriden in subclasses to copy fields as necessary to complete the full copy. It will be sent by the copy of the receiver.
  22. ##Comparison
  23. I understand equality `#=` and identity `#==` comparison.
  24. ##Error handling
  25. - `#halt` is the typical message to use for inserting breakpoints during debugging.
  26. - `#error:` throws a generic error exception
  27. - `#doesNotUnderstand:` handles the fact that there was an attempt to send the given message to the receiver but the receiver does not understand this message.
  28. Overriding this message can be useful to implement proxies for example.!
  29. !Object methodsFor: 'accessing'!
  30. basicAt: aString
  31. <return self[aString]>
  32. !
  33. basicAt: aString put: anObject
  34. <return self[aString] = anObject>
  35. !
  36. basicDelete: aString
  37. <delete self[aString]; return aString>
  38. !
  39. class
  40. <return self.klass>
  41. !
  42. identityHash
  43. <
  44. var hash=self.identityHash;
  45. if (hash) return hash;
  46. hash=smalltalk.nextId();
  47. Object.defineProperty(self, 'identityHash', {value:hash});
  48. return hash;
  49. >
  50. !
  51. instVarAt: aString
  52. < return self['@'+aString] >
  53. !
  54. instVarAt: aString put: anObject
  55. < self['@' + aString] = anObject >
  56. !
  57. size
  58. self error: 'Object not indexable'
  59. !
  60. value
  61. <return self.valueOf()>
  62. !
  63. yourself
  64. ^self
  65. ! !
  66. !Object methodsFor: 'comparing'!
  67. = anObject
  68. ^self == anObject
  69. !
  70. == anObject
  71. ^self identityHash = anObject identityHash
  72. !
  73. ~= anObject
  74. ^(self = anObject) = false
  75. !
  76. ~~ anObject
  77. ^(self == anObject) = false
  78. ! !
  79. !Object methodsFor: 'converting'!
  80. -> anObject
  81. ^Association key: self value: anObject
  82. !
  83. asJSON
  84. | variables |
  85. variables := HashedCollection new.
  86. self class allInstanceVariableNames do: [:each |
  87. variables at: each put: (self instVarAt: each) asJSON].
  88. ^variables
  89. !
  90. asJSONString
  91. ^JSON stringify: self asJSON
  92. !
  93. asJavascript
  94. ^self asString
  95. !
  96. asString
  97. ^self printString
  98. !
  99. test
  100. | a |
  101. a := 1.
  102. self halt
  103. ! !
  104. !Object methodsFor: 'copying'!
  105. copy
  106. ^self shallowCopy postCopy
  107. !
  108. deepCopy
  109. <
  110. var copy = self.klass._new();
  111. for(var i in self) {
  112. if(/^@.+/.test(i)) {
  113. copy[i] = self[i]._deepCopy();
  114. }
  115. }
  116. return copy;
  117. >
  118. !
  119. postCopy
  120. !
  121. shallowCopy
  122. <
  123. var copy = self.klass._new();
  124. for(var i in self) {
  125. if(/^@.+/.test(i)) {
  126. copy[i] = self[i];
  127. }
  128. }
  129. return copy;
  130. >
  131. ! !
  132. !Object methodsFor: 'error handling'!
  133. deprecatedAPI
  134. "Just a simple way to deprecate methods.
  135. #deprecatedAPI is in the 'error handling' protocol even if it doesn't throw an error,
  136. but it could in the future."
  137. console warn: thisContext home asString, ' is deprecated!! (in ', thisContext home home asString, ')'
  138. !
  139. doesNotUnderstand: aMessage
  140. MessageNotUnderstood new
  141. receiver: self;
  142. message: aMessage;
  143. signal
  144. !
  145. error: aString
  146. Error signal: aString
  147. !
  148. halt
  149. self error: 'Halt encountered'
  150. !
  151. shouldNotImplement
  152. self error: 'This method should not be implemented in ', self class name
  153. !
  154. subclassResponsibility
  155. self error: 'This method is a responsibility of a subclass'
  156. !
  157. throw: anObject
  158. < throw anObject >
  159. !
  160. try: aBlock catch: anotherBlock
  161. <try{return aBlock()} catch(e) {return anotherBlock(e)}>
  162. ! !
  163. !Object methodsFor: 'initialization'!
  164. initialize
  165. ! !
  166. !Object methodsFor: 'message handling'!
  167. basicPerform: aString
  168. ^self basicPerform: aString withArguments: #()
  169. !
  170. basicPerform: aString withArguments: aCollection
  171. <return self[aString].apply(self, aCollection);>
  172. !
  173. perform: aString
  174. ^self perform: aString withArguments: #()
  175. !
  176. perform: aString withArguments: aCollection
  177. <return smalltalk.send(self, aString._asSelector(), aCollection)>
  178. ! !
  179. !Object methodsFor: 'printing'!
  180. printOn: aStream
  181. "Append to the aStream, a string representing the receiver."
  182. aStream nextPutAll: (self class name first isVowel
  183. ifTrue: [ 'an ' ]
  184. ifFalse: [ 'a ' ]).
  185. aStream nextPutAll: self class name
  186. !
  187. printString
  188. "Answer a String representation of the receiver."
  189. ^ String streamContents: [ :stream | self printOn: stream ]
  190. ! !
  191. !Object methodsFor: 'streaming'!
  192. putOn: aStream
  193. aStream nextPut: self
  194. ! !
  195. !Object methodsFor: 'testing'!
  196. ifNil: aBlock
  197. "inlined in the Compiler"
  198. ^self
  199. !
  200. ifNil: aBlock ifNotNil: anotherBlock
  201. "inlined in the Compiler"
  202. ^anotherBlock value: self
  203. !
  204. ifNotNil: aBlock
  205. "inlined in the Compiler"
  206. ^aBlock value: self
  207. !
  208. ifNotNil: aBlock ifNil: anotherBlock
  209. "inlined in the Compiler"
  210. ^aBlock value: self
  211. !
  212. isBehavior
  213. ^ false
  214. !
  215. isBoolean
  216. ^ false
  217. !
  218. isClass
  219. ^false
  220. !
  221. isCompiledMethod
  222. ^ false
  223. !
  224. isImmutable
  225. ^ false
  226. !
  227. isKindOf: aClass
  228. ^(self isMemberOf: aClass)
  229. ifTrue: [true]
  230. ifFalse: [self class inheritsFrom: aClass]
  231. !
  232. isMemberOf: aClass
  233. ^self class = aClass
  234. !
  235. isMetaclass
  236. ^false
  237. !
  238. isNil
  239. ^false
  240. !
  241. isNumber
  242. ^false
  243. !
  244. isPackage
  245. ^ false
  246. !
  247. isParseFailure
  248. ^false
  249. !
  250. isString
  251. ^false
  252. !
  253. isSymbol
  254. ^false
  255. !
  256. notNil
  257. ^self isNil not
  258. !
  259. respondsTo: aSelector
  260. ^self class canUnderstand: aSelector
  261. ! !
  262. !Object class methodsFor: 'initialization'!
  263. initialize
  264. "no op"
  265. ! !
  266. Object subclass: #Boolean
  267. instanceVariableNames: ''
  268. package: 'Kernel-Objects'!
  269. !Boolean commentStamp!
  270. I define the protocol for logic testing operations and conditional control structures for the logical values (see the `controlling` protocol).
  271. I have two instances, `true` and `false`.
  272. I am directly mapped to JavaScript Boolean. The `true` and `false` objects are the JavaScript boolean objects.
  273. ## Usage Example:
  274. aBoolean not ifTrue: [ ... ] ifFalse: [ ... ]!
  275. !Boolean methodsFor: 'comparing'!
  276. = aBoolean
  277. <
  278. if(!! aBoolean._isBoolean || !! aBoolean._isBoolean()) {
  279. return false;
  280. }
  281. return Boolean(self == true) == aBoolean
  282. >
  283. !
  284. == aBoolean
  285. ^self = aBoolean
  286. ! !
  287. !Boolean methodsFor: 'controlling'!
  288. & aBoolean
  289. <
  290. if(self == true) {
  291. return aBoolean;
  292. } else {
  293. return false;
  294. }
  295. >
  296. !
  297. and: aBlock
  298. ^self = true
  299. ifTrue: aBlock
  300. ifFalse: [false]
  301. !
  302. ifFalse: aBlock
  303. "inlined in the Compiler"
  304. ^self ifTrue: [] ifFalse: aBlock
  305. !
  306. ifFalse: aBlock ifTrue: anotherBlock
  307. "inlined in the Compiler"
  308. ^self ifTrue: anotherBlock ifFalse: aBlock
  309. !
  310. ifTrue: aBlock
  311. "inlined in the Compiler"
  312. ^self ifTrue: aBlock ifFalse: []
  313. !
  314. ifTrue: aBlock ifFalse: anotherBlock
  315. "inlined in the Compiler"
  316. <
  317. if(self == true) {
  318. return aBlock();
  319. } else {
  320. return anotherBlock();
  321. }
  322. >
  323. !
  324. not
  325. ^self = false
  326. !
  327. or: aBlock
  328. ^self = true
  329. ifTrue: [true]
  330. ifFalse: aBlock
  331. !
  332. | aBoolean
  333. <
  334. if(self == true) {
  335. return true;
  336. } else {
  337. return aBoolean;
  338. }
  339. >
  340. ! !
  341. !Boolean methodsFor: 'converting'!
  342. asJSON
  343. ^self
  344. !
  345. asString
  346. < return self.toString() >
  347. ! !
  348. !Boolean methodsFor: 'copying'!
  349. deepCopy
  350. ^self
  351. !
  352. shallowCopy
  353. ^self
  354. ! !
  355. !Boolean methodsFor: 'printing'!
  356. printOn: aStream
  357. aStream nextPutAll: self asString
  358. ! !
  359. !Boolean methodsFor: 'testing'!
  360. isBoolean
  361. ^ true
  362. !
  363. isImmutable
  364. ^ true
  365. ! !
  366. Object subclass: #Date
  367. instanceVariableNames: ''
  368. package: 'Kernel-Objects'!
  369. !Date commentStamp!
  370. I am used to work with both dates and times. Therefore `Date today` and `Date now` are both valid in
  371. Amber and answer the same date object.
  372. Date directly maps to the `Date()` JavaScript constructor, and Amber date objects are JavaScript date objects.
  373. ## API
  374. The class-side `instance creation` protocol contains some convenience methods for creating date/time objects such as `#fromSeconds:`.
  375. Arithmetic and comparison is supported (see the `comparing` and `arithmetic` protocols).
  376. The `converting` protocol provides convenience methods for various convertions (to numbers, strings, etc.).!
  377. !Date methodsFor: 'accessing'!
  378. day
  379. ^self dayOfWeek
  380. !
  381. day: aNumber
  382. self dayOfWeek: aNumber
  383. !
  384. dayOfMonth
  385. <return self.getDate()>
  386. !
  387. dayOfMonth: aNumber
  388. <self.setDate(aNumber)>
  389. !
  390. dayOfWeek
  391. <return self.getDay() + 1>
  392. !
  393. dayOfWeek: aNumber
  394. <return self.setDay(aNumber - 1)>
  395. !
  396. hours
  397. <return self.getHours()>
  398. !
  399. hours: aNumber
  400. <self.setHours(aNumber)>
  401. !
  402. milliseconds
  403. <return self.getMilliseconds()>
  404. !
  405. milliseconds: aNumber
  406. <self.setMilliseconds(aNumber)>
  407. !
  408. minutes
  409. <return self.getMinutes()>
  410. !
  411. minutes: aNumber
  412. <self.setMinutes(aNumber)>
  413. !
  414. month
  415. <return self.getMonth() + 1>
  416. !
  417. month: aNumber
  418. <self.setMonth(aNumber - 1)>
  419. !
  420. seconds
  421. <return self.getSeconds()>
  422. !
  423. seconds: aNumber
  424. <self.setSeconds(aNumber)>
  425. !
  426. time
  427. <return self.getTime()>
  428. !
  429. time: aNumber
  430. <self.setTime(aNumber)>
  431. !
  432. year
  433. <return self.getFullYear()>
  434. !
  435. year: aNumber
  436. <self.setFullYear(aNumber)>
  437. ! !
  438. !Date methodsFor: 'arithmetic'!
  439. + aDate
  440. <return self + aDate>
  441. !
  442. - aDate
  443. <return self - aDate>
  444. ! !
  445. !Date methodsFor: 'comparing'!
  446. < aDate
  447. <return self < aDate>
  448. !
  449. <= aDate
  450. <return self <= aDate>
  451. !
  452. > aDate
  453. <return self >> aDate>
  454. !
  455. >= aDate
  456. <return self >>= aDate>
  457. ! !
  458. !Date methodsFor: 'converting'!
  459. asDateString
  460. <return self.toDateString()>
  461. !
  462. asLocaleString
  463. <return self.toLocaleString()>
  464. !
  465. asMilliseconds
  466. ^self time
  467. !
  468. asNumber
  469. ^self asMilliseconds
  470. !
  471. asString
  472. <return self.toString()>
  473. !
  474. asTimeString
  475. <return self.toTimeString()>
  476. ! !
  477. !Date methodsFor: 'printing'!
  478. printOn: aStream
  479. aStream nextPutAll: self asString
  480. ! !
  481. !Date class methodsFor: 'instance creation'!
  482. fromMilliseconds: aNumber
  483. ^self new: aNumber
  484. !
  485. fromSeconds: aNumber
  486. ^self fromMilliseconds: aNumber * 1000
  487. !
  488. fromString: aString
  489. "Example: Date fromString('2011/04/15 00:00:00')"
  490. ^self new: aString
  491. !
  492. millisecondsToRun: aBlock
  493. | t |
  494. t := Date now.
  495. aBlock value.
  496. ^Date now - t
  497. !
  498. new: anObject
  499. <return new Date(anObject)>
  500. !
  501. now
  502. ^self today
  503. !
  504. today
  505. ^self new
  506. ! !
  507. Object subclass: #Environment
  508. instanceVariableNames: ''
  509. package: 'Kernel-Objects'!
  510. !Environment commentStamp!
  511. I provide an unified entry point to manipulate Amber packages, classes and methods.
  512. Typical use cases include IDEs, remote access and restricting browsing.!
  513. !Environment methodsFor: 'accessing'!
  514. allSelectors
  515. ^ (Smalltalk current at: 'allSelectors') value
  516. !
  517. availableClassNames
  518. ^ Smalltalk current classes
  519. collect: [ :each | each name ]
  520. !
  521. availablePackageNames
  522. ^ Smalltalk current packages
  523. collect: [ :each | each name ]
  524. !
  525. availableProtocolsFor: aClass
  526. | protocols |
  527. protocols := aClass protocols.
  528. aClass superclass ifNotNil: [ protocols addAll: (self availableProtocolsFor: aClass superclass) ].
  529. ^ protocols asSet asArray
  530. !
  531. classBuilder
  532. ^ ClassBuilder new
  533. !
  534. classNamed: aString
  535. ^ (Smalltalk current at: aString asSymbol)
  536. ifNil: [ self error: 'Invalid class name' ]
  537. !
  538. classes
  539. ^ Smalltalk current classes
  540. !
  541. packages
  542. ^ Smalltalk current packages
  543. !
  544. systemAnnouncer
  545. ^ (Smalltalk current at: #SystemAnnouncer) current
  546. ! !
  547. !Environment methodsFor: 'actions'!
  548. commitPackage: aPackage
  549. aPackage commit
  550. !
  551. copyClass: aClass to: aClassName
  552. (Smalltalk current at: aClassName)
  553. ifNotNil: [ self error: 'A class named ', aClassName, ' already exists' ].
  554. ClassBuilder new copyClass: aClass named: aClassName
  555. !
  556. eval: aString on: aReceiver
  557. | compiler |
  558. compiler := Compiler new.
  559. [ compiler parseExpression: aString ] on: Error do: [ :ex |
  560. ^ window alert: ex messageText ].
  561. ^ compiler evaluateExpression: aString on: aReceiver
  562. !
  563. moveClass: aClass toPackage: aPackageName
  564. | package |
  565. package := Package named: aPackageName.
  566. package ifNil: [ self error: 'Invalid package name' ].
  567. package == aClass package ifTrue: [ ^ self ].
  568. aClass package: package
  569. !
  570. moveMethod: aMethod toClass: aClassName
  571. | destinationClass |
  572. destinationClass := Smalltalk current at: aClassName asSymbol.
  573. destinationClass ifNil: [ self error: 'Invalid class name' ].
  574. destinationClass == aMethod methodClass ifTrue: [ ^ self ].
  575. destinationClass
  576. compile: aMethod source
  577. category: aMethod protocol.
  578. aMethod methodClass
  579. removeCompiledMethod: aMethod
  580. !
  581. moveMethod: aMethod toProtocol: aProtocol
  582. aMethod category: aProtocol
  583. !
  584. removeClass: aClass
  585. Smalltalk current removeClass: aClass
  586. !
  587. removeMethod: aMethod
  588. aMethod methodClass removeCompiledMethod: aMethod
  589. !
  590. removeProtocol: aString from: aClass
  591. (aClass methods
  592. select: [ :each | each protocol = aString ])
  593. do: [ :each | aClass removeCompiledMethod: each ]
  594. !
  595. renameClass: aClass to: aClassName
  596. (Smalltalk current at: aClassName)
  597. ifNotNil: [ self error: 'A class named ', aClassName, ' already exists' ].
  598. ClassBuilder new renameClass: aClass to: aClassName
  599. !
  600. renameProtocol: aString to: anotherString in: aClass
  601. (aClass methods
  602. select: [ :each | each protocol = aString ])
  603. do: [ :each | each protocol: anotherString ]
  604. !
  605. setClassCommentOf: aClass to: aString
  606. aClass comment: aString
  607. ! !
  608. !Environment methodsFor: 'compiling'!
  609. addInstVarNamed: aString to: aClass
  610. self classBuilder
  611. addSubclassOf: aClass superclass
  612. named: aClass name
  613. instanceVariableNames: (aClass instanceVariableNames copy add: aString; yourself)
  614. package: aClass package name
  615. !
  616. compileClassComment: aString for: aClass
  617. aClass comment: aString
  618. !
  619. compileClassDefinition: aString
  620. self eval: aString on: DoIt new
  621. !
  622. compileMethod: sourceCode for: class protocol: protocol
  623. ^ class
  624. compile: sourceCode
  625. category: protocol
  626. ! !
  627. Object subclass: #JSObjectProxy
  628. instanceVariableNames: 'jsObject'
  629. package: 'Kernel-Objects'!
  630. !JSObjectProxy commentStamp!
  631. I handle sending messages to JavaScript objects, making JavaScript object accessing from Amber fully transparent.
  632. My instances make intensive use of `#doesNotUnderstand:`.
  633. My instances are automatically created by Amber whenever a message is sent to a JavaScript object.
  634. ## Usage examples
  635. JSObjectProxy objects are instanciated by Amber when a Smalltalk message is sent to a JavaScript object.
  636. window alert: 'hello world'.
  637. window inspect.
  638. (window jQuery: 'body') append: 'hello world'
  639. Amber messages sends are converted to JavaScript function calls or object property access _(in this order)_. If n one of them match, a `MessageNotUnderstood` error will be thrown.
  640. ## Message conversion rules
  641. - `someUser name` becomes `someUser.name`
  642. - `someUser name: 'John'` becomes `someUser name = "John"`
  643. - `console log: 'hello world'` becomes `console.log('hello world')`
  644. - `(window jQuery: 'foo') css: 'background' color: 'red'` becomes `window.jQuery('foo').css('background', 'red')`
  645. __Note:__ For keyword-based messages, only the first keyword is kept: `window foo: 1 bar: 2` is equivalent to `window foo: 1 baz: 2`.!
  646. !JSObjectProxy methodsFor: 'accessing'!
  647. at: aString
  648. <return self['@jsObject'][aString]>
  649. !
  650. at: aString ifAbsent: aBlock
  651. "return the aString property or evaluate aBlock if the property is not defined on the object"
  652. <
  653. var obj = self['@jsObject'];
  654. return aString in obj ? obj[aString] : aBlock();
  655. >
  656. !
  657. at: aString ifPresent: aBlock
  658. "return the evaluation of aBlock with the value if the property is defined or return nil"
  659. <
  660. var obj = self['@jsObject'];
  661. return aString in obj ? aBlock(obj[aString]) : nil;
  662. >
  663. !
  664. at: aString ifPresent: aBlock ifAbsent: anotherBlock
  665. "return the evaluation of aBlock with the value if the property is defined
  666. or return value of anotherBlock"
  667. <
  668. var obj = self['@jsObject'];
  669. return aString in obj ? aBlock(obj[aString]) : anotherBlock();
  670. >
  671. !
  672. at: aString put: anObject
  673. <self['@jsObject'][aString] = anObject>
  674. !
  675. jsObject
  676. ^jsObject
  677. !
  678. jsObject: aJSObject
  679. jsObject := aJSObject
  680. !
  681. lookupProperty: aString
  682. "Looks up a property in JS object.
  683. Answer the property if it is present, or nil if it is not present."
  684. <return aString in self._jsObject() ? aString : nil>
  685. !
  686. value
  687. "if attribute 'value' exists on the JS object return it,
  688. otherwise return the result of Object>>value."
  689. ^ self
  690. at: 'value'
  691. ifAbsent: [ super value ]
  692. ! !
  693. !JSObjectProxy methodsFor: 'enumerating'!
  694. keysAndValuesDo: aBlock
  695. <
  696. var o = self['@jsObject'];
  697. for(var i in o) {
  698. aBlock(i, o[i]);
  699. }
  700. >
  701. ! !
  702. !JSObjectProxy methodsFor: 'printing'!
  703. printOn: aStream
  704. aStream nextPutAll: self jsObject toString
  705. ! !
  706. !JSObjectProxy methodsFor: 'proxy'!
  707. addObjectVariablesTo: aDictionary
  708. <
  709. for(var i in self['@jsObject']) {
  710. aDictionary._at_put_(i, self['@jsObject'][i]);
  711. }
  712. >
  713. !
  714. doesNotUnderstand: aMessage
  715. ^ (self lookupProperty: aMessage selector asJavaScriptSelector)
  716. ifNil: [ super doesNotUnderstand: aMessage ]
  717. ifNotNil: [ :jsSelector |
  718. self
  719. forwardMessage: jsSelector
  720. withArguments: aMessage arguments ]
  721. !
  722. forwardMessage: aString withArguments: anArray
  723. <
  724. return smalltalk.send(self._jsObject(), aString, anArray);
  725. >
  726. !
  727. inspectOn: anInspector
  728. | variables |
  729. variables := Dictionary new.
  730. variables at: '#self' put: self jsObject.
  731. anInspector setLabel: self printString.
  732. self addObjectVariablesTo: variables.
  733. anInspector setVariables: variables
  734. ! !
  735. !JSObjectProxy class methodsFor: 'instance creation'!
  736. on: aJSObject
  737. ^self new
  738. jsObject: aJSObject;
  739. yourself
  740. ! !
  741. Object subclass: #Number
  742. instanceVariableNames: ''
  743. package: 'Kernel-Objects'!
  744. !Number commentStamp!
  745. I am the Amber representation for all numbers.
  746. I am directly mapped to JavaScript Number.
  747. ## API
  748. I provide all necessary methods for arithmetic operations, comparison, conversion and so on with numbers.
  749. My instances can also be used to evaluate a block a fixed number of times:
  750. 5 timesRepeat: [Transcript show: 'This will be printed 5 times'; cr].
  751. 1 to: 5 do: [:aNumber| Transcript show: aNumber asString; cr].
  752. 1 to: 10 by: 2 do: [:aNumber| Transcript show: aNumber asString; cr].!
  753. !Number methodsFor: 'accessing'!
  754. identityHash
  755. ^self asString, 'n'
  756. ! !
  757. !Number methodsFor: 'arithmetic'!
  758. * aNumber
  759. "Inlined in the Compiler"
  760. <return self * aNumber>
  761. !
  762. + aNumber
  763. "Inlined in the Compiler"
  764. <return self + aNumber>
  765. !
  766. - aNumber
  767. "Inlined in the Compiler"
  768. <return self - aNumber>
  769. !
  770. / aNumber
  771. "Inlined in the Compiler"
  772. <return self / aNumber>
  773. !
  774. \\ aNumber
  775. <return self % aNumber>
  776. !
  777. abs
  778. <return Math.abs(self);>
  779. !
  780. max: aNumber
  781. <return Math.max(self, aNumber);>
  782. !
  783. min: aNumber
  784. <return Math.min(self, aNumber);>
  785. !
  786. negated
  787. ^0 - self
  788. !
  789. sqrt
  790. <return Math.sqrt(self)>
  791. !
  792. squared
  793. ^self * self
  794. ! !
  795. !Number methodsFor: 'comparing'!
  796. < aNumber
  797. "Inlined in the Compiler"
  798. <return self < aNumber>
  799. !
  800. <= aNumber
  801. "Inlined in the Compiler"
  802. <return self <= aNumber>
  803. !
  804. = aNumber
  805. <
  806. if(!! aNumber._isNumber || !! aNumber._isNumber()) {
  807. return false;
  808. }
  809. return Number(self) == aNumber
  810. >
  811. !
  812. > aNumber
  813. "Inlined in the Compiler"
  814. <return self >> aNumber>
  815. !
  816. >= aNumber
  817. "Inlined in the Compiler"
  818. <return self >>= aNumber>
  819. ! !
  820. !Number methodsFor: 'converting'!
  821. & aNumber
  822. <return self & aNumber>
  823. !
  824. @ aNumber
  825. ^Point x: self y: aNumber
  826. !
  827. asJSON
  828. ^self
  829. !
  830. asJavascript
  831. ^'(', self printString, ')'
  832. !
  833. asPoint
  834. ^Point x: self y: self
  835. !
  836. asString
  837. < return String(self) >
  838. !
  839. atRandom
  840. ^(Random new next * self) truncated + 1
  841. !
  842. rounded
  843. <return Math.round(self);>
  844. !
  845. to: aNumber
  846. | array first last count |
  847. first := self truncated.
  848. last := aNumber truncated + 1.
  849. count := 1.
  850. array := Array new.
  851. (last - first) timesRepeat: [
  852. array at: count put: first.
  853. count := count + 1.
  854. first := first + 1].
  855. ^array
  856. !
  857. to: stop by: step
  858. | array value pos |
  859. value := self.
  860. array := Array new.
  861. pos := 1.
  862. step = 0 ifTrue: [self error: 'step must be non-zero'].
  863. step < 0
  864. ifTrue: [[ value >= stop ] whileTrue: [
  865. array at: pos put: value.
  866. pos := pos + 1.
  867. value := value + step]]
  868. ifFalse: [[ value <= stop ] whileTrue: [
  869. array at: pos put: value.
  870. pos := pos + 1.
  871. value := value + step]].
  872. ^array
  873. !
  874. truncated
  875. <
  876. if(self >>= 0) {
  877. return Math.floor(self);
  878. } else {
  879. return Math.floor(self * (-1)) * (-1);
  880. };
  881. >
  882. !
  883. | aNumber
  884. <return self | aNumber>
  885. ! !
  886. !Number methodsFor: 'copying'!
  887. copy
  888. ^self
  889. !
  890. deepCopy
  891. ^self copy
  892. ! !
  893. !Number methodsFor: 'enumerating'!
  894. timesRepeat: aBlock
  895. | count |
  896. count := 1.
  897. [count > self] whileFalse: [
  898. aBlock value.
  899. count := count + 1]
  900. !
  901. to: stop by: step do: aBlock
  902. | value |
  903. value := self.
  904. step = 0 ifTrue: [self error: 'step must be non-zero'].
  905. step < 0
  906. ifTrue: [[ value >= stop ] whileTrue: [
  907. aBlock value: value.
  908. value := value + step]]
  909. ifFalse: [[ value <= stop ] whileTrue: [
  910. aBlock value: value.
  911. value := value + step]]
  912. !
  913. to: stop do: aBlock
  914. "Evaluate aBlock for each number from self to aNumber."
  915. | nextValue |
  916. nextValue := self.
  917. [nextValue <= stop]
  918. whileTrue:
  919. [aBlock value: nextValue.
  920. nextValue := nextValue + 1]
  921. ! !
  922. !Number methodsFor: 'printing'!
  923. printOn: aStream
  924. aStream nextPutAll: self asString
  925. !
  926. printShowingDecimalPlaces: placesDesired
  927. <return self.toFixed(placesDesired)>
  928. ! !
  929. !Number methodsFor: 'testing'!
  930. even
  931. ^ 0 = (self \\ 2)
  932. !
  933. isImmutable
  934. ^ true
  935. !
  936. isNumber
  937. ^true
  938. !
  939. isZero
  940. ^self = 0
  941. !
  942. negative
  943. "Answer whether the receiver is mathematically negative."
  944. ^ self < 0
  945. !
  946. odd
  947. ^ self even not
  948. !
  949. positive
  950. "Answer whether the receiver is positive or equal to 0. (ST-80 protocol)."
  951. ^ self >= 0
  952. ! !
  953. !Number class methodsFor: 'instance creation'!
  954. pi
  955. <return Math.PI>
  956. ! !
  957. Object subclass: #Organizer
  958. instanceVariableNames: ''
  959. package: 'Kernel-Objects'!
  960. !Organizer commentStamp!
  961. I represent categorization information.
  962. ## API
  963. Use `#addElement:` and `#removeElement:` to manipulate instances.!
  964. !Organizer methodsFor: 'accessing'!
  965. addElement: anObject
  966. <self.elements.addElement(anObject)>
  967. !
  968. elements
  969. ^ (self basicAt: 'elements') copy
  970. !
  971. removeElement: anObject
  972. <self.elements.removeElement(anObject)>
  973. ! !
  974. Organizer subclass: #ClassOrganizer
  975. instanceVariableNames: ''
  976. package: 'Kernel-Objects'!
  977. !ClassOrganizer commentStamp!
  978. I am an organizer specific to classes. I hold method categorization information for classes.!
  979. !ClassOrganizer methodsFor: 'accessing'!
  980. addElement: aString
  981. super addElement: aString.
  982. SystemAnnouncer current announce: (ProtocolAdded new
  983. protocol: aString;
  984. theClass: self theClass;
  985. yourself)
  986. !
  987. removeElement: aString
  988. super removeElement: aString.
  989. SystemAnnouncer current announce: (ProtocolRemoved new
  990. protocol: aString;
  991. theClass: self theClass;
  992. yourself)
  993. !
  994. theClass
  995. < return self.theClass >
  996. ! !
  997. Organizer subclass: #PackageOrganizer
  998. instanceVariableNames: ''
  999. package: 'Kernel-Objects'!
  1000. !PackageOrganizer commentStamp!
  1001. I am an organizer specific to packages. I hold classes categorization information.!
  1002. Object subclass: #Package
  1003. instanceVariableNames: 'commitPathJs commitPathSt'
  1004. package: 'Kernel-Objects'!
  1005. !Package commentStamp!
  1006. I am similar to a "class category" typically found in other Smalltalks like Pharo or Squeak. Amber does not have class categories anymore, it had in the beginning but now each class in the system knows which package it belongs to.
  1007. Each package has a name and can be queried for its classes, but it will then resort to a reverse scan of all classes to find them.
  1008. ## API
  1009. Packages are manipulated through "Smalltalk current", like for example finding one based on a name or with `Package class >> #name` directly:
  1010. Smalltalk current packageAt: 'Kernel'
  1011. Package named: 'Kernel'
  1012. A package differs slightly from a Monticello package which can span multiple class categories using a naming convention based on hyphenation. But just as in Monticello a package supports "class extensions" so a package can define behaviors in foreign classes using a naming convention for method categories where the category starts with an asterisk and then the name of the owning package follows.
  1013. You can fetch a package from the server:
  1014. Package load: 'Additional-Examples'!
  1015. !Package methodsFor: 'accessing'!
  1016. commitPathJs
  1017. ^ commitPathJs ifNil: [self class defaultCommitPathJs]
  1018. !
  1019. commitPathJs: aString
  1020. commitPathJs := aString
  1021. !
  1022. commitPathSt
  1023. ^ commitPathSt ifNil: [self class defaultCommitPathSt]
  1024. !
  1025. commitPathSt: aString
  1026. commitPathSt := aString
  1027. !
  1028. name
  1029. <return self.pkgName>
  1030. !
  1031. name: aString
  1032. <self.pkgName = aString>
  1033. !
  1034. organization
  1035. ^ self basicAt: 'organization'
  1036. ! !
  1037. !Package methodsFor: 'classes'!
  1038. classes
  1039. ^ self organization elements
  1040. !
  1041. setupClasses
  1042. self classes
  1043. do: [ :each | ClassBuilder new setupClass: each ];
  1044. do: [ :each | each initialize ]
  1045. !
  1046. sortedClasses
  1047. "Answer all classes in the receiver, sorted by superclass/subclasses and by class name for common subclasses (Issue #143)."
  1048. ^self class sortedClasses: self classes
  1049. ! !
  1050. !Package methodsFor: 'printing'!
  1051. printOn: aStream
  1052. super printOn: aStream.
  1053. aStream
  1054. nextPutAll: ' (';
  1055. nextPutAll: self name;
  1056. nextPutAll: ')'
  1057. ! !
  1058. !Package methodsFor: 'testing'!
  1059. isPackage
  1060. ^ true
  1061. ! !
  1062. Package class instanceVariableNames: 'defaultCommitPathJs defaultCommitPathSt'!
  1063. !Package class methodsFor: 'accessing'!
  1064. named: aPackageName
  1065. ^Smalltalk current packageAt: aPackageName
  1066. !
  1067. named: aPackageName ifAbsent: aBlock
  1068. ^Smalltalk current packageAt: aPackageName ifAbsent: aBlock
  1069. ! !
  1070. !Package class methodsFor: 'commit paths'!
  1071. commitPathsFromLoader
  1072. <
  1073. var commitPath = typeof amber !!== 'undefined' && amber.commitPath;
  1074. if (!!commitPath) return;
  1075. if (commitPath.js) self._defaultCommitPathJs_(commitPath.js);
  1076. if (commitPath.st) self._defaultCommitPathSt_(commitPath.st);
  1077. >
  1078. !
  1079. defaultCommitPathJs
  1080. ^ defaultCommitPathJs ifNil: [ defaultCommitPathJs := 'js']
  1081. !
  1082. defaultCommitPathJs: aString
  1083. defaultCommitPathJs := aString
  1084. !
  1085. defaultCommitPathSt
  1086. ^ defaultCommitPathSt ifNil: [ defaultCommitPathSt := 'st']
  1087. !
  1088. defaultCommitPathSt: aString
  1089. defaultCommitPathSt := aString
  1090. !
  1091. resetCommitPaths
  1092. defaultCommitPathJs := nil.
  1093. defaultCommitPathSt := nil.
  1094. ! !
  1095. !Package class methodsFor: 'initialization'!
  1096. initialize
  1097. super initialize.
  1098. self commitPathsFromLoader
  1099. ! !
  1100. !Package class methodsFor: 'loading-storing'!
  1101. load: aPackageName
  1102. self load: aPackageName prefix: self defaultCommitPathJs, '/'
  1103. !
  1104. load: aPackageName prefix: aPrefix
  1105. jQuery
  1106. getScript: (aPrefix , aPackageName , '.js')
  1107. onSuccess: [
  1108. (Package named: aPackageName) setupClasses ]
  1109. ! !
  1110. !Package class methodsFor: 'sorting'!
  1111. sortedClasses: classes
  1112. "Answer classes, sorted by superclass/subclasses and by class name for common subclasses (Issue #143)"
  1113. | children others nodes expandedClasses |
  1114. children := #().
  1115. others := #().
  1116. classes do: [:each |
  1117. (classes includes: each superclass)
  1118. ifFalse: [children add: each]
  1119. ifTrue: [others add: each]].
  1120. nodes := children collect: [:each |
  1121. ClassSorterNode on: each classes: others level: 0].
  1122. nodes := nodes sorted: [:a :b | a theClass name <= b theClass name ].
  1123. expandedClasses := Array new.
  1124. nodes do: [:aNode |
  1125. aNode traverseClassesWith: expandedClasses].
  1126. ^expandedClasses
  1127. ! !
  1128. Object subclass: #Point
  1129. instanceVariableNames: 'x y'
  1130. package: 'Kernel-Objects'!
  1131. !Point commentStamp!
  1132. I represent an x-y pair of numbers usually designating a geometric coordinate.
  1133. ## API
  1134. Instances are traditionally created using the binary `#@` message to a number:
  1135. 100@120
  1136. Points can then be arithmetically manipulated:
  1137. 100@100 + (10@10)
  1138. ...or for example:
  1139. (100@100) * 2
  1140. **NOTE:** Creating a point with a negative y-value will need a space after `@` in order to avoid a parsing error:
  1141. 100@ -100 "but 100@-100 would not parse"!
  1142. !Point methodsFor: 'accessing'!
  1143. x
  1144. ^x
  1145. !
  1146. x: aNumber
  1147. x := aNumber
  1148. !
  1149. y
  1150. ^y
  1151. !
  1152. y: aNumber
  1153. y := aNumber
  1154. ! !
  1155. !Point methodsFor: 'arithmetic'!
  1156. * aPoint
  1157. ^Point x: self x * aPoint asPoint x y: self y * aPoint asPoint y
  1158. !
  1159. + aPoint
  1160. ^Point x: self x + aPoint asPoint x y: self y + aPoint asPoint y
  1161. !
  1162. - aPoint
  1163. ^Point x: self x - aPoint asPoint x y: self y - aPoint asPoint y
  1164. !
  1165. / aPoint
  1166. ^Point x: self x / aPoint asPoint x y: self y / aPoint asPoint y
  1167. !
  1168. = aPoint
  1169. ^aPoint class = self class and: [
  1170. (aPoint x = self x) & (aPoint y = self y)]
  1171. ! !
  1172. !Point methodsFor: 'converting'!
  1173. asPoint
  1174. ^self
  1175. ! !
  1176. !Point methodsFor: 'printing'!
  1177. printOn: aStream
  1178. "Print receiver in classic x@y notation."
  1179. x printOn: aStream.
  1180. aStream nextPutAll: '@'.
  1181. (y notNil and: [y negative]) ifTrue: [
  1182. "Avoid ambiguous @- construct"
  1183. aStream space ].
  1184. y printOn: aStream
  1185. ! !
  1186. !Point methodsFor: 'transforming'!
  1187. translateBy: delta
  1188. "Answer a Point translated by delta (an instance of Point)."
  1189. ^(delta x + x) @ (delta y + y)
  1190. ! !
  1191. !Point class methodsFor: 'instance creation'!
  1192. x: aNumber y: anotherNumber
  1193. ^self new
  1194. x: aNumber;
  1195. y: anotherNumber;
  1196. yourself
  1197. ! !
  1198. Object subclass: #Random
  1199. instanceVariableNames: ''
  1200. package: 'Kernel-Objects'!
  1201. !Random commentStamp!
  1202. I an used to generate a random number and I am implemented as a trivial wrapper around javascript `Math.random()`.
  1203. ## API
  1204. The typical use case it to use the `#next` method like the following:
  1205. Random new next
  1206. This will return a float x where x < 1 and x > 0. If you want a random integer from 1 to 10 you can use `#atRandom`
  1207. 10 atRandom
  1208. A random number in a specific interval can be obtained with the following:
  1209. (3 to: 7) atRandom
  1210. Be aware that `#to:` does not create an Interval as in other Smalltalk implementations but in fact an `Array` of numbers, so it's better to use:
  1211. 5 atRandom + 2
  1212. Since `#atRandom` is implemented in `SequencableCollection` you can easy pick an element at random:
  1213. #('a' 'b' 'c') atRandom
  1214. As well as letter from a `String`:
  1215. 'abc' atRandom
  1216. Since Amber does not have Characters this will return a `String` of length 1 like for example `'b'`.!
  1217. !Random methodsFor: 'accessing'!
  1218. next
  1219. <return Math.random()>
  1220. !
  1221. next: anInteger
  1222. ^(1 to: anInteger) collect: [:each | self next]
  1223. ! !
  1224. Object subclass: #Smalltalk
  1225. instanceVariableNames: ''
  1226. package: 'Kernel-Objects'!
  1227. !Smalltalk commentStamp!
  1228. I represent the global JavaScript variable `smalltalk` declared in `js/boot.js`.
  1229. ## API
  1230. I have only one instance, accessed with class-side method `#current`.
  1231. The `smalltalk` object holds all class and packages defined in the system.
  1232. ## Classes
  1233. Classes can be accessed using the following methods:
  1234. - `#classes` answers the full list of Smalltalk classes in the system
  1235. - `#at:` answers a specific class of `nil`
  1236. ## Packages
  1237. Packages can be accessed using the following methods:
  1238. - `#packages` answers the full list of packages
  1239. - `#packageAt:` answers a specific class of `nil`
  1240. __note:__ classes and packages are accessed using strings, not symbols
  1241. ## Parsing
  1242. The `#parse:` method is used to parse Amber source code.
  1243. It requires the `Compiler` package and the `js/parser.js` parser file in order to work!
  1244. !Smalltalk methodsFor: 'accessing'!
  1245. at: aString
  1246. <return self[aString]>
  1247. !
  1248. parse: aString
  1249. | result |
  1250. self try: [result := self basicParse: aString] catch: [:ex | (self parseError: ex parsing: aString) signal].
  1251. ^result
  1252. !
  1253. readJSObject: anObject
  1254. <return self.readJSObject(anObject)>
  1255. !
  1256. reservedWords
  1257. "JavaScript reserved words"
  1258. <return self.reservedWords>
  1259. !
  1260. version
  1261. "Answer the version string of Amber"
  1262. ^ '0.10'
  1263. ! !
  1264. !Smalltalk methodsFor: 'classes'!
  1265. classes
  1266. <return self.classes()>
  1267. !
  1268. deleteClass: aClass
  1269. "Deletes a class by deleting its binding only. Use #removeClass instead"
  1270. <self.removeClass(aClass)>
  1271. !
  1272. removeClass: aClass
  1273. aClass isMetaclass ifTrue: [self error: aClass asString, ' is a Metaclass and cannot be removed!!'].
  1274. self deleteClass: aClass.
  1275. SystemAnnouncer current
  1276. announce: (ClassRemoved new
  1277. theClass: aClass;
  1278. yourself)
  1279. ! !
  1280. !Smalltalk methodsFor: 'error handling'!
  1281. asSmalltalkException: anObject
  1282. "A JavaScript exception may be thrown.
  1283. We then need to convert it back to a Smalltalk object"
  1284. ^ ((self isSmalltalkObject: anObject) and: [ anObject isKindOf: Error ])
  1285. ifTrue: [ anObject ]
  1286. ifFalse: [ JavaScriptException on: anObject ]
  1287. !
  1288. parseError: anException parsing: aString
  1289. ^ ParseError new messageText: 'Parse error on line ', (anException basicAt: 'line') ,' column ' , (anException basicAt: 'column') ,' : Unexpected character ', (anException basicAt: 'found')
  1290. ! !
  1291. !Smalltalk methodsFor: 'packages'!
  1292. createPackage: packageName
  1293. "Create and bind a new package with given name and return it."
  1294. <return smalltalk.addPackage(packageName)>
  1295. !
  1296. deletePackage: packageName
  1297. "Deletes a package by deleting its binding, but does not check if it contains classes etc.
  1298. To remove a package, use #removePackage instead."
  1299. <delete smalltalk.packages[packageName]>
  1300. !
  1301. packageAt: packageName
  1302. <return self.packages[packageName]>
  1303. !
  1304. packageAt: packageName ifAbsent: aBlock
  1305. ^(self packageAt: packageName) ifNil: aBlock
  1306. !
  1307. packages
  1308. "Return all Package instances in the system."
  1309. <return self.packages.all()>
  1310. !
  1311. pseudoVariableNames
  1312. ^ #('self' 'super' 'nil' 'true' 'false' 'thisContext')
  1313. !
  1314. removePackage: packageName
  1315. "Removes a package and all its classes."
  1316. | pkg |
  1317. pkg := self packageAt: packageName ifAbsent: [self error: 'Missing package: ', packageName].
  1318. pkg classes do: [:each |
  1319. self removeClass: each].
  1320. self deletePackage: packageName
  1321. !
  1322. renamePackage: packageName to: newName
  1323. "Rename a package."
  1324. | pkg |
  1325. pkg := self packageAt: packageName ifAbsent: [self error: 'Missing package: ', packageName].
  1326. (self packageAt: newName) ifNotNil: [self error: 'Already exists a package called: ', newName].
  1327. (self basicAt: 'packages') at: newName put: pkg.
  1328. pkg name: newName.
  1329. self deletePackage: packageName.
  1330. ! !
  1331. !Smalltalk methodsFor: 'private'!
  1332. basicParse: aString
  1333. <return smalltalk.parser.parse(aString)>
  1334. !
  1335. createPackage: packageName properties: aDict
  1336. "Needed to import .st files: they begin with this call."
  1337. self deprecatedAPI.
  1338. aDict isEmpty ifFalse: [ self error: 'createPackage:properties: called with nonempty properties' ].
  1339. ^ self createPackage: packageName
  1340. ! !
  1341. !Smalltalk methodsFor: 'testing'!
  1342. isSmalltalkObject: anObject
  1343. "Consider anObject a Smalltalk object if it has a 'klass' property.
  1344. Note that this may be unaccurate"
  1345. <return typeof anObject.klass !!== 'undefined'>
  1346. ! !
  1347. Smalltalk class instanceVariableNames: 'current'!
  1348. !Smalltalk class methodsFor: 'accessing'!
  1349. current
  1350. <return smalltalk>
  1351. ! !
  1352. Object subclass: #Timeout
  1353. instanceVariableNames: 'rawTimeout'
  1354. package: 'Kernel-Objects'!
  1355. !Timeout commentStamp!
  1356. I am wrapping the returns from `set{Timeout,Interval}`.
  1357. ## Motivation
  1358. Number suffices in browsers, but node.js returns an object.!
  1359. !Timeout methodsFor: 'accessing'!
  1360. rawTimeout: anObject
  1361. rawTimeout := anObject
  1362. ! !
  1363. !Timeout methodsFor: 'timeout/interval'!
  1364. clearInterval
  1365. <
  1366. var interval = self["@rawTimeout"];
  1367. clearInterval(interval);
  1368. >
  1369. !
  1370. clearTimeout
  1371. <
  1372. var timeout = self["@rawTimeout"];
  1373. clearTimeout(timeout);
  1374. >
  1375. ! !
  1376. !Timeout class methodsFor: 'instance creation'!
  1377. on: anObject
  1378. ^self new rawTimeout: anObject; yourself
  1379. ! !
  1380. Object subclass: #UndefinedObject
  1381. instanceVariableNames: ''
  1382. package: 'Kernel-Objects'!
  1383. !UndefinedObject commentStamp!
  1384. I describe the behavior of my sole instance, `nil`. `nil` represents a prior value for variables that have not been initialized, or for results which are meaningless.
  1385. `nil` is the Smalltalk equivalent of the `undefined` JavaScript object.
  1386. __note:__ When sending messages to the `undefined` JavaScript object, it will be replaced by `nil`.!
  1387. !UndefinedObject methodsFor: 'class creation'!
  1388. subclass: aString instanceVariableNames: anotherString
  1389. ^self subclass: aString instanceVariableNames: anotherString package: nil
  1390. !
  1391. subclass: aString instanceVariableNames: aString2 category: aString3
  1392. "Kept for compatibility."
  1393. self deprecatedAPI.
  1394. ^self subclass: aString instanceVariableNames: aString2 package: aString3
  1395. !
  1396. subclass: aString instanceVariableNames: aString2 package: aString3
  1397. ^ClassBuilder new
  1398. superclass: self subclass: aString asString instanceVariableNames: aString2 package: aString3
  1399. ! !
  1400. !UndefinedObject methodsFor: 'converting'!
  1401. asJSON
  1402. ^null
  1403. ! !
  1404. !UndefinedObject methodsFor: 'copying'!
  1405. deepCopy
  1406. ^self
  1407. !
  1408. shallowCopy
  1409. ^self
  1410. ! !
  1411. !UndefinedObject methodsFor: 'printing'!
  1412. printOn: aStream
  1413. aStream nextPutAll: 'nil'
  1414. ! !
  1415. !UndefinedObject methodsFor: 'testing'!
  1416. ifNil: aBlock
  1417. "inlined in the Compiler"
  1418. ^self ifNil: aBlock ifNotNil: []
  1419. !
  1420. ifNil: aBlock ifNotNil: anotherBlock
  1421. "inlined in the Compiler"
  1422. ^aBlock value
  1423. !
  1424. ifNotNil: aBlock
  1425. "inlined in the Compiler"
  1426. ^self
  1427. !
  1428. ifNotNil: aBlock ifNil: anotherBlock
  1429. "inlined in the Compiler"
  1430. ^anotherBlock value
  1431. !
  1432. isImmutable
  1433. ^ true
  1434. !
  1435. isNil
  1436. ^true
  1437. !
  1438. notNil
  1439. ^false
  1440. ! !
  1441. !UndefinedObject class methodsFor: 'instance creation'!
  1442. new
  1443. self error: 'You cannot create new instances of UndefinedObject. Use nil'
  1444. ! !
  1445. !String methodsFor: '*Kernel-Objects'!
  1446. asJavaScriptSelector
  1447. "Return first keyword of the selector, without trailing colon."
  1448. ^self replace: '^([a-zA-Z0-9]*).*$' with: '$1'
  1449. ! !