Not logged in.  Login/Logout/Register | List snippets | | Create snippet | Upload image | Upload data

391
LINES

< > BotCompany Repo | #1035077 // test_leftArrowScript_classDefs (OK)

JavaX fragment (include) [tags: use-pretranspiled]

Transpiled version (37081L) is out of date.

1  
set flag OurSyncCollections.
2  
3  
!include once #1034831 // Gazelle 22 Function Include for Testing
4  
5  
svoid test_leftArrowScript_classDefs() {
6  
  temp LASMultiClassLoader cl = new(mc());
7  
  test_leftArrowScript_classDefs(cl);
8  
}
9  
10  
sclass test_leftArrowScript_classDefs_Base {
11  
  S hey() { ret "ho"; }
12  
}
13  
14  
svoid test_leftArrowScript_classDefs(LASMultiClassLoader cl) {
15  
  var test = new TestFunctionValues<S, O>(l1 leftArrowVerbose);
16  
17  
  // define a class with two fields
18  
  
19  
  S classPrefix = "scriptClasses.";
20  
21  
  embedded O runScript(S code) {  
22  
    new GazelleV_LeftArrowScriptParser parser;
23  
    enableScaffolding(parser);
24  
    parser.classDefPrefix(classPrefix);
25  
    parser.lasClassLoader(cl);
26  
    ret leftArrowVerbose(parser, code);
27  
  }
28  
29  
  S classSrc = [[
30  
    class MyClass {
31  
      a: String
32  
      b: String
33  
    }
34  
  ]], src = classSrc;
35  
36  
  Class c = cast runScript(src);
37  
  assertStartsWith(print(c.getName()), classPrefix + "MyClass" + "_");
38  
  
39  
  // compile same source again - make sure we get the same class object
40  
  assertSame(c, runScript(src));
41  
  
42  
  assertEqualsVerbose("Number of fields", 3, l(getDeclaredFields_cached(c)));
43  
  assertEqualsVerbose("Type of a", S.class, getField(c, "a").getType());
44  
  assertEqualsVerbose("Type of b", S.class, getField(c, "b").getType());
45  
  
46  
  // Make sure a change in the class definition gives us a new class name
47  
  Class c2 = cast runScript([[
48  
    class MyClass {
49  
      a: String
50  
      c: String
51  
    }
52  
  ]]);
53  
  print(className(c2));
54  
  assertNotSame(c, c2);
55  
  
56  
  // Make sure a change in the methods also gives us a new class name
57  
  S classSrc2 = [[
58  
    class MyClass {
59  
      def bla { "x" }
60  
    }
61  
  ]];
62  
  c = (Class) runScript(classSrc2);
63  
  assertSame(c, runScript(classSrc2));
64  
  c2 = (Class) runScript([[
65  
    class MyClass {
66  
      def bla { "y" }
67  
    }
68  
  ]]);
69  
  assertNotSame(c, c2);
70  
  
71  
  // Now let's try and use a script-defined class
72  
  
73  
  src = classSrc + [[
74  
    x <- new MyClass
75  
    y <- new MyClass
76  
    x a <- "yo"
77  
    y a <- "oy"
78  
    x a
79  
  ]];
80  
  
81  
  assertEqualsVerbose("yo", runScript(src));
82  
  
83  
  // Using the class in a function
84  
  
85  
  src = classSrc + [[
86  
    def bla {
87  
      x <- new MyClass
88  
      x a <- "yo"
89  
      x a
90  
    }
91  
    bla
92  
  ]];
93  
  
94  
  assertEqualsVerbose("yo", runScript(src));
95  
  
96  
  // Now for defining some methods (yay!)
97  
  
98  
  src = [[
99  
    class MyClass2 {
100  
      def method1 { "I'm here" }
101  
      def method2 a { reversed a }
102  
    }
103  
    
104  
    x <- new MyClass2
105  
    pair (x method1) (x method2 "sey")
106  
  ]];
107  
  
108  
  assertEqualsVerbose(pair("I'm here", "yes"), runScript(src));
109  
  
110  
  // accessing instance fields
111  
  
112  
  src = [[
113  
    class MyClass3 {
114  
      a: String
115  
      
116  
      def getA { this a } // requiring the this keyword for now
117  
      def setA a { this a <- a }
118  
      def aLength { (this a) length }
119  
    }
120  
    
121  
    x <- new MyClass3
122  
    x setA "abc"
123  
    assertEquals (x aLength) 3
124  
    x getA
125  
  ]];
126  
  
127  
  assertEqualsVerbose("abc", runScript(src));
128  
129  
  // fully qualified type  
130  
  classSrc = [[
131  
    class MyClass4 {
132  
      a: java.util.List
133  
    }
134  
  ]];
135  
136  
  c = (Class) runScript(classSrc);
137  
  assertEqualsVerbose(fieldType(c, "a"), L.class);
138  
  
139  
  // type with type parameter
140  
  classSrc = [[
141  
    class MyClass5 {
142  
      a: L<S>
143  
    }
144  
  ]];
145  
146  
  c = (Class) runScript(classSrc);
147  
  assertEqualsVerbose("Raw type of L<S> field", fieldType(c, "a"), L.class);
148  
  assertEqualsVerbose("Generic type of L<S> field", genericFieldType(c, "a"),
149  
    new ParameterizedTypeImpl(null, L, S));
150  
    
151  
  // primitive type
152  
  classSrc = [[
153  
    class MyClass6 {
154  
      x: int
155  
    }
156  
  ]];
157  
158  
  c = (Class) runScript(classSrc);
159  
  assertEqualsVerbose(fieldType(c, "x"), int.class);
160  
  
161  
  classSrc = [[
162  
    class ToString {
163  
      def toString : S { "It's me, George!" }
164  
    }
165  
    new ToString
166  
  ]];
167  
  
168  
  assertEqualsVerbose("It's me, George!", str(runScript(classSrc)));
169  
  
170  
  // primitive array
171  
  classSrc = [[
172  
    class MyClass7 {
173  
      x: int[]
174  
    }
175  
  ]];
176  
177  
  c = (Class) runScript(classSrc);
178  
  assertEqualsVerbose(fieldType(c, "x"), int[].class);
179  
180  
  // define class implementing interface
181  
  
182  
  classSrc =
183  
    [[ class Bla is IF0 { def get { "hello" } }
184  
       new Bla ]];
185  
    
186  
  IF0 f = cast runScript(classSrc);
187  
  assertEqualsVerbose("hello", f!);
188  
  
189  
  // call function on class defined inline
190  
  
191  
  assertEqualsVerbose(Class.class, runScript([[
192  
    _getClass2 class A { }
193  
  ]]));
194  
  
195  
  // constructor
196  
197  
  assertEqualsVerbose(5, runScript([[
198  
    class MyClass8 {
199  
      x: int
200  
      
201  
      ctor { this x <- 5 }
202  
    }
203  
    
204  
    new MyClass8, x
205  
  ]]);
206  
  
207  
  // initialized field
208  
209  
  assertEqualsVerbose(7, runScript([[
210  
    class MyClass9 {
211  
      x: int <- 7
212  
    }
213  
    
214  
    new MyClass9, x
215  
  ]]);
216  
  
217  
  cl.rememberClassBytes(true);
218  
  cl.onClassDefined(l1 disassembleClass);
219  
  
220  
  // define class with superclass
221  
  
222  
  classSrc = [[
223  
    class A { def yo { "yay" } }
224  
    class B extends A { def wow { joinWithSpace (this yo) "amazing!" } }
225  
    new B, wow
226  
  ]];
227  
  
228  
  assertEqualsVerbose("yay amazing!", runScript(classSrc));
229  
    
230  
  // define class with superclass from outside of script
231  
  
232  
  classSrc = [[
233  
    class B extends test_leftArrowScript_classDefs_Base {
234  
      def wow { joinWithSpace (this hey) (this hey) (this hey) } }
235  
    new B, wow
236  
  ]];
237  
    
238  
  assertEqualsVerbose("ho ho ho", runScript(classSrc));
239  
  
240  
  // initializer
241  
242  
  runScript([[
243  
    class MyClass9 {
244  
      x: int
245  
      initializer { this x <- 5 }
246  
    }
247  
    
248  
    assertEqualsVerbose 5 < new MyClass9, x
249  
  ]]);
250  
    
251  
  runScript([[
252  
    class MyClass10 {
253  
      l: L <- new ArrayList
254  
      initializer { this l, add "init" }
255  
      ctor { this l, add "ctor" }
256  
    }
257  
    
258  
    assertEqualsVerbose (ll "init" "ctor") < new MyClass10, l
259  
  ]]);
260  
  
261  
  // TODO: Call superclass method (basically needs full method compilation)
262  
  
263  
  /*runScript([[
264  
    class MyClassA {
265  
      def x: S { "hello" }
266  
    }
267  
    
268  
    class MyClassB extends MyClassA {
269  
      def x: S { ret concat (super x) " world" }
270  
    }
271  
    
272  
    assertEqualsVerbose "hello world" < new MyClassB, x
273  
  ]]);*/
274  
  
275  
  // Reference own class name
276  
  
277  
  runScript([[
278  
    class MyClassSelf {
279  
      def me: MyClassSelf { this }
280  
    }
281  
  ]]);
282  
  
283  
  // Methods have proper argument types
284  
  
285  
  runScript([[
286  
    class ArgTypes {
287  
      def doIt (s: S) { "a string" }
288  
      def doIt (s: O) { "not a string" }
289  
    }
290  
    
291  
    assertEqualsVerbose "a string" < new ArgTypes, doIt "yo"
292  
    assertEqualsVerbose "not a string" < new ArgTypes, doIt 123
293  
  ]]);
294  
  
295  
  // Methods with primitive return type
296  
  
297  
  runScript([[
298  
    class PrimReturn {
299  
      def theNumber: int { 123 }
300  
    }
301  
    
302  
    assertEqualsVerbose 123 < new PrimReturn, theNumber
303  
    assertEqualsVerbose "int" < str < findMethod (new PrimReturn) "theNumber", getReturnType
304  
  ]]);
305  
  
306  
  // settable fields
307  
  
308  
  runScript([[
309  
    class Settable {
310  
      settable x: int
311  
      settable b: bool
312  
      settable l: long
313  
      settable d: double
314  
      settable y: S
315  
    }
316  
    
317  
    s <- new Settable, x 5, y "test", b true
318  
    assertEqualsVerbose 5 < s x
319  
    assertEqualsVerbose 5 < call s "x"
320  
    assertEqualsVerbose "test" < s y
321  
    assertEqualsVerbose "test" < call s "y"
322  
    assertEqualsVerbose true < s b
323  
  ]]);
324  
  
325  
  // settable field with initializer
326  
  
327  
  runScript([[
328  
    class Settable {
329  
      settable s: S <- "hello"
330  
    }
331  
    
332  
    assertEqualsVerbose "hello" < new Settable, s
333  
  ]]);
334  
  
335  
  // selfType as method return type
336  
  
337  
  runScript([[
338  
    class SelfTypeTest {
339  
      def me: selfType { this }
340  
    }
341  
    
342  
    t <- new SelfTypeTest
343  
    assertEqualsVerbose t < t me
344  
  ]]);
345  
  
346  
  // void methods
347  
  
348  
  runScript([[
349  
    class VoidMethodTest is Closeable {
350  
      def close: void {}
351  
    }
352  
  ]]);
353  
  
354  
  // transient field
355  
  
356  
  O o = runScript([[
357  
    class TransientTest {
358  
      transient i: int
359  
    }
360  
    new TransientTest
361  
  ]]);
362  
  assertTrueVerbose("transient", isTransient(fieldObject(o, "i")));
363  
  
364  
  // LS as type
365  
  
366  
  o = runScript([[
367  
    class LSTest {
368  
      l: LS
369  
    }
370  
    new LSTest
371  
  ]]);
372  
  assertEqualsVerbose("java.util.List<java.lang.String>",
373  
    str(genericFieldType(o, "l")));
374  
    
375  
  // Referring to a script-defined class as a Class
376  
  
377  
  o = runScript([[
378  
    class MyClass {}
379  
    MyClass
380  
  ]]);
381  
  assertContainsVerbose("MyClass", className((Class) o));
382  
  
383  
  // static field
384  
  
385  
  o = runScript([[
386  
    class MyClass {
387  
      static hello: S <- "world"
388  
    }
389  
  ]]);
390  
  assertEqualsVerbose("world", get((Class) o, "hello"));
391  
}

download  show line numbers  debug dex  old transpilations   

Travelled to 6 computer(s): bhatertpkbcr, ekrmjmnbrukm, elmgxqgtpvxh, mowyntqkapby, mqqgnosmbjvj, wnsclhtenguj

No comments. add comment

Snippet ID: #1035077
Snippet name: test_leftArrowScript_classDefs (OK)
Eternal ID of this version: #1035077/86
Text MD5: 63cf200439f165632fcba747d09ca9cf
Author: stefan
Category: javax / left arrow script
Type: JavaX fragment (include)
Public (visible to everyone): Yes
Archived (hidden from active list): No
Created/modified: 2023-04-29 23:36:14
Source code size: 8666 bytes / 391 lines
Pitched / IR pitched: No / No
Views / Downloads: 238 / 686
Version history: 85 change(s)
Referenced in: [show references]