Warning: session_start(): open(/var/lib/php/sessions/sess_t8cjn6tcsc2uff9mjmq1gq4503, O_RDWR) failed: No space left on device (28) in /var/www/tb-usercake/models/config.php on line 51
Warning: session_start(): Failed to read session data: files (path: /var/lib/php/sessions) in /var/www/tb-usercake/models/config.php on line 51
set flag OurSyncCollections.
!include once #1034831 // Gazelle 22 Function Include for Testing
svoid test_leftArrowScript_classDefs() {
temp LASMultiClassLoader cl = new(mc());
test_leftArrowScript_classDefs(cl);
}
sclass test_leftArrowScript_classDefs_Base {
S hey() { ret "ho"; }
}
svoid test_leftArrowScript_classDefs(LASMultiClassLoader cl) {
var test = new TestFunctionValues(l1 leftArrowVerbose);
// define a class with two fields
S classPrefix = "scriptClasses.";
embedded O runScript(S code) {
new GazelleV_LeftArrowScriptParser parser;
enableScaffolding(parser);
parser.classDefPrefix(classPrefix);
parser.lasClassLoader(cl);
ret leftArrowVerbose(parser, code);
}
S classSrc = [[
class MyClass {
a: String
b: String
}
]], src = classSrc;
Class c = cast runScript(src);
assertStartsWith(print(c.getName()), classPrefix + "MyClass" + "_");
// compile same source again - make sure we get the same class object
assertSame(c, runScript(src));
assertEqualsVerbose("Number of fields", 3, l(getDeclaredFields_cached(c)));
assertEqualsVerbose("Type of a", S.class, getField(c, "a").getType());
assertEqualsVerbose("Type of b", S.class, getField(c, "b").getType());
// Make sure a change in the class definition gives us a new class name
Class c2 = cast runScript([[
class MyClass {
a: String
c: String
}
]]);
print(className(c2));
assertNotSame(c, c2);
// Make sure a change in the methods also gives us a new class name
S classSrc2 = [[
class MyClass {
def bla { "x" }
}
]];
c = (Class) runScript(classSrc2);
assertSame(c, runScript(classSrc2));
c2 = (Class) runScript([[
class MyClass {
def bla { "y" }
}
]]);
assertNotSame(c, c2);
// Now let's try and use a script-defined class
src = classSrc + [[
x <- new MyClass
y <- new MyClass
x a <- "yo"
y a <- "oy"
x a
]];
assertEqualsVerbose("yo", runScript(src));
// Using the class in a function
src = classSrc + [[
def bla {
x <- new MyClass
x a <- "yo"
x a
}
bla
]];
assertEqualsVerbose("yo", runScript(src));
// Now for defining some methods (yay!)
src = [[
class MyClass2 {
def method1 { "I'm here" }
def method2 a { reversed a }
}
x <- new MyClass2
pair (x method1) (x method2 "sey")
]];
assertEqualsVerbose(pair("I'm here", "yes"), runScript(src));
// accessing instance fields
src = [[
class MyClass3 {
a: String
def getA { this a } // requiring the this keyword for now
def setA a { this a <- a }
def aLength { (this a) length }
}
x <- new MyClass3
x setA "abc"
assertEquals (x aLength) 3
x getA
]];
assertEqualsVerbose("abc", runScript(src));
// fully qualified type
classSrc = [[
class MyClass4 {
a: java.util.List
}
]];
c = (Class) runScript(classSrc);
assertEqualsVerbose(fieldType(c, "a"), L.class);
// type with type parameter
classSrc = [[
class MyClass5 {
a: L
}
]];
c = (Class) runScript(classSrc);
assertEqualsVerbose("Raw type of L field", fieldType(c, "a"), L.class);
assertEqualsVerbose("Generic type of L field", genericFieldType(c, "a"),
new ParameterizedTypeImpl(null, L, S));
// primitive type
classSrc = [[
class MyClass6 {
x: int
}
]];
c = (Class) runScript(classSrc);
assertEqualsVerbose(fieldType(c, "x"), int.class);
classSrc = [[
class ToString {
def toString : S { "It's me, George!" }
}
new ToString
]];
assertEqualsVerbose("It's me, George!", str(runScript(classSrc)));
// primitive array
classSrc = [[
class MyClass7 {
x: int[]
}
]];
c = (Class) runScript(classSrc);
assertEqualsVerbose(fieldType(c, "x"), int[].class);
// define class implementing interface
classSrc =
[[ class Bla is IF0 { def get { "hello" } }
new Bla ]];
IF0 f = cast runScript(classSrc);
assertEqualsVerbose("hello", f!);
// call function on class defined inline
assertEqualsVerbose(Class.class, runScript([[
_getClass2 class A { }
]]));
// constructor
assertEqualsVerbose(5, runScript([[
class MyClass8 {
x: int
ctor { this x <- 5 }
}
new MyClass8, x
]]);
// initialized field
assertEqualsVerbose(7, runScript([[
class MyClass9 {
x: int <- 7
}
new MyClass9, x
]]);
cl.rememberClassBytes(true);
cl.onClassDefined(l1 disassembleClass);
// define class with superclass
classSrc = [[
class A { def yo { "yay" } }
class B extends A { def wow { joinWithSpace (this yo) "amazing!" } }
new B, wow
]];
assertEqualsVerbose("yay amazing!", runScript(classSrc));
// define class with superclass from outside of script
classSrc = [[
class B extends test_leftArrowScript_classDefs_Base {
def wow { joinWithSpace (this hey) (this hey) (this hey) } }
new B, wow
]];
assertEqualsVerbose("ho ho ho", runScript(classSrc));
// initializer
runScript([[
class MyClass9 {
x: int
initializer { this x <- 5 }
}
assertEqualsVerbose 5 < new MyClass9, x
]]);
runScript([[
class MyClass10 {
l: L <- new ArrayList
initializer { this l, add "init" }
ctor { this l, add "ctor" }
}
assertEqualsVerbose (ll "init" "ctor") < new MyClass10, l
]]);
// TODO: Call superclass method (basically needs full method compilation)
/*runScript([[
class MyClassA {
def x: S { "hello" }
}
class MyClassB extends MyClassA {
def x: S { ret concat (super x) " world" }
}
assertEqualsVerbose "hello world" < new MyClassB, x
]]);*/
// Reference own class name
runScript([[
class MyClassSelf {
def me: MyClassSelf { this }
}
]]);
// Methods have proper argument types
runScript([[
class ArgTypes {
def doIt (s: S) { "a string" }
def doIt (s: O) { "not a string" }
}
assertEqualsVerbose "a string" < new ArgTypes, doIt "yo"
assertEqualsVerbose "not a string" < new ArgTypes, doIt 123
]]);
// Methods with primitive return type
runScript([[
class PrimReturn {
def theNumber: int { 123 }
}
assertEqualsVerbose 123 < new PrimReturn, theNumber
assertEqualsVerbose "int" < str < findMethod (new PrimReturn) "theNumber", getReturnType
]]);
// settable fields
runScript([[
class Settable {
settable x: int
settable b: bool
settable l: long
settable d: double
settable y: S
}
s <- new Settable, x 5, y "test", b true
assertEqualsVerbose 5 < s x
assertEqualsVerbose 5 < call s "x"
assertEqualsVerbose "test" < s y
assertEqualsVerbose "test" < call s "y"
assertEqualsVerbose true < s b
]]);
// settable field with initializer
runScript([[
class Settable {
settable s: S <- "hello"
}
assertEqualsVerbose "hello" < new Settable, s
]]);
// selfType as method return type
runScript([[
class SelfTypeTest {
def me: selfType { this }
}
t <- new SelfTypeTest
assertEqualsVerbose t < t me
]]);
// void methods
runScript([[
class VoidMethodTest is Closeable {
def close: void {}
}
]]);
// transient field
O o = runScript([[
class TransientTest {
transient i: int
}
new TransientTest
]]);
assertTrueVerbose("transient", isTransient(fieldObject(o, "i")));
// LS as type
o = runScript([[
class LSTest {
l: LS
}
new LSTest
]]);
assertEqualsVerbose("java.util.List",
str(genericFieldType(o, "l")));
// Referring to a script-defined class as a Class
o = runScript([[
class MyClass {}
MyClass
]]);
assertContainsVerbose("MyClass", className((Class) o));
// static field
o = runScript([[
class MyClass {
static hello: S <- "world"
}
]]);
assertEqualsVerbose("world", get((Class) o, "hello"));
// other script-defined class as field type
runScript([[
class MyA {}
class MyB { settable a: MyA }
]]);
}