diff options
author | Stephan Herrmann | 2011-12-09 23:30:58 +0000 |
---|---|---|
committer | Stephan Herrmann | 2011-12-09 23:30:58 +0000 |
commit | aa1e2846406913c2667ae663cfe66712153297c9 (patch) | |
tree | cd3b7b3a16764288eafa0cd4000b47000fe81ea4 /org.eclipse.jdt.core.tests.model/src | |
parent | 10a91bb434c0bfac6d957fc01aa1adbc9a49923f (diff) | |
download | org.eclipse.objectteams-aa1e2846406913c2667ae663cfe66712153297c9.tar.gz org.eclipse.objectteams-aa1e2846406913c2667ae663cfe66712153297c9.tar.xz org.eclipse.objectteams-aa1e2846406913c2667ae663cfe66712153297c9.zip |
Merged with JDT/Core (+tests) up to v20111205-1355
Diffstat (limited to 'org.eclipse.jdt.core.tests.model/src')
7 files changed, 835 insertions, 3 deletions
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter15JLS4Test.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter15JLS4Test.java index 00678f753..9c7b8e99d 100644 --- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter15JLS4Test.java +++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter15JLS4Test.java @@ -7,6 +7,7 @@ * * Contributors: * IBM Corporation - initial API and implementation + * Stephan Herrmann - Contribution for bug 186342 - [compiler][null] Using annotations for null checking *******************************************************************************/ package org.eclipse.jdt.core.tests.dom; @@ -7475,7 +7476,6 @@ public class ASTConverter15JLS4Test extends ConverterTestSetup { assertTrue("Not assignement compatible", typeBinding.isAssignmentCompatible(typeBinding2)); assertTrue("Not assignement compatible", typeBinding.isAssignmentCompatible(collectionTypeBinding)); } - /* * https://bugs.eclipse.org/bugs/show_bug.cgi?id=156352 */ @@ -7494,6 +7494,12 @@ public class ASTConverter15JLS4Test extends ConverterTestSetup { buffer.append(typeBinding.getAnnotations().length); typeBinding= typeBinding.getSuperclass(); } + // the right outcome would be "020", but depending on the strategy when exactly + // annotations are resolved the annotations on Test2 are (not) present when + // traversing the super-class chain. + // The patch in https://bugs.eclipse.org/186342#c196 produced "020" but + // the previous behavior ("000") was restored in https://bugs.eclipse.org/365387 + // (see the change in SourceTypeBinding.resolveTypesFor(..)) assertEquals("Wrong number of annotations", "000", String.valueOf(buffer)); } } diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter15Test.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter15Test.java index 2af2c81bd..fd388a619 100644 --- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter15Test.java +++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter15Test.java @@ -10,6 +10,7 @@ * Stephan Herrmann - Contributions for * Bug 342671 - ClassCastException: org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding cannot be cast to org.eclipse.jdt.internal.compiler.lookup.ArrayBinding * Bug 353474 - type converters should include more annotations + * Bug 186342 - [compiler][null] Using annotations for null checking *******************************************************************************/ package org.eclipse.jdt.core.tests.dom; @@ -7497,6 +7498,12 @@ public class ASTConverter15Test extends ConverterTestSetup { buffer.append(typeBinding.getAnnotations().length); typeBinding= typeBinding.getSuperclass(); } + // the right outcome would be "020", but depending on the strategy when exactly + // annotations are resolved the annotations on Test2 are (not) present when + // traversing the super-class chain. + // The patch in https://bugs.eclipse.org/186342#c196 produced "020" but + // the previous behavior ("000") was restored in https://bugs.eclipse.org/365387 + // (see the change in SourceTypeBinding.resolveTypesFor(..)) assertEquals("Wrong number of annotations", "000", String.valueOf(buffer)); } } diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverterTestAST3_2.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverterTestAST3_2.java index 9ca2795cf..8f7991f48 100644 --- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverterTestAST3_2.java +++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverterTestAST3_2.java @@ -10613,4 +10613,22 @@ public class ASTConverterTestAST3_2 extends ConverterTestSetup { assertEquals("wrong tag name", "@literal", element.getTagName()); checkSourceRange((TextElement) element.fragments().get(0), " stars**** ", source); } + // https://bugs.eclipse.org/bugs/show_bug.cgi?id=361938 + public void test0722() throws JavaModelException { + String source = "public class X {\n" + + " X(){\n" + + " try {\n" + + " }\n" + + " finally {\n" + + " }\n" + + " }\n" + + "}\n"; + + ASTParser parser = ASTParser.newParser(AST.JLS3); + parser.setKind(ASTParser.K_COMPILATION_UNIT); + parser.setSource(source.toCharArray()); + CompilationUnit resultCompilationUnit = (CompilationUnit) parser.createAST(null); + Object o = resultCompilationUnit.types().get(0); + assertEquals(o.toString(), source); + } }
\ No newline at end of file diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AllJavaModelTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AllJavaModelTests.java index d3e6b2bfc..537f730fd 100644 --- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AllJavaModelTests.java +++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AllJavaModelTests.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2010 IBM Corporation and others. + * Copyright (c) 2000, 2011 IBM Corporation and others. * 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 @@ -185,6 +185,9 @@ private static Class[] getAllTestClasses() { UtilTests.class, JavaCoreOptionsTests.class, + + // Tests regarding null-annotations: + NullAnnotationModelTests.class, }; Class[] deprecatedClasses = getDeprecatedJDOMTestClasses(); diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CompletionTests2.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CompletionTests2.java index a06792488..8cf9c88c3 100644 --- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CompletionTests2.java +++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CompletionTests2.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2010 IBM Corporation and others. + * Copyright (c) 2000, 2011 IBM Corporation and others. * 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 @@ -38,6 +38,7 @@ import org.eclipse.jdt.core.ICompilationUnit; import org.eclipse.jdt.core.IJavaProject; import org.eclipse.jdt.core.IType; import org.eclipse.jdt.core.JavaCore; +import org.eclipse.jdt.core.JavaModelException; import org.eclipse.jdt.core.tests.util.Util; import org.eclipse.jdt.internal.codeassist.RelevanceConstants; import org.eclipse.jdt.internal.compiler.impl.CompilerOptions; @@ -45,6 +46,10 @@ import org.eclipse.jdt.internal.core.JavaModelManager; import org.eclipse.jdt.internal.core.search.indexing.IndexManager; public class CompletionTests2 extends ModifyingResourceTests implements RelevanceConstants { + + static { +// TESTS_NAMES = new String[]{"testBug340945"}; + } public static class CompletionContainerInitializer implements ContainerInitializer.ITestInitializer { @@ -5591,4 +5596,260 @@ public void testBug317264d() throws CoreException { deleteProject(project); } } + +//https://bugs.eclipse.org/bugs/show_bug.cgi?id=292087 +public void testBug340945() throws JavaModelException { + this.workingCopies = new ICompilationUnit[1]; + this.workingCopies[0] = getWorkingCopy( + "/Completion/src/test/Try.java", + "package test;\n" + + "public class Try extends Thread{\n" + + " int inty = 1;\n" + + " void foo() {\n" + + " int i = 1;\n" + + " Object o = new Object() {\n" + + " void running() {\n" + + " int j = 1;\n" + + " int k = " + + " }\n" + + " }\n" + + " }\n" + + "}\n"); + + CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true); + requestor.setRequireExtendedContext(true); + requestor.allowAllRequiredProposals(); + requestor.setComputeVisibleElements(true); +// requestor.setAssignableType("I"); + String str = this.workingCopies[0].getSource(); + String completeBehind = "int k ="; + int cursorLocation = str.lastIndexOf(completeBehind) + completeBehind.length(); + this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner); + assertResults( + "<CompleteOnName:>", + requestor.getCompletionNode()); + assertResults( + "int k = <CompleteOnName:>;", + requestor.getCompletionNodeParent()); + assertResults( + "int j[pos: unused][id:2]\n" + + "int i[pos: unused][id:0]\n" + + "java.lang.Object o[pos: unused][id:1]\n", + requestor.getVisibleLocalVariables()); + assertResults( + "int inty\n", + requestor.getVisibleFields()); + assertResults( + "void running() \n" + + "public final void wait(long, int) throws java.lang.IllegalMonitorStateException, java.lang.InterruptedException\n" + + "public final void wait(long) throws java.lang.IllegalMonitorStateException, java.lang.InterruptedException\n" + + "public final void wait() throws java.lang.IllegalMonitorStateException, java.lang.InterruptedException\n" + + "public java.lang.String toString() \n" + + "public final void notifyAll() throws java.lang.IllegalMonitorStateException\n" + + "public final void notify() throws java.lang.IllegalMonitorStateException\n" + + "public int hashCode() \n" + + "public final java.lang.Class getClass() \n" + + "protected void finalize() throws java.lang.Throwable\n" + + "public boolean equals(java.lang.Object) \n" + + "protected java.lang.Object clone() throws java.lang.CloneNotSupportedException\n" + + "void foo() \n", + requestor.getVisibleMethods()); +} + +// https://bugs.eclipse.org/bugs/show_bug.cgi?id=292087 +public void testBug340945a() throws JavaModelException { + this.workingCopies = new ICompilationUnit[1]; + this.workingCopies[0] = getWorkingCopy( + "/Completion/src/test/Try.java", + "package test;\n" + + "public class Try extends Thread{\n" + + " int int1 = 1;\n" + + " int int2 = 2;\n" + + " int int3 = " + + "}\n"); + + CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true); + requestor.setRequireExtendedContext(true); + requestor.allowAllRequiredProposals(); + requestor.setComputeVisibleElements(true); + String str = this.workingCopies[0].getSource(); + String completeBehind = "int int3 ="; + int cursorLocation = str.lastIndexOf(completeBehind) + completeBehind.length(); + this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner); + assertResults( + "<CompleteOnName:>", + requestor.getCompletionNode()); + assertResults( + "int int3 = <CompleteOnName:>;", + requestor.getCompletionNodeParent()); + assertResults( + "", + requestor.getVisibleLocalVariables()); + assertResults( + "int int2\n" + + "int int1\n", + requestor.getVisibleFields()); + assertResults( + "public final void wait(long, int) throws java.lang.IllegalMonitorStateException, java.lang.InterruptedException\n" + + "public final void wait(long) throws java.lang.IllegalMonitorStateException, java.lang.InterruptedException\n" + + "public final void wait() throws java.lang.IllegalMonitorStateException, java.lang.InterruptedException\n" + + "public java.lang.String toString() \n" + + "public final void notifyAll() throws java.lang.IllegalMonitorStateException\n" + + "public final void notify() throws java.lang.IllegalMonitorStateException\n" + + "public int hashCode() \n" + + "public final java.lang.Class getClass() \n" + + "protected void finalize() throws java.lang.Throwable\n" + + "public boolean equals(java.lang.Object) \n" + + "protected java.lang.Object clone() throws java.lang.CloneNotSupportedException\n", + requestor.getVisibleMethods()); +} + +// https://bugs.eclipse.org/bugs/show_bug.cgi?id=292087 +public void testBug340945b() throws JavaModelException { + this.workingCopies = new ICompilationUnit[1]; + this.workingCopies[0] = getWorkingCopy( + "/Completion/src/test/Try.java", + "package test;\n" + + "public class Try extends Thread{\n" + + "Object field;\n" + + "void foo() {\n" + + " int int1 = 1;\n" + + " int int2 = 2;\n" + + " int int3 = " + + "}\n" + + "}\n"); + + CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true); + requestor.setRequireExtendedContext(true); + requestor.allowAllRequiredProposals(); + requestor.setComputeVisibleElements(true); + String str = this.workingCopies[0].getSource(); + String completeBehind = "int int3 ="; + int cursorLocation = str.lastIndexOf(completeBehind) + completeBehind.length(); + this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner); + assertResults( + "<CompleteOnName:>", + requestor.getCompletionNode()); + assertResults( + "int int3 = <CompleteOnName:>;", + requestor.getCompletionNodeParent()); + assertResults( + "int int1[pos: unused][id:0]\n" + + "int int2[pos: unused][id:1]\n", + requestor.getVisibleLocalVariables()); + assertResults( + "java.lang.Object field\n", + requestor.getVisibleFields()); + assertResults( + "void foo() \n" + + "public final void wait(long, int) throws java.lang.IllegalMonitorStateException, java.lang.InterruptedException\n" + + "public final void wait(long) throws java.lang.IllegalMonitorStateException, java.lang.InterruptedException\n" + + "public final void wait() throws java.lang.IllegalMonitorStateException, java.lang.InterruptedException\n" + + "public java.lang.String toString() \n" + + "public final void notifyAll() throws java.lang.IllegalMonitorStateException\n" + + "public final void notify() throws java.lang.IllegalMonitorStateException\n" + + "public int hashCode() \n" + + "public final java.lang.Class getClass() \n" + + "protected void finalize() throws java.lang.Throwable\n" + + "public boolean equals(java.lang.Object) \n" + + "protected java.lang.Object clone() throws java.lang.CloneNotSupportedException\n", + requestor.getVisibleMethods()); +} + +// https://bugs.eclipse.org/bugs/show_bug.cgi?id=292087 +public void testBug340945c() throws JavaModelException { + this.workingCopies = new ICompilationUnit[1]; + this.workingCopies[0] = getWorkingCopy( + "/Completion/src/test/Try.java", + "package test;\n" + + "public class Try extends Thread{\n" + + "Object field;\n" + + "void foo() {\n" + + " int int1 = 1;\n" + + " int int2 = 2;\n" + + " Object o1 = new Object();\n" + + " o1." + + "}\n" + + "}\n"); + + CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true); + requestor.setRequireExtendedContext(true); + requestor.allowAllRequiredProposals(); + requestor.setComputeVisibleElements(true); + String str = this.workingCopies[0].getSource(); + String completeBehind = "o1."; + int cursorLocation = str.lastIndexOf(completeBehind) + completeBehind.length(); + this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner); + assertResults( + "<CompleteOnName:o1.>", + requestor.getCompletionNode()); + assertNull( + "should be null", + requestor.getCompletionNodeParent()); + assertResults( + "int int1[pos: unused][id:0]\n" + + "int int2[pos: unused][id:1]\n" + + "java.lang.Object o1[pos: unused][id:2]\n", + requestor.getVisibleLocalVariables()); + assertResults( + "java.lang.Object field\n", + requestor.getVisibleFields()); + assertResults( + "void foo() \n" + + "public final void wait(long, int) throws java.lang.IllegalMonitorStateException, java.lang.InterruptedException\n" + + "public final void wait(long) throws java.lang.IllegalMonitorStateException, java.lang.InterruptedException\n" + + "public final void wait() throws java.lang.IllegalMonitorStateException, java.lang.InterruptedException\n" + + "public java.lang.String toString() \n" + + "public final void notifyAll() throws java.lang.IllegalMonitorStateException\n" + + "public final void notify() throws java.lang.IllegalMonitorStateException\n" + + "public int hashCode() \n" + + "public final java.lang.Class getClass() \n" + + "protected void finalize() throws java.lang.Throwable\n" + + "public boolean equals(java.lang.Object) \n" + + "protected java.lang.Object clone() throws java.lang.CloneNotSupportedException\n", + requestor.getVisibleMethods()); +} + +// https://bugs.eclipse.org/bugs/show_bug.cgi?id=292087 +public void testBug340945d() throws JavaModelException { + this.workingCopies = new ICompilationUnit[1]; + this.workingCopies[0] = getWorkingCopy( + "/Completion/src/test/Try.java", + "package test;\n" + + "public class Try extends Thread{\n" + + "Object field;\n" + + "static void foo() {\n" + // field should not be visible here + " int int1 = 1;\n" + + " int int2 = 2;\n" + + " Object o1 = new Object();\n" + + " o1." + + "}\n" + + "}\n"); + + CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true); + requestor.setRequireExtendedContext(true); + requestor.allowAllRequiredProposals(); + requestor.setComputeVisibleElements(true); + String str = this.workingCopies[0].getSource(); + String completeBehind = "o1."; + int cursorLocation = str.lastIndexOf(completeBehind) + completeBehind.length(); + this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner); + assertResults( + "<CompleteOnName:o1.>", + requestor.getCompletionNode()); + assertNull( + "should be null", + requestor.getCompletionNodeParent()); + assertResults( + "int int1[pos: unused][id:0]\n" + + "int int2[pos: unused][id:1]\n" + + "java.lang.Object o1[pos: unused][id:2]\n", + requestor.getVisibleLocalVariables()); + assertResults( + "", + requestor.getVisibleFields()); + assertResults( + "static void foo() \n", + requestor.getVisibleMethods()); +} } diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CompletionTestsRequestor2.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CompletionTestsRequestor2.java index c3102c438..38e73744e 100644 --- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CompletionTestsRequestor2.java +++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CompletionTestsRequestor2.java @@ -20,6 +20,9 @@ import org.eclipse.jdt.core.Flags; import org.eclipse.jdt.core.IJavaElement; import org.eclipse.jdt.core.Signature; import org.eclipse.jdt.core.compiler.IProblem; +import org.eclipse.jdt.internal.codeassist.InternalCompletionContext; +import org.eclipse.jdt.internal.compiler.ast.ASTNode; +import org.eclipse.jdt.internal.compiler.util.ObjectVector; import org.eclipse.jdt.internal.core.JavaElement; public class CompletionTestsRequestor2 extends CompletionRequestor { @@ -605,4 +608,54 @@ public class CompletionTestsRequestor2 extends CompletionRequestor { } return false; } + + public String getCompletionNode() { + if (this.context instanceof InternalCompletionContext) { + InternalCompletionContext internalCompletionContext = (InternalCompletionContext) this.context; + ASTNode astNode = internalCompletionContext.getCompletionNode(); + if (astNode != null) return astNode.toString(); + + } + return null; + } + + public String getCompletionNodeParent() { + if (this.context instanceof InternalCompletionContext) { + InternalCompletionContext internalCompletionContext = (InternalCompletionContext) this.context; + ASTNode astNode = internalCompletionContext.getCompletionNodeParent(); + if (astNode != null) return astNode.toString(); + + } + return null; + } + + public String getVisibleLocalVariables() { + if (this.context instanceof InternalCompletionContext) { + InternalCompletionContext internalCompletionContext = (InternalCompletionContext) this.context; + ObjectVector locals = internalCompletionContext.getVisibleLocalVariables(); + if (locals != null) return locals.toString(); + + } + return null; + } + + public String getVisibleFields() { + if (this.context instanceof InternalCompletionContext) { + InternalCompletionContext internalCompletionContext = (InternalCompletionContext) this.context; + ObjectVector fields = internalCompletionContext.getVisibleFields(); + if (fields != null) return fields.toString(); + + } + return null; + } + + public String getVisibleMethods() { + if (this.context instanceof InternalCompletionContext) { + InternalCompletionContext internalCompletionContext = (InternalCompletionContext) this.context; + ObjectVector methods = internalCompletionContext.getVisibleMethods(); + if (methods != null) return methods.toString(); + + } + return null; + } } diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/NullAnnotationModelTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/NullAnnotationModelTests.java new file mode 100644 index 000000000..d38f045a4 --- /dev/null +++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/NullAnnotationModelTests.java @@ -0,0 +1,484 @@ +/******************************************************************************* + * Copyright (c) 2011 GK Software AG and others. + * 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 + * + * Contributors: + * Stephan Herrmann - initial API and implementation + *******************************************************************************/ +package org.eclipse.jdt.core.tests.model; + +import java.io.File; +import java.io.IOException; +import java.io.ByteArrayInputStream; +import java.net.URL; +import java.util.Hashtable; +import java.util.List; + +import junit.framework.Test; + +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IMarker; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.IncrementalProjectBuilder; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.FileLocator; +import org.eclipse.core.runtime.Platform; +import org.eclipse.jdt.core.ICompilationUnit; +import org.eclipse.jdt.core.IJavaModelMarker; +import org.eclipse.jdt.core.IJavaProject; +import org.eclipse.jdt.core.JavaCore; +import org.eclipse.jdt.core.compiler.IProblem; +import org.eclipse.jdt.core.dom.AST; +import org.eclipse.jdt.core.dom.ASTParser; +import org.eclipse.jdt.core.dom.CompilationUnit; +import org.eclipse.jdt.core.dom.MarkerAnnotation; +import org.eclipse.jdt.core.dom.MethodDeclaration; +import org.eclipse.jdt.core.dom.Modifier; +import org.eclipse.jdt.core.dom.SingleVariableDeclaration; +import org.eclipse.jdt.core.dom.TypeDeclaration; + +public class NullAnnotationModelTests extends ReconcilerTests { + + String ANNOTATION_LIB; + + public static Test suite() { + return buildModelTestSuite(NullAnnotationModelTests.class); + } + + public NullAnnotationModelTests(String name) { + super(name); + } + + static { +// TESTS_NAMES = new String[] { "testMissingAnnotation5" }; + } + + public void setUp() throws Exception { + super.setUp(); + File bundleFile = FileLocator.getBundleFile(Platform.getBundle("org.eclipse.jdt.annotation")); + this.ANNOTATION_LIB = bundleFile.isDirectory() ? bundleFile.getPath()+"/bin" : bundleFile.getPath(); + } + + protected String testJarPath(String jarName) throws IOException { + URL libEntry = Platform.getBundle("org.eclipse.jdt.core.tests.model").getEntry("/workspace/NullAnnotations/lib/"+jarName); + return FileLocator.toFileURL(libEntry).getPath(); + } + + + public void testConvertedSourceType1() throws CoreException, InterruptedException { + try { + // Resources creation + IJavaProject p = createJavaProject("P", new String[] {""}, new String[] {"JCL15_LIB", this.ANNOTATION_LIB}, "bin", "1.5"); + p.setOption(JavaCore.COMPILER_ANNOTATION_NULL_ANALYSIS, JavaCore.ENABLED); + p.setOption(JavaCore.COMPILER_NONNULL_IS_DEFAULT, JavaCore.ENABLED); + + this.createFolder("/P/p1"); + String c1SourceString = + "package p1;\n" + + "import org.eclipse.jdt.annotation.*;\n" + + "public class C1 {\n" + + " public String foo(@Nullable Object arg) {\n" + // this is consumed via SourceTypeConverter + " return arg == null ? \"\" : arg.toString();\n" + + " }\n" + + "}\n"; + this.createFile( + "/P/p1/C1.java", + c1SourceString); + + this.createFolder("/P/p2"); + String c2SourceString = + "package p2;\n" + + "public class C2 {\n" + + " String bar(p1.C1 c, C2 c2) {;\n" + + " return c.foo(null);\n" + // don't complain despite default nonnull, foo has explicit @Nullable + " }\n" + + " String foo(Object arg) {\n" + + " return arg == null ? null : arg.toString();\n" + + " }\n" + + "}\n"; + this.createFile( + "/P/p2/C2.java", + c2SourceString); + + char[] c2SourceChars = c2SourceString.toCharArray(); + this.problemRequestor.initialize(c2SourceChars); + + getCompilationUnit("/P/p2/C2.java").getWorkingCopy(this.wcOwner, null); + + assertProblems("Unexpected problems", "----------\n" + + "1. WARNING in /P/p2/C2.java (at line 7)\n" + + " return arg == null ? null : arg.toString();\n" + + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + + "Potential type mismatch: required \'@NonNull String\' but nullness of the provided value is unknown\n" + + "----------\n"); + } finally { + deleteProject("P"); + } + } + + public void testBinaryType1() throws CoreException, InterruptedException, IOException { + try { + // Resources creation + IJavaProject p = createJavaProject("P", new String[] {""}, + new String[] {"JCL15_LIB", this.ANNOTATION_LIB, testJarPath("example.jar")}, + "bin", "1.5"); + p.setOption(JavaCore.COMPILER_ANNOTATION_NULL_ANALYSIS, JavaCore.ENABLED); + p.setOption(JavaCore.COMPILER_NONNULL_IS_DEFAULT, JavaCore.ENABLED); + + // example.jar contains p1/C1.java just like testConvertedSourceType1() + + this.createFolder("/P/p2"); + String c2SourceString = + "package p2;\n" + + "public class C2 {\n" + + " String bar(p1.C1 c) {;\n" + + " return c.foo(null);\n" + // don't complain despite default nonnull, foo has explicit @Nullable + " }\n" + + " String foo(Object arg) {\n" + + " return arg == null ? null : arg.toString();\n" + + " }\n" + + "}\n"; + this.createFile( + "/P/p2/C2.java", + c2SourceString); + + char[] c2SourceChars = c2SourceString.toCharArray(); + this.problemRequestor.initialize(c2SourceChars); + + getCompilationUnit("/P/p2/C2.java").getWorkingCopy(this.wcOwner, null); + + assertProblems("Unexpected problems", "----------\n" + + "1. WARNING in /P/p2/C2.java (at line 7)\n" + + " return arg == null ? null : arg.toString();\n" + + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + + "Potential type mismatch: required \'@NonNull String\' but nullness of the provided value is unknown\n" + + "----------\n"); + } finally { + deleteProject("P"); + } + } + + public void testMissingAnnotation1() throws CoreException { + try { + // Resources creation + IJavaProject p = createJavaProject("P", new String[] {""}, new String[] {"JCL15_LIB", this.ANNOTATION_LIB}, "bin", "1.5"); + p.setOption(JavaCore.COMPILER_ANNOTATION_NULL_ANALYSIS, JavaCore.ENABLED); + p.setOption(JavaCore.COMPILER_NONNULL_ANNOTATION_NAME, "in.valid"); + + this.createFolder("/P/p1"); + String c1SourceString = + "package p1;\n" + + "@org.eclipse.jdt.annotation.NonNullByDefault\n" + + "public class C1 {\n" + + " public String foo(Object arg) {\n" + + " return arg == null ? \"\" : arg.toString();\n" + + " }\n" + + "}\n"; + this.createFile( + "/P/p1/C1.java", + c1SourceString); + + this.problemRequestor.initialize(c1SourceString.toCharArray()); + + getCompilationUnit("/P/p1/C1.java").getWorkingCopy(this.wcOwner, null); + + assertProblems("Unexpected problems", + "----------\n" + + "1. ERROR in /P/p1/C1.java (at line 1)\n" + + " package p1;\n" + + " ^\n" + + "Buildpath problem: the type in.valid, which is configured as a null annotation type, cannot be resolved\n" + + "----------\n"); + } finally { + deleteProject("P"); + } + } + + public void testMissingAnnotation2() throws CoreException { + Hashtable javaOptions = JavaCore.getOptions(); + try { + // Resources creation + IJavaProject p = createJavaProject("P", new String[] {""}, new String[] {"JCL15_LIB", this.ANNOTATION_LIB}, "bin", "1.5"); + IFile settings = (IFile) p.getProject().findMember(".settings/org.eclipse.jdt.core.prefs"); + settings.appendContents(new ByteArrayInputStream("\norg.eclipse.jdt.core.compiler.annotation.nonnull=not.valid\n".getBytes()), 0, null); + p.setOption(JavaCore.COMPILER_ANNOTATION_NULL_ANALYSIS, JavaCore.ENABLED); + + this.createFolder("/P/p1"); + String c1SourceString = + "package p1;\n" + + "@org.eclipse.jdt.annotation.NonNullByDefault\n" + + "public class C1 {\n" + + " public String foo(Object arg) {\n" + + " return arg == null ? \"\" : arg.toString();\n" + + " }\n" + + "}\n"; + this.createFile( + "/P/p1/C1.java", + c1SourceString); + + this.problemRequestor.initialize(c1SourceString.toCharArray()); + + getCompilationUnit("/P/p1/C1.java").getWorkingCopy(this.wcOwner, null); + + assertProblems("Unexpected problems", + "----------\n" + + "1. ERROR in /P/p1/C1.java (at line 1)\n" + + " package p1;\n" + + " ^\n" + + "Buildpath problem: the type not.valid, which is configured as a null annotation type, cannot be resolved\n" + + "----------\n"); + } finally { + deleteProject("P"); + JavaCore.setOptions(javaOptions); + // work against side-effect of JavaRuntime listening to change of prefs-file. + // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=302850#c25 + } + } + + // Bug 363858 - [dom] early throwing of AbortCompilation causes NPE in CompilationUnitResolver + // currently not actually challenging the NPE, because we no longer report + // "Cannot use the unqualified name \'invalid\' as an annotation name for null specification" + public void testMissingAnnotation3() throws CoreException { + try { + // Resources creation + IJavaProject p = createJavaProject("P", new String[] {""}, new String[] {"JCL15_LIB", this.ANNOTATION_LIB}, "bin", "1.5"); + p.setOption(JavaCore.COMPILER_ANNOTATION_NULL_ANALYSIS, JavaCore.ENABLED); + p.setOption(JavaCore.COMPILER_NONNULL_ANNOTATION_NAME, "invalid"); + + this.createFolder("/P/p1"); + String c1SourceString = + "package p1;\n" + + "@org.eclipse.jdt.annotation.NonNullByDefault\n" + + "public class C1 {\n" + + " public String foo(Object arg) {\n" + + " return arg == null ? \"\" : arg.toString();\n" + + " }\n" + + "}\n"; + this.createFile( + "/P/p1/C1.java", + c1SourceString); + + this.problemRequestor.initialize(c1SourceString.toCharArray()); + + final ICompilationUnit unit = getCompilationUnit("/P/p1/C1.java").getWorkingCopy(this.wcOwner, null); + assertProblems("Unexpected problems", + "----------\n" + + "1. ERROR in /P/p1/C1.java (at line 1)\n" + + " package p1;\n" + + " ^\n" + + "Buildpath problem: the type invalid, which is configured as a null annotation type, cannot be resolved\n" + + "----------\n"); + + ASTParser parser = ASTParser.newParser(AST.JLS4); + parser.setProject(p); + parser.setResolveBindings(true); + parser.setSource(unit); + CompilationUnit ast = (CompilationUnit) parser.createAST(null); + assertNotNull("ast should not be null", ast); + this.problemRequestor.reset(); + this.problemRequestor.beginReporting(); + IProblem[] problems = ast.getProblems(); + for (int i=0; i<problems.length; i++) + this.problemRequestor.acceptProblem(problems[i]); + assertProblems("Unexpected problems (2)", + "----------\n" + + "1. ERROR in /P/p1/C1.java (at line 1)\n" + + " package p1;\n" + + " ^\n" + + "Buildpath problem: the type invalid, which is configured as a null annotation type, cannot be resolved\n" + + "----------\n"); + } finally { + deleteProject("P"); + } + } + + // initialization of null annotations is triggered from package-info.java: illegal simple name + public void testMissingAnnotation4() throws CoreException, InterruptedException { + try { + // Resources creation + IJavaProject p = createJavaProject("P", new String[] {""}, new String[] {"JCL15_LIB", this.ANNOTATION_LIB}, "bin", "1.5"); + p.setOption(JavaCore.COMPILER_ANNOTATION_NULL_ANALYSIS, JavaCore.ENABLED); + p.setOption(JavaCore.COMPILER_NONNULL_ANNOTATION_NAME, "invalid"); + + this.createFolder("/P/p1"); + String piSourceString = + "@org.eclipse.jdt.annotation.NonNullByDefault\n" + + "package p1;\n"; + this.createFile( + "/P/p1/package-info.java", + piSourceString); + + this.problemRequestor.initialize(piSourceString.toCharArray()); + + // Challenge CompilationUnitProblemFinder: + final ICompilationUnit unit = getCompilationUnit("/P/p1/package-info.java").getWorkingCopy(this.wcOwner, null); +// This error is not raised currently: +// String expectedError = "----------\n" + +// "1. ERROR in /P/p1/package-info.java (at line 0)\n" + +// " @org.eclipse.jdt.annotation.NonNullByDefault\n" + +// " ^\n" + +// "Cannot use the unqualified name \'invalid\' as an annotation name for null specification\n" + +// "----------\n"; +// assertProblems("Unexpected problems from CompilationUnitProblemFinder", expectedError); + assertNoProblem(unit.getBuffer().getCharacters(), unit); + + // Challenge JavaBuilder: + p.getProject().build(IncrementalProjectBuilder.FULL_BUILD, null); + IMarker[] markers = p.getProject().findMarkers(IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER, true, IResource.DEPTH_INFINITE); +// assertMarkers("Unexpected markers", +// "Cannot use the unqualified name 'invalid' as an annotation name for null specification", +// markers); +// assertEquals("Unexpected marker path", "/P", markers[0].getResource().getFullPath().toString()); + assertEquals("Should have no markers", 0, markers.length); + + // Challenge CompilationUnitResolver: + ASTParser parser = ASTParser.newParser(AST.JLS4); + parser.setProject(p); + parser.setResolveBindings(true); + parser.setSource(unit); + CompilationUnit ast = (CompilationUnit) parser.createAST(null); + assertNotNull("ast should not be null", ast); +// this.problemRequestor.reset(); +// this.problemRequestor.beginReporting(); +// IProblem[] problems = ast.getProblems(); +// for (int i=0; i<problems.length; i++) +// this.problemRequestor.acceptProblem(problems[i]); +// assertProblems("Unexpected problems from CompilationUnitResolver", expectedError); + assertEquals("Should have no problems", 0, ast.getProblems().length); + } finally { + deleteProject("P"); + } + } + + // initialization of null annotations is + // - triggered from resolveTypesFor(MethodBinding) + // - default is defined in package-info.java: + // must detect missing non-null annotation and report against the project + public void testMissingAnnotation5() throws CoreException, InterruptedException { + try { + // Resources creation + IJavaProject p = createJavaProject("P", new String[] {""}, new String[] {"JCL15_LIB", this.ANNOTATION_LIB}, "bin", "1.5"); + p.setOption(JavaCore.COMPILER_ANNOTATION_NULL_ANALYSIS, JavaCore.ENABLED); + p.setOption(JavaCore.COMPILER_NONNULL_ANNOTATION_NAME, "pack.Missing"); + + this.createFolder("/P/p1"); + String piSourceString = + "@org.eclipse.jdt.annotation.NonNullByDefault\n" + + "package p1;\n"; + this.createFile("/P/p1/package-info.java", piSourceString); + + String c1SourceString = + "package p1;\n" + + "public class C1 {\n" + + " String foo(String arg) { return arg; }\n" + + "}\n"; + this.createFile("/P/p1/C1.java", c1SourceString); + + this.problemRequestor.initialize(piSourceString.toCharArray()); + + // Challenge CompilationUnitProblemFinder: + assertNoProblem(piSourceString.toCharArray(), getCompilationUnit("/P/p1/package-info.java")); + + this.problemRequestor.initialize(c1SourceString.toCharArray()); + + // Challenge CompilationUnitProblemFinder: + ICompilationUnit unit = getCompilationUnit("/P/p1/C1.java").getWorkingCopy(this.wcOwner, null); + String expectedError = "----------\n" + + "1. ERROR in /P/p1/C1.java (at line 1)\n" + + " package p1;\n" + + " ^\n" + + "Buildpath problem: the type pack.Missing, which is configured as a null annotation type, cannot be resolved\n" + + "----------\n"; + assertProblems("Unexpected problems", expectedError); + + // Challenge JavaBuilder: + p.getProject().build(IncrementalProjectBuilder.FULL_BUILD, null); + IMarker[] markers = p.getProject().findMarkers(IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER, true, IResource.DEPTH_INFINITE); + assertMarkers("Unexpected markers", + "Buildpath problem: the type pack.Missing, which is configured as a null annotation type, cannot be resolved", + markers); +// toggle expectation depending on how CAT_BUILDPATH problems are reported (see AbstractImageBuilder.storeProblemsFor(..)) +// assertEquals("Unexpected marker path", "/P", markers[0].getResource().getFullPath().toString()); + assertEquals("Unexpected marker path", "/P/p1/C1.java", markers[0].getResource().getFullPath().toString()); + + // Challenge CompilationUnitResolver: + ASTParser parser = ASTParser.newParser(AST.JLS4); + parser.setProject(p); + parser.setResolveBindings(true); + parser.setSource(unit); + CompilationUnit ast = (CompilationUnit) parser.createAST(null); + assertNotNull("ast should not be null", ast); + this.problemRequestor.reset(); + this.problemRequestor.beginReporting(); + IProblem[] problems = ast.getProblems(); + for (int i=0; i<problems.length; i++) + this.problemRequestor.acceptProblem(problems[i]); + assertProblems("Unexpected problems (2)", expectedError); + } finally { + deleteProject("P"); + } + } + + // A synthetic annotation from a default should not be converted to DOM AST + public void testAnnotationAST1() throws CoreException, InterruptedException { + try { + // Resources creation + IJavaProject p = createJavaProject("P", new String[] {""}, new String[] {"JCL15_LIB", this.ANNOTATION_LIB}, "bin", "1.5"); + p.setOption(JavaCore.COMPILER_ANNOTATION_NULL_ANALYSIS, JavaCore.ENABLED); + + this.createFolder("/P/p1"); + // bug could only be triggered if ASTConvert actually finds a '@' + // so in addition to the synthetic annotation there must also be a real one: + String annotSourceString = + "package p1;\n" + + "import java.lang.annotation.ElementType;\n" + + "import java.lang.annotation.Target;\n" + + "@Target({ElementType.PARAMETER,ElementType.METHOD})\n" + + "public @interface Annot {}\n"; + this.createFile( + "/P/p1/Annot.java", + annotSourceString); + String c1SourceString = + "package p1;\n" + + "@org.eclipse.jdt.annotation.NonNullByDefault\n" + + "public class C1 {\n" + + " public @Annot Object foo(@Annot Object arg) {\n" + + " return this;\n" + + " }\n" + + "}\n"; + this.createFile( + "/P/p1/C1.java", + c1SourceString); + + this.problemRequestor.initialize(c1SourceString.toCharArray()); + + final ICompilationUnit unit = getCompilationUnit("/P/p1/C1.java").getWorkingCopy(this.wcOwner, null); + assertNoProblem(c1SourceString.toCharArray(), unit); + + ASTParser parser = ASTParser.newParser(AST.JLS4); + parser.setProject(p); + parser.setResolveBindings(true); + parser.setSource(unit); + CompilationUnit ast = (CompilationUnit) parser.createAST(null); + assertNotNull("ast should not be null", ast); + TypeDeclaration type = (TypeDeclaration) ast.types().get(0); + assertNotNull("type should not be null", type); + MethodDeclaration method = (MethodDeclaration) type.bodyDeclarations().get(0); + assertNotNull("method should not be null", method); + SingleVariableDeclaration arg = (SingleVariableDeclaration) method.parameters().get(0); + assertNotNull("argument should not be null", arg); + List modifiers = arg.modifiers(); + assertEquals("Should have exactly one modifier", 1, modifiers.size()); + assertEquals("Unexpected modifier", "@Annot", ((MarkerAnnotation)modifiers.get(0)).toString()); + modifiers = method.modifiers(); + assertEquals("Method should have exactly two modifiers", 2, modifiers.size()); + assertEquals("Unexpected modifier #1 for method", "public", ((Modifier)modifiers.get(0)).toString()); + assertEquals("Unexpected modifier #2 for method", "@Annot", ((MarkerAnnotation)modifiers.get(1)).toString()); + } finally { + deleteProject("P"); + } + } +} |