| /********************************************************************** |
| * This file is part of "Object Teams Development Tooling"-Software |
| * |
| * Copyright 2012 Stephan Herrmann |
| * |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Please visit http://www.eclipse.org/objectteams for updates and contact. |
| * |
| * Contributors: |
| * Stephan Herrmann - Initial API and implementation |
| **********************************************************************/ |
| package org.eclipse.objectteams.otdt.tests.otjld.other; |
| |
| import java.util.Map; |
| |
| import junit.framework.Test; |
| |
| import org.eclipse.jdt.core.JavaCore; |
| import org.eclipse.jdt.core.tests.util.CompilerTestSetup; |
| import org.eclipse.jdt.internal.compiler.impl.CompilerOptions; |
| import org.eclipse.objectteams.otdt.core.ext.WeavingScheme; |
| import org.eclipse.objectteams.otdt.tests.otjld.AbstractOTJLDTest; |
| |
| public class Java8 extends AbstractOTJLDTest { |
| |
| public Java8(String name) { |
| super(name); |
| } |
| |
| // Static initializer to specify tests subset using TESTS_* static variables |
| // All tests which do not belong to the subset are skipped... |
| static { |
| TESTS_NAMES = new String[] { "testBug541865"}; |
| // TESTS_NUMBERS = new int[] { 1459 }; |
| // TESTS_RANGE = new int[] { 1097, -1 }; |
| } |
| |
| public static Test suite() { |
| Test suite = buildMinimalComplianceTestSuite(Java8.class, F_1_8); |
| TESTS_COUNTERS.put(Java8.class.getName(), new Integer(suite.countTestCases())); |
| return suite; |
| } |
| |
| public static Class<Java8> testClass() { |
| return Java8.class; |
| } |
| |
| @Override |
| public void initialize(CompilerTestSetup setUp) { |
| super.initialize(setUp); |
| if (this.weavingScheme == WeavingScheme.OTRE) |
| System.err.println("Running Java8 tests for OTRE weaver will skip most tests"); |
| } |
| |
| private void runNegativeTestNoFlush(String[] testFiles, Map<String, String> compilerOptions, String error) { |
| runNegativeTest(false, testFiles, null, compilerOptions, error, DEFAULT_TEST_OPTIONS); |
| } |
| |
| private void runConformTestNoFlush(String[] testFiles, Map<String, String> compilerOptions) { |
| runConformTest(false, testFiles, null, compilerOptions, "", "", "", DEFAULT_TEST_OPTIONS); |
| } |
| |
| // A lambda expression appears in a parameter mapping |
| // - empty param list |
| public void testA11_lambdaExpression01() { |
| if (this.weavingScheme == WeavingScheme.OTRE) return; |
| runConformTest( |
| new String[] { |
| "p1/TeamA11le01.java", |
| "package p1;\n" + |
| "public team class TeamA11le01 {\n" + |
| " protected class Role playedBy TA11le01 {\n" + |
| " protected String v = \"OK\";\n" + |
| " void outside() -> void run(Runnable r) with {\n" + |
| " () -> System.out.println(v) -> r\n" + |
| " }\n" + |
| " }\n" + |
| " void test(TA11le01 as Role r) {\n" + |
| " r.outside();\n" + |
| " } \n" + |
| " public static void main(String[] args) throws Exception {\n" + |
| " new TeamA11le01().test(new TA11le01());\n" + |
| " }\n" + |
| "}", |
| "p1/TA11le01.java", |
| "package p1;\n" + |
| "public class TA11le01 {\n" + |
| " public void run(Runnable r) {\n" + |
| " try {\n" + |
| " r.run();\n" + |
| " } catch (NullPointerException npe) {System.out.print(\"caught\"); }\n" + |
| " }\n" + |
| "}", |
| }, |
| "OK"); // FIXME real execution of lambda |
| } |
| |
| // A lambda expression appears in a parameter mapping |
| // - single ident param |
| // - lambda is 2nd mapping |
| public void testA11_lambdaExpression02() { |
| if (this.weavingScheme == WeavingScheme.OTRE) return; |
| runConformTest( |
| new String[] { |
| "p1/TeamA11le02.java", |
| "package p1;\n" + |
| "public team class TeamA11le02 {\n" + |
| " protected class Role playedBy TA11le02 {\n" + |
| " protected String v;\n" + |
| " void outside() -> void run(String s, RunWithArg<String> r) with {\n" + |
| " \"prefix.\" -> s,\n" + |
| " x -> System.out.println(Role.this.v) -> r\n" + |
| " }\n" + |
| " }\n" + |
| " void test(TA11le02 as Role r) {\n" + |
| " r.v = \"OK\";" + |
| " r.outside();\n" + |
| " } \n" + |
| " public static void main(String[] args) throws Exception {\n" + |
| " new TeamA11le02().test(new TA11le02());\n" + |
| " }\n" + |
| "}", |
| "p1/RunWithArg.java", |
| "package p1;\n" + |
| "public interface RunWithArg<T> {\n" + |
| " void run(T a);\n" + |
| "}\n", |
| "p1/TA11le02.java", |
| "package p1;\n" + |
| "public class TA11le02 {\n" + |
| " public void run(String s, RunWithArg<String> r) {\n" + |
| " System.out.print(s);\n" + |
| " try {\n" + |
| " r.run(s);\n" + |
| " } catch (NullPointerException npe) {System.out.print(\"caught\"); }\n" + |
| " }\n" + |
| "}", |
| }, |
| "prefix.OK"); |
| } |
| |
| // A lambda expression appears in a parameter mapping |
| // - two type elided params |
| public void testA11_lambdaExpression03() { |
| if (this.weavingScheme == WeavingScheme.OTRE) return; |
| runConformTest( |
| new String[] { |
| "p1/TeamA11le03.java", |
| "package p1;\n" + |
| "public team class TeamA11le03 {\n" + |
| " protected class Role playedBy TA11le03 {\n" + |
| " void outside() -> void run(IA11le03 r) with {\n" + |
| " (x,y) -> System.out.println(\"\"+x+y) -> r\n" + |
| " }\n" + |
| " }\n" + |
| " void test(TA11le03 as Role r) {\n" + |
| " r.outside();\n" + |
| " } \n" + |
| " public static void main(String[] args) throws Exception {\n" + |
| " new TeamA11le03().test(new TA11le03());\n" + |
| " }\n" + |
| "}", |
| "p1/IA11le03.java", |
| "package p1;\n" + |
| "public interface IA11le03 {\n" + |
| " void invoke(String s1, String s2);\n" + |
| "}", |
| "p1/TA11le03.java", |
| "package p1;\n" + |
| "public class TA11le03 {\n" + |
| " public void run(IA11le03 r) {\n" + |
| " try {\n" + |
| " r.invoke(\"O\", \"K\");\n" + |
| " } catch (NullPointerException npe) {System.out.print(\"caught\"); }\n" + |
| " }\n" + |
| "}", |
| }, |
| "OK"); |
| } |
| |
| // A lambda expression appears in a parameter mapping |
| // - two typed params |
| public void testA11_lambdaExpression04() { |
| if (this.weavingScheme == WeavingScheme.OTRE) return; |
| runConformTest( |
| new String[] { |
| "p1/TeamA11le04.java", |
| "package p1;\n" + |
| "public team class TeamA11le04 {\n" + |
| " protected class Role playedBy TA11le04 {\n" + |
| " void outside() -> void run(IA11le04 r) with {\n" + |
| " (String x, String y) -> System.out.println(\"\"+x+y) -> r\n" + |
| " }\n" + |
| " }\n" + |
| " void test(TA11le04 as Role r) {\n" + |
| " r.outside();\n" + |
| " } \n" + |
| " public static void main(String[] args) throws Exception {\n" + |
| " new TeamA11le04().test(new TA11le04());\n" + |
| " }\n" + |
| "}", |
| "p1/IA11le04.java", |
| "package p1;\n" + |
| "public interface IA11le04 {\n" + |
| " void invoke(String s1, String s2);\n" + |
| "}", |
| "p1/TA11le04.java", |
| "package p1;\n" + |
| "public class TA11le04 {\n" + |
| " public void run(IA11le04 r) {\n" + |
| " try {\n" + |
| " r.invoke(\"O\", \"K\");\n" + |
| " } catch (NullPointerException npe) {System.out.print(\"caught\"); }\n" + |
| " }\n" + |
| "}", |
| }, |
| "OK"); |
| } |
| |
| public void testTypeAnnotationAndTypeAnchor_1() { |
| if (this.weavingScheme == WeavingScheme.OTRE) return; |
| runConformTest( |
| new String[] { |
| "Marker.java", |
| "import java.lang.annotation.*;\n" + |
| "@Retention(RetentionPolicy.CLASS)\n" + |
| "@Target({ ElementType.TYPE_USE })\n" + |
| "public @interface Marker {}\n", |
| "T1.java,", |
| "public team class T1 {\n" + |
| " public class R {}\n" + |
| "}\n", |
| "C1.java", |
| "public abstract class C1 {\n" + |
| " abstract void test1(final T1 o, R<@o> c);\n" + |
| " abstract void test2(final Object o, C2<@Marker Object> c);\n" + |
| "}\n" + |
| "class C2<T> {}\n" |
| }); |
| } |
| |
| public void testTypeAnnotationAndTypeAnchor_2() { |
| if (this.weavingScheme == WeavingScheme.OTRE) return; |
| runConformTest( |
| new String[] { |
| "p1/Marker.java", |
| "package p1;\n" + |
| "import java.lang.annotation.*;\n" + |
| "@Retention(RetentionPolicy.CLASS)\n" + |
| "@Target({ ElementType.TYPE_USE })\n" + |
| "public @interface Marker {}\n", |
| "p1/Marker2.java", |
| "package p1;\n" + |
| "import java.lang.annotation.*;\n" + |
| "@Retention(RetentionPolicy.CLASS)\n" + |
| "@Target({ ElementType.TYPE_USE })\n" + |
| "public @interface Marker2 {}\n", |
| "T1.java,", |
| "public team class T1 {\n" + |
| " public class R {}\n" + |
| "}\n", |
| "C1.java", |
| "public abstract team class C1 {\n" + |
| " final T1 t = new T1();\n" + |
| " abstract void test1(final C1 a, R<@a.t> c);\n" + |
| " abstract void test2(final Object o, C2<java.lang.@p1.Marker Object> c);\n" + // bug, should be java.lang. @p1.Marker Object |
| " abstract void test3(final Object o, C2<@p1.Marker @p1.Marker2 Object> c);\n" + // bug, should be java.lang. @p1.Marker Object |
| "}\n" + |
| "class C2<T> {}\n" |
| }); |
| } |
| |
| public void testOtreWarning() { |
| runConformTest( |
| new String[] { |
| "B.java", |
| "public class B {}\n" |
| }); |
| Map<String, String> compilerOptions = getCompilerOptions(); |
| compilerOptions.put(CompilerOptions.OPTION_ReportOtreWeavingIntoJava8, CompilerOptions.ERROR); |
| String[] teamSource = new String[] { "MyTeam.java", |
| "public team class MyTeam {\n" + |
| " protected class R playedBy B {}\n" + |
| "}\n" }; |
| if (this.weavingScheme == WeavingScheme.OTRE) |
| runNegativeTestNoFlush( |
| teamSource, |
| compilerOptions, |
| "----------\n" + |
| "1. WARNING in MyTeam.java (at line 2)\n" + |
| " protected class R playedBy B {}\n" + |
| " ^\n" + |
| "Base class B has class file version 52 which cannot be handled by the traditional OTRE based on BCEL. Please consider using the ASM based OTDRE instead.\n" + |
| "----------\n"); |
| else |
| runConformTestNoFlush(teamSource, compilerOptions); |
| } |
| |
| |
| public void testImplicitInheritanceWithDefaultMethods1() { |
| if (this.weavingScheme == WeavingScheme.OTRE) return; |
| runConformTest( |
| new String[]{ |
| "SubTeam.java", |
| "public team class SubTeam extends SuperTeam {\n" + |
| " public interface I2 {\n" + |
| " default void bar() { System.out.println(\"subbar\"); }\n" + |
| " }\n" + |
| " protected class R {\n" + |
| " protected void foo() {\n" + |
| " System.out.println(\"foosub\");\n" + |
| " }\n" + |
| " }\n" + |
| " public static void main(String[] args) {\n" + |
| " new SubTeam().test();\n" + |
| " }\n" + |
| "}\n", |
| "SuperTeam.java", |
| "public team class SuperTeam {\n" + |
| " public interface I2 {\n" + |
| " default void bar() { System.out.println(\"bar\"); }\n" + |
| " }\n" + |
| " protected class R implements I2 {\n" + |
| " protected void foo() {\n" + |
| " System.out.println(\"foo\");\n" + |
| " }\n" + |
| " }\n" + |
| " protected void test() {\n" + |
| " R r = new R();\n" + |
| " r.foo();\n" + |
| " r.bar();\n" + |
| " }\n" + |
| "}\n" |
| }, |
| "foosub\n" + |
| "subbar"); |
| } |
| |
| // Bug475635 |
| public void testBaseCallsInLambdas() { |
| runConformTest( |
| new String[] { |
| "b/Base.java", |
| "package b;\n" + |
| "public class Base {\n" + |
| " public void bm() { System.out.print(\"b\"); }\n" + |
| " public static void main(String... args) {\n" + |
| " new t.MyT().activate();\n" + |
| " new Base().bm();\n" + |
| " }\n" + |
| "}\n", |
| "t/MyT.java", |
| "package t;\n" + |
| "import base b.Base;\n" + |
| "\n" + |
| "public team class MyT {\n" + |
| "\n" + |
| " protected class R playedBy Base {\n" + |
| " void perform(Runnable r) { r.run(); }\n" + |
| " @SuppressWarnings(\"basecall\")\n" + |
| " callin void test() {\n" + |
| " perform(() -> {\n" + |
| " System.out.print(0);\n" + |
| " base.test();\n" + |
| " System.out.print(1);\n" + |
| " perform(() -> base.test());\n" + |
| " });\n" + |
| " new Runnable() {\n" + |
| " @Override\n" + |
| " public void run() {\n" + |
| " perform(() -> {\n" + |
| " System.out.print(2);\n" + |
| " base.test(); \n" + |
| " });\n" + |
| " System.out.print(3);\n" + |
| " base.test();\n" + |
| " System.out.println(4);\n" + |
| " }\n" + |
| " }.run();\n" + |
| " }\n" + |
| " test <- replace bm;\n" + |
| " }\n" + |
| "}\n" |
| }, |
| "0b1b2b3b4"); |
| } |
| |
| public void testBug506747() { |
| Map<String,String> options = getCompilerOptions(); |
| options.put(JavaCore.COMPILER_ANNOTATION_NULL_ANALYSIS, JavaCore.ENABLED); // enable AnnotatableTypeSystem |
| runNegativeTest( |
| new String[] { |
| "p/X.java", |
| "package p;\n" + |
| "import java.lang.annotation.*;\n" + |
| "@Target(ElementType.TYPE_USE)\n" + |
| "@interface Ann {}\n" + |
| "public class X {\n" + |
| " void m(final @Ann X X) {\n" + |
| " X.Inner i;\n" + |
| " }\n" + |
| "}\n" |
| }, |
| "----------\n" + |
| "1. ERROR in p\\X.java (at line 7)\n" + |
| " X.Inner i;\n" + |
| " ^^^^^^^\n" + |
| "X.Inner cannot be resolved to a type\n" + |
| "----------\n", |
| null, // libs |
| true, // flush |
| options); |
| } |
| |
| public void testBug506749a() { |
| runNegativeTest( |
| new String[] { |
| "Bug506749.java", |
| "public team class Bug506749 {\n" + |
| " protected class R {\n" + |
| " void test() {\n" + |
| " Runnable r = () -> base();\n" + |
| " }\n" + |
| " }\n" + |
| "}\n" |
| }, |
| "----------\n" + |
| "1. ERROR in Bug506749.java (at line 4)\n" + |
| " Runnable r = () -> base();\n" + |
| " ^^^^\n" + |
| "Illegal base constructor call: enclosing '() -> <no expression yet>' is not a constructor of a bound role (OTJLD 2.4.2).\n" + |
| "----------\n"); |
| } |
| |
| public void testBug506749b() { |
| runNegativeTest( |
| new String[] { |
| "Bug506749.java", |
| "public team class Bug506749 {\n" + |
| " protected class R {\n" + |
| " void test() {\n" + |
| " Runnable r = () -> { base(); };\n" + |
| " }\n" + |
| " }\n" + |
| "}\n" |
| }, |
| "----------\n" + |
| "1. ERROR in Bug506749.java (at line 4)\n" + |
| " Runnable r = () -> { base(); };\n" + |
| " ^^^^\n" + |
| "Illegal base constructor call: enclosing \'() -> {\n" + |
| " <no expression yet>;\n" + |
| "}\' is not a constructor of a bound role (OTJLD 2.4.2).\n" + |
| "----------\n"); |
| } |
| |
| public void testBug541865() { |
| runConformTest( |
| new String[] { |
| "Bug541865Main.java", |
| "public class Bug541865Main {\n" + |
| " public static void main(String... args) throws Exception {\n" + |
| " new Bug541865Team().activate();\n" + |
| " new Bug541865().log(\"orgarg\");\n" + |
| " Thread.sleep(100);\n" + |
| " }\n" + |
| "}\n", |
| "Bug541865.java", |
| "public class Bug541865 {\n" + |
| " public void log(String msg) { System.out.print(msg); }\n" + |
| "}\n", |
| "Bug541865Team.java", |
| "import java.util.concurrent.*;\n" + |
| "public team class Bug541865Team {\n" + |
| " protected class R playedBy Bug541865 {\n" + |
| " callin void logLater() {\n" + |
| " CompletableFuture.runAsync(() -> base.logLater());\n" + |
| " }\n" + |
| " logLater <- replace log;\n" + |
| " }\n" + |
| "}\n" |
| }, |
| "orgarg"); |
| } |
| public void testBug541865_static() { |
| runConformTest( |
| new String[] { |
| "Bug541865sMain.java", |
| "import java.util.*;\n" + |
| "public class Bug541865sMain {\n" + |
| " public static void main(String... args) throws Exception {\n" + |
| " new Bug541865sTeam().activate();\n" + |
| " Bug541865s.log(new ArrayList<String>(), \"orgarg\");\n" + |
| " Thread.sleep(100);\n" + |
| " }\n" + |
| "}\n", |
| "Bug541865s.java", |
| "import java.util.*;\n" + |
| "public class Bug541865s {\n" + |
| " public static void log(List<?> dummy, String msg) { System.out.print(msg); }\n" + |
| "}\n", |
| "Bug541865sTeam.java", |
| "import java.util.concurrent.*;\n" + |
| "public team class Bug541865sTeam {\n" + |
| " protected class R playedBy Bug541865s {\n" + |
| " static callin void logLater() {\n" + |
| " CompletableFuture.runAsync(() -> base.logLater());\n" + |
| " }\n" + |
| " logLater <- replace log;\n" + |
| " }\n" + |
| "}\n" |
| }, |
| "orgarg"); |
| } |
| public void testBug541865b() { |
| runConformTest( |
| new String[] { |
| "Bug541865bMain.java", |
| "public class Bug541865bMain {\n" + |
| " public static void main(String... args) {\n" + |
| " org.objectteams.Team t = new Bug541865bTeam();\n" + |
| " t.activate();\n" + |
| " new Bug541865b().log(\"orgarg\");\n" + |
| " t.deactivate();\n" + |
| " }\n" + |
| "}\n", |
| "Bug541865b.java", |
| "public class Bug541865b {\n" + |
| " public void log(String msg) { System.out.print(msg); }\n" + |
| "}\n", |
| "Bug541865bTeam.java", |
| "public team class Bug541865bTeam {\n" + |
| " protected class R playedBy Bug541865b {\n" + |
| " callin void logWrapped() {\n" + |
| " System.out.print('(');\n" + |
| " wrapped(() -> base.logWrapped());\n" + |
| " System.out.print(')');\n" + |
| " }\n" + |
| " logWrapped <- replace log;\n" + |
| " }\n" + |
| " void wrapped(Runnable run) {\n" + |
| " System.out.print('<');\n" + |
| " run.run();\n" + |
| " System.out.print('>');\n" + |
| " }\n" + |
| "}\n" |
| }, |
| "(<orgarg>)"); |
| } |
| public void testBug541865b_static() { |
| runConformTest( |
| new String[] { |
| "Bug541865bsbMain.java", |
| "public class Bug541865bsbMain {\n" + |
| " public static void main(String... args) {\n" + |
| " org.objectteams.Team t = new Bug541865bsbTeam();\n" + |
| " t.activate();\n" + |
| " Bug541865bsb.log(\"orgarg\");\n" + |
| " t.deactivate();\n" + |
| " }\n" + |
| "}\n", |
| "Bug541865bsb.java", |
| "public class Bug541865bsb {\n" + |
| " public static void log(String msg) { System.out.print(msg); }\n" + |
| "}\n", |
| "Bug541865bsbTeam.java", |
| "public team class Bug541865bsbTeam {\n" + |
| " protected class R playedBy Bug541865bsb {\n" + |
| " static callin void logWrapped() {\n" + |
| " System.out.print('(');\n" + |
| " wrapped(() -> base.logWrapped());\n" + |
| " System.out.print(')');\n" + |
| " }\n" + |
| " logWrapped <- replace log;\n" + |
| " }\n" + |
| " static void wrapped(Runnable run) {\n" + |
| " System.out.print('<');\n" + |
| " run.run();\n" + |
| " System.out.print('>');\n" + |
| " }\n" + |
| "}\n" |
| }, |
| "(<orgarg>)"); |
| } |
| } |