Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephan Herrmann2016-06-04 20:41:32 +0000
committerStephan Herrmann2016-06-05 00:04:33 +0000
commitca85fc25b968cc407c8b7e2ebf75044c0a42107d (patch)
tree5cf0ee4a18640207062c11859d2e9fadc96cc99c
parentc45a87ae53eb97cc7def646c521a55cacc3dae49 (diff)
downloadorg.eclipse.objectteams-ca85fc25b968cc407c8b7e2ebf75044c0a42107d.tar.gz
org.eclipse.objectteams-ca85fc25b968cc407c8b7e2ebf75044c0a42107d.tar.xz
org.eclipse.objectteams-ca85fc25b968cc407c8b7e2ebf75044c0a42107d.zip
Bug 444231: Copyinheritance of method with parameter annotations causes
AIOOBE - fix NPE when reporting ambiguous role ctor - copy null annotations to copied methods (copyInh. & creationMethods)
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SourceTypeBinding.java19
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java1
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/mappings/CallinImplementorDyn.java2
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/statemachine/copyinheritance/CopyInheritance.java8
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/util/AstEdit.java18
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/util/AstGenerator.java9
-rw-r--r--testplugins/org.eclipse.objectteams.otdt.tests/otjld/org/eclipse/objectteams/otdt/tests/otjld/other/OTNullAnnotationTest.java68
7 files changed, 111 insertions, 14 deletions
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SourceTypeBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SourceTypeBinding.java
index 6882cdbc7..3a8231a07 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SourceTypeBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SourceTypeBinding.java
@@ -3267,12 +3267,23 @@ public MethodBinding resolveGeneratedMethod(MethodBinding mb) {
* Create and link binding for a generated method.
* @param methodDeclaration
* @param wasSynthetic
- * @param copyInheritanceSrc
+ * @param original copyInheritanceSource or original ctor
+ * @param isCopyInheritance whether or not original is copyInheritanceSource
*/
-public void resolveGeneratedMethod(AbstractMethodDeclaration methodDeclaration, boolean wasSynthetic, MethodBinding copyInheritanceSrc) {
+public void resolveGeneratedMethod(AbstractMethodDeclaration methodDeclaration, boolean wasSynthetic, MethodBinding original, boolean isCopyInheritance) {
if (this.scope != null) {
MethodBinding binding = this.scope.createMethod(methodDeclaration);
- binding.setCopyInheritanceSrc(copyInheritanceSrc);
+ if (isCopyInheritance)
+ binding.setCopyInheritanceSrc(original);
+ if (original != null && original.parameterNonNullness != null && methodDeclaration.arguments != null) {
+ int len = Math.min(methodDeclaration.arguments.length, original.parameterNonNullness.length);
+ AstGenerator gen = new AstGenerator(methodDeclaration);
+ for (int i=0; i<len; i++) {
+ Boolean nonNull = original.parameterNonNullness[i];
+ if (nonNull != null)
+ gen.addNullAnnotation(methodDeclaration.arguments[i], this.scope.environment(), nonNull);
+ }
+ }
} else {
// in STATE_FINAL we can only fake this method:
// (this way, dependent classes can already be fully translated).
@@ -3284,7 +3295,7 @@ public void resolveGeneratedMethod(AbstractMethodDeclaration methodDeclaration,
methodDeclaration.selector,
null, null, null,
this);
- binding.setCopyInheritanceSrc(copyInheritanceSrc);
+ binding.setCopyInheritanceSrc(original);
methodDeclaration.binding = binding;
resolveTypesFor(binding);
return;
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java
index 3dc613f23..fb72c1b15 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java
@@ -4476,6 +4476,7 @@ public void invalidMethod(MessageSend messageSend, MethodBinding method, Scope s
} else {
ProblemMethodBinding problemMethod = new ProblemMethodBinding(
constructor, selector, constructor.parameters, method.problemId());
+ problemMethod.declaringClass = declaringClass;
invalidConstructor(messageSend, problemMethod);
}
return;
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/mappings/CallinImplementorDyn.java b/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/mappings/CallinImplementorDyn.java
index 99db29058..f07347c51 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/mappings/CallinImplementorDyn.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/mappings/CallinImplementorDyn.java
@@ -1086,7 +1086,7 @@ public class CallinImplementorDyn extends MethodMappingImplementor {
decl.hasParsedStatements = true;
if (teamMethods != null && idxOfExisting > -1) {
teamMethods[idxOfExisting] = decl; // directly replace
- teamDecl.binding.resolveGeneratedMethod(decl, false, null);
+ teamDecl.binding.resolveGeneratedMethod(decl, false, null, false);
} else {
AstEdit.addMethod(teamDecl, decl);
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/statemachine/copyinheritance/CopyInheritance.java b/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/statemachine/copyinheritance/CopyInheritance.java
index 5475a1278..f5636e8d8 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/statemachine/copyinheritance/CopyInheritance.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/statemachine/copyinheritance/CopyInheritance.java
@@ -1006,7 +1006,7 @@ public class CopyInheritance implements IOTConstants, ClassFileConstants, ExtraC
// it would invoke the wrong super().
ConstructorDeclaration ctor =
targetRoleDecl.createDefaultConstructor(true, true);
- targetRoleDecl.binding.resolveGeneratedMethod(ctor, false, origin);
+ targetRoleDecl.binding.resolveGeneratedMethod(ctor, false, origin, true);
return;
}
else if (targetRoleDecl.getRoleModel()._refinesExtends)
@@ -1119,7 +1119,7 @@ public class CopyInheritance implements IOTConstants, ClassFileConstants, ExtraC
}
}
- AstEdit.addMethod(targetRoleDecl, newMethodDecl, wasSynthetic, false/*addToFront*/, origin);
+ AstEdit.addMethod(targetRoleDecl, newMethodDecl, wasSynthetic, false/*addToFront*/, origin, true);
}
if (method.isPrivate()) {
newMethodDecl.binding.modifiers |= ExtraCompilerModifiers.AccLocallyUsed; // don't warn unused copied method
@@ -1507,6 +1507,7 @@ public class CopyInheritance implements IOTConstants, ClassFileConstants, ExtraC
MethodDeclaration newMethod = internalCreateCreationMethod(
teamDeclaration,
roleModel,
+ constructorBinding,
modifiers,
newArguments,
exceptions,
@@ -1546,6 +1547,7 @@ public class CopyInheritance implements IOTConstants, ClassFileConstants, ExtraC
private static MethodDeclaration internalCreateCreationMethod(
TypeDeclaration teamDeclaration,
RoleModel roleModel,
+ MethodBinding constructor,
int ctorModifiers,
Argument[] newArguments,
TypeReference[] thrownExceptions,
@@ -1623,7 +1625,7 @@ public class CopyInheritance implements IOTConstants, ClassFileConstants, ExtraC
}
newMethod.isGenerated = true;
- AstEdit.addMethod(teamDeclaration, newMethod);
+ AstEdit.addMethod(teamDeclaration, newMethod, false, false, constructor, false);
return newMethod;
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/util/AstEdit.java b/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/util/AstEdit.java
index b75b50cde..7f7bf7987 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/util/AstEdit.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/util/AstEdit.java
@@ -10,7 +10,6 @@
* 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
- * $Id: AstEdit.java 23416 2010-02-03 19:59:31Z stephan $
*
* Please visit http://www.eclipse.org/objectteams for updates and contact.
*
@@ -175,6 +174,15 @@ public class AstEdit {
}
addMethod(classTypeDeclaration, methodDeclaration);
}
+ public static void addMethod(
+ TypeDeclaration classTypeDeclaration,
+ AbstractMethodDeclaration methodDeclaration,
+ boolean wasSynthetic,
+ boolean addToFront,
+ MethodBinding copyInheritanceSrc)
+ {
+ addMethod(classTypeDeclaration, methodDeclaration, wasSynthetic, addToFront, copyInheritanceSrc, true);
+ }
/**
* Adds a new Method to TypeDeclaration and resolve its types.
*
@@ -182,18 +190,20 @@ public class AstEdit {
* @param methodDeclaration
* @param wasSynthetic was the method copied from a synthetic method?
* @param addToFront should the method be added to the front of 'methods'?
- * @param copyInheritanceSrc tsuper method from which this method is copied
+ * @param original tsuper method or original ctor from which this method is copied
+ * @param isCopyInheritance
*/
public static void addMethod(
TypeDeclaration classTypeDeclaration,
AbstractMethodDeclaration methodDeclaration,
boolean wasSynthetic,
boolean addToFront,
- MethodBinding copyInheritanceSrc)
+ MethodBinding original,
+ boolean isCopyInheritance)
{
boolean modifiersAdjusted = addMethodDeclOnly(classTypeDeclaration, methodDeclaration, addToFront);
if (classTypeDeclaration.binding != null) {
- classTypeDeclaration.binding.resolveGeneratedMethod(methodDeclaration, wasSynthetic, copyInheritanceSrc);
+ classTypeDeclaration.binding.resolveGeneratedMethod(methodDeclaration, wasSynthetic, original, isCopyInheritance);
if (modifiersAdjusted)
methodDeclaration.binding.tagBits |= TagBits.ClearPrivateModifier;
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/util/AstGenerator.java b/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/util/AstGenerator.java
index 791882a30..418ea1f15 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/util/AstGenerator.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/util/AstGenerator.java
@@ -1492,14 +1492,19 @@ public class AstGenerator extends AstFactory {
}
public void addNonNullAnnotation(Argument argument, LookupEnvironment environment) {
+ addNullAnnotation(argument, environment, true);
+ }
+
+ public void addNullAnnotation(Argument argument, LookupEnvironment environment, boolean nonNull) {
CompilerOptions compilerOptions = environment.globalOptions;
if (compilerOptions.isAnnotationBasedNullAnalysisEnabled) {
+ char[][] annotationName = nonNull ? environment.getNonNullAnnotationName() : environment.getNullableAnnotationName();
if (compilerOptions.sourceLevel < ClassFileConstants.JDK1_8) {
- argument.annotations = new Annotation[]{ markerAnnotation(environment.getNonNullAnnotationName()) };
+ argument.annotations = new Annotation[]{ markerAnnotation(annotationName) };
} else {
int levels = argument.type.getAnnotatableLevels();
argument.type.annotations = new Annotation[levels][];
- argument.type.annotations[levels-1] = new Annotation[] { markerAnnotation(environment.getNonNullAnnotationName()) };
+ argument.type.annotations[levels-1] = new Annotation[] { markerAnnotation(annotationName) };
}
}
}
diff --git a/testplugins/org.eclipse.objectteams.otdt.tests/otjld/org/eclipse/objectteams/otdt/tests/otjld/other/OTNullAnnotationTest.java b/testplugins/org.eclipse.objectteams.otdt.tests/otjld/org/eclipse/objectteams/otdt/tests/otjld/other/OTNullAnnotationTest.java
index eed4b20aa..8430dcb1b 100644
--- a/testplugins/org.eclipse.objectteams.otdt.tests/otjld/org/eclipse/objectteams/otdt/tests/otjld/other/OTNullAnnotationTest.java
+++ b/testplugins/org.eclipse.objectteams.otdt.tests/otjld/org/eclipse/objectteams/otdt/tests/otjld/other/OTNullAnnotationTest.java
@@ -17,6 +17,7 @@ package org.eclipse.objectteams.otdt.tests.otjld.other;
import junit.framework.Test;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
import org.eclipse.objectteams.otdt.tests.otjld.AbstractOTJLDNullAnnotationTest;
public class OTNullAnnotationTest extends AbstractOTJLDNullAnnotationTest {
@@ -68,4 +69,71 @@ public class OTNullAnnotationTest extends AbstractOTJLDNullAnnotationTest {
"Null type mismatch: required \'@NonNull MyBase\' but the provided value is null\n" +
"----------\n");
}
+
+ public void testBug444231() {
+ if (this.complianceLevel >= ClassFileConstants.JDK1_8) return; // not ready for type annotations, yet
+ runNegativeTestWithLibs(
+ new String[] {
+ "b/Base444231.java",
+ "package b;\n" +
+ "public class Base444231 {}\n",
+ "p/Team444231Super.java",
+ "package p;\n" +
+ "import org.eclipse.jdt.annotation.*;\n" +
+ "import base b.Base444231;\n" +
+ "public team class Team444231Super {\n" +
+ " protected class R playedBy Base444231 {\n" +
+ " protected R(@NonNull String s) { base(); }\n" +
+ " }\n" +
+ "}\n",
+ "p/Team444231Sub.java",
+ "package p;\n" +
+ "public team class Team444231Sub extends Team444231Super {\n" +
+ " void test() {\n" +
+ " String val = null;\n" +
+ " new R(val);\n" +
+ " }\n" +
+ "}\n"
+ },
+ getCompilerOptions(),
+ "----------\n" +
+ "1. ERROR in p\\Team444231SubSub.java (at line 6)\n" +
+ " new R(val);\n" +
+ " ^^^\n" +
+ "Null type mismatch: required '@NonNull String' but the provided value is null\n" +
+ "----------\n");
+ }
+
+ public void testBug444231_ambiguous() {
+ if (this.complianceLevel >= ClassFileConstants.JDK1_8) return; // not ready for type annotations, yet
+ runNegativeTestWithLibs(
+ new String[] {
+ "b/Base444231.java",
+ "package b;\n" +
+ "public class Base444231 {}\n",
+ "p/Team444231Super.java",
+ "package p;\n" +
+ "import org.eclipse.jdt.annotation.*;\n" +
+ "import base b.Base444231;\n" +
+ "public team class Team444231Super {\n" +
+ " protected class R playedBy Base444231 {\n" +
+ " protected R(@NonNull String s) { base(); }\n" +
+ " }\n" +
+ "}\n",
+ "p/Team444231Sub.java",
+ "package p;\n" +
+ "public team class Team444231Sub extends Team444231Super {\n" +
+ " void test() {\n" +
+ " new R(null);\n" +
+ " }\n" +
+ "}\n"
+ },
+ getCompilerOptions(),
+ "----------\n" +
+ "1. ERROR in p\\Team444231Sub.java (at line 4)\n" +
+ " new R(null);\n" +
+ " ^^^^^^^^^^^\n" +
+ "The constructor Team444231Sub.R(null) is ambiguous\n" +
+ "----------\n");
+ }
}

Back to the top