Kernel-Objects.st 41 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196
  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._value()} catch(e) {return anotherBlock._value_(e)}>
  162. ! !
  163. !Object methodsFor: 'initialization'!
  164. initialize
  165. ! !
  166. !Object methodsFor: 'inspecting'!
  167. inspect
  168. InspectorHandler inspect: self
  169. !
  170. inspectOn: anInspector
  171. | variables |
  172. variables := Dictionary new.
  173. variables at: '#self' put: self.
  174. self class allInstanceVariableNames do: [:each |
  175. variables at: each put: (self instVarAt: each)].
  176. anInspector
  177. setLabel: self printString;
  178. setVariables: variables
  179. ! !
  180. !Object methodsFor: 'message handling'!
  181. basicPerform: aString
  182. ^self basicPerform: aString withArguments: #()
  183. !
  184. basicPerform: aString withArguments: aCollection
  185. <return self[aString].apply(self, aCollection);>
  186. !
  187. perform: aString
  188. ^self perform: aString withArguments: #()
  189. !
  190. perform: aString withArguments: aCollection
  191. <return smalltalk.send(self, aString._asSelector(), aCollection)>
  192. ! !
  193. !Object methodsFor: 'printing'!
  194. printOn: aStream
  195. "Append to the aStream, a string representing the receiver."
  196. aStream nextPutAll: (self class name first isVowel
  197. ifTrue: [ 'an ' ]
  198. ifFalse: [ 'a ' ]).
  199. aStream nextPutAll: self class name
  200. !
  201. printString
  202. "Answer a String representation of the receiver."
  203. ^ String streamContents: [ :stream | self printOn: stream ]
  204. ! !
  205. !Object methodsFor: 'streaming'!
  206. putOn: aStream
  207. aStream nextPut: self
  208. ! !
  209. !Object methodsFor: 'testing'!
  210. ifNil: aBlock
  211. "inlined in the Compiler"
  212. ^self
  213. !
  214. ifNil: aBlock ifNotNil: anotherBlock
  215. "inlined in the Compiler"
  216. ^anotherBlock value: self
  217. !
  218. ifNotNil: aBlock
  219. "inlined in the Compiler"
  220. ^aBlock value: self
  221. !
  222. ifNotNil: aBlock ifNil: anotherBlock
  223. "inlined in the Compiler"
  224. ^aBlock value: self
  225. !
  226. isBehavior
  227. ^ false
  228. !
  229. isBoolean
  230. ^ false
  231. !
  232. isClass
  233. ^false
  234. !
  235. isCompiledMethod
  236. ^ false
  237. !
  238. isImmutable
  239. ^ false
  240. !
  241. isKindOf: aClass
  242. ^(self isMemberOf: aClass)
  243. ifTrue: [true]
  244. ifFalse: [self class inheritsFrom: aClass]
  245. !
  246. isMemberOf: aClass
  247. ^self class = aClass
  248. !
  249. isMetaclass
  250. ^false
  251. !
  252. isNil
  253. ^false
  254. !
  255. isNumber
  256. ^false
  257. !
  258. isPackage
  259. ^ false
  260. !
  261. isParseFailure
  262. ^false
  263. !
  264. isString
  265. ^false
  266. !
  267. isSymbol
  268. ^false
  269. !
  270. notNil
  271. ^self isNil not
  272. !
  273. respondsTo: aSelector
  274. ^self class canUnderstand: aSelector
  275. ! !
  276. !Object class methodsFor: 'helios'!
  277. heliosClass
  278. "Should be an Helios extension. Unfortunately, since helios can browse remote
  279. environments, we can't extend base classes"
  280. ^ 'class'
  281. ! !
  282. !Object class methodsFor: 'initialization'!
  283. initialize
  284. "no op"
  285. ! !
  286. Object subclass: #Boolean
  287. instanceVariableNames: ''
  288. package: 'Kernel-Objects'!
  289. !Boolean commentStamp!
  290. I define the protocol for logic testing operations and conditional control structures for the logical values (see the `controlling` protocol).
  291. I have two instances, `true` and `false`.
  292. I am directly mapped to JavaScript Boolean. The `true` and `false` objects are the JavaScript boolean objects.
  293. ## Usage Example:
  294. aBoolean not ifTrue: [ ... ] ifFalse: [ ... ]!
  295. !Boolean methodsFor: 'comparing'!
  296. = aBoolean
  297. <
  298. if(!! aBoolean._isBoolean || !! aBoolean._isBoolean()) {
  299. return false;
  300. }
  301. return Boolean(self == true) == aBoolean
  302. >
  303. !
  304. == aBoolean
  305. ^self = aBoolean
  306. ! !
  307. !Boolean methodsFor: 'controlling'!
  308. & aBoolean
  309. <
  310. if(self == true) {
  311. return aBoolean;
  312. } else {
  313. return false;
  314. }
  315. >
  316. !
  317. and: aBlock
  318. ^self = true
  319. ifTrue: aBlock
  320. ifFalse: [false]
  321. !
  322. ifFalse: aBlock
  323. "inlined in the Compiler"
  324. ^self ifTrue: [] ifFalse: aBlock
  325. !
  326. ifFalse: aBlock ifTrue: anotherBlock
  327. "inlined in the Compiler"
  328. ^self ifTrue: anotherBlock ifFalse: aBlock
  329. !
  330. ifTrue: aBlock
  331. "inlined in the Compiler"
  332. ^self ifTrue: aBlock ifFalse: []
  333. !
  334. ifTrue: aBlock ifFalse: anotherBlock
  335. "inlined in the Compiler"
  336. <
  337. if(self == true) {
  338. return aBlock._value();
  339. } else {
  340. return anotherBlock._value();
  341. }
  342. >
  343. !
  344. not
  345. ^self = false
  346. !
  347. or: aBlock
  348. ^self = true
  349. ifTrue: [true]
  350. ifFalse: aBlock
  351. !
  352. | aBoolean
  353. <
  354. if(self == true) {
  355. return true;
  356. } else {
  357. return aBoolean;
  358. }
  359. >
  360. ! !
  361. !Boolean methodsFor: 'converting'!
  362. asBit
  363. ^ self ifTrue: [ 1 ] ifFalse: [ 0 ]
  364. !
  365. asJSON
  366. ^self
  367. !
  368. asString
  369. < return self.toString() >
  370. ! !
  371. !Boolean methodsFor: 'copying'!
  372. deepCopy
  373. ^self
  374. !
  375. shallowCopy
  376. ^self
  377. ! !
  378. !Boolean methodsFor: 'printing'!
  379. printOn: aStream
  380. aStream nextPutAll: self asString
  381. ! !
  382. !Boolean methodsFor: 'testing'!
  383. isBoolean
  384. ^ true
  385. !
  386. isImmutable
  387. ^ true
  388. ! !
  389. Object subclass: #BrowserInterface
  390. instanceVariableNames: ''
  391. package: 'Kernel-Objects'!
  392. !BrowserInterface commentStamp!
  393. I am superclass of all object that interface with user or environment. `Widget` and a few other classes are subclasses of me.
  394. ## API
  395. self alert: 'Hey, there is a problem'.
  396. self confirm: 'Affirmative?'.
  397. self prompt: 'Your name:'.
  398. self ajax: #{
  399. 'url' -> '/patch.js'. 'type' -> 'GET'. dataType->'script'
  400. }.!
  401. !BrowserInterface methodsFor: 'actions'!
  402. ajax: anObject
  403. ^jQuery ajax: anObject
  404. !
  405. alert: aString
  406. ^window alert: aString
  407. !
  408. confirm: aString
  409. ^window confirm: aString
  410. !
  411. prompt: aString
  412. ^window prompt: aString
  413. ! !
  414. !BrowserInterface methodsFor: 'testing'!
  415. isAvailable
  416. <return typeof window !!== "undefined" && typeof jQuery !!== "undefined">
  417. ! !
  418. BrowserInterface class instanceVariableNames: 'uiWorker ajaxWorker'!
  419. Object subclass: #Date
  420. instanceVariableNames: ''
  421. package: 'Kernel-Objects'!
  422. !Date commentStamp!
  423. I am used to work with both dates and times. Therefore `Date today` and `Date now` are both valid in
  424. Amber and answer the same date object.
  425. Date directly maps to the `Date()` JavaScript constructor, and Amber date objects are JavaScript date objects.
  426. ## API
  427. The class-side `instance creation` protocol contains some convenience methods for creating date/time objects such as `#fromSeconds:`.
  428. Arithmetic and comparison is supported (see the `comparing` and `arithmetic` protocols).
  429. The `converting` protocol provides convenience methods for various convertions (to numbers, strings, etc.).!
  430. !Date methodsFor: 'accessing'!
  431. day
  432. ^self dayOfWeek
  433. !
  434. day: aNumber
  435. self dayOfWeek: aNumber
  436. !
  437. dayOfMonth
  438. <return self.getDate()>
  439. !
  440. dayOfMonth: aNumber
  441. <self.setDate(aNumber)>
  442. !
  443. dayOfWeek
  444. <return self.getDay() + 1>
  445. !
  446. dayOfWeek: aNumber
  447. <return self.setDay(aNumber - 1)>
  448. !
  449. hours
  450. <return self.getHours()>
  451. !
  452. hours: aNumber
  453. <self.setHours(aNumber)>
  454. !
  455. milliseconds
  456. <return self.getMilliseconds()>
  457. !
  458. milliseconds: aNumber
  459. <self.setMilliseconds(aNumber)>
  460. !
  461. minutes
  462. <return self.getMinutes()>
  463. !
  464. minutes: aNumber
  465. <self.setMinutes(aNumber)>
  466. !
  467. month
  468. <return self.getMonth() + 1>
  469. !
  470. month: aNumber
  471. <self.setMonth(aNumber - 1)>
  472. !
  473. seconds
  474. <return self.getSeconds()>
  475. !
  476. seconds: aNumber
  477. <self.setSeconds(aNumber)>
  478. !
  479. time
  480. <return self.getTime()>
  481. !
  482. time: aNumber
  483. <self.setTime(aNumber)>
  484. !
  485. year
  486. <return self.getFullYear()>
  487. !
  488. year: aNumber
  489. <self.setFullYear(aNumber)>
  490. ! !
  491. !Date methodsFor: 'arithmetic'!
  492. + aDate
  493. <return self + aDate>
  494. !
  495. - aDate
  496. <return self - aDate>
  497. ! !
  498. !Date methodsFor: 'comparing'!
  499. < aDate
  500. <return self < aDate>
  501. !
  502. <= aDate
  503. <return self <= aDate>
  504. !
  505. > aDate
  506. <return self >> aDate>
  507. !
  508. >= aDate
  509. <return self >>= aDate>
  510. ! !
  511. !Date methodsFor: 'converting'!
  512. asDateString
  513. <return self.toDateString()>
  514. !
  515. asLocaleString
  516. <return self.toLocaleString()>
  517. !
  518. asMilliseconds
  519. ^self time
  520. !
  521. asNumber
  522. ^self asMilliseconds
  523. !
  524. asString
  525. <return self.toString()>
  526. !
  527. asTimeString
  528. <return self.toTimeString()>
  529. ! !
  530. !Date methodsFor: 'printing'!
  531. printOn: aStream
  532. aStream nextPutAll: self asString
  533. ! !
  534. !Date class methodsFor: 'helios'!
  535. heliosClass
  536. ^ 'magnitude'
  537. ! !
  538. !Date class methodsFor: 'instance creation'!
  539. fromMilliseconds: aNumber
  540. ^self new: aNumber
  541. !
  542. fromSeconds: aNumber
  543. ^self fromMilliseconds: aNumber * 1000
  544. !
  545. fromString: aString
  546. "Example: Date fromString('2011/04/15 00:00:00')"
  547. ^self new: aString
  548. !
  549. millisecondsToRun: aBlock
  550. | t |
  551. t := Date now.
  552. aBlock value.
  553. ^Date now - t
  554. !
  555. new: anObject
  556. <return new Date(anObject)>
  557. !
  558. now
  559. ^self today
  560. !
  561. today
  562. ^self new
  563. ! !
  564. Object subclass: #Environment
  565. instanceVariableNames: ''
  566. package: 'Kernel-Objects'!
  567. !Environment commentStamp!
  568. I provide an unified entry point to manipulate Amber packages, classes and methods.
  569. Typical use cases include IDEs, remote access and restricting browsing.!
  570. !Environment methodsFor: 'accessing'!
  571. allSelectors
  572. ^ (Smalltalk current at: 'allSelectors') value
  573. !
  574. availableClassNames
  575. ^ Smalltalk current classes
  576. collect: [ :each | each name ]
  577. !
  578. availablePackageNames
  579. ^ Smalltalk current packages
  580. collect: [ :each | each name ]
  581. !
  582. availableProtocolsFor: aClass
  583. | protocols |
  584. protocols := aClass protocols.
  585. aClass superclass ifNotNil: [ protocols addAll: (self availableProtocolsFor: aClass superclass) ].
  586. ^ protocols asSet asArray
  587. !
  588. classBuilder
  589. ^ ClassBuilder new
  590. !
  591. classNamed: aString
  592. ^ (Smalltalk current at: aString asSymbol)
  593. ifNil: [ self error: 'Invalid class name' ]
  594. !
  595. classes
  596. ^ Smalltalk current classes
  597. !
  598. packages
  599. ^ Smalltalk current packages
  600. !
  601. systemAnnouncer
  602. ^ (Smalltalk current at: #SystemAnnouncer) current
  603. ! !
  604. !Environment methodsFor: 'actions'!
  605. commitPackage: aPackage
  606. aPackage commit
  607. !
  608. copyClass: aClass to: aClassName
  609. (Smalltalk current at: aClassName)
  610. ifNotNil: [ self error: 'A class named ', aClassName, ' already exists' ].
  611. ClassBuilder new copyClass: aClass named: aClassName
  612. !
  613. eval: aString on: aReceiver
  614. | compiler |
  615. compiler := Compiler new.
  616. [ compiler parseExpression: aString ] on: Error do: [ :ex |
  617. ^ window alert: ex messageText ].
  618. ^ compiler evaluateExpression: aString on: aReceiver
  619. !
  620. inspect: anObject
  621. InspectorHandler inspector inspect: anObject
  622. !
  623. moveClass: aClass toPackage: aPackageName
  624. | package |
  625. package := Package named: aPackageName.
  626. package ifNil: [ self error: 'Invalid package name' ].
  627. package == aClass package ifTrue: [ ^ self ].
  628. aClass package: package
  629. !
  630. moveMethod: aMethod toClass: aClassName
  631. | destinationClass |
  632. destinationClass := Smalltalk current at: aClassName asSymbol.
  633. destinationClass ifNil: [ self error: 'Invalid class name' ].
  634. destinationClass == aMethod methodClass ifTrue: [ ^ self ].
  635. destinationClass
  636. compile: aMethod source
  637. category: aMethod protocol.
  638. aMethod methodClass
  639. removeCompiledMethod: aMethod
  640. !
  641. moveMethod: aMethod toProtocol: aProtocol
  642. aMethod category: aProtocol
  643. !
  644. registerErrorHandler: anErrorHandler
  645. ErrorHandler setCurrent: anErrorHandler
  646. !
  647. registerInspector: anInspector
  648. InspectorHandler register: anInspector
  649. !
  650. registerProgressHandler: aProgressHandler
  651. ProgressHandler setCurrent: aProgressHandler
  652. !
  653. removeClass: aClass
  654. Smalltalk current removeClass: aClass
  655. !
  656. removeMethod: aMethod
  657. aMethod methodClass removeCompiledMethod: aMethod
  658. !
  659. removeProtocol: aString from: aClass
  660. (aClass methods
  661. select: [ :each | each protocol = aString ])
  662. do: [ :each | aClass removeCompiledMethod: each ]
  663. !
  664. renameClass: aClass to: aClassName
  665. (Smalltalk current at: aClassName)
  666. ifNotNil: [ self error: 'A class named ', aClassName, ' already exists' ].
  667. ClassBuilder new renameClass: aClass to: aClassName
  668. !
  669. renameProtocol: aString to: anotherString in: aClass
  670. (aClass methods
  671. select: [ :each | each protocol = aString ])
  672. do: [ :each | each protocol: anotherString ]
  673. !
  674. setClassCommentOf: aClass to: aString
  675. aClass comment: aString
  676. ! !
  677. !Environment methodsFor: 'compiling'!
  678. addInstVarNamed: aString to: aClass
  679. self classBuilder
  680. addSubclassOf: aClass superclass
  681. named: aClass name
  682. instanceVariableNames: (aClass instanceVariableNames copy add: aString; yourself)
  683. package: aClass package name
  684. !
  685. compileClassComment: aString for: aClass
  686. aClass comment: aString
  687. !
  688. compileClassDefinition: aString
  689. self eval: aString on: DoIt new
  690. !
  691. compileMethod: sourceCode for: class protocol: protocol
  692. ^ class
  693. compile: sourceCode
  694. category: protocol
  695. ! !
  696. !Environment methodsFor: 'error handling'!
  697. evaluate: aBlock on: anErrorClass do: exceptionBlock
  698. "Evaluate a block and catch exceptions happening on the environment stack"
  699. self try: aBlock catch: [ :exception |
  700. (exception isKindOf: (self classNamed: anErrorClass name))
  701. ifTrue: [ exceptionBlock value: exception ]
  702. ifFalse: [ exception signal ] ]
  703. ! !
  704. Object subclass: #InspectorHandler
  705. instanceVariableNames: ''
  706. package: 'Kernel-Objects'!
  707. !InspectorHandler commentStamp!
  708. I am responsible for inspecting object.
  709. My class-side `inspector` inst var holds the current inspector I'm delegating object inspection to.
  710. The default inspector object is the transcript.!
  711. InspectorHandler class instanceVariableNames: 'inspector'!
  712. !InspectorHandler class methodsFor: 'accessing'!
  713. inspector
  714. ^ inspector ifNil: [ inspector := Transcript ]
  715. ! !
  716. !InspectorHandler class methodsFor: 'registration'!
  717. inspect: anObject
  718. ^ self inspector inspect: anObject
  719. !
  720. register: anInspector
  721. inspector := anInspector
  722. ! !
  723. Object subclass: #InterfacingObject
  724. instanceVariableNames: ''
  725. package: 'Kernel-Objects'!
  726. !InterfacingObject commentStamp!
  727. I am superclass of all object that interface with user or environment. `Widget` and a few other classes are subclasses of me.
  728. ## API
  729. self alert: 'Hey, there is a problem'.
  730. self confirm: 'Affirmative?'.
  731. self prompt: 'Your name:'.
  732. self ajax: #{
  733. 'url' -> '/patch.js'. 'type' -> 'GET'. dataType->'script'
  734. }.!
  735. !InterfacingObject methodsFor: 'actions'!
  736. ajax: anObject
  737. ^PlatformInterface ajax: anObject
  738. !
  739. alert: aString
  740. ^PlatformInterface alert: aString
  741. !
  742. confirm: aString
  743. ^PlatformInterface confirm: aString
  744. !
  745. prompt: aString
  746. ^PlatformInterface prompt: aString
  747. ! !
  748. Object subclass: #JSObjectProxy
  749. instanceVariableNames: 'jsObject'
  750. package: 'Kernel-Objects'!
  751. !JSObjectProxy commentStamp!
  752. I handle sending messages to JavaScript objects, making JavaScript object accessing from Amber fully transparent.
  753. My instances make intensive use of `#doesNotUnderstand:`.
  754. My instances are automatically created by Amber whenever a message is sent to a JavaScript object.
  755. ## Usage examples
  756. JSObjectProxy objects are instanciated by Amber when a Smalltalk message is sent to a JavaScript object.
  757. window alert: 'hello world'.
  758. window inspect.
  759. (window jQuery: 'body') append: 'hello world'
  760. 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.
  761. ## Message conversion rules
  762. - `someUser name` becomes `someUser.name`
  763. - `someUser name: 'John'` becomes `someUser name = "John"`
  764. - `console log: 'hello world'` becomes `console.log('hello world')`
  765. - `(window jQuery: 'foo') css: 'background' color: 'red'` becomes `window.jQuery('foo').css('background', 'red')`
  766. __Note:__ For keyword-based messages, only the first keyword is kept: `window foo: 1 bar: 2` is equivalent to `window foo: 1 baz: 2`.!
  767. !JSObjectProxy methodsFor: 'accessing'!
  768. at: aString
  769. <return self['@jsObject'][aString]>
  770. !
  771. at: aString ifAbsent: aBlock
  772. "return the aString property or evaluate aBlock if the property is not defined on the object"
  773. <
  774. var obj = self['@jsObject'];
  775. return aString in obj ? obj[aString] : aBlock._value();
  776. >
  777. !
  778. at: aString ifPresent: aBlock
  779. "return the evaluation of aBlock with the value if the property is defined or return nil"
  780. <
  781. var obj = self['@jsObject'];
  782. return aString in obj ? aBlock._value_(obj[aString]) : nil;
  783. >
  784. !
  785. at: aString ifPresent: aBlock ifAbsent: anotherBlock
  786. "return the evaluation of aBlock with the value if the property is defined
  787. or return value of anotherBlock"
  788. <
  789. var obj = self['@jsObject'];
  790. return aString in obj ? aBlock._value_(obj[aString]) : anotherBlock._value();
  791. >
  792. !
  793. at: aString put: anObject
  794. <self['@jsObject'][aString] = anObject>
  795. !
  796. jsObject
  797. ^jsObject
  798. !
  799. jsObject: aJSObject
  800. jsObject := aJSObject
  801. !
  802. lookupProperty: aString
  803. "Looks up a property in JS object.
  804. Answer the property if it is present, or nil if it is not present."
  805. <return aString in self._jsObject() ? aString : nil>
  806. !
  807. value
  808. "if attribute 'value' exists on the JS object return it,
  809. otherwise return the result of Object>>value."
  810. ^ self
  811. at: 'value'
  812. ifAbsent: [ super value ]
  813. ! !
  814. !JSObjectProxy methodsFor: 'enumerating'!
  815. keysAndValuesDo: aBlock
  816. <
  817. var o = self['@jsObject'];
  818. for(var i in o) {
  819. aBlock._value_value_(i, o[i]);
  820. }
  821. >
  822. ! !
  823. !JSObjectProxy methodsFor: 'printing'!
  824. printOn: aStream
  825. aStream nextPutAll: self jsObject toString
  826. ! !
  827. !JSObjectProxy methodsFor: 'proxy'!
  828. addObjectVariablesTo: aDictionary
  829. <
  830. for(var i in self['@jsObject']) {
  831. aDictionary._at_put_(i, self['@jsObject'][i]);
  832. }
  833. >
  834. !
  835. doesNotUnderstand: aMessage
  836. ^ (self lookupProperty: aMessage selector asJavaScriptSelector)
  837. ifNil: [ super doesNotUnderstand: aMessage ]
  838. ifNotNil: [ :jsSelector |
  839. self
  840. forwardMessage: jsSelector
  841. withArguments: aMessage arguments ]
  842. !
  843. forwardMessage: aString withArguments: anArray
  844. <
  845. return smalltalk.send(self._jsObject(), aString, anArray);
  846. >
  847. !
  848. inspectOn: anInspector
  849. | variables |
  850. variables := Dictionary new.
  851. variables at: '#self' put: self jsObject.
  852. anInspector setLabel: self printString.
  853. self addObjectVariablesTo: variables.
  854. anInspector setVariables: variables
  855. ! !
  856. !JSObjectProxy class methodsFor: 'instance creation'!
  857. on: aJSObject
  858. ^self new
  859. jsObject: aJSObject;
  860. yourself
  861. ! !
  862. Object subclass: #Number
  863. instanceVariableNames: ''
  864. package: 'Kernel-Objects'!
  865. !Number commentStamp!
  866. I am the Amber representation for all numbers.
  867. I am directly mapped to JavaScript Number.
  868. ## API
  869. I provide all necessary methods for arithmetic operations, comparison, conversion and so on with numbers.
  870. My instances can also be used to evaluate a block a fixed number of times:
  871. 5 timesRepeat: [Transcript show: 'This will be printed 5 times'; cr].
  872. 1 to: 5 do: [:aNumber| Transcript show: aNumber asString; cr].
  873. 1 to: 10 by: 2 do: [:aNumber| Transcript show: aNumber asString; cr].!
  874. !Number methodsFor: 'accessing'!
  875. identityHash
  876. ^self asString, 'n'
  877. ! !
  878. !Number methodsFor: 'arithmetic'!
  879. * aNumber
  880. "Inlined in the Compiler"
  881. <return self * aNumber>
  882. !
  883. + aNumber
  884. "Inlined in the Compiler"
  885. <return self + aNumber>
  886. !
  887. - aNumber
  888. "Inlined in the Compiler"
  889. <return self - aNumber>
  890. !
  891. / aNumber
  892. "Inlined in the Compiler"
  893. <return self / aNumber>
  894. !
  895. \\ aNumber
  896. <return self % aNumber>
  897. !
  898. abs
  899. <return Math.abs(self);>
  900. !
  901. max: aNumber
  902. <return Math.max(self, aNumber);>
  903. !
  904. min: aNumber
  905. <return Math.min(self, aNumber);>
  906. !
  907. negated
  908. ^0 - self
  909. !
  910. sqrt
  911. <return Math.sqrt(self)>
  912. !
  913. squared
  914. ^self * self
  915. ! !
  916. !Number methodsFor: 'comparing'!
  917. < aNumber
  918. "Inlined in the Compiler"
  919. <return self < aNumber>
  920. !
  921. <= aNumber
  922. "Inlined in the Compiler"
  923. <return self <= aNumber>
  924. !
  925. = aNumber
  926. <
  927. if(!! aNumber._isNumber || !! aNumber._isNumber()) {
  928. return false;
  929. }
  930. return Number(self) == aNumber
  931. >
  932. !
  933. > aNumber
  934. "Inlined in the Compiler"
  935. <return self >> aNumber>
  936. !
  937. >= aNumber
  938. "Inlined in the Compiler"
  939. <return self >>= aNumber>
  940. ! !
  941. !Number methodsFor: 'converting'!
  942. & aNumber
  943. <return self & aNumber>
  944. !
  945. @ aNumber
  946. ^Point x: self y: aNumber
  947. !
  948. asJSON
  949. ^self
  950. !
  951. asJavascript
  952. ^'(', self printString, ')'
  953. !
  954. asPoint
  955. ^Point x: self y: self
  956. !
  957. asString
  958. < return String(self) >
  959. !
  960. atRandom
  961. ^(Random new next * self) truncated + 1
  962. !
  963. rounded
  964. <return Math.round(self);>
  965. !
  966. to: aNumber
  967. | array first last count |
  968. first := self truncated.
  969. last := aNumber truncated + 1.
  970. count := 1.
  971. array := Array new.
  972. (last - first) timesRepeat: [
  973. array at: count put: first.
  974. count := count + 1.
  975. first := first + 1].
  976. ^array
  977. !
  978. to: stop by: step
  979. | array value pos |
  980. value := self.
  981. array := Array new.
  982. pos := 1.
  983. step = 0 ifTrue: [self error: 'step must be non-zero'].
  984. step < 0
  985. ifTrue: [[ value >= stop ] whileTrue: [
  986. array at: pos put: value.
  987. pos := pos + 1.
  988. value := value + step]]
  989. ifFalse: [[ value <= stop ] whileTrue: [
  990. array at: pos put: value.
  991. pos := pos + 1.
  992. value := value + step]].
  993. ^array
  994. !
  995. truncated
  996. <
  997. if(self >>= 0) {
  998. return Math.floor(self);
  999. } else {
  1000. return Math.floor(self * (-1)) * (-1);
  1001. };
  1002. >
  1003. !
  1004. | aNumber
  1005. <return self | aNumber>
  1006. ! !
  1007. !Number methodsFor: 'copying'!
  1008. copy
  1009. ^self
  1010. !
  1011. deepCopy
  1012. ^self copy
  1013. ! !
  1014. !Number methodsFor: 'enumerating'!
  1015. timesRepeat: aBlock
  1016. | count |
  1017. count := 1.
  1018. [count > self] whileFalse: [
  1019. aBlock value.
  1020. count := count + 1]
  1021. !
  1022. to: stop by: step do: aBlock
  1023. | value |
  1024. value := self.
  1025. step = 0 ifTrue: [self error: 'step must be non-zero'].
  1026. step < 0
  1027. ifTrue: [[ value >= stop ] whileTrue: [
  1028. aBlock value: value.
  1029. value := value + step]]
  1030. ifFalse: [[ value <= stop ] whileTrue: [
  1031. aBlock value: value.
  1032. value := value + step]]
  1033. !
  1034. to: stop do: aBlock
  1035. "Evaluate aBlock for each number from self to aNumber."
  1036. | nextValue |
  1037. nextValue := self.
  1038. [nextValue <= stop]
  1039. whileTrue:
  1040. [aBlock value: nextValue.
  1041. nextValue := nextValue + 1]
  1042. ! !
  1043. !Number methodsFor: 'printing'!
  1044. printOn: aStream
  1045. aStream nextPutAll: self asString
  1046. !
  1047. printShowingDecimalPlaces: placesDesired
  1048. <return self.toFixed(placesDesired)>
  1049. ! !
  1050. !Number methodsFor: 'testing'!
  1051. even
  1052. ^ 0 = (self \\ 2)
  1053. !
  1054. isImmutable
  1055. ^ true
  1056. !
  1057. isNumber
  1058. ^true
  1059. !
  1060. isZero
  1061. ^self = 0
  1062. !
  1063. negative
  1064. "Answer whether the receiver is mathematically negative."
  1065. ^ self < 0
  1066. !
  1067. odd
  1068. ^ self even not
  1069. !
  1070. positive
  1071. "Answer whether the receiver is positive or equal to 0. (ST-80 protocol)."
  1072. ^ self >= 0
  1073. ! !
  1074. !Number class methodsFor: 'helios'!
  1075. heliosClass
  1076. ^ 'magnitude'
  1077. ! !
  1078. !Number class methodsFor: 'instance creation'!
  1079. pi
  1080. <return Math.PI>
  1081. ! !
  1082. Object subclass: #Organizer
  1083. instanceVariableNames: ''
  1084. package: 'Kernel-Objects'!
  1085. !Organizer commentStamp!
  1086. I represent categorization information.
  1087. ## API
  1088. Use `#addElement:` and `#removeElement:` to manipulate instances.!
  1089. !Organizer methodsFor: 'accessing'!
  1090. addElement: anObject
  1091. <self.elements.addElement(anObject)>
  1092. !
  1093. elements
  1094. ^ (self basicAt: 'elements') copy
  1095. !
  1096. removeElement: anObject
  1097. <self.elements.removeElement(anObject)>
  1098. ! !
  1099. Organizer subclass: #ClassOrganizer
  1100. instanceVariableNames: ''
  1101. package: 'Kernel-Objects'!
  1102. !ClassOrganizer commentStamp!
  1103. I am an organizer specific to classes. I hold method categorization information for classes.!
  1104. !ClassOrganizer methodsFor: 'accessing'!
  1105. addElement: aString
  1106. super addElement: aString.
  1107. SystemAnnouncer current announce: (ProtocolAdded new
  1108. protocol: aString;
  1109. theClass: self theClass;
  1110. yourself)
  1111. !
  1112. removeElement: aString
  1113. super removeElement: aString.
  1114. SystemAnnouncer current announce: (ProtocolRemoved new
  1115. protocol: aString;
  1116. theClass: self theClass;
  1117. yourself)
  1118. !
  1119. theClass
  1120. < return self.theClass >
  1121. ! !
  1122. Organizer subclass: #PackageOrganizer
  1123. instanceVariableNames: ''
  1124. package: 'Kernel-Objects'!
  1125. !PackageOrganizer commentStamp!
  1126. I am an organizer specific to packages. I hold classes categorization information.!
  1127. Object subclass: #Package
  1128. instanceVariableNames: 'extension'
  1129. package: 'Kernel-Objects'!
  1130. !Package commentStamp!
  1131. 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.
  1132. 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.
  1133. ## API
  1134. Packages are manipulated through "Smalltalk current", like for example finding one based on a name or with `Package class >> #name` directly:
  1135. Smalltalk current packageAt: 'Kernel'
  1136. Package named: 'Kernel'
  1137. 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.
  1138. You can fetch a package from the server:
  1139. Package load: 'Additional-Examples'!
  1140. !Package methodsFor: 'accessing'!
  1141. name
  1142. <return self.pkgName>
  1143. !
  1144. name: aString
  1145. <self.pkgName = aString>
  1146. !
  1147. organization
  1148. ^ self basicAt: 'organization'
  1149. ! !
  1150. !Package methodsFor: 'classes'!
  1151. classes
  1152. ^ self organization elements
  1153. !
  1154. setupClasses
  1155. self classes
  1156. do: [ :each | ClassBuilder new setupClass: each ];
  1157. do: [ :each | each initialize ]
  1158. !
  1159. sortedClasses
  1160. "Answer all classes in the receiver, sorted by superclass/subclasses and by class name for common subclasses (Issue #143)."
  1161. ^self class sortedClasses: self classes
  1162. ! !
  1163. !Package methodsFor: 'printing'!
  1164. printOn: aStream
  1165. super printOn: aStream.
  1166. aStream
  1167. nextPutAll: ' (';
  1168. nextPutAll: self name;
  1169. nextPutAll: ')'
  1170. ! !
  1171. !Package methodsFor: 'testing'!
  1172. isPackage
  1173. ^ true
  1174. ! !
  1175. Package class instanceVariableNames: 'defaultCommitPathJs defaultCommitPathSt'!
  1176. !Package class methodsFor: 'accessing'!
  1177. named: aPackageName
  1178. ^Smalltalk current packageAt: aPackageName
  1179. !
  1180. named: aPackageName ifAbsent: aBlock
  1181. ^Smalltalk current packageAt: aPackageName ifAbsent: aBlock
  1182. ! !
  1183. !Package class methodsFor: 'loading-storing'!
  1184. load: aPackageName
  1185. self deprecatedAPI.
  1186. self load: aPackageName prefix: self defaultCommitPathJs, '/'
  1187. !
  1188. load: aPackageName prefix: aPrefix
  1189. self deprecatedAPI.
  1190. PlatformInterface ajax: #{
  1191. 'url' -> (aPrefix , aPackageName , '.js').
  1192. 'dataType' -> 'script'.
  1193. 'success' -> [
  1194. (Package named: aPackageName) setupClasses ]
  1195. }
  1196. ! !
  1197. !Package class methodsFor: 'sorting'!
  1198. sortedClasses: classes
  1199. "Answer classes, sorted by superclass/subclasses and by class name for common subclasses (Issue #143)"
  1200. | children others nodes expandedClasses |
  1201. children := #().
  1202. others := #().
  1203. classes do: [:each |
  1204. (classes includes: each superclass)
  1205. ifFalse: [children add: each]
  1206. ifTrue: [others add: each]].
  1207. nodes := children collect: [:each |
  1208. ClassSorterNode on: each classes: others level: 0].
  1209. nodes := nodes sorted: [:a :b | a theClass name <= b theClass name ].
  1210. expandedClasses := Array new.
  1211. nodes do: [:aNode |
  1212. aNode traverseClassesWith: expandedClasses].
  1213. ^expandedClasses
  1214. ! !
  1215. Object subclass: #PlatformInterface
  1216. instanceVariableNames: ''
  1217. package: 'Kernel-Objects'!
  1218. !PlatformInterface commentStamp!
  1219. I am superclass of all object that interface with user or environment. `Widget` and a few other classes are subclasses of me.
  1220. ## API
  1221. self alert: 'Hey, there is a problem'.
  1222. self confirm: 'Affirmative?'.
  1223. self prompt: 'Your name:'.
  1224. self ajax: #{
  1225. 'url' -> '/patch.js'. 'type' -> 'GET'. dataType->'script'
  1226. }.!
  1227. PlatformInterface class instanceVariableNames: 'worker'!
  1228. !PlatformInterface class methodsFor: 'accessing'!
  1229. setWorker: anObject
  1230. worker := anObject
  1231. ! !
  1232. !PlatformInterface class methodsFor: 'actions'!
  1233. ajax: anObject
  1234. ^worker
  1235. ifNotNil: [ worker ajax: anObject ]
  1236. ifNil: [ self error: 'ajax: not available' ]
  1237. !
  1238. alert: aString
  1239. ^worker
  1240. ifNotNil: [ worker alert: aString ]
  1241. ifNil: [ self error: 'alert: not available' ]
  1242. !
  1243. confirm: aString
  1244. ^worker
  1245. ifNotNil: [ worker confirm: aString ]
  1246. ifNil: [ self error: 'confirm: not available' ]
  1247. !
  1248. prompt: aString
  1249. ^worker
  1250. ifNotNil: [ worker prompt: aString ]
  1251. ifNil: [ self error: 'prompt: not available' ]
  1252. ! !
  1253. !PlatformInterface class methodsFor: 'initialization'!
  1254. initialize
  1255. | candidate |
  1256. super initialize.
  1257. candidate := BrowserInterface new.
  1258. candidate isAvailable ifTrue: [ self setWorker: candidate. ^self ]
  1259. ! !
  1260. Object subclass: #Point
  1261. instanceVariableNames: 'x y'
  1262. package: 'Kernel-Objects'!
  1263. !Point commentStamp!
  1264. I represent an x-y pair of numbers usually designating a geometric coordinate.
  1265. ## API
  1266. Instances are traditionally created using the binary `#@` message to a number:
  1267. 100@120
  1268. Points can then be arithmetically manipulated:
  1269. 100@100 + (10@10)
  1270. ...or for example:
  1271. (100@100) * 2
  1272. **NOTE:** Creating a point with a negative y-value will need a space after `@` in order to avoid a parsing error:
  1273. 100@ -100 "but 100@-100 would not parse"!
  1274. !Point methodsFor: 'accessing'!
  1275. x
  1276. ^x
  1277. !
  1278. x: aNumber
  1279. x := aNumber
  1280. !
  1281. y
  1282. ^y
  1283. !
  1284. y: aNumber
  1285. y := aNumber
  1286. ! !
  1287. !Point methodsFor: 'arithmetic'!
  1288. * aPoint
  1289. ^Point x: self x * aPoint asPoint x y: self y * aPoint asPoint y
  1290. !
  1291. + aPoint
  1292. ^Point x: self x + aPoint asPoint x y: self y + aPoint asPoint y
  1293. !
  1294. - aPoint
  1295. ^Point x: self x - aPoint asPoint x y: self y - aPoint asPoint y
  1296. !
  1297. / aPoint
  1298. ^Point x: self x / aPoint asPoint x y: self y / aPoint asPoint y
  1299. !
  1300. = aPoint
  1301. ^aPoint class = self class and: [
  1302. (aPoint x = self x) & (aPoint y = self y)]
  1303. ! !
  1304. !Point methodsFor: 'converting'!
  1305. asPoint
  1306. ^self
  1307. ! !
  1308. !Point methodsFor: 'printing'!
  1309. printOn: aStream
  1310. "Print receiver in classic x@y notation."
  1311. x printOn: aStream.
  1312. aStream nextPutAll: '@'.
  1313. (y notNil and: [y negative]) ifTrue: [
  1314. "Avoid ambiguous @- construct"
  1315. aStream space ].
  1316. y printOn: aStream
  1317. ! !
  1318. !Point methodsFor: 'transforming'!
  1319. translateBy: delta
  1320. "Answer a Point translated by delta (an instance of Point)."
  1321. ^(delta x + x) @ (delta y + y)
  1322. ! !
  1323. !Point class methodsFor: 'helios'!
  1324. heliosClass
  1325. ^ 'magnitude'
  1326. ! !
  1327. !Point class methodsFor: 'instance creation'!
  1328. x: aNumber y: anotherNumber
  1329. ^self new
  1330. x: aNumber;
  1331. y: anotherNumber;
  1332. yourself
  1333. ! !
  1334. Object subclass: #ProgressHandler
  1335. instanceVariableNames: ''
  1336. package: 'Kernel-Objects'!
  1337. !ProgressHandler commentStamp!
  1338. I am used to manage progress in collection iterations, see `SequenceableCollection >> #do:displayingProgress:`.
  1339. Subclasses of can register themselves as the current handler with
  1340. `ProgressHandler class >> register`.
  1341. The default behavior is to simply iterate over the collection.!
  1342. !ProgressHandler methodsFor: 'progress handling'!
  1343. do: aBlock on: aCollection displaying: aString
  1344. aCollection do: aBlock
  1345. ! !
  1346. ProgressHandler class instanceVariableNames: 'current'!
  1347. !ProgressHandler class methodsFor: 'accessing'!
  1348. current
  1349. ^current ifNil: [ current := self new ]
  1350. !
  1351. setCurrent: anHandler
  1352. current := anHandler
  1353. ! !
  1354. !ProgressHandler class methodsFor: 'initialization'!
  1355. initialize
  1356. self register
  1357. !
  1358. register
  1359. ProgressHandler setCurrent: self new
  1360. ! !
  1361. Object subclass: #Random
  1362. instanceVariableNames: ''
  1363. package: 'Kernel-Objects'!
  1364. !Random commentStamp!
  1365. I an used to generate a random number and I am implemented as a trivial wrapper around javascript `Math.random()`.
  1366. ## API
  1367. The typical use case it to use the `#next` method like the following:
  1368. Random new next
  1369. 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`
  1370. 10 atRandom
  1371. A random number in a specific interval can be obtained with the following:
  1372. (3 to: 7) atRandom
  1373. 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:
  1374. 5 atRandom + 2
  1375. Since `#atRandom` is implemented in `SequencableCollection` you can easy pick an element at random:
  1376. #('a' 'b' 'c') atRandom
  1377. As well as letter from a `String`:
  1378. 'abc' atRandom
  1379. Since Amber does not have Characters this will return a `String` of length 1 like for example `'b'`.!
  1380. !Random methodsFor: 'accessing'!
  1381. next
  1382. <return Math.random()>
  1383. !
  1384. next: anInteger
  1385. ^(1 to: anInteger) collect: [:each | self next]
  1386. ! !
  1387. Object subclass: #Smalltalk
  1388. instanceVariableNames: ''
  1389. package: 'Kernel-Objects'!
  1390. !Smalltalk commentStamp!
  1391. I represent the global JavaScript variable `smalltalk` declared in `js/boot.js`.
  1392. ## API
  1393. I have only one instance, accessed with class-side method `#current`.
  1394. The `smalltalk` object holds all class and packages defined in the system.
  1395. ## Classes
  1396. Classes can be accessed using the following methods:
  1397. - `#classes` answers the full list of Smalltalk classes in the system
  1398. - `#at:` answers a specific class or `nil`
  1399. ## Packages
  1400. Packages can be accessed using the following methods:
  1401. - `#packages` answers the full list of packages
  1402. - `#packageAt:` answers a specific package or `nil`
  1403. ## Parsing
  1404. The `#parse:` method is used to parse Amber source code.
  1405. It requires the `Compiler` package and the `js/parser.js` parser file in order to work.!
  1406. !Smalltalk methodsFor: 'accessing'!
  1407. at: aString
  1408. <return self[aString]>
  1409. !
  1410. parse: aString
  1411. | result |
  1412. self
  1413. try: [result := self basicParse: aString]
  1414. catch: [:ex | (self parseError: ex parsing: aString) signal].
  1415. ^ result
  1416. source: aString;
  1417. yourself
  1418. !
  1419. readJSObject: anObject
  1420. <return self.readJSObject(anObject)>
  1421. !
  1422. reservedWords
  1423. "JavaScript reserved words"
  1424. <return self.reservedWords>
  1425. !
  1426. version
  1427. "Answer the version string of Amber"
  1428. ^ '0.11.0'
  1429. ! !
  1430. !Smalltalk methodsFor: 'classes'!
  1431. classes
  1432. <return self.classes()>
  1433. !
  1434. deleteClass: aClass
  1435. "Deletes a class by deleting its binding only. Use #removeClass instead"
  1436. <self.removeClass(aClass)>
  1437. !
  1438. removeClass: aClass
  1439. aClass isMetaclass ifTrue: [self error: aClass asString, ' is a Metaclass and cannot be removed!!'].
  1440. self deleteClass: aClass.
  1441. SystemAnnouncer current
  1442. announce: (ClassRemoved new
  1443. theClass: aClass;
  1444. yourself)
  1445. ! !
  1446. !Smalltalk methodsFor: 'error handling'!
  1447. asSmalltalkException: anObject
  1448. "A JavaScript exception may be thrown.
  1449. We then need to convert it back to a Smalltalk object"
  1450. ^ ((self isSmalltalkObject: anObject) and: [ anObject isKindOf: Error ])
  1451. ifTrue: [ anObject ]
  1452. ifFalse: [ JavaScriptException on: anObject ]
  1453. !
  1454. parseError: anException parsing: aString
  1455. ^ ParseError new messageText: 'Parse error on line ', (anException basicAt: 'line') ,' column ' , (anException basicAt: 'column') ,' : Unexpected character ', (anException basicAt: 'found')
  1456. ! !
  1457. !Smalltalk methodsFor: 'globals'!
  1458. addGlobalJsVariable: aString
  1459. self globalJsVariables add: aString
  1460. !
  1461. deleteGlobalJsVariable: aString
  1462. self globalJsVariables remove: aString ifAbsent:[]
  1463. !
  1464. globalJsVariables
  1465. "Array of global JavaScript variables"
  1466. <return self.globalJsVariables>
  1467. ! !
  1468. !Smalltalk methodsFor: 'packages'!
  1469. createPackage: packageName
  1470. "Create and bind a new package with given name and return it."
  1471. <return smalltalk.addPackage(packageName)>
  1472. !
  1473. deletePackage: packageName
  1474. "Deletes a package by deleting its binding, but does not check if it contains classes etc.
  1475. To remove a package, use #removePackage instead."
  1476. <delete smalltalk.packages[packageName]>
  1477. !
  1478. packageAt: packageName
  1479. <return self.packages[packageName]>
  1480. !
  1481. packageAt: packageName ifAbsent: aBlock
  1482. ^(self packageAt: packageName) ifNil: aBlock
  1483. !
  1484. packages
  1485. "Return all Package instances in the system."
  1486. <return self.packages.all()>
  1487. !
  1488. pseudoVariableNames
  1489. ^ #('self' 'super' 'nil' 'true' 'false' 'thisContext')
  1490. !
  1491. removePackage: packageName
  1492. "Removes a package and all its classes."
  1493. | pkg |
  1494. pkg := self packageAt: packageName ifAbsent: [self error: 'Missing package: ', packageName].
  1495. pkg classes do: [:each |
  1496. self removeClass: each].
  1497. self deletePackage: packageName
  1498. !
  1499. renamePackage: packageName to: newName
  1500. "Rename a package."
  1501. | pkg |
  1502. pkg := self packageAt: packageName ifAbsent: [self error: 'Missing package: ', packageName].
  1503. (self packageAt: newName) ifNotNil: [self error: 'Already exists a package called: ', newName].
  1504. (self basicAt: 'packages') at: newName put: pkg.
  1505. pkg name: newName.
  1506. self deletePackage: packageName.
  1507. ! !
  1508. !Smalltalk methodsFor: 'private'!
  1509. basicParse: aString
  1510. <return smalltalk.parser.parse(aString)>
  1511. !
  1512. createPackage: packageName properties: aDict
  1513. "Needed to import .st files: they begin with this call."
  1514. self deprecatedAPI.
  1515. aDict isEmpty ifFalse: [ self error: 'createPackage:properties: called with nonempty properties' ].
  1516. ^ self createPackage: packageName
  1517. ! !
  1518. !Smalltalk methodsFor: 'testing'!
  1519. isSmalltalkObject: anObject
  1520. "Consider anObject a Smalltalk object if it has a 'klass' property.
  1521. Note that this may be unaccurate"
  1522. <return typeof anObject.klass !!== 'undefined'>
  1523. ! !
  1524. Smalltalk class instanceVariableNames: 'current'!
  1525. !Smalltalk class methodsFor: 'accessing'!
  1526. current
  1527. <return smalltalk>
  1528. ! !
  1529. Object subclass: #Timeout
  1530. instanceVariableNames: 'rawTimeout'
  1531. package: 'Kernel-Objects'!
  1532. !Timeout commentStamp!
  1533. I am wrapping the returns from `set{Timeout,Interval}`.
  1534. ## Motivation
  1535. Number suffices in browsers, but node.js returns an object.!
  1536. !Timeout methodsFor: 'accessing'!
  1537. rawTimeout: anObject
  1538. rawTimeout := anObject
  1539. ! !
  1540. !Timeout methodsFor: 'timeout/interval'!
  1541. clearInterval
  1542. <
  1543. var interval = self["@rawTimeout"];
  1544. clearInterval(interval);
  1545. >
  1546. !
  1547. clearTimeout
  1548. <
  1549. var timeout = self["@rawTimeout"];
  1550. clearTimeout(timeout);
  1551. >
  1552. ! !
  1553. !Timeout class methodsFor: 'instance creation'!
  1554. on: anObject
  1555. ^self new rawTimeout: anObject; yourself
  1556. ! !
  1557. Object subclass: #UndefinedObject
  1558. instanceVariableNames: ''
  1559. package: 'Kernel-Objects'!
  1560. !UndefinedObject commentStamp!
  1561. 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.
  1562. `nil` is the Smalltalk equivalent of the `undefined` JavaScript object.
  1563. __note:__ When sending messages to the `undefined` JavaScript object, it will be replaced by `nil`.!
  1564. !UndefinedObject methodsFor: 'class creation'!
  1565. subclass: aString instanceVariableNames: anotherString
  1566. ^self subclass: aString instanceVariableNames: anotherString package: nil
  1567. !
  1568. subclass: aString instanceVariableNames: aString2 category: aString3
  1569. "Kept for compatibility."
  1570. self deprecatedAPI.
  1571. ^self subclass: aString instanceVariableNames: aString2 package: aString3
  1572. !
  1573. subclass: aString instanceVariableNames: aString2 package: aString3
  1574. ^ClassBuilder new
  1575. superclass: self subclass: aString asString instanceVariableNames: aString2 package: aString3
  1576. ! !
  1577. !UndefinedObject methodsFor: 'converting'!
  1578. asJSON
  1579. ^null
  1580. ! !
  1581. !UndefinedObject methodsFor: 'copying'!
  1582. deepCopy
  1583. ^self
  1584. !
  1585. shallowCopy
  1586. ^self
  1587. ! !
  1588. !UndefinedObject methodsFor: 'printing'!
  1589. printOn: aStream
  1590. aStream nextPutAll: 'nil'
  1591. ! !
  1592. !UndefinedObject methodsFor: 'testing'!
  1593. ifNil: aBlock
  1594. "inlined in the Compiler"
  1595. ^self ifNil: aBlock ifNotNil: []
  1596. !
  1597. ifNil: aBlock ifNotNil: anotherBlock
  1598. "inlined in the Compiler"
  1599. ^aBlock value
  1600. !
  1601. ifNotNil: aBlock
  1602. "inlined in the Compiler"
  1603. ^self
  1604. !
  1605. ifNotNil: aBlock ifNil: anotherBlock
  1606. "inlined in the Compiler"
  1607. ^anotherBlock value
  1608. !
  1609. isImmutable
  1610. ^ true
  1611. !
  1612. isNil
  1613. ^true
  1614. !
  1615. notNil
  1616. ^false
  1617. ! !
  1618. !UndefinedObject class methodsFor: 'instance creation'!
  1619. new
  1620. self error: 'You cannot create new instances of UndefinedObject. Use nil'
  1621. ! !
  1622. !String methodsFor: '*Kernel-Objects'!
  1623. asJavaScriptSelector
  1624. "Return first keyword of the selector, without trailing colon."
  1625. ^self replace: '^([a-zA-Z0-9]*).*$' with: '$1'
  1626. ! !