Compiler-Tests.st 35 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321
  1. Smalltalk createPackage: 'Compiler-Tests'!
  2. TestCase subclass: #ASTMethodRunningTest
  3. slots: {#receiver}
  4. package: 'Compiler-Tests'!
  5. !ASTMethodRunningTest methodsFor: 'accessing'!
  6. receiver
  7. ^ receiver
  8. ! !
  9. !ASTMethodRunningTest methodsFor: 'initialization'!
  10. setUp
  11. receiver := DoIt new
  12. ! !
  13. !ASTMethodRunningTest methodsFor: 'testing'!
  14. should: aString class: aClass receiver: anObject return: aResult
  15. receiver := anObject.
  16. self while: aString inClass: aClass should: [ :runBlock |
  17. self assert: runBlock value equals: aResult ]
  18. !
  19. should: aString receiver: anObject raise: anErrorClass
  20. receiver := anObject.
  21. self while: aString should: [ :runBlock |
  22. self should: runBlock raise: anErrorClass ]
  23. !
  24. should: aString receiver: anObject return: aResult
  25. receiver := anObject.
  26. self should: aString return: aResult
  27. !
  28. should: aString return: anObject
  29. self while: aString should: [ :runBlock |
  30. self assert: runBlock value equals: anObject ]
  31. ! !
  32. ASTMethodRunningTest subclass: #AbstractCompilerTest
  33. slots: {}
  34. package: 'Compiler-Tests'!
  35. !AbstractCompilerTest methodsFor: 'tests'!
  36. testAfterInliningNonLocalBlockReturnIndexSend
  37. self should: 'foo [ ^ true ifTrue: [ self class ] ] value. self class' return: DoIt.
  38. !
  39. testAfterInliningNonLocalBlockReturnSuperSend
  40. self should: 'foo [ ^ true ifTrue: [ super class ] ] value' return: DoIt.
  41. !
  42. testAssignment
  43. self should: 'foo | a | a := true ifTrue: [ 1 ]. ^ a' return: 1.
  44. self should: 'foo | a | a := false ifTrue: [ 1 ]. ^ a' return: nil.
  45. self should: 'foo | a | ^ a := true ifTrue: [ 1 ]' return: 1
  46. !
  47. testBackslashSelectors
  48. self should: '\ arg ^ 4' return: 4.
  49. self should: '\\ arg ^ 42' return: 42
  50. !
  51. testBlockReturn
  52. self should: 'foo ^ #(1 2 3) collect: [ :each | true ifTrue: [ each + 1 ] ]' return: #(2 3 4).
  53. self should: 'foo ^ #(1 2 3) collect: [ :each | false ifFalse: [ each + 1 ] ]' return: #(2 3 4).
  54. self should: 'foo ^ #(1 2 3) collect: [ :each | each odd ifTrue: [ each + 1 ] ifFalse: [ each - 1 ] ]' return: #(2 1 4).
  55. !
  56. testCascades
  57. self should: 'foo ^ Array new add: 3; add: 4; yourself' return: #(3 4)
  58. !
  59. testCascadesInDynamicArray
  60. self should: 'foo | x | x := 1. ^ {x. [x:=2] value; in: [x]}' return: #(1 2)
  61. !
  62. testCascadesInDynamicDictioary
  63. self should: 'foo | x | x := 1. ^ #{''one'' -> x. ''two'' -> ([x:=2] value; in: [x])}' return: #{'one' -> 1. 'two' -> 2}
  64. !
  65. testCascadesInSend
  66. self should: 'foo | x | x := 1. ^ Array with: x with: ([x:=2] value; in: [x])' return: #(1 2)
  67. !
  68. testCascadesWithInlining
  69. self should: 'foo ^ true class; ifTrue: [ 1 ] ifFalse: [ 2 ]' return: 1.
  70. self should: 'foo ^ false class; ifTrue: [ 1 ] ifFalse: [ 2 ]' return: 2
  71. !
  72. testDynamicArrayElementsOrdered
  73. self should: 'foo
  74. | x |
  75. x := 1.
  76. ^ { x. x := 2 }
  77. ' return: #(1 2).
  78. self should: 'foo
  79. | x |
  80. x := 1.
  81. ^ { x. true ifTrue: [ x := 2 ] }
  82. ' return: #(1 2).
  83. !
  84. testDynamicDictionaryElementsOrdered
  85. self should: 'foo
  86. | x |
  87. x := ''foo''.
  88. ^ #{ x->1. ''bar''->(true ifTrue: [ 2 ]) }
  89. ' return: #{'foo'->1. 'bar'->2}.
  90. !
  91. testDynamicDictionaryWithMoreArrows
  92. self should: 'foo ^ #{1->2->3}' return: (HashedCollection with: 1->2->3)
  93. !
  94. testGlobalVar
  95. self should: 'foo ^ eval class' return: BlockClosure.
  96. self should: 'foo ^ Math cos: 0' return: 1.
  97. self should: 'foo ^ NonExistingVar' return: nil
  98. !
  99. testInnerTemporalDependentElementsOrdered
  100. self should: 'foo
  101. | x |
  102. x := Array.
  103. ^ x with: ''foo''->x with: ''bar''->(x := 2)
  104. ' return: {'foo'->Array. 'bar'->2}.
  105. self should: 'foo
  106. | x |
  107. x := Array.
  108. ^ x with: ''foo''->x with: ''bar''->(true ifTrue: [ x := 2 ])
  109. ' return: {'foo'->Array. 'bar'->2}.
  110. self should: 'foo
  111. | x |
  112. x := 1.
  113. ^ Array with: ''foo''->x with: ''bar''->(true ifTrue: [ x := 2 ])
  114. ' return: {'foo'->1. 'bar'->2}.
  115. self should: 'foo
  116. | x |
  117. x := 1.
  118. ^ { ''foo''->x. ''bar''->(true ifTrue: [ x := 2 ]) }
  119. ' return: {'foo'->1. 'bar'->2}.
  120. self should: 'foo
  121. | x |
  122. x := 1.
  123. ^ #{ ''foo''->x. ''bar''->(true ifTrue: [ x := 2 ]) }
  124. ' return: #{'foo'->1. 'bar'->2}.
  125. !
  126. testLexicalScope
  127. self should: 'foo | a | a := 1. [ a := 2 ] value. ^ a' return: 2
  128. !
  129. testLiterals
  130. self should: 'foo ^ 1' return: 1.
  131. self should: 'foo ^ ''hello''' return: 'hello'.
  132. self should: 'foo ^ #(1 2 3 4)' return: #(1 2 3 4).
  133. self should: 'foo ^ {1. [:x | x ] value: 2. 3. [4] value}' return: #(1 2 3 4).
  134. self should: 'foo ^ true' return: true.
  135. self should: 'foo ^ false' return: false.
  136. self should: 'foo ^ #{1->2. 3->4}' return: #{1->2. 3->4}.
  137. self should: 'foo ^ #hello' return: #hello.
  138. self should: 'foo ^ $h' return: 'h'.
  139. self should: 'foo ^ -123.456' return: -123.456.
  140. self should: 'foo ^ -2.5e4' return: -25000.
  141. !
  142. testLocalReturn
  143. self should: 'foo ^ 1' return: 1.
  144. self should: 'foo ^ 1 + 1' return: 2.
  145. self should: 'foo ' return: receiver.
  146. self should: 'foo self asString' return: receiver.
  147. self should: 'foo | a b | a := 1. b := 2. ^ a + b' return: 3
  148. !
  149. testMessageSends
  150. self should: 'foo ^ 1 asString' return: '1'.
  151. self should: 'foo ^ 1 + 1' return: 2.
  152. self should: 'foo ^ 1 + 2 * 3' return: 9.
  153. self should: 'foo ^ 1 to: 3' return: #(1 2 3).
  154. self should: 'foo ^ 1 to: 5 by: 2' return: #(1 3 5)
  155. !
  156. testMultipleSequences
  157. self should: 'foo | a b c | a := 2. b := 3. c := a + b. ^ c * 6' return: 30
  158. !
  159. testMutableLiterals
  160. "Mutable literals must be aliased in cascades.
  161. See https://lolg.it/amber/amber/issues/428"
  162. self
  163. should: 'foo ^ #( 1 2 ) at: 1 put: 3; yourself'
  164. return: #(3 2)
  165. !
  166. testNestedIfTrue
  167. self should: 'foo ^ true ifTrue: [ false ifFalse: [ 1 ] ]' return: 1.
  168. self should: 'foo ^ true ifTrue: [ false ifTrue: [ 1 ] ]' return: nil.
  169. self should: 'foo true ifTrue: [ false ifFalse: [ ^ 1 ] ]' return: 1.
  170. self should: 'foo true ifTrue: [ false ifTrue: [ ^ 1 ] ]' return: receiver.
  171. !
  172. testNestedSends
  173. self should: 'foo ^ (Point x: (Point x: 2 y: 3) y: 4) asString' return: (Point x: (2@3) y: 4) asString
  174. !
  175. testNilPerform
  176. self should: 'foo ^ nil perform: #yourself' return: nil
  177. !
  178. testNonLocalReturn
  179. self should: 'foo [ ^ 1 ] value' return: 1.
  180. self should: 'foo [ ^ 1 + 1 ] value' return: 2.
  181. self should: 'foo | a b | a := 1. b := 2. [ ^ a + b ] value. self halt' return: 3.
  182. self should: 'foo [ :x | ^ x + x ] value: 4. ^ 2' return: 8
  183. !
  184. testPascalCaseGlobal
  185. self should: 'foo ^Object' return: (Smalltalk globals at: 'Object').
  186. self should: 'foo ^NonExistent' return: nil
  187. !
  188. testPragmaJSStatement
  189. self should: 'foo < inlineJS: ''return 2+3'' >' return: 5
  190. !
  191. testReceiverEvaluatedOnceInSpecials
  192. self should: 'foo |x| x := 1. ^ {[ x := x+1 ] value ifNil: []. x}' return: {2. 2}.
  193. self should: 'foo |xs| xs := {nil. nil}. ^ {[ xs removeLast ] value ifNotNil: []. xs}' return: {nil. {nil}}.
  194. !
  195. testRegression1242
  196. self should: '
  197. foo
  198. |x|
  199. x := 2.
  200. x := nil ifNil: [].
  201. ^ x
  202. ' return: nil.
  203. self should: '
  204. foo
  205. |x|
  206. x := 2.
  207. x := 1 ifNotNil: [].
  208. ^ x
  209. ' return: nil.
  210. self should: '
  211. foo
  212. |x|
  213. x := 2.
  214. x := false ifFalse: [].
  215. ^ x
  216. ' return: nil.
  217. self should: '
  218. foo
  219. |x|
  220. x := 2.
  221. x := true ifTrue: [].
  222. ^ x
  223. ' return: nil.
  224. !
  225. testRegression1242ForReturn
  226. self should: 'foo [ ^ nil ifNil: [] ] value' return: nil.
  227. self should: 'foo [ ^ 1 ifNotNil: [] ] value' return: nil.
  228. self should: 'foo [ ^ false ifFalse: [] ] value' return: nil.
  229. self should: 'foo [ ^ true ifTrue: [] ] value' return: nil.
  230. !
  231. testRegression1244
  232. self should: 'foo [ ^ true ifTrue: [1] ifFalse: [2] ] value' return: 1
  233. !
  234. testRootSuperSend
  235. self
  236. should: 'foo ^ super class'
  237. receiver: ProtoObject new
  238. raise: MessageNotUnderstood
  239. !
  240. testSendReceiverAndArgumentsOrdered
  241. self should: 'foo
  242. | x |
  243. x := 1.
  244. ^ Array with: x with: (true ifTrue: [ x := 2 ])
  245. ' return: #(1 2).
  246. self should: 'foo
  247. | x |
  248. x := Array.
  249. ^ x with: x with: (true ifTrue: [ x := 2 ])
  250. ' return: {Array. 2}.
  251. !
  252. testSuperSend
  253. self
  254. should: 'foo ^ super isBoolean'
  255. receiver: true
  256. return: false
  257. !
  258. testSuperSend2
  259. self
  260. should: 'foo ^ super isNil'
  261. receiver: nil
  262. return: false
  263. !
  264. testSuperSend3
  265. self
  266. should: 'doo ^ super isNil'
  267. class: Object
  268. receiver: nil
  269. return: false
  270. !
  271. testSuperSend4
  272. self
  273. should: 'foo ^ super asJavaScriptObject'
  274. receiver: 'me'
  275. return: #('m' 'e')
  276. !
  277. testSuperSend5
  278. self
  279. should: 'foo [super addLast: 4] on: Error do: [ self add: 5 ]. ^ self'
  280. class: SequenceableCollection
  281. receiver: #(1 2 3)
  282. return: #(1 2 3 5)
  283. !
  284. testSuperSend6
  285. self
  286. should: 'foo ^ super ifTrue: [ true ] ifFalse: [ false ]'
  287. receiver: true
  288. raise: Error
  289. !
  290. testTempVariables
  291. self should: 'foo | a | ^ a' return: nil.
  292. self should: 'foo | AVariable | ^ AVariable' return: nil.
  293. self should: 'foo | a b c | ^ c' return: nil.
  294. self should: 'foo | a | [ | d | ^ d ] value' return: nil.
  295. self should: 'foo | a | a:= 1. ^ a' return: 1.
  296. self should: 'foo | AVariable | AVariable := 1. ^ AVariable' return: 1.
  297. !
  298. testThisContext
  299. self should: 'foo ^ [ thisContext ] value outerContext == thisContext' return: true
  300. !
  301. testUnknownPragma
  302. self should: 'foo < fooBar: ''return 2+3'' > | x | ^ x := 6' return: 6.
  303. self should: 'foo | x | < fooBar: ''return 2+3'' > ^ x := 6' return: 6
  304. !
  305. testifFalse
  306. self should: 'foo true ifFalse: [ ^ 1 ]' return: receiver.
  307. self should: 'foo false ifFalse: [ ^ 2 ]' return: 2.
  308. self should: 'foo ^ true ifFalse: [ 1 ]' return: nil.
  309. self should: 'foo ^ false ifFalse: [ 2 ]' return: 2.
  310. !
  311. testifFalseIfTrue
  312. self should: 'foo true ifFalse: [ ^ 1 ] ifTrue: [ ^ 2 ]' return: 2.
  313. self should: 'foo false ifFalse: [ ^ 2 ] ifTrue: [ ^1 ]' return: 2.
  314. self should: 'foo ^ true ifFalse: [ 1 ] ifTrue: [ 2 ]' return: 2.
  315. self should: 'foo ^ false ifFalse: [ 2 ] ifTrue: [ 1 ]' return: 2.
  316. !
  317. testifNil
  318. self should: 'foo ^ 1 ifNil: [ 2 ]' return: 1.
  319. self should: 'foo ^ nil ifNil: [ 2 ]' return: 2.
  320. self should: 'foo 1 ifNil: [ ^ 2 ]' return: receiver.
  321. self should: 'foo nil ifNil: [ ^ 2 ]' return: 2.
  322. !
  323. testifNilIfNotNil
  324. self should: 'foo ^ 1 ifNil: [ 2 ] ifNotNil: [ 3 ]' return: 3.
  325. self should: 'foo ^ nil ifNil: [ 2 ] ifNotNil: [ 3 ]' return: 2.
  326. self should: 'foo 1 ifNil: [ ^ 2 ] ifNotNil: [ ^3 ]' return: 3.
  327. self should: 'foo nil ifNil: [ ^ 2 ] ifNotNil: [ ^3 ]' return: 2.
  328. !
  329. testifNotNil
  330. self should: 'foo ^ 1 ifNotNil: [ 2 ]' return: 2.
  331. self should: 'foo ^ nil ifNotNil: [ 2 ]' return: nil.
  332. self should: 'foo 1 ifNotNil: [ ^ 2 ]' return: 2.
  333. self should: 'foo nil ifNotNil: [ ^ 2 ]' return: receiver.
  334. !
  335. testifNotNilWithArgument
  336. self should: 'foo ^ 1 ifNotNil: [ :val | val + 2 ]' return: 3.
  337. self should: 'foo ^ nil ifNotNil: [ :val | val + 2 ]' return: nil.
  338. self should: 'foo ^ 1 ifNil: [ 5 ] ifNotNil: [ :val | val + 2 ]' return: 3.
  339. self should: 'foo ^ nil ifNil: [ 5 ] ifNotNil: [ :val | val + 2 ]' return: 5.
  340. self should: 'foo ^ 1 ifNotNil: [ :val | val + 2 ] ifNil: [ 5 ]' return: 3.
  341. self should: 'foo ^ nil ifNotNil: [ :val | val + 2 ] ifNil: [ 5 ]' return: 5
  342. !
  343. testifTrue
  344. self should: 'foo false ifTrue: [ ^ 1 ]' return: receiver.
  345. self should: 'foo true ifTrue: [ ^ 2 ]' return: 2.
  346. self should: 'foo ^ false ifTrue: [ 1 ]' return: nil.
  347. self should: 'foo ^ true ifTrue: [ 2 ]' return: 2.
  348. !
  349. testifTrueIfFalse
  350. self should: 'foo false ifTrue: [ ^ 1 ] ifFalse: [ ^2 ]' return: 2.
  351. self should: 'foo true ifTrue: [ ^ 1 ] ifFalse: [ ^ 2 ]' return: 1.
  352. self should: 'foo ^ false ifTrue: [ 2 ] ifFalse: [ 1 ]' return: 1.
  353. self should: 'foo ^ true ifTrue: [ 2 ] ifFalse: [ 1 ]' return: 2.
  354. ! !
  355. !AbstractCompilerTest class methodsFor: 'testing'!
  356. isAbstract
  357. ^ self name = AbstractCompilerTest name
  358. ! !
  359. AbstractCompilerTest subclass: #ASTDebuggerTest
  360. slots: {}
  361. package: 'Compiler-Tests'!
  362. AbstractCompilerTest subclass: #ASTInterpreterTest
  363. slots: {}
  364. package: 'Compiler-Tests'!
  365. AbstractCompilerTest subclass: #CodeGeneratorTest
  366. slots: {}
  367. package: 'Compiler-Tests'!
  368. AbstractCompilerTest subclass: #InliningCodeGeneratorTest
  369. slots: {}
  370. package: 'Compiler-Tests'!
  371. ASTMethodRunningTest subclass: #AbstractJavaScriptGatewayTest
  372. slots: {#theClass}
  373. package: 'Compiler-Tests'!
  374. !AbstractJavaScriptGatewayTest methodsFor: 'accessing'!
  375. theClass
  376. ^ theClass
  377. ! !
  378. !AbstractJavaScriptGatewayTest methodsFor: 'running'!
  379. jsConstructor
  380. <inlineJS: '
  381. var ctr = function () {};
  382. ctr.prototype.foo = function (a,b) {return a+","+b};
  383. return ctr;
  384. '>
  385. ! !
  386. !AbstractJavaScriptGatewayTest methodsFor: 'tests'!
  387. testDyadicSuperDifferentNames
  388. theClass := ObjectMock subclass: #ObjectMock2 slots: #() package: 'Compiler-Tests'.
  389. theClass beJavaScriptSubclassOf: self jsConstructor.
  390. receiver := ObjectMock2 new foo: 'should be shadowed'; yourself.
  391. self while: 'bar: anObject baz: anotherObject
  392. <jsOverride: #foo args: #(anObject anotherObject)>
  393. ^ super bar: anObject baz: anotherObject' should: [
  394. self shouldnt: [ receiver bar: 3 baz: 4 ] raise: Error.
  395. self assert: (receiver bar: 4 baz: true) equals: '4,true' ]
  396. !
  397. testDyadicSuperDifferentNamesNested
  398. theClass := ObjectMock subclass: #ObjectMock2 slots: #() package: 'Compiler-Tests'.
  399. theClass beJavaScriptSubclassOf: self jsConstructor.
  400. receiver := ObjectMock2 new foo: 'should be shadowed'; yourself.
  401. self while: 'bar: anObject baz: anotherObject
  402. <jsOverride: #foo args: #(anObject anotherObject)>
  403. ^ [ super bar: anObject baz: anotherObject ] value' should: [
  404. self shouldnt: [ receiver bar: 3 baz: 4 ] raise: Error.
  405. self assert: (receiver bar: 4 baz: true) equals: '4,true' ]
  406. !
  407. testDyadicSuperDifferentNamesPermutated
  408. theClass := ObjectMock subclass: #ObjectMock2 slots: #() package: 'Compiler-Tests'.
  409. theClass beJavaScriptSubclassOf: self jsConstructor.
  410. receiver := ObjectMock2 new foo: 'should be shadowed'; yourself.
  411. self while: 'bar: anObject baz: anotherObject
  412. <jsOverride: #foo args: #(anotherObject anObject)>
  413. ^ super bar: anObject baz: anotherObject' should: [
  414. self shouldnt: [ receiver bar: 3 baz: 4 ] raise: Error.
  415. self assert: (receiver bar: 4 baz: true) equals: 'true,4' ]
  416. !
  417. testMonadicSuperDifferentNames
  418. theClass := ObjectMock subclass: #ObjectMock2 slots: #() package: 'Compiler-Tests'.
  419. theClass beJavaScriptSubclassOf: self jsConstructor.
  420. receiver := ObjectMock2 new foo: 'should be shadowed'; yourself.
  421. self while: 'bar: anObject <jsOverride: #foo args: #(anObject)> ^ super bar: anObject' should: [
  422. self shouldnt: [ receiver bar: 3 ] raise: Error.
  423. self assert: (receiver bar: 4) equals: '4,undefined' ]
  424. !
  425. testNiladicSuper
  426. theClass := ObjectMock subclass: #ObjectMock2 slots: #() package: 'Compiler-Tests'.
  427. theClass beJavaScriptSubclassOf: self jsConstructor.
  428. self
  429. should: 'foo <jsOverride: #foo> ^ super foo'
  430. receiver: (ObjectMock2 new foo: 'should be shadowed'; yourself)
  431. return: 'undefined,undefined'
  432. !
  433. testNiladicSuperDifferentNames
  434. theClass := ObjectMock subclass: #ObjectMock2 slots: #() package: 'Compiler-Tests'.
  435. theClass beJavaScriptSubclassOf: self jsConstructor.
  436. receiver := ObjectMock2 new foo: 'should be shadowed'; yourself.
  437. self while: 'bar <jsOverride: #foo> ^ super bar' should: [
  438. self shouldnt: [ receiver bar ] raise: Error.
  439. self assert: receiver bar equals: 'undefined,undefined' ]
  440. !
  441. testNiladicSuperNested
  442. theClass := ObjectMock subclass: #ObjectMock2 slots: #() package: 'Compiler-Tests'.
  443. theClass beJavaScriptSubclassOf: self jsConstructor.
  444. self
  445. should: 'foo <jsOverride: #foo> ^ [ super foo ] value'
  446. receiver: (ObjectMock2 new foo: 'should be shadowed'; yourself)
  447. return: 'undefined,undefined'
  448. !
  449. testTriadicSuperDifferentNamesPermutated
  450. theClass := ObjectMock subclass: #ObjectMock2 slots: #() package: 'Compiler-Tests'.
  451. theClass beJavaScriptSubclassOf: self jsConstructor.
  452. receiver := ObjectMock2 new foo: 'should be shadowed'; yourself.
  453. self while: 'bar: anObject baz: anotherObject moo: yao
  454. <jsOverride: #foo args: #(yao anObject anotherObject)>
  455. ^ super bar: anObject baz: anotherObject moo: yao' should: [
  456. self shouldnt: [ receiver bar: 3 baz: 4 moo: 5 ] raise: Error.
  457. self assert: (receiver bar: 4 baz: true moo: 'hello') equals: 'hello,4' ]
  458. ! !
  459. !AbstractJavaScriptGatewayTest class methodsFor: 'testing'!
  460. isAbstract
  461. ^ self name = AbstractJavaScriptGatewayTest name
  462. ! !
  463. AbstractJavaScriptGatewayTest subclass: #DebuggedJSGTest
  464. slots: {}
  465. package: 'Compiler-Tests'!
  466. AbstractJavaScriptGatewayTest subclass: #InlinedJSGTest
  467. slots: {}
  468. package: 'Compiler-Tests'!
  469. AbstractJavaScriptGatewayTest subclass: #InterpretedJSGTest
  470. slots: {}
  471. package: 'Compiler-Tests'!
  472. AbstractJavaScriptGatewayTest subclass: #PlainJSGTest
  473. slots: {}
  474. package: 'Compiler-Tests'!
  475. TestCase subclass: #ASTPCNodeVisitorTest
  476. slots: {}
  477. package: 'Compiler-Tests'!
  478. !ASTPCNodeVisitorTest methodsFor: 'factory'!
  479. astPCNodeVisitor
  480. ^ ASTPCNodeVisitor new
  481. index: 0;
  482. yourself
  483. !
  484. astPCNodeVisitorForSelector: aString
  485. ^ ASTPCNodeVisitor new
  486. selector: aString;
  487. index: 0;
  488. yourself
  489. !
  490. newTeachableVisitor
  491. | result |
  492. result := Teachable new
  493. whenSend: #visit: evaluate: [ :one | one acceptDagVisitor: result ];
  494. acceptSend: #visitDagNode:.
  495. ^ result
  496. ! !
  497. !ASTPCNodeVisitorTest methodsFor: 'tests'!
  498. testJSStatementNode
  499. | ast result |
  500. ast := self parse: 'foo <inlineJS: ''consolee.log(1)''>' forClass: Object.
  501. result := self astPCNodeVisitor visit: ast; currentNode.
  502. self
  503. assert: ((self newTeachableVisitor whenSend: #visitJSStatementNode: return: 'JS'; yourself) visit: result)
  504. equals: 'JS'
  505. !
  506. testMessageSend
  507. | ast |
  508. ast := self parse: 'foo self asString yourself. ^ self asBoolean' forClass: Object.
  509. self assert: ((self astPCNodeVisitorForSelector: 'yourself')
  510. visit: ast;
  511. currentNode) selector equals: 'yourself'
  512. !
  513. testMessageSendWithBlocks
  514. | ast |
  515. ast := self parse: 'foo true ifTrue: [ [ self asString yourself ] value. ]. ^ self asBoolean' forClass: Object.
  516. self assert: ((self astPCNodeVisitorForSelector: 'yourself')
  517. visit: ast;
  518. currentNode) selector equals: 'yourself'
  519. !
  520. testMessageSendWithInlining
  521. | ast |
  522. ast := self parse: 'foo true ifTrue: [ self asString yourself ]. ^ self asBoolean' forClass: Object.
  523. self assert: ((self astPCNodeVisitorForSelector: 'yourself')
  524. visit: ast;
  525. currentNode) selector equals: 'yourself'.
  526. ast := self parse: 'foo true ifTrue: [ self asString yourself ]. ^ self asBoolean' forClass: Object.
  527. self assert: ((self astPCNodeVisitorForSelector: 'asBoolean')
  528. visit: ast;
  529. currentNode) selector equals: 'asBoolean'
  530. !
  531. testNoMessageSend
  532. | ast |
  533. ast := self parse: 'foo ^ self' forClass: Object.
  534. self assert: (self astPCNodeVisitor
  535. visit: ast;
  536. currentNode) isNil
  537. ! !
  538. TestCase subclass: #ASTPositionTest
  539. slots: {}
  540. package: 'Compiler-Tests'!
  541. !ASTPositionTest methodsFor: 'tests'!
  542. testNodeAtPosition
  543. | node |
  544. node := self parse: 'yourself
  545. ^ self' forClass: Object.
  546. self assert: (node navigationNodeAt: 2@4 ifAbsent: [ nil ]) source equals: 'self'.
  547. node := self parse: 'foo
  548. true ifTrue: [ 1 ]' forClass: Object.
  549. self assert: (node navigationNodeAt: 2@7 ifAbsent: [ nil ]) selector equals: 'ifTrue:'.
  550. node := self parse: 'foo
  551. self foo; bar; baz' forClass: Object.
  552. self assert: (node navigationNodeAt: 2@8 ifAbsent: [ nil ]) selector equals: 'foo'
  553. ! !
  554. TestCase subclass: #AbstractCodeGeneratorInstallTest
  555. slots: {#receiver}
  556. package: 'Compiler-Tests'!
  557. !AbstractCodeGeneratorInstallTest methodsFor: 'accessing'!
  558. receiver
  559. ^ receiver
  560. ! !
  561. !AbstractCodeGeneratorInstallTest methodsFor: 'testing'!
  562. shouldntInstall: aString andRaise: anErrorClass
  563. | method |
  564. [ self
  565. should: [ method := self install: aString forClass: receiver class ]
  566. raise: anErrorClass ]
  567. ensure: [ method ifNotNil: [ receiver class removeCompiledMethod: method ] ]
  568. ! !
  569. !AbstractCodeGeneratorInstallTest methodsFor: 'tests'!
  570. testDyadicJSOverrideArgMismatch
  571. receiver := ObjectMock new.
  572. self
  573. shouldntInstall: 'quux: aNumber foo: anotherNumber
  574. <jsOverride: #mux args: #(anInteger anotherNumber)>
  575. ^ (foo := foo * aNumber + anotherNumber)'
  576. andRaise: CompilerError.
  577. self
  578. shouldntInstall: 'quux: aNumber foo: anotherNumber
  579. <jsOverride: #mux args: #(aNumber anotherInteger)>
  580. ^ (foo := foo * aNumber + anotherNumber)'
  581. andRaise: CompilerError.
  582. self
  583. shouldntInstall: 'quux: aNumber foo: anotherNumber
  584. <jsOverride: #mux args: #(anotherNumber anInteger)>
  585. ^ (foo := foo * aNumber + anotherNumber)'
  586. andRaise: CompilerError
  587. !
  588. testDyadicJSOverrideDifferentNames
  589. receiver := ObjectMock new.
  590. receiver foo: 4.
  591. self while: 'quux: anInteger foo: anotherInteger
  592. <jsOverride: #mux args: #(anInteger anotherInteger)>
  593. ^ (foo := foo * anInteger + anotherInteger)' should: [
  594. self should: [ receiver mux ] raise: MessageNotUnderstood.
  595. self should: [ receiver mux: 2 and: -1 ] raise: MessageNotUnderstood.
  596. self assert: (receiver basicPerform: #mux withArguments: #(2 -2)) equals: 6.
  597. self assert: (receiver quux: 1 foo: 4) equals: 10.
  598. self should: [ receiver basicPerform: #quux ] raise: Error.
  599. self assert: receiver foo equals: 10 ]
  600. !
  601. testDyadicJSOverrideDifferentNamesPermutated
  602. receiver := ObjectMock new.
  603. receiver foo: 4.
  604. self while: 'quux: anInteger foo: anotherInteger
  605. <jsOverride: #mux args: #(anotherInteger anInteger)>
  606. ^ (foo := foo * anInteger + anotherInteger)' should: [
  607. self should: [ receiver mux ] raise: MessageNotUnderstood.
  608. self should: [ receiver mux: 2 and: -1 ] raise: MessageNotUnderstood.
  609. self assert: (receiver basicPerform: #mux withArguments: #(-2 2)) equals: 6.
  610. self assert: (receiver quux: 1 foo: 4) equals: 10.
  611. self should: [ receiver basicPerform: #quux ] raise: Error.
  612. self assert: receiver foo equals: 10 ]
  613. !
  614. testDyadicJSOverrideInOneArg
  615. receiver := ObjectMock new.
  616. self
  617. shouldntInstall: 'quux: anInteger
  618. <jsOverride: #mux args: #(anInteger anotherInteger)>
  619. ^ (foo := foo + anInteger)'
  620. andRaise: CompilerError.
  621. self
  622. shouldntInstall: 'quux: anInteger
  623. <jsOverride: #mux args: #(anotherInteger anInteger)>
  624. ^ (foo := foo + anInteger)'
  625. andRaise: CompilerError
  626. !
  627. testDyadicJSOverrideInUnary
  628. receiver := ObjectMock new.
  629. self
  630. shouldntInstall: 'quux <jsOverride: #mux args: #(anInteger anotherInteger)> ^ (foo := foo + 3)'
  631. andRaise: CompilerError
  632. !
  633. testDyadicJSOverrideRepeatedArgs
  634. receiver := ObjectMock new.
  635. self
  636. shouldntInstall: 'quux: anInteger
  637. <jsOverride: #mux args: #(anInteger anInteger)>
  638. ^ (foo := foo + anInteger)'
  639. andRaise: CompilerError.
  640. self
  641. shouldntInstall: 'quux: anInteger foo: anotherInteger
  642. <jsOverride: #mux args: #(anInteger anInteger)>
  643. ^ (foo := foo * anInteger + anotherInteger)'
  644. andRaise: CompilerError
  645. !
  646. testInvalidAssignment
  647. self shouldntInstall: 'foo:a a:=1' andRaise: InvalidAssignmentError.
  648. self shouldntInstall: 'foo false:=1' andRaise: InvalidAssignmentError.
  649. self shouldntInstall: 'foo console:=1' andRaise: InvalidAssignmentError.
  650. self shouldntInstall: 'foo Number:=1' andRaise: InvalidAssignmentError
  651. !
  652. testMistypedPragmaJSStatement
  653. self shouldntInstall: 'foo < inlineJS: ''return ''foo'''' >' andRaise: ParseError
  654. !
  655. testMonadicJSOverrideArgMismatch
  656. receiver := ObjectMock new.
  657. self
  658. shouldntInstall: 'quux: aNumber <jsOverride: #mux args: #(anInteger)> ^ (foo := foo + aNumber)'
  659. andRaise: CompilerError
  660. !
  661. testMonadicJSOverrideDifferentNames
  662. receiver := ObjectMock new.
  663. receiver foo: 4.
  664. self while: 'quux: anInteger <jsOverride: #mux args: #(anInteger)> ^ (foo := foo + anInteger)' should: [
  665. self should: [ receiver mux ] raise: MessageNotUnderstood.
  666. self should: [ receiver mux: 2 ] raise: MessageNotUnderstood.
  667. self assert: (receiver basicPerform: #mux withArguments: #(2)) equals: 6.
  668. self assert: (receiver quux: 4) equals: 10.
  669. self should: [ receiver basicPerform: #quux ] raise: Error.
  670. self assert: receiver foo equals: 10 ]
  671. !
  672. testMonadicJSOverrideInUnary
  673. receiver := ObjectMock new.
  674. self
  675. shouldntInstall: 'quux <jsOverride: #mux args: #(anInteger)> ^ (foo := foo + 3)'
  676. andRaise: CompilerError
  677. !
  678. testNiladicJSOverride
  679. receiver := ObjectMock new.
  680. receiver foo: 4.
  681. self while: 'baz <jsOverride: #baz> ^ (foo := foo + 3)' should: [
  682. self assert: receiver baz equals: 7.
  683. self assert: (receiver basicPerform: #baz) equals: 10.
  684. self assert: receiver baz equals: 13.
  685. self assert: receiver foo equals: 13 ]
  686. !
  687. testNiladicJSOverrideDifferentNames
  688. receiver := ObjectMock new.
  689. receiver foo: 4.
  690. self while: 'quux <jsOverride: #mux> ^ (foo := foo + 3)' should: [
  691. self should: [ receiver mux ] raise: MessageNotUnderstood.
  692. self assert: (receiver basicPerform: #mux) equals: 7.
  693. self assert: receiver quux equals: 10.
  694. self should: [ receiver basicPerform: #quux ] raise: Error.
  695. self assert: receiver foo equals: 10 ]
  696. !
  697. testNiladicJSOverrideInOneArg
  698. receiver := ObjectMock new.
  699. self
  700. shouldntInstall: 'quux: anInteger <jsOverride: #mux> ^ (foo := foo + anInteger)'
  701. andRaise: CompilerError
  702. !
  703. testPragmaInBlock
  704. self shouldntInstall: 'foo ^ [ < fooBar > 4 ] value' andRaise: ParseError
  705. !
  706. testTriadicJSOverrideDifferentNamesPermutated
  707. receiver := ObjectMock new.
  708. receiver foo: 4.
  709. self while: 'quux: anInteger foo: anotherInteger bar: yaInt
  710. <jsOverride: #mux args: #(yaInt anInteger anotherInteger)>
  711. ^ (foo := foo * anInteger + anotherInteger - yaInt)' should: [
  712. self should: [ receiver mux ] raise: MessageNotUnderstood.
  713. self should: [ receiver mux: 2 and: -1 and: 0 ] raise: MessageNotUnderstood.
  714. self assert: (receiver basicPerform: #mux withArguments: #(5 2 3)) equals: 6.
  715. self assert: (receiver quux: 1 foo: 4 bar: 20) equals: -10.
  716. self should: [ receiver basicPerform: #quux ] raise: Error.
  717. self assert: receiver foo equals: -10 ]
  718. ! !
  719. !AbstractCodeGeneratorInstallTest class methodsFor: 'testing'!
  720. isAbstract
  721. ^ self name = AbstractCodeGeneratorInstallTest name
  722. ! !
  723. AbstractCodeGeneratorInstallTest subclass: #CodeGeneratorInstallTest
  724. slots: {}
  725. package: 'Compiler-Tests'!
  726. AbstractCodeGeneratorInstallTest subclass: #InliningCodeGeneratorInstallTest
  727. slots: {}
  728. package: 'Compiler-Tests'!
  729. TestCase subclass: #ScopeVarTest
  730. slots: {}
  731. package: 'Compiler-Tests'!
  732. !ScopeVarTest methodsFor: 'tests'!
  733. testClassRefVar
  734. | node binding |
  735. node := VariableNode new
  736. identifier: 'Object';
  737. yourself.
  738. SemanticAnalyzer new
  739. pushScope: MethodLexicalScope new;
  740. visit: node.
  741. binding := node binding.
  742. self deny: binding isAssignable.
  743. self deny: binding isIdempotent.
  744. self assert: (binding alias includesSubString: 'Object').
  745. self assert: (binding alias ~= 'Object')
  746. !
  747. testExternallyKnownVar
  748. | node binding |
  749. node := VariableNode new
  750. identifier: 'console';
  751. yourself.
  752. SemanticAnalyzer new
  753. pushScope: MethodLexicalScope new;
  754. visit: node.
  755. binding := node binding.
  756. self deny: binding isAssignable.
  757. self deny: binding isIdempotent.
  758. self assert: binding alias equals: 'console'
  759. !
  760. testExternallyUnknownVar
  761. | node |
  762. node := VariableNode new
  763. identifier: 'bzzz';
  764. yourself.
  765. self
  766. should: [
  767. SemanticAnalyzer new
  768. pushScope: MethodLexicalScope new;
  769. visit: node ]
  770. raise: UnknownVariableError
  771. !
  772. testInstanceVar
  773. | binding |
  774. binding := MethodLexicalScope new
  775. addIVar: 'bzzz';
  776. bindingFor: 'bzzz'.
  777. self assert: binding isAssignable.
  778. self deny: binding isIdempotent.
  779. self assert: (binding alias includesSubString: 'bzzz').
  780. self assert: (binding alias ~= 'bzzz')
  781. !
  782. testPseudoVar
  783. #('self' 'super' 'true' 'false' 'nil' 'thisContext') do: [ :each |
  784. | binding |
  785. binding := MethodLexicalScope new bindingFor: each.
  786. self deny: binding isAssignable.
  787. self assert: binding isIdempotent ]
  788. !
  789. testTempVar
  790. | binding |
  791. binding := MethodLexicalScope new
  792. addTemp: 'bzzz';
  793. bindingFor: 'bzzz'.
  794. self assert: binding isAssignable.
  795. self deny: binding isIdempotent.
  796. self assert: binding alias equals: 'bzzz'
  797. !
  798. testUnknownVar
  799. self assert: (MethodLexicalScope new bindingFor: 'bzzz') isNil
  800. ! !
  801. TestCase subclass: #SemanticAnalyzerTest
  802. slots: {#analyzer}
  803. package: 'Compiler-Tests'!
  804. !SemanticAnalyzerTest methodsFor: 'running'!
  805. setUp
  806. analyzer := SemanticAnalyzer on: Object
  807. ! !
  808. !SemanticAnalyzerTest methodsFor: 'tests'!
  809. testAssignment
  810. | src ast |
  811. src := 'foo self := 1'.
  812. ast := Smalltalk parse: src.
  813. self should: [analyzer visit: ast] raise: InvalidAssignmentError
  814. !
  815. testNonLocalReturn
  816. | src ast |
  817. src := 'foo | a | a + 1. ^ a'.
  818. ast := Smalltalk parse: src.
  819. analyzer visit: ast.
  820. self deny: ast scope hasNonLocalReturn
  821. !
  822. testNonLocalReturn2
  823. | src ast |
  824. src := 'foo | a | a + 1. [ [ ^ a] ]'.
  825. ast := Smalltalk parse: src.
  826. analyzer visit: ast.
  827. self assert: ast scope hasNonLocalReturn
  828. !
  829. testScope
  830. | src ast |
  831. src := 'foo | a | a + 1. [ | b | b := a ]'.
  832. ast := Smalltalk parse: src.
  833. analyzer visit: ast.
  834. self deny: ast sequenceNode dagChildren last scope == ast scope.
  835. !
  836. testScope2
  837. | src ast |
  838. src := 'foo | a | a + 1. [ [ | b | b := a ] ]'.
  839. ast := Smalltalk parse: src.
  840. analyzer visit: ast.
  841. self deny: ast sequenceNode dagChildren last sequenceNode dagChildren first scope == ast scope.
  842. !
  843. testScopeLevel
  844. | src ast |
  845. src := 'foo | a | a + 1. [ [ | b | b := a ] ]'.
  846. ast := Smalltalk parse: src.
  847. analyzer visit: ast.
  848. self assert: ast scope scopeLevel equals: 1.
  849. self assert: ast sequenceNode dagChildren last sequenceNode dagChildren first scope scopeLevel equals: 3
  850. !
  851. testUnknownVariables
  852. | src ast |
  853. src := 'foo | a | b + a'.
  854. ast := Smalltalk parse: src.
  855. self should: [ analyzer visit: ast ] raise: UnknownVariableError
  856. !
  857. testUnknownVariablesWithScope
  858. | src ast |
  859. src := 'foo | a b | [ c + 1. [ a + 1. d + 1 ]]'.
  860. ast := Smalltalk parse: src.
  861. self should: [ analyzer visit: ast ] raise: UnknownVariableError
  862. !
  863. testVariableShadowing
  864. | src ast |
  865. src := 'foo | a | a + 1'.
  866. ast := Smalltalk parse: src.
  867. analyzer visit: ast
  868. !
  869. testVariableShadowing2
  870. | src ast |
  871. src := 'foo | a | a + 1. [ | a | a := 2 ]'.
  872. ast := Smalltalk parse: src.
  873. self should: [analyzer visit: ast] raise: ShadowingVariableError
  874. !
  875. testVariableShadowing3
  876. | src ast |
  877. src := 'foo | a | a + 1. [ | b | b := 2 ]'.
  878. ast := Smalltalk parse: src.
  879. analyzer visit: ast
  880. !
  881. testVariableShadowing4
  882. | src ast |
  883. src := 'foo | a | a + 1. [ [ [ | b | b := 2 ] ] ]'.
  884. ast := Smalltalk parse: src.
  885. analyzer visit: ast
  886. !
  887. testVariableShadowing5
  888. | src ast |
  889. src := 'foo | a | a + 1. [ [ [ | a | a := 2 ] ] ]'.
  890. ast := Smalltalk parse: src.
  891. self should: [analyzer visit: ast] raise: ShadowingVariableError
  892. !
  893. testVariablesLookup
  894. | src ast |
  895. src := 'foo | a | a + 1. [ | b | b := a ]'.
  896. ast := Smalltalk parse: src.
  897. analyzer visit: ast.
  898. "Binding for `a` in the message send"
  899. self assert: ast sequenceNode dagChildren first receiver binding isAssignable.
  900. self assert: ast sequenceNode dagChildren first receiver binding alias equals: 'a'.
  901. self assert: ast sequenceNode dagChildren first receiver binding scope == ast scope.
  902. "Binding for `b`"
  903. self assert: ast sequenceNode dagChildren last sequenceNode dagChildren first left binding isAssignable.
  904. self assert: ast sequenceNode dagChildren last sequenceNode dagChildren first left binding alias equals: 'b'.
  905. self assert: ast sequenceNode dagChildren last sequenceNode dagChildren first left binding scope == ast sequenceNode dagChildren last scope.
  906. ! !
  907. SemanticAnalyzerTest subclass: #AISemanticAnalyzerTest
  908. slots: {}
  909. package: 'Compiler-Tests'!
  910. !AISemanticAnalyzerTest methodsFor: 'running'!
  911. setUp
  912. analyzer := (AISemanticAnalyzer on: Object)
  913. context: (AIContext new
  914. defineLocal: 'local';
  915. localAt: 'local' put: 3;
  916. yourself);
  917. yourself
  918. ! !
  919. !AISemanticAnalyzerTest methodsFor: 'tests'!
  920. testContextVariables
  921. | src ast |
  922. src := 'foo | a | local + a'.
  923. ast := Smalltalk parse: src.
  924. self shouldnt: [ analyzer visit: ast ] raise: UnknownVariableError
  925. ! !
  926. Trait named: #TASTCompilingTest
  927. package: 'Compiler-Tests'!
  928. !TASTCompilingTest methodsFor: 'accessing'!
  929. codeGeneratorClass
  930. self subclassResponsibility
  931. ! !
  932. !TASTCompilingTest methodsFor: 'compiling'!
  933. install: aString forClass: aClass
  934. ^ self compiler
  935. install: aString
  936. forClass: aClass
  937. protocol: 'tests'
  938. ! !
  939. !TASTCompilingTest methodsFor: 'factory'!
  940. compiler
  941. ^ Compiler new
  942. codeGeneratorClass: self codeGeneratorClass;
  943. yourself
  944. ! !
  945. !TASTCompilingTest methodsFor: 'testing'!
  946. while: aString inClass: aClass should: aBlock
  947. | method |
  948. [
  949. method := self install: aString forClass: aClass.
  950. aBlock value: method ]
  951. ensure: [ method ifNotNil: [ aClass removeCompiledMethod: method ] ]
  952. !
  953. while: aString should: aBlock
  954. self while: aString inClass: self receiver class should: aBlock
  955. ! !
  956. Trait named: #TASTParsingTest
  957. package: 'Compiler-Tests'!
  958. !TASTParsingTest methodsFor: 'parsing'!
  959. parse: aString forClass: aClass
  960. ^ Compiler new
  961. ast: aString
  962. forClass: aClass
  963. protocol: 'test'
  964. ! !
  965. Trait named: #TCTDebugged
  966. package: 'Compiler-Tests'!
  967. !TCTDebugged methodsFor: 'private'!
  968. interpret: aString forClass: aClass receiver: anObject withArguments: aDictionary
  969. "The food is a methodNode. Interpret the sequenceNode only"
  970. | ctx |
  971. ctx := self prepareContextFor: aString class: aClass receiver: anObject withArguments: aDictionary.
  972. ^ (ASTDebugger context: ctx) proceed; result
  973. ! !
  974. Trait named: #TCTExecuted
  975. package: 'Compiler-Tests'!
  976. !TCTExecuted methodsFor: 'testing'!
  977. while: aString inClass: aClass should: aBlock
  978. super
  979. while: aString
  980. inClass: aClass
  981. should: [ :method | aBlock value: [
  982. self receiver perform: method selector ] ]
  983. ! !
  984. Trait named: #TCTInlined
  985. package: 'Compiler-Tests'!
  986. !TCTInlined methodsFor: 'accessing'!
  987. codeGeneratorClass
  988. ^ InliningCodeGenerator
  989. ! !
  990. Trait named: #TCTInterpreted
  991. package: 'Compiler-Tests'!
  992. !TCTInterpreted methodsFor: 'private'!
  993. interpret: aString forClass: aClass receiver: anObject withArguments: aDictionary
  994. "The food is a methodNode. Interpret the sequenceNode only"
  995. | ctx |
  996. ctx := self prepareContextFor: aString class: aClass receiver: anObject withArguments: aDictionary.
  997. ^ ctx interpreter proceed; result
  998. !
  999. prepareContextFor: aString class: aClass receiver: anObject withArguments: aDictionary
  1000. "The food is a methodNode. Interpret the sequenceNode only"
  1001. | ctx ast |
  1002. ast := self parse: aString forClass: aClass.
  1003. ctx := AIContext new
  1004. receiver: anObject;
  1005. selector: ast selector;
  1006. interpreter: ASTInterpreter new;
  1007. yourself.
  1008. "Define locals for the context"
  1009. ast sequenceNode ifNotNil: [ :sequence |
  1010. sequence temps do: [ :each |
  1011. ctx defineLocal: each ] ].
  1012. aDictionary keysAndValuesDo: [ :key :value |
  1013. ctx localAt: key put: value ].
  1014. ctx interpreter
  1015. context: ctx;
  1016. node: ast;
  1017. enterNode.
  1018. ^ctx
  1019. ! !
  1020. !TCTInterpreted methodsFor: 'testing'!
  1021. while: aString inClass: aClass should: aBlock
  1022. super
  1023. while: aString
  1024. inClass: aClass
  1025. should: [ aBlock value: [
  1026. self
  1027. interpret: aString
  1028. forClass: aClass
  1029. receiver: self receiver
  1030. withArguments: #{} ] ]
  1031. ! !
  1032. Trait named: #TCTNonInlined
  1033. package: 'Compiler-Tests'!
  1034. !TCTNonInlined methodsFor: 'accessing'!
  1035. codeGeneratorClass
  1036. ^ CodeGenerator
  1037. ! !
  1038. TASTCompilingTest setTraitComposition: {TASTParsingTest} asTraitComposition!
  1039. TCTDebugged setTraitComposition: {TCTInterpreted} asTraitComposition!
  1040. ASTMethodRunningTest setTraitComposition: {TASTCompilingTest} asTraitComposition!
  1041. ASTDebuggerTest setTraitComposition: {TCTNonInlined. TCTDebugged} asTraitComposition!
  1042. ASTInterpreterTest setTraitComposition: {TCTNonInlined. TCTInterpreted} asTraitComposition!
  1043. CodeGeneratorTest setTraitComposition: {TCTNonInlined. TCTExecuted} asTraitComposition!
  1044. InliningCodeGeneratorTest setTraitComposition: {TCTInlined. TCTExecuted} asTraitComposition!
  1045. AbstractJavaScriptGatewayTest setTraitComposition: {TClassBuildingTest} asTraitComposition!
  1046. DebuggedJSGTest setTraitComposition: {TCTNonInlined. TCTDebugged} asTraitComposition!
  1047. InlinedJSGTest setTraitComposition: {TCTInlined. TCTExecuted} asTraitComposition!
  1048. InterpretedJSGTest setTraitComposition: {TCTNonInlined. TCTInterpreted} asTraitComposition!
  1049. PlainJSGTest setTraitComposition: {TCTNonInlined. TCTExecuted} asTraitComposition!
  1050. ASTPCNodeVisitorTest setTraitComposition: {TASTParsingTest} asTraitComposition!
  1051. ASTPositionTest setTraitComposition: {TASTParsingTest} asTraitComposition!
  1052. AbstractCodeGeneratorInstallTest setTraitComposition: {TASTCompilingTest} asTraitComposition!
  1053. CodeGeneratorInstallTest setTraitComposition: {TCTNonInlined} asTraitComposition!
  1054. InliningCodeGeneratorInstallTest setTraitComposition: {TCTInlined} asTraitComposition!
  1055. ! !