| |
| import core.stdc.stdio; |
| |
| /*******************************************************/ |
| |
| class Outer |
| { |
| int o; |
| static int os = 3; |
| |
| static class StaticInner |
| { |
| int si; |
| |
| int foo() |
| { |
| return si + os; |
| } |
| } |
| |
| class Inner |
| { |
| int i; |
| |
| int foo(int m) |
| { |
| return i * o + m; |
| } |
| |
| this(int k) |
| { |
| i = k + 7; |
| os = 6; |
| } |
| } |
| |
| Inner bar() |
| { |
| return new Inner(17); |
| } |
| } |
| |
| void test1() |
| { |
| Outer p = new Outer(); |
| |
| assert(p.o == 0); |
| assert(p.os == 3); |
| p.o = 9; |
| |
| Outer.StaticInner s = new Outer.StaticInner; |
| s.si = 10; |
| assert(s.foo() == 13); |
| |
| Outer.Inner q = p.bar(); |
| assert(q.i == 24); |
| assert(q.foo(8) == 24*9+8); |
| } |
| |
| /*******************************************************/ |
| |
| class C1 |
| { |
| int c1; |
| |
| this() |
| { |
| c1 = 2; |
| } |
| |
| class C2 |
| { |
| class C3 |
| { |
| int c3; |
| |
| this(int n) |
| { |
| c3 = n + c1 + c2; |
| } |
| } |
| |
| int c2; |
| |
| C3 foo() |
| { |
| return new C3(8); |
| } |
| |
| this(int k) |
| { |
| c2 = k + 7; |
| } |
| } |
| |
| C2 bar() |
| { |
| return new C2(17); |
| } |
| } |
| |
| void test2() |
| { |
| C1 p = new C1(); |
| assert(p.c1 == 2); |
| |
| C1.C2 q = p.bar(); |
| assert(q.c2 == 24); |
| |
| C1.C2.C3 r = q.foo(); |
| assert(r.c3 == 2+24+8); |
| } |
| |
| /*******************************************************/ |
| |
| class C3 |
| { |
| int c1; |
| |
| this() |
| { |
| c1 = 2; |
| } |
| |
| class B { } |
| |
| class C2 : B |
| { |
| int c2; |
| |
| this(int k) |
| { |
| c2 = c1 + k + 7; |
| } |
| } |
| |
| C2 bar() |
| { |
| return new C2(17); |
| } |
| } |
| |
| void test3() |
| { |
| C3 q = new C3(); |
| assert(q.c1 == 2); |
| C3.C2 p = q.bar(); |
| assert(p.c2 == 26); |
| } |
| |
| |
| /*******************************************************/ |
| |
| void test4() |
| { |
| int m = 3; |
| |
| class C |
| { |
| void foo() |
| { |
| assert(m == 3); |
| } |
| } |
| |
| void bar() |
| { |
| assert(m == 3); |
| } |
| |
| bar(); |
| C c = new C; |
| c.foo(); |
| } |
| |
| /*******************************************************/ |
| |
| void test5() |
| { |
| int m = 3; |
| |
| void bar() |
| { |
| assert(m == 3); |
| } |
| |
| class C |
| { |
| void foo() |
| { |
| assert(m == 3); |
| bar(); |
| } |
| } |
| |
| bar(); |
| C c = new C; |
| c.foo(); |
| } |
| |
| |
| /*******************************************************/ |
| |
| void test6() |
| { |
| int m = 3; |
| |
| void bar() |
| { |
| assert(m == 3); |
| } |
| |
| void abc() |
| { |
| class C |
| { |
| void foo() |
| { |
| assert(m == 3); |
| bar(); |
| } |
| } |
| |
| bar(); |
| C c = new C; |
| c.foo(); |
| } |
| |
| abc(); |
| } |
| |
| /*******************************************************/ |
| |
| void test7() |
| { |
| int m = 3; |
| |
| void bar() |
| { |
| assert(m == 3); |
| } |
| |
| void ghi() |
| { |
| void abc() |
| { |
| class C |
| { |
| void foo() |
| { |
| assert(m == 3); |
| bar(); |
| } |
| } |
| |
| bar(); |
| C c = new C; |
| c.foo(); |
| } |
| |
| abc(); |
| } |
| |
| ghi(); |
| } |
| |
| /*******************************************************/ |
| |
| void test8() |
| { |
| int m = 3; |
| |
| void bar() |
| { |
| assert(m == 3); |
| } |
| |
| void ghi() |
| { |
| void abc() |
| { |
| class C |
| { |
| void foo() |
| { |
| void fooey() |
| { |
| assert(m == 3); |
| bar(); |
| } |
| |
| fooey(); |
| } |
| } |
| |
| bar(); |
| C c = new C; |
| c.foo(); |
| } |
| |
| abc(); |
| } |
| |
| ghi(); |
| } |
| |
| /*******************************************************/ |
| |
| class C9 |
| { |
| int m; |
| |
| void ccc() |
| { |
| assert(m == 3); |
| } |
| |
| this() |
| { |
| m = 3; |
| } |
| |
| class D |
| { |
| int n; |
| |
| this() { n = 4; } |
| |
| void abc() |
| { |
| assert(m == 3); |
| ccc(); |
| } |
| } |
| |
| D def() |
| { |
| return new D; |
| } |
| } |
| |
| |
| void test9() |
| { |
| C9 c = new C9; |
| assert(c.m == 3); |
| c.ccc(); |
| |
| C9.D d = c.def(); |
| assert(d.n == 4); |
| d.abc(); |
| } |
| |
| /*******************************************************/ |
| |
| void test10() |
| { |
| int m = 3; |
| |
| class C |
| { |
| void foo() |
| { |
| assert(m == 3); |
| } |
| } |
| |
| void abc() |
| { |
| C c = new C; |
| c.foo(); |
| } |
| |
| abc(); |
| } |
| |
| /*******************************************************/ |
| |
| void test11() |
| { |
| int m = 3; |
| |
| class C |
| { |
| void foo() |
| { |
| assert(m == 3); |
| } |
| } |
| |
| void abc() |
| { |
| void def() |
| { |
| C c = new C; |
| c.foo(); |
| } |
| |
| def(); |
| } |
| |
| abc(); |
| } |
| |
| /*******************************************************/ |
| |
| void test12() |
| { |
| int m = 3; |
| |
| class C |
| { |
| void foo() |
| { |
| assert(m == 3); |
| } |
| |
| void abc() |
| { |
| assert(m == 3); |
| C c = new C; |
| c.foo(); |
| } |
| } |
| |
| C d = new C; |
| d.abc(); |
| } |
| |
| /*******************************************************/ |
| |
| void test13() |
| { |
| int m = 3; |
| |
| class C |
| { |
| void foo() |
| { |
| assert(m == 3); |
| } |
| |
| void abc() |
| { |
| void def() |
| { |
| assert(m == 3); |
| C c = new C; |
| c.foo(); |
| } |
| |
| def(); |
| } |
| } |
| |
| C d = new C; |
| d.abc(); |
| } |
| |
| /*******************************************************/ |
| |
| class C14 |
| { |
| void foo() |
| { |
| assert(0); |
| } |
| } |
| |
| void test14() |
| { |
| int m = 3; |
| |
| C14 c = new class C14 |
| { |
| override void foo() |
| { |
| printf("in inner class\n"); |
| assert(m == 3); |
| } |
| }; |
| |
| c.foo(); |
| } |
| |
| /*******************************************************/ |
| |
| class C15 |
| { |
| void foo() |
| { |
| assert(0); |
| } |
| } |
| |
| void test15() |
| { |
| int m = 3; |
| |
| C15 c = new class(1,2) C15 |
| { |
| this(int i, int j) |
| { |
| printf("in inner class ctor\n"); |
| assert(i == 1); |
| assert(j == 2); |
| } |
| |
| override void foo() |
| { |
| printf("in inner class\n"); |
| assert(m == 3); |
| } |
| }; |
| |
| c.foo(); |
| } |
| |
| /*******************************************************/ |
| |
| class C16 |
| { |
| int w = 3; |
| |
| void iterator() |
| { |
| class Foo |
| { |
| void current() |
| { |
| assert(w == 3); |
| } |
| } |
| |
| Foo f = new Foo(); |
| f.current(); |
| } |
| } |
| |
| void test16() |
| { |
| C16 s = new C16(); |
| |
| s.iterator(); |
| } |
| |
| /*******************************************************/ |
| |
| class Owner |
| { |
| |
| this() |
| { |
| n = new Nested(this); |
| } |
| |
| class Nested |
| { |
| this(Owner owner) |
| { |
| m = owner; |
| } |
| |
| Owner foo() |
| { |
| return m; |
| } |
| |
| Owner m; |
| } |
| |
| Nested n; |
| } |
| |
| class OwnerDerived : Owner |
| { |
| } |
| |
| void test17() |
| { |
| OwnerDerived o = new OwnerDerived(); |
| |
| assert(o.n.foo() is o); |
| } |
| |
| /*******************************************************/ |
| |
| class Foo18 |
| { |
| class Bar |
| { |
| void doSayHello() |
| { |
| printf("Betty\n"); |
| sayHello(); |
| } |
| } |
| Bar bar; |
| |
| void sayHello() |
| { |
| printf("Hello\n"); |
| } |
| } |
| |
| class Foo182 : Foo18 |
| { |
| this() |
| { |
| bar = new Bar(); |
| } |
| } |
| |
| void test18() |
| { |
| Foo182 foo = new Foo182(); |
| printf("This should print Hello:\n"); |
| |
| foo.bar.doSayHello(); |
| } |
| |
| /*******************************************************/ |
| |
| class Foo19 |
| { |
| class Bar |
| { |
| void doSayHello() |
| { |
| printf("Betty\n"); |
| sayHello(); |
| } |
| } |
| Bar bar; |
| |
| void sayHello() |
| { |
| printf("Hello\n"); |
| } |
| |
| this() |
| { |
| bar = new Bar(); |
| } |
| } |
| |
| class Foo192 : Foo19 |
| { |
| } |
| |
| void test19() |
| { |
| Foo192 foo = new Foo192(); |
| printf("This should print Hello:\n"); |
| |
| foo.bar.doSayHello(); |
| } |
| |
| /*******************************************************/ |
| |
| class Outer20 |
| { |
| int a; |
| |
| class Inner |
| { |
| int foo() |
| { |
| return a; |
| } |
| } |
| } |
| |
| void test20() |
| { |
| Outer20 o = new Outer20; |
| o.a = 3; |
| Outer20.Inner oi = o.new Inner; |
| assert(oi.foo() == 3); |
| } |
| |
| /*******************************************************/ |
| |
| class Foo21{} |
| |
| static if (is(typeof(new class Foo21{}))) {} |
| |
| void test21() |
| { |
| } |
| |
| /*******************************************************/ |
| |
| class Outer22 |
| { |
| class Inner |
| { |
| Outer22 foo() |
| { |
| return this.outer; |
| } |
| } |
| |
| void bar() |
| { |
| Inner i = new Inner; |
| assert(this == i.foo()); |
| } |
| } |
| |
| void test22() |
| { |
| Outer22 o = new Outer22; |
| o.bar(); |
| } |
| |
| /*******************************************************/ |
| |
| class Adapter23 |
| { |
| void func() { } |
| } |
| |
| class Foo23 |
| { |
| class AnonAdapter : Adapter23 |
| { |
| } |
| |
| void bar() |
| { |
| Adapter23 a = cast( Adapter23 )( new AnonAdapter() ); |
| } |
| } |
| |
| void test23() |
| { |
| Foo23 f = new Foo23(); |
| f.bar(); |
| Adapter23 a = cast( Adapter23 )( f.new AnonAdapter() ); |
| auto aa = f.new AnonAdapter(); |
| Adapter23 ab = cast( Adapter23 )(aa); |
| |
| } |
| |
| /*******************************************************/ |
| |
| class I24 |
| { |
| public abstract void callI(); |
| } |
| |
| C24 c24; |
| |
| class C24 |
| { |
| private int index; |
| void foo() |
| { |
| printf( "ok, this = %p\n", this); |
| assert(this == c24); |
| } |
| I24 bar() |
| { |
| auto i = new class() I24 |
| { |
| override public void callI() |
| { |
| foo(); |
| } |
| }; |
| printf("bar.this = %p\n", this); |
| printf(" i.this = %p\n", (cast(void**)i)[2]); |
| assert(*cast(void**)&c24 == (cast(void**)i)[2]); |
| return i; |
| } |
| } |
| |
| void test24() |
| { |
| c24 = new C24; |
| printf("c = %p\n", c24); |
| auto i = c24.bar(); |
| i.callI(); |
| } |
| |
| /*******************************************************/ |
| |
| struct S7426 |
| { |
| static struct Inner |
| { |
| int x; |
| alias typeof(Inner.tupleof) T; |
| } |
| } |
| |
| /*******************************************************/ |
| // https://issues.dlang.org/show_bug.cgi?id=14046 |
| |
| class A14046 |
| { |
| class NestedA { } |
| } |
| |
| class B14046 : A14046 |
| { |
| int field; |
| |
| class NestedB : NestedA |
| { |
| void foo() |
| { |
| this.outer.field = 1; // ok <- disallowed |
| |
| //(cast(B14046)this.outer).field = 1; // workaround |
| } |
| } |
| } |
| |
| void test14046() |
| { |
| auto b = new B14046(); |
| auto nb = b.new NestedB(); |
| assert(b.field == 0); |
| nb.foo(); |
| assert(b.field == 1); |
| } |
| |
| /*******************************************************/ |
| // https://issues.dlang.org/show_bug.cgi?id=15839 |
| |
| class AnimatedProgress15839(bool makeClosure) |
| { |
| static AnimatedProgress15839 saveThis; |
| |
| interface Runnable {} |
| |
| static class GC |
| { |
| this(AnimatedProgress15839 ap) |
| { |
| assert(ap is saveThis); |
| } |
| } |
| |
| void start() |
| { |
| assert(this is saveThis); |
| |
| static if (makeClosure) int a; |
| |
| auto r = new class Runnable |
| { |
| void run() |
| { |
| static assert(is(typeof(this.outer) == AnimatedProgress15839)); |
| assert(this.outer is saveThis); |
| |
| GC gc = new GC(this.outer); |
| |
| static if (makeClosure) int b = a; |
| } |
| }; |
| r.run(); |
| } |
| } |
| |
| void test15839() |
| { |
| auto ap1 = new AnimatedProgress15839!false(); |
| ap1.saveThis = ap1; |
| ap1.start(); |
| |
| auto ap2 = new AnimatedProgress15839!true(); |
| ap2.saveThis = ap2; |
| ap2.start(); |
| } |
| |
| /*******************************************************/ |
| |
| int main() |
| { |
| |
| test1(); |
| test2(); |
| test3(); |
| test4(); |
| test5(); |
| test6(); |
| test7(); |
| test8(); |
| test9(); |
| test10(); |
| |
| test11(); |
| test12(); |
| test13(); |
| |
| test14(); |
| test15(); |
| test16(); |
| test17(); |
| test18(); |
| test19(); |
| test20(); |
| |
| test21(); |
| test22(); |
| test23(); |
| test24(); |
| |
| test14046(); |
| test15839(); |
| |
| printf("Success\n"); |
| return 0; |
| } |