blob: 199652844da5ca6c7cee45bec2dcfa407be02e3c [file] [log] [blame]
/**********************************************************************
* This file is part of "Object Teams Development Tooling"-Software
*
* Copyright 2014 Stephan Herrmann
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* 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.tests.util.CompilerTestSetup;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.objectteams.otdt.core.ext.WeavingScheme;
import org.eclipse.objectteams.otdt.tests.otjld.AbstractOTJLDNullAnnotationTest;
/** Test combination of OT-types with null type annotations. */
public class OTNullTypeAnnotationTest extends AbstractOTJLDNullAnnotationTest {
public OTNullTypeAnnotationTest(String name) {
super(name);
}
// Static initializer to specify tests subset using TESTS_* static variables
// All specified tests which do not belong to the class are skipped...
static {
// TESTS_NAMES = new String[] { "testExplicitTeamAnchor1" };
// TESTS_NUMBERS = new int[] { 561 };
// TESTS_RANGE = new int[] { 1, 2049 };
}
public static Test suite() {
return buildMinimalComplianceTestSuite(testClass(), F_1_8);
}
public static Class testClass() {
return OTNullTypeAnnotationTest.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");
}
// test standard generated methods via basic team-role-base setup
// Bug 443306 - [1.8][null] generated method getAllRoles() triggers null pointer warning / error
public void testBoundRole() {
if (this.weavingScheme == WeavingScheme.OTRE) return;
runConformTestWithLibs(
new String[] {
"bug443306/MyTeam.java",
"package bug443306;\n" +
"import base bug443306.b.MyBase;\n" +
"public team class MyTeam {\n" +
" protected class MyRole playedBy MyBase {\n" +
" protected void print() {\n" +
" System.out.println(\"print\");\n" +
" }\n" +
" print <- after bar;\n" +
" }\n" +
" public static void main(String... args) {\n" +
" System.out.print(\"main\");\n" +
" new MyTeam().activate();\n" +
" new bug443306.b.MyBase().bar();\n" +
" }\n" +
"}\n",
"bub443306/b/MyBase.java",
"package bug443306.b;\n" +
"public class MyBase {\n" +
" public void bar() { System.out.print(\"bar\"); }\n" +
"}\n"
},
getCompilerOptions(),
"",
"mainbarprint");
}
// test standard generated methods via basic team-role-base setup
// Bug 443299 - [1.8][null] lowered 'this' is not recognized as non-null
public void testLoweringThis() {
if (this.weavingScheme == WeavingScheme.OTRE) return;
runConformTestWithLibs(
new String[] {
"bug443299/MyTeam.java",
"package bug443299;\n" +
"import base bug443299.b.MyBase;\n" +
"public team class MyTeam {\n" +
" protected class MyRole playedBy MyBase {\n" +
" protected void print() {\n" +
" System.out.println(bug443299.b.MyBase.getString(this));\n" +
" }\n" +
" print <- after bar;\n" +
" }\n" +
" public static void main(String... args) {\n" +
" System.out.print(\"main\");\n" +
" new MyTeam().activate();\n" +
" new bug443299.b.MyBase().bar();\n" +
" }\n" +
"}\n",
"bug443299/b/MyBase.java",
"package bug443299.b;\n" +
"import org.eclipse.jdt.annotation.*;\n" +
"public class MyBase {\n" +
" public void bar() { System.out.print(\"bar\"); }\n" +
" public static String getString(@NonNull MyBase b) { return \"MyBase\"; }\n" +
"}\n"
},
getCompilerOptions(),
"",
"mainbarMyBase");
}
// Bug 437767 - [java8][null] semantically integrate null type annotations with anchored role types
// see comment 1
public void testImplicitTeamAnchor1() {
if (this.weavingScheme == WeavingScheme.OTRE) return;
Map<String,String> compilerOptions = getCompilerOptions();
compilerOptions.put(JavaCore.COMPILER_PB_NONNULL_TYPEVAR_FROM_LEGACY_INVOCATION, JavaCore.IGNORE);
runConformTestWithLibs(
new String[] {
"MyTeam.java",
"import org.eclipse.jdt.annotation.*;\n" +
"import java.util.*;\n" +
"public team class MyTeam {\n" +
" protected class MyRole {\n" +
" protected void print() {}\n" +
" }\n" +
" void test() {\n" +
" List<@NonNull MyRole> someRoles = new ArrayList<>();\n" +
" @NonNull MyRole role = someRoles.get(0);\n" +
" role.print();\n" +
" }\n" +
"}\n"
},
compilerOptions,
"");
}
public void testImplicitTeamAnchor2() {
if (this.weavingScheme == WeavingScheme.OTRE) return;
runNegativeTestWithLibs(
new String[] {
"MyTeam.java",
"import org.eclipse.jdt.annotation.*;\n" +
"import java.util.*;\n" +
"public team class MyTeam {\n" +
" protected class MyRole {\n" +
" protected void print() {}\n" +
" }\n" +
" void test() {\n" +
" List<@Nullable MyRole> someRoles = new ArrayList<>();\n" +
" @NonNull MyRole role = someRoles.get(0);\n" +
" role.print();\n" +
" }\n" +
"}\n"
},
getCompilerOptions(),
"----------\n" +
"1. ERROR in MyTeam.java (at line 9)\n" +
" @NonNull MyRole role = someRoles.get(0);\n" +
" ^^^^^^^^^^^^^^^^\n" +
"Null type mismatch (type annotations): required \'MyTeam.@NonNull MyRole\' but this expression has type \'MyTeam.@Nullable MyRole\'\n" +
"----------\n");
}
public void testExplicitTeamAnchor1() {
if (this.weavingScheme == WeavingScheme.OTRE) return;
runNegativeTestWithLibs(
new String[] {
"Main.java",
"import org.eclipse.jdt.annotation.*;\n" +
"import java.util.*;\n" +
"public class Main {\n" +
" void test(final MyTeam t, List<@Nullable MyRole<@t>> someRoles) {\n" +
" @NonNull MyRole<@t> role = someRoles.get(0);\n" +
" role.print();\n" +
" }\n" +
"}\n",
"MyTeam.java",
"public team class MyTeam {\n" +
" public class MyRole {\n" +
" public void print() {}\n" +
" }\n" +
"}\n"
},
getCompilerOptions(),
"----------\n" +
"1. ERROR in Main.java (at line 5)\n" +
" @NonNull MyRole<@t> role = someRoles.get(0);\n" +
" ^^^^^^^^^^^^^^^^\n" +
"Null type mismatch (type annotations): required \'MyTeam.@NonNull MyRole\' but this expression has type \'MyTeam.@Nullable MyRole\'\n" +
"----------\n");
}
public void testLiftingType1() {
if (this.weavingScheme == WeavingScheme.OTRE) return;
runNegativeTestWithLibs(
new String[] {
"MyTeam.java",
"import org.eclipse.jdt.annotation.*;\n" +
"public team class MyTeam {\n" +
" protected class MyRole playedBy MyBase {\n" +
" protected void print() {}\n" +
" }\n" +
" void test(@Nullable MyBase as @NonNull MyRole r) {}\n" +
"}\n",
"MyBase.java",
"public class MyBase {}\n"
},
getCompilerOptions(),
"----------\n" +
"1. ERROR in MyTeam.java (at line 6)\n" +
" void test(@Nullable MyBase as @NonNull MyRole r) {}\n" +
" ^^^^^^^^^^^^^^^^^^^^^^^^^\n" +
"Null type mismatch (type annotations): required \'MyTeam.@NonNull MyRole\' but this expression has type \'@Nullable MyBase\'\n" +
"----------\n");
}
public void testLiftingType2() {
if (this.weavingScheme == WeavingScheme.OTRE) return;
runNegativeTestWithLibs(
new String[] {
"MyTeam.java",
"import org.eclipse.jdt.annotation.*;\n" +
"public team class MyTeam {\n" +
" protected class MyRole playedBy MyBase {\n" +
" protected void print() {}\n" +
" }\n" +
" void test1(MyBase @Nullable[] as MyRole @NonNull[] r) {}\n" +
" void test2(@Nullable MyBase @NonNull[] as @NonNull MyRole @NonNull[] r) {}\n" +
"}\n",
"MyBase.java",
"public class MyBase {}\n"
},
getCompilerOptions(),
"----------\n" +
"1. ERROR in MyTeam.java (at line 6)\n" +
" void test1(MyBase @Nullable[] as MyRole @NonNull[] r) {}\n" +
" ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" +
"Null type mismatch (type annotations): required \'MyTeam.MyRole @NonNull[]\' but this expression has type \'MyBase @Nullable[]\'\n" +
"----------\n" +
"2. ERROR in MyTeam.java (at line 7)\n" +
" void test2(@Nullable MyBase @NonNull[] as @NonNull MyRole @NonNull[] r) {}\n" +
" ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" +
"Null type mismatch (type annotations): required \'MyTeam.@NonNull MyRole @NonNull[]\' but this expression has type \'@Nullable MyBase @NonNull[]\'\n" +
"----------\n");
}
public void testBug486292() {
runConformTestWithLibs(
new String[] {
"X.java",
"import java.util.*;\n" +
"import org.eclipse.jdt.annotation.*;\n" +
"public class X {\n" +
" public static <C extends Collection<?>>@NonNull C requireNonEmpty(@Nullable C value) {\n" +
" if ((value == null))\n" +
" throw new NullPointerException();\n" +
" if (value.isEmpty())\n" +
" throw new IllegalArgumentException();\n" +
" return value;\n" +
" }\n" +
"}\n"
},
getCompilerOptions(),
"");
}
public void _testIllegalBaseCall() {
runNegativeTestWithLibs(
new String[] {
"TeamIBC.java",
"\n" +
"@org.eclipse.jdt.annotation.NonNullByDefault\n" +
"public team class TeamIBC {\n" +
" protected class Role playedBy TIBC {\n" +
" void rm() {}\n" +
" callin void rm2(Integer s, boolean b) {\n" +
" if (b)\n" +
" base.rm2(1, false);\n" +
" else\n" +
" base.rm2(null, true);\n" +
" }\n" +
" }\n" +
"} \n" +
" \n",
"TIBC.java",
"\n" +
"public class TIBC {\n" +
" public void foo() { }\n" +
"} \n" +
" \n"
},
getCompilerOptions(),
"----------\n" +
"1. ERROR in TeamIBC.java (at line 9)\n" +
" base.rm2(\"wrong\", true);\n" +
" ^^^\n" +
"Base call rm2(Integer, boolean) is not applicable for the arguments (String, boolean)\n" +
"----------\n");
}
}