Kernel-Infrastructure.st 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931
  1. Smalltalk current createPackage: 'Kernel-Infrastructure'!
  2. Object subclass: #InspectorHandler
  3. instanceVariableNames: ''
  4. package: 'Kernel-Infrastructure'!
  5. !InspectorHandler commentStamp!
  6. I am responsible for inspecting object.
  7. My class-side `inspector` inst var holds the current inspector I'm delegating object inspection to.
  8. The default inspector object is the transcript.!
  9. InspectorHandler class instanceVariableNames: 'inspector'!
  10. !InspectorHandler class methodsFor: 'accessing'!
  11. inspector
  12. ^ inspector ifNil: [ inspector := Transcript ]
  13. ! !
  14. !InspectorHandler class methodsFor: 'registration'!
  15. inspect: anObject
  16. ^ self inspector inspect: anObject
  17. !
  18. register: anInspector
  19. inspector := anInspector
  20. ! !
  21. Object subclass: #InterfacingObject
  22. instanceVariableNames: ''
  23. package: 'Kernel-Infrastructure'!
  24. !InterfacingObject commentStamp!
  25. I am superclass of all object that interface with user or environment. `Widget` and a few other classes are subclasses of me. I delegate all of the above APIs to `PlatformInterface`.
  26. ## API
  27. self alert: 'Hey, there is a problem'.
  28. self confirm: 'Affirmative?'.
  29. self prompt: 'Your name:'.
  30. self ajax: #{
  31. 'url' -> '/patch.js'. 'type' -> 'GET'. dataType->'script'
  32. }.!
  33. !InterfacingObject methodsFor: 'actions'!
  34. ajax: anObject
  35. ^PlatformInterface ajax: anObject
  36. !
  37. alert: aString
  38. ^PlatformInterface alert: aString
  39. !
  40. confirm: aString
  41. ^PlatformInterface confirm: aString
  42. !
  43. prompt: aString
  44. ^PlatformInterface prompt: aString
  45. ! !
  46. InterfacingObject subclass: #Environment
  47. instanceVariableNames: ''
  48. package: 'Kernel-Infrastructure'!
  49. !Environment commentStamp!
  50. I provide an unified entry point to manipulate Amber packages, classes and methods.
  51. Typical use cases include IDEs, remote access and restricting browsing.!
  52. !Environment methodsFor: 'accessing'!
  53. allSelectors
  54. ^ (Smalltalk current at: 'allSelectors') value
  55. !
  56. availableClassNames
  57. ^ Smalltalk current classes
  58. collect: [ :each | each name ]
  59. !
  60. availablePackageNames
  61. ^ Smalltalk current packages
  62. collect: [ :each | each name ]
  63. !
  64. availableProtocolsFor: aClass
  65. | protocols |
  66. protocols := aClass protocols.
  67. aClass superclass ifNotNil: [ protocols addAll: (self availableProtocolsFor: aClass superclass) ].
  68. ^ protocols asSet asArray
  69. !
  70. classBuilder
  71. ^ ClassBuilder new
  72. !
  73. classNamed: aString
  74. ^ (Smalltalk current at: aString asSymbol)
  75. ifNil: [ self error: 'Invalid class name' ]
  76. !
  77. classes
  78. ^ Smalltalk current classes
  79. !
  80. packages
  81. ^ Smalltalk current packages
  82. !
  83. systemAnnouncer
  84. ^ (Smalltalk current at: #SystemAnnouncer) current
  85. ! !
  86. !Environment methodsFor: 'actions'!
  87. commitPackage: aPackage
  88. aPackage commit
  89. !
  90. copyClass: aClass to: aClassName
  91. (Smalltalk current at: aClassName)
  92. ifNotNil: [ self error: 'A class named ', aClassName, ' already exists' ].
  93. ClassBuilder new copyClass: aClass named: aClassName
  94. !
  95. eval: aString on: aReceiver
  96. | compiler |
  97. compiler := Compiler new.
  98. [ compiler parseExpression: aString ] on: Error do: [ :ex |
  99. ^ self alert: ex messageText ].
  100. ^ compiler evaluateExpression: aString on: aReceiver
  101. !
  102. inspect: anObject
  103. InspectorHandler inspector inspect: anObject
  104. !
  105. moveClass: aClass toPackage: aPackageName
  106. | package |
  107. package := Package named: aPackageName.
  108. package ifNil: [ self error: 'Invalid package name' ].
  109. package == aClass package ifTrue: [ ^ self ].
  110. aClass package: package
  111. !
  112. moveMethod: aMethod toClass: aClassName
  113. | destinationClass |
  114. destinationClass := Smalltalk current at: aClassName asSymbol.
  115. destinationClass ifNil: [ self error: 'Invalid class name' ].
  116. destinationClass == aMethod methodClass ifTrue: [ ^ self ].
  117. destinationClass
  118. compile: aMethod source
  119. category: aMethod protocol.
  120. aMethod methodClass
  121. removeCompiledMethod: aMethod
  122. !
  123. moveMethod: aMethod toProtocol: aProtocol
  124. aMethod category: aProtocol
  125. !
  126. registerErrorHandler: anErrorHandler
  127. ErrorHandler setCurrent: anErrorHandler
  128. !
  129. registerInspector: anInspector
  130. InspectorHandler register: anInspector
  131. !
  132. registerProgressHandler: aProgressHandler
  133. ProgressHandler setCurrent: aProgressHandler
  134. !
  135. removeClass: aClass
  136. Smalltalk current removeClass: aClass
  137. !
  138. removeMethod: aMethod
  139. aMethod methodClass removeCompiledMethod: aMethod
  140. !
  141. removeProtocol: aString from: aClass
  142. (aClass methods
  143. select: [ :each | each protocol = aString ])
  144. do: [ :each | aClass removeCompiledMethod: each ]
  145. !
  146. renameClass: aClass to: aClassName
  147. (Smalltalk current at: aClassName)
  148. ifNotNil: [ self error: 'A class named ', aClassName, ' already exists' ].
  149. ClassBuilder new renameClass: aClass to: aClassName
  150. !
  151. renameProtocol: aString to: anotherString in: aClass
  152. (aClass methods
  153. select: [ :each | each protocol = aString ])
  154. do: [ :each | each protocol: anotherString ]
  155. !
  156. setClassCommentOf: aClass to: aString
  157. aClass comment: aString
  158. ! !
  159. !Environment methodsFor: 'compiling'!
  160. addInstVarNamed: aString to: aClass
  161. self classBuilder
  162. addSubclassOf: aClass superclass
  163. named: aClass name
  164. instanceVariableNames: (aClass instanceVariableNames copy add: aString; yourself)
  165. package: aClass package name
  166. !
  167. compileClassComment: aString for: aClass
  168. aClass comment: aString
  169. !
  170. compileClassDefinition: aString
  171. self eval: aString on: DoIt new
  172. !
  173. compileMethod: sourceCode for: class protocol: protocol
  174. ^ class
  175. compile: sourceCode
  176. category: protocol
  177. ! !
  178. !Environment methodsFor: 'error handling'!
  179. evaluate: aBlock on: anErrorClass do: exceptionBlock
  180. "Evaluate a block and catch exceptions happening on the environment stack"
  181. self try: aBlock catch: [ :exception |
  182. (exception isKindOf: (self classNamed: anErrorClass name))
  183. ifTrue: [ exceptionBlock value: exception ]
  184. ifFalse: [ exception signal ] ]
  185. ! !
  186. Object subclass: #JSObjectProxy
  187. instanceVariableNames: 'jsObject'
  188. package: 'Kernel-Infrastructure'!
  189. !JSObjectProxy commentStamp!
  190. I handle sending messages to JavaScript objects, making JavaScript object accessing from Amber fully transparent.
  191. My instances make intensive use of `#doesNotUnderstand:`.
  192. My instances are automatically created by Amber whenever a message is sent to a JavaScript object.
  193. ## Usage examples
  194. JSObjectProxy objects are instanciated by Amber when a Smalltalk message is sent to a JavaScript object.
  195. window alert: 'hello world'.
  196. window inspect.
  197. (window jQuery: 'body') append: 'hello world'
  198. 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.
  199. ## Message conversion rules
  200. - `someUser name` becomes `someUser.name`
  201. - `someUser name: 'John'` becomes `someUser name = "John"`
  202. - `console log: 'hello world'` becomes `console.log('hello world')`
  203. - `(window jQuery: 'foo') css: 'background' color: 'red'` becomes `window.jQuery('foo').css('background', 'red')`
  204. __Note:__ For keyword-based messages, only the first keyword is kept: `window foo: 1 bar: 2` is equivalent to `window foo: 1 baz: 2`.!
  205. !JSObjectProxy methodsFor: 'accessing'!
  206. at: aString
  207. <return self['@jsObject'][aString]>
  208. !
  209. at: aString ifAbsent: aBlock
  210. "return the aString property or evaluate aBlock if the property is not defined on the object"
  211. <
  212. var obj = self['@jsObject'];
  213. return aString in obj ? obj[aString] : aBlock._value();
  214. >
  215. !
  216. at: aString ifPresent: aBlock
  217. "return the evaluation of aBlock with the value if the property is defined or return nil"
  218. <
  219. var obj = self['@jsObject'];
  220. return aString in obj ? aBlock._value_(obj[aString]) : nil;
  221. >
  222. !
  223. at: aString ifPresent: aBlock ifAbsent: anotherBlock
  224. "return the evaluation of aBlock with the value if the property is defined
  225. or return value of anotherBlock"
  226. <
  227. var obj = self['@jsObject'];
  228. return aString in obj ? aBlock._value_(obj[aString]) : anotherBlock._value();
  229. >
  230. !
  231. at: aString put: anObject
  232. <self['@jsObject'][aString] = anObject>
  233. !
  234. jsObject
  235. ^jsObject
  236. !
  237. jsObject: aJSObject
  238. jsObject := aJSObject
  239. !
  240. lookupProperty: aString
  241. "Looks up a property in JS object.
  242. Answer the property if it is present, or nil if it is not present."
  243. <return aString in self._jsObject() ? aString : nil>
  244. !
  245. value
  246. "if attribute 'value' exists on the JS object return it,
  247. otherwise return the result of Object>>value."
  248. ^ self
  249. at: 'value'
  250. ifAbsent: [ super value ]
  251. ! !
  252. !JSObjectProxy methodsFor: 'enumerating'!
  253. keysAndValuesDo: aBlock
  254. <
  255. var o = self['@jsObject'];
  256. for(var i in o) {
  257. aBlock._value_value_(i, o[i]);
  258. }
  259. >
  260. ! !
  261. !JSObjectProxy methodsFor: 'printing'!
  262. printOn: aStream
  263. aStream nextPutAll: self jsObject toString
  264. ! !
  265. !JSObjectProxy methodsFor: 'proxy'!
  266. addObjectVariablesTo: aDictionary
  267. <
  268. for(var i in self['@jsObject']) {
  269. aDictionary._at_put_(i, self['@jsObject'][i]);
  270. }
  271. >
  272. !
  273. doesNotUnderstand: aMessage
  274. ^ (self lookupProperty: aMessage selector asJavaScriptSelector)
  275. ifNil: [ super doesNotUnderstand: aMessage ]
  276. ifNotNil: [ :jsSelector |
  277. self
  278. forwardMessage: jsSelector
  279. withArguments: aMessage arguments ]
  280. !
  281. forwardMessage: aString withArguments: anArray
  282. <
  283. return smalltalk.send(self._jsObject(), aString, anArray);
  284. >
  285. !
  286. inspectOn: anInspector
  287. | variables |
  288. variables := Dictionary new.
  289. variables at: '#self' put: self jsObject.
  290. anInspector setLabel: self printString.
  291. self addObjectVariablesTo: variables.
  292. anInspector setVariables: variables
  293. ! !
  294. !JSObjectProxy class methodsFor: 'instance creation'!
  295. on: aJSObject
  296. ^self new
  297. jsObject: aJSObject;
  298. yourself
  299. ! !
  300. Object subclass: #Organizer
  301. instanceVariableNames: ''
  302. package: 'Kernel-Infrastructure'!
  303. !Organizer commentStamp!
  304. I represent categorization information.
  305. ## API
  306. Use `#addElement:` and `#removeElement:` to manipulate instances.!
  307. !Organizer methodsFor: 'accessing'!
  308. addElement: anObject
  309. <self.elements.addElement(anObject)>
  310. !
  311. elements
  312. ^ (self basicAt: 'elements') copy
  313. !
  314. removeElement: anObject
  315. <self.elements.removeElement(anObject)>
  316. ! !
  317. Organizer subclass: #ClassOrganizer
  318. instanceVariableNames: ''
  319. package: 'Kernel-Infrastructure'!
  320. !ClassOrganizer commentStamp!
  321. I am an organizer specific to classes. I hold method categorization information for classes.!
  322. !ClassOrganizer methodsFor: 'accessing'!
  323. addElement: aString
  324. super addElement: aString.
  325. SystemAnnouncer current announce: (ProtocolAdded new
  326. protocol: aString;
  327. theClass: self theClass;
  328. yourself)
  329. !
  330. removeElement: aString
  331. super removeElement: aString.
  332. SystemAnnouncer current announce: (ProtocolRemoved new
  333. protocol: aString;
  334. theClass: self theClass;
  335. yourself)
  336. !
  337. theClass
  338. < return self.theClass >
  339. ! !
  340. Organizer subclass: #PackageOrganizer
  341. instanceVariableNames: ''
  342. package: 'Kernel-Infrastructure'!
  343. !PackageOrganizer commentStamp!
  344. I am an organizer specific to packages. I hold classes categorization information.!
  345. Object subclass: #Package
  346. instanceVariableNames: 'extension'
  347. package: 'Kernel-Infrastructure'!
  348. !Package commentStamp!
  349. 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.
  350. 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.
  351. ## API
  352. Packages are manipulated through "Smalltalk current", like for example finding one based on a name or with `Package class >> #name` directly:
  353. Smalltalk current packageAt: 'Kernel'
  354. Package named: 'Kernel'
  355. 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.
  356. You can fetch a package from the server:
  357. Package load: 'Additional-Examples'!
  358. !Package methodsFor: 'accessing'!
  359. name
  360. <return self.pkgName>
  361. !
  362. name: aString
  363. <self.pkgName = aString>
  364. !
  365. organization
  366. ^ self basicAt: 'organization'
  367. !
  368. withDefaultTransport
  369. <return self.withDefaultTransport()>
  370. ! !
  371. !Package methodsFor: 'classes'!
  372. classes
  373. ^ self organization elements
  374. !
  375. setupClasses
  376. self classes
  377. do: [ :each | ClassBuilder new setupClass: each ];
  378. do: [ :each | each initialize ]
  379. !
  380. sortedClasses
  381. "Answer all classes in the receiver, sorted by superclass/subclasses and by class name for common subclasses (Issue #143)."
  382. ^self class sortedClasses: self classes
  383. ! !
  384. !Package methodsFor: 'dependencies'!
  385. loadDependencies
  386. "Returns list of packages that need to be loaded
  387. before loading this package."
  388. | classes packages |
  389. classes := self loadDependencyClasses.
  390. ^(classes collect: [ :each | each package ]) asSet
  391. remove: self ifAbsent: [];
  392. yourself
  393. !
  394. loadDependencyClasses
  395. "Returns classes needed at the time of loading a package.
  396. These are all that are used to subclass
  397. and to define an extension method"
  398. | starCategoryName |
  399. starCategoryName := '*', self name.
  400. ^(self classes collect: [ :each | each superclass ]) asSet
  401. remove: nil ifAbsent: [];
  402. addAll: (Smalltalk current classes select: [ :each | each protocols includes: starCategoryName ]);
  403. yourself
  404. ! !
  405. !Package methodsFor: 'printing'!
  406. printOn: aStream
  407. super printOn: aStream.
  408. aStream
  409. nextPutAll: ' (';
  410. nextPutAll: self name;
  411. nextPutAll: ')'
  412. ! !
  413. !Package methodsFor: 'testing'!
  414. isPackage
  415. ^ true
  416. ! !
  417. Package class instanceVariableNames: 'defaultCommitPathJs defaultCommitPathSt'!
  418. !Package class methodsFor: 'accessing'!
  419. named: aPackageName
  420. ^Smalltalk current packageAt: aPackageName
  421. !
  422. named: aPackageName ifAbsent: aBlock
  423. ^Smalltalk current packageAt: aPackageName ifAbsent: aBlock
  424. ! !
  425. !Package class methodsFor: 'loading-storing'!
  426. load: aPackageName
  427. self deprecatedAPI.
  428. self load: aPackageName prefix: self defaultCommitPathJs, '/'
  429. !
  430. load: aPackageName prefix: aPrefix
  431. self deprecatedAPI.
  432. PlatformInterface ajax: #{
  433. 'url' -> (aPrefix , aPackageName , '.js').
  434. 'dataType' -> 'script'.
  435. 'success' -> [
  436. (Package named: aPackageName) setupClasses ]
  437. }
  438. ! !
  439. !Package class methodsFor: 'sorting'!
  440. sortedClasses: classes
  441. "Answer classes, sorted by superclass/subclasses and by class name for common subclasses (Issue #143)"
  442. | children others nodes expandedClasses |
  443. children := #().
  444. others := #().
  445. classes do: [:each |
  446. (classes includes: each superclass)
  447. ifFalse: [children add: each]
  448. ifTrue: [others add: each]].
  449. nodes := children collect: [:each |
  450. ClassSorterNode on: each classes: others level: 0].
  451. nodes := nodes sorted: [:a :b | a theClass name <= b theClass name ].
  452. expandedClasses := Array new.
  453. nodes do: [:aNode |
  454. aNode traverseClassesWith: expandedClasses].
  455. ^expandedClasses
  456. ! !
  457. Object subclass: #PlatformInterface
  458. instanceVariableNames: ''
  459. package: 'Kernel-Infrastructure'!
  460. !PlatformInterface commentStamp!
  461. I am single entry point to UI and environment interface.
  462. My `initialize` tries several options (for now, browser environment only) to set myself up.
  463. ## API
  464. PlatformInterface alert: 'Hey, there is a problem'.
  465. PlatformInterface confirm: 'Affirmative?'.
  466. PlatformInterface prompt: 'Your name:'.
  467. PlatformInterface ajax: #{
  468. 'url' -> '/patch.js'. 'type' -> 'GET'. dataType->'script'
  469. }.!
  470. PlatformInterface class instanceVariableNames: 'worker'!
  471. !PlatformInterface class methodsFor: 'accessing'!
  472. setWorker: anObject
  473. worker := anObject
  474. ! !
  475. !PlatformInterface class methodsFor: 'actions'!
  476. ajax: anObject
  477. ^worker
  478. ifNotNil: [ worker ajax: anObject ]
  479. ifNil: [ self error: 'ajax: not available' ]
  480. !
  481. alert: aString
  482. ^worker
  483. ifNotNil: [ worker alert: aString ]
  484. ifNil: [ self error: 'alert: not available' ]
  485. !
  486. confirm: aString
  487. ^worker
  488. ifNotNil: [ worker confirm: aString ]
  489. ifNil: [ self error: 'confirm: not available' ]
  490. !
  491. existsGlobal: aString
  492. <
  493. var f = new Function('aString',
  494. 'if (/^[0-9]/.test(aString) || !!/^[\\w_]+$/.test(aString))\n'+
  495. ' return false;\n'+
  496. 'try { eval(aString); return true; } catch (ex) {}\n'+
  497. 'return false;');
  498. return f(aString);
  499. >
  500. !
  501. prompt: aString
  502. ^worker
  503. ifNotNil: [ worker prompt: aString ]
  504. ifNil: [ self error: 'prompt: not available' ]
  505. ! !
  506. !PlatformInterface class methodsFor: 'initialization'!
  507. initialize
  508. | candidate |
  509. super initialize.
  510. BrowserInterface ifNotNil: [
  511. candidate := BrowserInterface new.
  512. candidate isAvailable ifTrue: [ self setWorker: candidate. ^self ]
  513. ]
  514. ! !
  515. Object subclass: #ProgressHandler
  516. instanceVariableNames: ''
  517. package: 'Kernel-Infrastructure'!
  518. !ProgressHandler commentStamp!
  519. I am used to manage progress in collection iterations, see `SequenceableCollection >> #do:displayingProgress:`.
  520. Subclasses of can register themselves as the current handler with
  521. `ProgressHandler class >> register`.
  522. The default behavior is to simply iterate over the collection.!
  523. !ProgressHandler methodsFor: 'progress handling'!
  524. do: aBlock on: aCollection displaying: aString
  525. aCollection do: aBlock
  526. ! !
  527. ProgressHandler class instanceVariableNames: 'current'!
  528. !ProgressHandler class methodsFor: 'accessing'!
  529. current
  530. ^current ifNil: [ current := self new ]
  531. !
  532. setCurrent: anHandler
  533. current := anHandler
  534. ! !
  535. !ProgressHandler class methodsFor: 'initialization'!
  536. initialize
  537. self register
  538. !
  539. register
  540. ProgressHandler setCurrent: self new
  541. ! !
  542. Object subclass: #Smalltalk
  543. instanceVariableNames: ''
  544. package: 'Kernel-Infrastructure'!
  545. !Smalltalk commentStamp!
  546. I represent the global JavaScript variable `smalltalk` declared in `js/boot.js`.
  547. ## API
  548. I have only one instance, accessed with class-side method `#current`.
  549. The `smalltalk` object holds all class and packages defined in the system.
  550. ## Classes
  551. Classes can be accessed using the following methods:
  552. - `#classes` answers the full list of Smalltalk classes in the system
  553. - `#at:` answers a specific class or `nil`
  554. ## Packages
  555. Packages can be accessed using the following methods:
  556. - `#packages` answers the full list of packages
  557. - `#packageAt:` answers a specific package or `nil`
  558. ## Parsing
  559. The `#parse:` method is used to parse Amber source code.
  560. It requires the `Compiler` package and the `js/parser.js` parser file in order to work.!
  561. !Smalltalk methodsFor: 'accessing'!
  562. at: aString
  563. <return self[aString]>
  564. !
  565. parse: aString
  566. | result |
  567. self
  568. try: [result := self basicParse: aString]
  569. catch: [:ex | (self parseError: ex parsing: aString) signal].
  570. ^ result
  571. source: aString;
  572. yourself
  573. !
  574. readJSObject: anObject
  575. <return self.readJSObject(anObject)>
  576. !
  577. reservedWords
  578. "JavaScript reserved words"
  579. <return self.reservedWords>
  580. !
  581. version
  582. "Answer the version string of Amber"
  583. ^ '0.11.0'
  584. ! !
  585. !Smalltalk methodsFor: 'classes'!
  586. classes
  587. <return self.classes()>
  588. !
  589. deleteClass: aClass
  590. "Deletes a class by deleting its binding only. Use #removeClass instead"
  591. <self.removeClass(aClass)>
  592. !
  593. removeClass: aClass
  594. aClass isMetaclass ifTrue: [self error: aClass asString, ' is a Metaclass and cannot be removed!!'].
  595. self deleteClass: aClass.
  596. SystemAnnouncer current
  597. announce: (ClassRemoved new
  598. theClass: aClass;
  599. yourself)
  600. ! !
  601. !Smalltalk methodsFor: 'error handling'!
  602. asSmalltalkException: anObject
  603. "A JavaScript exception may be thrown.
  604. We then need to convert it back to a Smalltalk object"
  605. ^ ((self isSmalltalkObject: anObject) and: [ anObject isKindOf: Error ])
  606. ifTrue: [ anObject ]
  607. ifFalse: [ JavaScriptException on: anObject ]
  608. !
  609. parseError: anException parsing: aString
  610. ^ ParseError new messageText: 'Parse error on line ', (anException basicAt: 'line') ,' column ' , (anException basicAt: 'column') ,' : Unexpected character ', (anException basicAt: 'found')
  611. ! !
  612. !Smalltalk methodsFor: 'globals'!
  613. addGlobalJsVariable: aString
  614. self globalJsVariables add: aString
  615. !
  616. deleteGlobalJsVariable: aString
  617. self globalJsVariables remove: aString ifAbsent:[]
  618. !
  619. globalJsVariables
  620. "Array of global JavaScript variables"
  621. <return self.globalJsVariables>
  622. ! !
  623. !Smalltalk methodsFor: 'packages'!
  624. createDefaultPackage: packageName
  625. "Create and bind a new package with given name and default transport type and return it."
  626. ^ (self createPackage: packageName) withDefaultTransport
  627. !
  628. deletePackage: packageName
  629. "Deletes a package by deleting its binding, but does not check if it contains classes etc.
  630. To remove a package, use #removePackage instead."
  631. <delete smalltalk.packages[packageName]>
  632. !
  633. packageAt: packageName
  634. <return self.packages[packageName]>
  635. !
  636. packageAt: packageName ifAbsent: aBlock
  637. ^(self packageAt: packageName) ifNil: aBlock
  638. !
  639. packages
  640. "Return all Package instances in the system."
  641. <return self.packages.all()>
  642. !
  643. pseudoVariableNames
  644. ^ #('self' 'super' 'nil' 'true' 'false' 'thisContext')
  645. !
  646. removePackage: packageName
  647. "Removes a package and all its classes."
  648. | pkg |
  649. pkg := self packageAt: packageName ifAbsent: [self error: 'Missing package: ', packageName].
  650. pkg classes do: [:each |
  651. self removeClass: each].
  652. self deletePackage: packageName
  653. !
  654. renamePackage: packageName to: newName
  655. "Rename a package."
  656. | pkg |
  657. pkg := self packageAt: packageName ifAbsent: [self error: 'Missing package: ', packageName].
  658. (self packageAt: newName) ifNotNil: [self error: 'Already exists a package called: ', newName].
  659. (self basicAt: 'packages') at: newName put: pkg.
  660. pkg name: newName.
  661. self deletePackage: packageName.
  662. ! !
  663. !Smalltalk methodsFor: 'private'!
  664. basicParse: aString
  665. <return smalltalk.parser.parse(aString)>
  666. !
  667. createPackage: packageName
  668. "Create and bind a new bare package with given name and return it."
  669. <return smalltalk.addPackage(packageName)>
  670. !
  671. createPackage: packageName properties: aDict
  672. "Needed to import .st files: they begin with this call."
  673. self deprecatedAPI.
  674. aDict isEmpty ifFalse: [ self error: 'createPackage:properties: called with nonempty properties' ].
  675. ^ self createPackage: packageName
  676. ! !
  677. !Smalltalk methodsFor: 'testing'!
  678. isSmalltalkObject: anObject
  679. "Consider anObject a Smalltalk object if it has a 'klass' property.
  680. Note that this may be unaccurate"
  681. <return typeof anObject.klass !!== 'undefined'>
  682. ! !
  683. Smalltalk class instanceVariableNames: 'current'!
  684. !Smalltalk class methodsFor: 'accessing'!
  685. current
  686. <return smalltalk>
  687. ! !
  688. !String methodsFor: '*Kernel-Infrastructure'!
  689. asJavaScriptSelector
  690. "Return first keyword of the selector, without trailing colon."
  691. ^self replace: '^([a-zA-Z0-9]*).*$' with: '$1'
  692. ! !