Kernel-Methods.st 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975
  1. Smalltalk createPackage: 'Kernel-Methods'!
  2. Object subclass: #BlockClosure
  3. slots: {#prototype. #length}
  4. package: 'Kernel-Methods'!
  5. !BlockClosure commentStamp!
  6. I represent a lexical closure.
  7. I am is directly mapped to JavaScript Function.
  8. ## API
  9. 1. Evaluation
  10. My instances get evaluated with the `#value*` methods in the 'evaluating' protocol.
  11. Example: ` [ :x | x + 1 ] value: 3 "Answers 4" `
  12. 2. Control structures
  13. Blocks are used (together with `Boolean`) for control structures (methods in the `controlling` protocol).
  14. Example: `aBlock whileTrue: [ ... ]`
  15. 3. Error handling
  16. I provide the `#on:do:` method for handling exceptions.
  17. Example: ` aBlock on: MessageNotUnderstood do: [ :ex | ... ] `!
  18. !BlockClosure methodsFor: 'accessing'!
  19. compiledSource
  20. <inlineJS: 'return self.toString()'>
  21. !
  22. numArgs
  23. ^ length
  24. !
  25. prototype
  26. ^ prototype
  27. !
  28. receiver
  29. ^ nil
  30. ! !
  31. !BlockClosure methodsFor: 'controlling'!
  32. whileFalse
  33. self whileFalse: []
  34. !
  35. whileFalse: aBlock
  36. <inlineJS: 'while(!!$core.assert($self._value())) {aBlock._value()}'>
  37. !
  38. whileTrue
  39. self whileTrue: []
  40. !
  41. whileTrue: aBlock
  42. <inlineJS: 'while($core.assert($self._value())) {aBlock._value()}'>
  43. ! !
  44. !BlockClosure methodsFor: 'converting'!
  45. asCompiledMethod: aString
  46. <inlineJS: 'return $core.method({selector:aString, fn:self});'>
  47. !
  48. currySelf
  49. "Transforms [ :selfarg :x :y | stcode ] block
  50. which represents JS function (selfarg, x, y, ...) {jscode}
  51. into function (x, y, ...) {jscode} that takes selfarg from 'this'.
  52. IOW, it is usable as JS method and first arg takes the receiver."
  53. <inlineJS: '
  54. return function () {
  55. var args = [ this ];
  56. args.push.apply(args, arguments);
  57. return self.apply(null, args);
  58. }
  59. '>
  60. !
  61. provided
  62. "Returns JS proxy that allows to access 'static API', as in
  63. require provided resolve: ...
  64. or
  65. XMLHttpRequest provided DONE"
  66. ^ JSObjectProxy on: self
  67. ! !
  68. !BlockClosure methodsFor: 'error handling'!
  69. on: anErrorClass do: aBlock
  70. "All exceptions thrown in the Smalltalk stack are cought.
  71. Convert all JS exceptions to JavaScriptException instances."
  72. ^ self tryCatch: [ :error | | smalltalkError |
  73. smalltalkError := Smalltalk asSmalltalkException: error.
  74. (smalltalkError isKindOf: anErrorClass)
  75. ifTrue: [ aBlock value: smalltalkError ]
  76. ifFalse: [ smalltalkError pass ] ]
  77. !
  78. tryCatch: aBlock
  79. <inlineJS: '
  80. try {
  81. return $self._value();
  82. } catch(error) {
  83. // pass non-local returns undetected
  84. if (Array.isArray(error) && error.length === 1) throw error;
  85. return aBlock._value_(error);
  86. }
  87. '>
  88. ! !
  89. !BlockClosure methodsFor: 'evaluating'!
  90. applyTo: anObject arguments: aCollection
  91. <inlineJS: 'return self.apply(anObject, aCollection)'>
  92. !
  93. ensure: aBlock
  94. <inlineJS: 'try{return $self._value()}finally{aBlock._value()}'>
  95. !
  96. new
  97. "Use the receiver as a JS constructor.
  98. *Do not* use this method to instanciate Smalltalk objects!!"
  99. <inlineJS: 'return new self()'>
  100. !
  101. newValue: anObject
  102. ^ self newWithValues: { anObject }
  103. !
  104. newValue: anObject value: anObject2
  105. ^ self newWithValues: { anObject. anObject2 }.
  106. !
  107. newValue: anObject value: anObject2 value: anObject3
  108. ^ self newWithValues: { anObject. anObject2. anObject3 }.
  109. !
  110. newWithValues: aCollection
  111. "Simulates JS new operator by combination of Object.create and .apply"
  112. <inlineJS: '
  113. var object = Object.create(self.prototype);
  114. var result = self.apply(object, aCollection);
  115. return typeof result === "object" ? result : object;
  116. '>
  117. !
  118. timeToRun
  119. "Answer the number of milliseconds taken to execute this block."
  120. ^ Date millisecondsToRun: self
  121. !
  122. value
  123. <inlineJS: 'return self();'>
  124. !
  125. value: anArg
  126. <inlineJS: 'return self(anArg);'>
  127. !
  128. value: firstArg value: secondArg
  129. <inlineJS: 'return self(firstArg, secondArg);'>
  130. !
  131. value: firstArg value: secondArg value: thirdArg
  132. <inlineJS: 'return self(firstArg, secondArg, thirdArg);'>
  133. !
  134. valueWithPossibleArguments: aCollection
  135. <inlineJS: 'return self.apply(null, aCollection);'>
  136. ! !
  137. !BlockClosure methodsFor: 'timeout/interval'!
  138. fork
  139. ForkPool default fork: self
  140. !
  141. valueWithInterval: aNumber
  142. <inlineJS: '
  143. var interval = setInterval(self, aNumber);
  144. return $globals.Timeout._on_(interval);
  145. '>
  146. !
  147. valueWithTimeout: aNumber
  148. <inlineJS: '
  149. var timeout = setTimeout(self, aNumber);
  150. return $globals.Timeout._on_(timeout);
  151. '>
  152. ! !
  153. Object subclass: #CompiledMethod
  154. slots: {#args. #fn. #messageSends. #pragmas. #owner. #protocol. #referencedClasses. #selector. #source}
  155. package: 'Kernel-Methods'!
  156. !CompiledMethod commentStamp!
  157. I represent a class method of the system. I hold the source and compiled code of a class method.
  158. ## API
  159. My instances can be accessed using `Behavior >> #methodAt:`
  160. Object methodAt: 'asString'
  161. Source code access:
  162. (String methodAt: 'lines') source
  163. Referenced classes:
  164. (String methodAt: 'lines') referencedClasses
  165. Messages sent from an instance:
  166. (String methodAt: 'lines') messageSends!
  167. !CompiledMethod methodsFor: 'accessing'!
  168. arguments
  169. ^ args ifNil: [ #() ]
  170. !
  171. basicPragmas
  172. ^ pragmas ifNil: [ #() ]
  173. !
  174. category
  175. ^ self protocol
  176. !
  177. fn
  178. ^ fn
  179. !
  180. fn: aBlock
  181. fn := aBlock
  182. !
  183. messageSends
  184. ^ messageSends
  185. !
  186. methodClass
  187. ^ owner
  188. !
  189. package
  190. "Answer the package the receiver belongs to:
  191. - if it is an extension method, answer the corresponding package
  192. - else answer the `methodClass` package"
  193. ^ self methodClass ifNotNil: [ :class | class packageOfProtocol: self protocol ]
  194. !
  195. pragmas
  196. ^ self basicPragmas collect: [ :each | Message selector: each first arguments: each second ]
  197. !
  198. pragmas: anArrayOfMessages
  199. pragmas := anArrayOfMessages collect: [ :each | { each selector. each arguments } ]
  200. !
  201. protocol
  202. ^ protocol ifNil: [ self defaultProtocol ]
  203. !
  204. protocol: aString
  205. | oldProtocol |
  206. oldProtocol := self protocol.
  207. protocol := aString.
  208. oldProtocol ifNotNil: [
  209. SystemAnnouncer current announce: (MethodMoved new
  210. method: self;
  211. oldProtocol: oldProtocol;
  212. yourself) ].
  213. self methodClass ifNotNil: [ :methodClass |
  214. methodClass organization addElement: aString.
  215. methodClass removeProtocolIfEmpty: oldProtocol ]
  216. !
  217. referencedClasses
  218. ^ referencedClasses
  219. !
  220. selector
  221. ^ selector
  222. !
  223. selector: aString
  224. selector := aString
  225. !
  226. source
  227. ^ source ifNil: [ '' ]
  228. !
  229. source: aString
  230. source := aString
  231. ! !
  232. !CompiledMethod methodsFor: 'browsing'!
  233. browse
  234. Finder findMethod: self
  235. ! !
  236. !CompiledMethod methodsFor: 'defaults'!
  237. defaultProtocol
  238. ^ 'as yet unclassified'
  239. ! !
  240. !CompiledMethod methodsFor: 'evaluating'!
  241. sendTo: anObject arguments: aCollection
  242. ^ self fn applyTo: anObject arguments: aCollection
  243. ! !
  244. !CompiledMethod methodsFor: 'testing'!
  245. isCompiledMethod
  246. ^ true
  247. !
  248. isOverridden
  249. self methodClass allSubclassesDo: [ :each |
  250. (each includesSelector: selector)
  251. ifTrue: [ ^ true ] ].
  252. ^ false
  253. !
  254. isOverride
  255. | superclass |
  256. superclass := self methodClass superclass.
  257. superclass ifNil: [ ^ false ].
  258. ^ (self methodClass superclass lookupSelector: self selector) notNil
  259. ! !
  260. Object subclass: #ForkPool
  261. slots: {#poolSize. #maxPoolSize. #queue. #worker}
  262. package: 'Kernel-Methods'!
  263. !ForkPool commentStamp!
  264. I am responsible for handling forked blocks.
  265. The pool size sets the maximum concurrent forked blocks.
  266. ## API
  267. The default instance is accessed with `#default`.
  268. The maximum concurrent forked blocks can be set with `#maxPoolSize:`.
  269. Forking is done via `BlockClosure >> #fork`!
  270. !ForkPool methodsFor: 'accessing'!
  271. maxPoolSize
  272. ^ maxPoolSize ifNil: [ self defaultMaxPoolSize ]
  273. !
  274. maxPoolSize: anInteger
  275. maxPoolSize := anInteger
  276. ! !
  277. !ForkPool methodsFor: 'actions'!
  278. fork: aBlock
  279. poolSize < self maxPoolSize ifTrue: [ self addWorker ].
  280. queue nextPut: aBlock
  281. ! !
  282. !ForkPool methodsFor: 'defaults'!
  283. defaultMaxPoolSize
  284. ^ self class defaultMaxPoolSize
  285. ! !
  286. !ForkPool methodsFor: 'initialization'!
  287. initialize
  288. super initialize.
  289. poolSize := 0.
  290. queue := Queue new.
  291. worker := self makeWorker
  292. !
  293. makeWorker
  294. | sentinel |
  295. sentinel := Object new.
  296. ^ [ | block |
  297. poolSize := poolSize - 1.
  298. block := queue nextIfAbsent: [ sentinel ].
  299. block == sentinel ifFalse: [
  300. [ block value ] ensure: [ self addWorker ] ]]
  301. ! !
  302. !ForkPool methodsFor: 'private'!
  303. addWorker
  304. worker valueWithTimeout: 0.
  305. poolSize := poolSize + 1
  306. ! !
  307. ForkPool class slots: {#default}!
  308. !ForkPool class methodsFor: 'accessing'!
  309. default
  310. ^ default ifNil: [ default := self new ]
  311. !
  312. defaultMaxPoolSize
  313. ^ 100
  314. !
  315. resetDefault
  316. default := nil
  317. ! !
  318. Object subclass: #Message
  319. slots: {#selector. #arguments}
  320. package: 'Kernel-Methods'!
  321. !Message commentStamp!
  322. In general, the system does not use instances of me for efficiency reasons.
  323. However, when a message is not understood by its receiver, the interpreter will make up an instance of it in order to capture the information involved in an actual message transmission.
  324. This instance is sent it as an argument with the message `#doesNotUnderstand:` to the receiver.
  325. See boot.js, `messageNotUnderstood` and its counterpart `Object >> #doesNotUnderstand:`
  326. ## API
  327. Besides accessing methods, `#sendTo:` provides a convenient way to send a message to an object.!
  328. !Message methodsFor: 'accessing'!
  329. arguments
  330. ^ arguments
  331. !
  332. arguments: anArray
  333. arguments := anArray
  334. !
  335. selector
  336. ^ selector
  337. !
  338. selector: aString
  339. selector := aString
  340. ! !
  341. !Message methodsFor: 'actions'!
  342. sendTo: anObject
  343. ^ anObject perform: self selector withArguments: self arguments
  344. ! !
  345. !Message methodsFor: 'printing'!
  346. printOn: aStream
  347. super printOn: aStream.
  348. aStream
  349. nextPutAll: '(';
  350. nextPutAll: self selector;
  351. nextPutAll: ')'
  352. ! !
  353. !Message class methodsFor: 'dnu handling'!
  354. selector: aString arguments: anArray notUnderstoodBy: anObject
  355. "Creates the message and passes it to #doesNotUnderstand:.
  356. Used by kernel to handle MNU."
  357. ^ anObject doesNotUnderstand:
  358. (self selector: aString arguments: anArray)
  359. ! !
  360. !Message class methodsFor: 'instance creation'!
  361. selector: aString arguments: anArray
  362. ^ self new
  363. selector: aString;
  364. arguments: anArray;
  365. yourself
  366. ! !
  367. Object subclass: #MessageSend
  368. slots: {#receiver. #message}
  369. package: 'Kernel-Methods'!
  370. !MessageSend commentStamp!
  371. I encapsulate message sends to objects. Arguments can be either predefined or supplied when the message send is performed.
  372. ## API
  373. Use `#value` to perform a message send with its predefined arguments and `#value:*` if additonal arguments have to supplied.!
  374. !MessageSend methodsFor: 'accessing'!
  375. arguments
  376. ^ message arguments
  377. !
  378. arguments: aCollection
  379. message arguments: aCollection
  380. !
  381. receiver
  382. ^ receiver
  383. !
  384. receiver: anObject
  385. receiver := anObject
  386. !
  387. selector
  388. ^ message selector
  389. !
  390. selector: aString
  391. message selector: aString
  392. ! !
  393. !MessageSend methodsFor: 'evaluating'!
  394. value
  395. ^ message sendTo: self receiver
  396. !
  397. value: anObject
  398. ^ message
  399. arguments: { anObject };
  400. sendTo: self receiver
  401. !
  402. value: firstArgument value: secondArgument
  403. ^ message
  404. arguments: { firstArgument. secondArgument };
  405. sendTo: self receiver
  406. !
  407. value: firstArgument value: secondArgument value: thirdArgument
  408. ^ message
  409. arguments: { firstArgument. secondArgument. thirdArgument };
  410. sendTo: self receiver
  411. !
  412. valueWithPossibleArguments: aCollection
  413. self arguments: aCollection.
  414. ^ self value
  415. ! !
  416. !MessageSend methodsFor: 'initialization'!
  417. initialize
  418. super initialize.
  419. message := Message new
  420. ! !
  421. !MessageSend methodsFor: 'printing'!
  422. printOn: aStream
  423. super printOn: aStream.
  424. aStream
  425. nextPutAll: '(';
  426. nextPutAll: self receiver;
  427. nextPutAll: ' >> ';
  428. nextPutAll: self selector;
  429. nextPutAll: ')'
  430. ! !
  431. Object subclass: #MethodContext
  432. slots: {#receiver. #evaluatedSelector. #homeContext. #index. #locals. #outerContext. #selector. #sendIdx. #supercall}
  433. package: 'Kernel-Methods'!
  434. !MethodContext commentStamp!
  435. I hold all the dynamic state associated with the execution of either a method activation resulting from a message send. I am used to build the call stack while debugging.
  436. My instances are JavaScript `SmalltalkMethodContext` objects defined in `boot.js`.!
  437. !MethodContext methodsFor: 'accessing'!
  438. basicReceiver
  439. ^ receiver
  440. !
  441. evaluatedSelector
  442. ^ evaluatedSelector
  443. !
  444. home
  445. ^ homeContext
  446. !
  447. index
  448. ^ index ifNil: [ 0 ]
  449. !
  450. locals
  451. ^ locals
  452. !
  453. outerContext
  454. ^ outerContext ifNil: [ self home ]
  455. !
  456. selector
  457. ^ selector ifNotNil: [ Smalltalk core js2st: selector ]
  458. !
  459. sendIndexes
  460. ^ sendIdx
  461. !
  462. stubHere
  463. homeContext := JSObjectProxy undefined
  464. !
  465. supercall
  466. ^ supercall = true
  467. ! !
  468. !MethodContext methodsFor: 'error handling'!
  469. stubToAtMost: anInteger
  470. | context |
  471. context := self.
  472. anInteger timesRepeat: [ context := context ifNotNil: [ context home ] ].
  473. context ifNotNil: [ context stubHere ]
  474. ! !
  475. Object subclass: #NativeFunction
  476. slots: {}
  477. package: 'Kernel-Methods'!
  478. !NativeFunction commentStamp!
  479. I am a wrapper around native functions, such as `WebSocket`.
  480. For 'normal' functions (whose constructor is the JavaScript `Function` object), use `BlockClosure`.
  481. ## API
  482. See the class-side `instance creation` methods for instance creation.
  483. Created instances will most probably be instance of `JSObjectProxy`.
  484. ## Usage example:
  485. | ws |
  486. ws := NativeFunction constructor: 'WebSocket' value: 'ws://localhost'.
  487. ws at: 'onopen' put: [ ws send: 'hey there from Amber' ]!
  488. !NativeFunction class methodsFor: 'function calling'!
  489. functionNamed: aString
  490. <inlineJS: '
  491. var nativeFunc=$globals.Platform._globals[aString];
  492. return nativeFunc();
  493. '>
  494. !
  495. functionNamed: aString value: anObject
  496. <inlineJS: '
  497. var nativeFunc=$globals.Platform._globals()[aString];
  498. return nativeFunc(anObject);
  499. '>
  500. !
  501. functionNamed: aString value: anObject value: anObject2
  502. <inlineJS: '
  503. var nativeFunc=$globals.Platform._globals()[aString];
  504. return nativeFunc(anObject,anObject2);
  505. '>
  506. !
  507. functionNamed: aString value: anObject value: anObject2 value: anObject3
  508. <inlineJS: '
  509. var nativeFunc=$globals.Platform._globals()[aString];
  510. return nativeFunc(anObject,anObject2, anObject3);
  511. '>
  512. !
  513. functionNamed: aString valueWithArgs: args
  514. <inlineJS: '
  515. var nativeFunc=$globals.Platform._globals()[aString];
  516. return Function.prototype.apply.call(nativeFunc, null, args);
  517. '>
  518. !
  519. functionOf: nativeFunc
  520. <inlineJS: '
  521. return nativeFunc();
  522. '>
  523. !
  524. functionOf: nativeFunc value: anObject
  525. <inlineJS: '
  526. return nativeFunc(anObject);
  527. '>
  528. !
  529. functionOf: nativeFunc value: anObject value: anObject2
  530. <inlineJS: '
  531. return nativeFunc(anObject,anObject2);
  532. '>
  533. !
  534. functionOf: nativeFunc value: anObject value: anObject2 value: anObject3
  535. <inlineJS: '
  536. return nativeFunc(anObject,anObject2, anObject3);
  537. '>
  538. !
  539. functionOf: nativeFunc valueWithArgs: args
  540. <inlineJS: '
  541. return Function.prototype.apply.call(nativeFunc, null, args);
  542. '>
  543. ! !
  544. !NativeFunction class methodsFor: 'instance creation'!
  545. constructorNamed: aString
  546. <inlineJS: '
  547. var nativeFunc=$globals.Platform._globals()[aString];
  548. return new nativeFunc();
  549. '>
  550. !
  551. constructorNamed: aString value: anObject
  552. <inlineJS: '
  553. var nativeFunc=$globals.Platform._globals()[aString];
  554. return new nativeFunc(anObject);
  555. '>
  556. !
  557. constructorNamed: aString value: anObject value: anObject2
  558. <inlineJS: '
  559. var nativeFunc=$globals.Platform._globals[aString];
  560. return new nativeFunc(anObject,anObject2);
  561. '>
  562. !
  563. constructorNamed: aString value: anObject value: anObject2 value: anObject3
  564. <inlineJS: '
  565. var nativeFunc=$globals.Platform._globals[aString];
  566. return new nativeFunc(anObject,anObject2, anObject3);
  567. '>
  568. !
  569. constructorOf: nativeFunc
  570. <inlineJS: '
  571. return new nativeFunc();
  572. '>
  573. !
  574. constructorOf: nativeFunc value: anObject
  575. <inlineJS: '
  576. return new nativeFunc(anObject);
  577. '>
  578. !
  579. constructorOf: nativeFunc value: anObject value: anObject2
  580. <inlineJS: '
  581. return new nativeFunc(anObject,anObject2);
  582. '>
  583. !
  584. constructorOf: nativeFunc value: anObject value: anObject2 value: anObject3
  585. <inlineJS: '
  586. return new nativeFunc(anObject,anObject2, anObject3);
  587. '>
  588. ! !
  589. !NativeFunction class methodsFor: 'method calling'!
  590. methodOf: nativeFunc this: thisObject
  591. <inlineJS: '
  592. return Function.prototype.call.call(nativeFunc, thisObject);
  593. '>
  594. !
  595. methodOf: nativeFunc this: thisObject value: anObject
  596. <inlineJS: '
  597. return Function.prototype.call.call(nativeFunc, thisObject, anObject);
  598. '>
  599. !
  600. methodOf: nativeFunc this: thisObject value: anObject value: anObject2
  601. <inlineJS: '
  602. return Function.prototype.call.call(nativeFunc, thisObject,anObject,anObject2);
  603. '>
  604. !
  605. methodOf: nativeFunc this: thisObject value: anObject value: anObject2 value: anObject3
  606. <inlineJS: '
  607. return Function.prototype.call.call(nativeFunc, thisObject,anObject,anObject2, anObject3);
  608. '>
  609. !
  610. methodOf: nativeFunc this: thisObject valueWithArgs: args
  611. <inlineJS: '
  612. return Function.prototype.apply.call(nativeFunc, thisObject, args);
  613. '>
  614. ! !
  615. !NativeFunction class methodsFor: 'testing'!
  616. exists: aString
  617. ^ Platform includesGlobal: aString
  618. !
  619. isNativeFunction: anObject
  620. <inlineJS: 'return typeof anObject === "function"'>
  621. ! !
  622. Trait named: #TMethodContext
  623. package: 'Kernel-Methods'!
  624. !TMethodContext methodsFor: 'accessing'!
  625. basicReceiver
  626. self subclassResponsibility
  627. !
  628. findContextSuchThat: testBlock
  629. "Search self and my sender chain for first one that satisfies `testBlock`.
  630. Answer `nil` if none satisfy"
  631. | context |
  632. context := self.
  633. [ context isNil] whileFalse: [
  634. (testBlock value: context)
  635. ifTrue: [ ^ context ].
  636. context := context outerContext ].
  637. ^ nil
  638. !
  639. home
  640. self subclassResponsibility
  641. !
  642. index
  643. self subclassResponsibility
  644. !
  645. locals
  646. self subclassResponsibility
  647. !
  648. method
  649. | method lookupClass receiverClass supercall |
  650. self methodContext ifNil: [ ^ nil ].
  651. receiverClass := self methodContext receiver class.
  652. method := receiverClass lookupSelector: self methodContext selector.
  653. supercall := self outerContext
  654. ifNil: [ false ]
  655. ifNotNil: [ :outer | outer supercall ].
  656. ^ supercall
  657. ifFalse: [ method ]
  658. ifTrue: [ method methodClass superclass lookupSelector: self methodContext selector ]
  659. !
  660. methodContext
  661. self isBlockContext ifFalse: [ ^ self ].
  662. ^ self outerContext ifNotNil: [ :outer |
  663. outer methodContext ]
  664. !
  665. outerContext
  666. self subclassResponsibility
  667. !
  668. receiver
  669. ^ (self isBlockContext and: [ self outerContext notNil ])
  670. ifTrue: [ self outerContext receiver ]
  671. ifFalse: [ self basicReceiver ]
  672. !
  673. selector
  674. self subclassResponsibility
  675. !
  676. sendIndexes
  677. self subclassResponsibility
  678. !
  679. supercall
  680. self subclassResponsibility
  681. ! !
  682. !TMethodContext methodsFor: 'converting'!
  683. asString
  684. ^ self isBlockContext
  685. ifTrue: [ 'a block (in ', self methodContext asString, ')' ]
  686. ifFalse: [
  687. | methodClass |
  688. methodClass := self method ifNotNil: [ :method | method methodClass ].
  689. methodClass = self receiver class
  690. ifTrue: [ self receiver class name, ' >> ', self selector ]
  691. ifFalse: [ self receiver class name, '(', (methodClass ifNil: [ 'nil' ] ifNotNil: [ methodClass name ]), ') >> ', self selector ] ]
  692. ! !
  693. !TMethodContext methodsFor: 'printing'!
  694. printOn: aStream
  695. super printOn: aStream.
  696. aStream
  697. nextPutAll: '(';
  698. nextPutAll: self asString;
  699. nextPutAll: ')'
  700. ! !
  701. !TMethodContext methodsFor: 'testing'!
  702. isBlockContext
  703. "Block context do not have selectors."
  704. ^ self selector isNil
  705. ! !
  706. Object subclass: #Timeout
  707. slots: {#rawTimeout}
  708. package: 'Kernel-Methods'!
  709. !Timeout commentStamp!
  710. I am wrapping the returns from `set{Timeout,Interval}`.
  711. ## Motivation
  712. Number suffices in browsers, but node.js returns an object.!
  713. !Timeout methodsFor: 'accessing'!
  714. rawTimeout: anObject
  715. rawTimeout := anObject
  716. ! !
  717. !Timeout methodsFor: 'timeout/interval'!
  718. clearInterval
  719. <inlineJS: '
  720. var interval = $self.rawTimeout;
  721. clearInterval(interval);
  722. '>
  723. !
  724. clearTimeout
  725. <inlineJS: '
  726. var timeout = $self.rawTimeout;
  727. clearTimeout(timeout);
  728. '>
  729. ! !
  730. !Timeout class methodsFor: 'instance creation'!
  731. on: anObject
  732. ^ self new rawTimeout: anObject; yourself
  733. ! !
  734. MethodContext setTraitComposition: {TMethodContext} asTraitComposition!
  735. ! !