diff options
| author | Jay Arthanareeswaran | 2016-02-19 08:01:44 +0000 |
|---|---|---|
| committer | Jay Arthanareeswaran | 2016-02-22 06:35:01 +0000 |
| commit | c5316735ee17d65960d7fcf7b16e0e8ec7cd9b5d (patch) | |
| tree | a226071c261e2e56867b74af56699b6bde824064 | |
| parent | 4e45ab99254d6cea7c5b77a3a7dbb62be55ae2cf (diff) | |
| download | eclipse.jdt.core-c5316735ee17d65960d7fcf7b16e0e8ec7cd9b5d.tar.gz eclipse.jdt.core-c5316735ee17d65960d7fcf7b16e0e8ec7cd9b5d.tar.xz eclipse.jdt.core-c5316735ee17d65960d7fcf7b16e0e8ec7cd9b5d.zip | |
Bug 487716 - Type use annotations should not be attached to constructorI20160223-0800
elements
Change-Id: I3a618482d0cf5fe0050b0a945d09c3e1572f70a5
13 files changed, 169 insertions, 9 deletions
diff --git a/org.eclipse.jdt.compiler.apt.tests/lib/apttestprocessors.jar b/org.eclipse.jdt.compiler.apt.tests/lib/apttestprocessors.jar Binary files differindex 46647188ae..821e180e49 100644 --- a/org.eclipse.jdt.compiler.apt.tests/lib/apttestprocessors.jar +++ b/org.eclipse.jdt.compiler.apt.tests/lib/apttestprocessors.jar diff --git a/org.eclipse.jdt.compiler.apt.tests/lib/apttestprocessors8.jar b/org.eclipse.jdt.compiler.apt.tests/lib/apttestprocessors8.jar Binary files differindex 67595968f3..177bbda441 100644 --- a/org.eclipse.jdt.compiler.apt.tests/lib/apttestprocessors8.jar +++ b/org.eclipse.jdt.compiler.apt.tests/lib/apttestprocessors8.jar diff --git a/org.eclipse.jdt.compiler.apt.tests/processors/org/eclipse/jdt/compiler/apt/tests/annotations/Type1.java b/org.eclipse.jdt.compiler.apt.tests/processors/org/eclipse/jdt/compiler/apt/tests/annotations/Type1.java new file mode 100644 index 0000000000..069da444e2 --- /dev/null +++ b/org.eclipse.jdt.compiler.apt.tests/processors/org/eclipse/jdt/compiler/apt/tests/annotations/Type1.java @@ -0,0 +1,22 @@ +/******************************************************************************* + * Copyright (c) 2016 IBM Corporation. + * 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: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.jdt.compiler.apt.tests.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target({ElementType.TYPE_USE, ElementType.CONSTRUCTOR}) +@Retention(RetentionPolicy.RUNTIME) +public @interface Type1 { + String value() default ""; +} diff --git a/org.eclipse.jdt.compiler.apt.tests/processors8/org/eclipse/jdt/compiler/apt/tests/processors/elements/Java8ElementProcessor.java b/org.eclipse.jdt.compiler.apt.tests/processors8/org/eclipse/jdt/compiler/apt/tests/processors/elements/Java8ElementProcessor.java index 37c7d7a4c6..077d7079af 100644 --- a/org.eclipse.jdt.compiler.apt.tests/processors8/org/eclipse/jdt/compiler/apt/tests/processors/elements/Java8ElementProcessor.java +++ b/org.eclipse.jdt.compiler.apt.tests/processors8/org/eclipse/jdt/compiler/apt/tests/processors/elements/Java8ElementProcessor.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2013, 2014 IBM Corporation. + * Copyright (c) 2013, 2016 IBM Corporation. * 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 @@ -65,7 +65,8 @@ import org.eclipse.jdt.compiler.apt.tests.processors.base.BaseProcessor; * @since 3.10 */ @SupportedAnnotationTypes({"targets.model8.TypeAnnot", - "org.eclipse.jdt.compiler.apt.tests.annotations.Type", "org.eclipse.jdt.compiler.apt.tests.annotations.Type$1", + "org.eclipse.jdt.compiler.apt.tests.annotations.Type", "org.eclipse.jdt.compiler.apt.tests.annotations.Type1", + "org.eclipse.jdt.compiler.apt.tests.annotations.Type$1", "org.eclipse.jdt.compiler.apt.tests.annotations.Foo", "org.eclipse.jdt.compiler.apt.tests.annotations.FooContainer", "org.eclipse.jdt.compiler.apt.tests.annotations.IFoo", "org.eclipse.jdt.compiler.apt.tests.annotations.IFooContainer", "org.eclipse.jdt.compiler.apt.tests.annotations.Goo", "org.eclipse.jdt.compiler.apt.tests.annotations.GooNonContainer", @@ -602,15 +603,31 @@ public class Java8ElementProcessor extends BaseProcessor { TypeElement annotatedType = _elementUtils.getTypeElement("targets.model8.X"); List<? extends Element> members = _elementUtils.getAllMembers(annotatedType); ExecutableElement bar2 = null; + ExecutableElement constr = null; + ExecutableElement constr2 = null; for (Element member : members) { if ("bar2".equals(member.getSimpleName().toString())) { bar2 = (ExecutableElement) member; + } else if ("<init>".equals(member.getSimpleName().toString())) { + if (((ExecutableElement) member).getParameters().isEmpty()) { + constr = (ExecutableElement) member; + } else { + constr2 = (ExecutableElement) member; + } } } TypeMirror typeMirror = bar2.getReceiverType(); verifyAnnotations(typeMirror, new String[]{"@Type(value=receiver)"}); ExecutableType type = (ExecutableType) bar2.asType(); verifyAnnotations(type.getReceiverType(), new String[]{"@Type(value=receiver)"}); + + verifyAnnotations(constr, new String[]{}); + type = (ExecutableType) constr.asType(); + verifyAnnotations(type, new String[]{}); + + verifyAnnotations(constr2, new String[]{"@Type1(value=constr2)"}); + type = (ExecutableType) constr2.asType(); + verifyAnnotations(type, new String[]{}); } public void testTypeAnnotations13() { diff --git a/org.eclipse.jdt.compiler.apt.tests/resources/targets/model8/X.java b/org.eclipse.jdt.compiler.apt.tests/resources/targets/model8/X.java index 5b16058e54..2e9409c607 100644 --- a/org.eclipse.jdt.compiler.apt.tests/resources/targets/model8/X.java +++ b/org.eclipse.jdt.compiler.apt.tests/resources/targets/model8/X.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2013 IBM Corporation. + * Copyright (c) 2013, 2016 IBM Corporation. * 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 @@ -11,6 +11,7 @@ package targets.model8; import org.eclipse.jdt.compiler.apt.tests.annotations.Type; +import org.eclipse.jdt.compiler.apt.tests.annotations.Type1; import org.eclipse.jdt.compiler.apt.tests.annotations.Type$1; import org.eclipse.jdt.compiler.apt.tests.annotations.Type.One; @@ -32,7 +33,8 @@ public class X extends @Type("s") Object implements @Type("i1") I, @Type("i2") J public void bar2(@Type("receiver") X this) {} // Static methods and top level constructors do not have receivers public static void main(String[] args) {} - public X(){} + @Type("constr1") public X(){} + @Type1("constr2") public X(int i){} class XY { XY(@Type("receiver") X X.this) {} } diff --git a/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/model/ExecutableTypeImpl.java b/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/model/ExecutableTypeImpl.java index e6cfa6d4c7..c88e7a069b 100644 --- a/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/model/ExecutableTypeImpl.java +++ b/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/model/ExecutableTypeImpl.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2006, 2015 IBM Corporation and others. + * Copyright (c) 2006, 2016 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 @@ -22,6 +22,7 @@ import javax.lang.model.type.TypeVariable; import javax.lang.model.type.TypeVisitor; import org.eclipse.jdt.internal.compiler.apt.dispatch.BaseProcessingEnvImpl; +import org.eclipse.jdt.internal.compiler.lookup.AnnotationBinding; import org.eclipse.jdt.internal.compiler.lookup.ExtraCompilerModifiers; import org.eclipse.jdt.internal.compiler.lookup.MethodBinding; import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding; @@ -77,6 +78,10 @@ public class ExecutableTypeImpl extends TypeMirrorImpl implements ExecutableType return _env.getFactory().newTypeMirror(((MethodBinding) this._binding).returnType); } + protected AnnotationBinding[] getAnnotationBindings() { + return ((MethodBinding) this._binding).returnType.getTypeAnnotations(); + } + /* (non-Javadoc) * @see javax.lang.model.type.ExecutableType#getThrownTypes() */ @@ -126,4 +131,8 @@ public class ExecutableTypeImpl extends TypeMirrorImpl implements ExecutableType public TypeMirror getReceiverType() { return _env.getFactory().getReceiverType((MethodBinding) _binding); } + @Override + public String toString() { + return new String(((MethodBinding) this._binding).returnType.readableName()); + } } diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/TypeBindingTests308.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/TypeBindingTests308.java index 0e046f7b24..20affbf89e 100644 --- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/TypeBindingTests308.java +++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/TypeBindingTests308.java @@ -2569,4 +2569,87 @@ public class TypeBindingTests308 extends ConverterTestSetup { deleteFile("/Converter18/src/X.java"); } } + // https://bugs.eclipse.org/bugs/show_bug.cgi?id=487716 + public void testBug487716() throws Exception { + try { + String contents = + "import java.lang.annotation.ElementType; \n" + + "import java.lang.annotation.Target; \n" + + "@Target({ElementType.TYPE_USE, ElementType.CONSTRUCTOR})\n" + + "@interface A {} \n" + + "class X {\n" + + " @A X() {}\n" + + " X _x_ = new X();\n" + + "}\n"; + + this.workingCopy = getWorkingCopy("/Converter18/src/X.java", true/*resolve*/); + ASTNode node = buildAST(contents, this.workingCopy, false); + assertEquals("Not a compilation unit", ASTNode.COMPILATION_UNIT, node.getNodeType()); + CompilationUnit compilationUnit = (CompilationUnit) node; + + List types = compilationUnit.types(); + TypeDeclaration typeDecl = (TypeDeclaration) types.get(1); + + // On the Allocation expression type - new X() + FieldDeclaration field = typeDecl.getFields()[0]; + VariableDeclarationFragment fragment = (VariableDeclarationFragment) field.fragments().get(0); + ITypeBinding type = fragment.getInitializer().resolveTypeBinding(); + IAnnotationBinding[] annots = type.getTypeAnnotations(); + assertEquals("Incorrect no of annotations", 1, annots.length); + + // On constructor declaration - X() + MethodDeclaration method = typeDecl.getMethods()[0]; + assertTrue("Should be a constructor", method.isConstructor()); + IMethodBinding methodBinding = method.resolveBinding(); + annots = methodBinding.getAnnotations(); + assertEquals("Incorrect no of annotations", 1, annots.length); + } finally { + deleteFile("/Converter18/src/X.java"); + } + } + // https://bugs.eclipse.org/bugs/show_bug.cgi?id=487716 + public void testBug487716a() throws Exception { + try { + String contents = + "package p;\n" + + "import java.lang.annotation.ElementType; \n" + + "import java.lang.annotation.Target; \n" + + "@Target({ElementType.TYPE_USE})\n" + + "@interface A {} \n" + + "class X {\n" + + " @A X() {}\n" + + " class Y {\n" + + " @A Y() {}\n" + + " Y _y_ = new X().new Y();\n" + + " }\n" + + "}\n"; + + this.workingCopy = getWorkingCopy("/Converter18/src/p/X.java", true/*resolve*/); + ASTNode node = buildAST(contents, this.workingCopy, false); + assertEquals("Not a compilation unit", ASTNode.COMPILATION_UNIT, node.getNodeType()); + CompilationUnit compilationUnit = (CompilationUnit) node; + + List types = compilationUnit.types(); + TypeDeclaration typeDecl = (TypeDeclaration) types.get(1); + + assertEquals(1, typeDecl.getTypes().length); + typeDecl = typeDecl.getTypes()[0]; + + // On the Qualified Allocation expression type - new X().new Y() + FieldDeclaration field = typeDecl.getFields()[0]; + VariableDeclarationFragment fragment = (VariableDeclarationFragment) field.fragments().get(0); + ITypeBinding type = fragment.getInitializer().resolveTypeBinding(); + IAnnotationBinding[] annots = type.getTypeAnnotations(); + assertEquals("Incorrect no of annotations", 1, annots.length); + + // On constructor declaration - Y() + MethodDeclaration method = typeDecl.getMethods()[0]; + assertTrue("Should be a constructor", method.isConstructor()); + IMethodBinding methodBinding = method.resolveBinding(); + annots = methodBinding.getAnnotations(); + assertEquals("Incorrect no of annotations", 0, annots.length); + } finally { + deleteFile("/Converter18/src/X.java"); + } + } } diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ASTNode.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ASTNode.java index 5e68f96785..d4703f632e 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ASTNode.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ASTNode.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2015 IBM Corporation and others. + * Copyright (c) 2000, 2016 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 @@ -947,7 +947,8 @@ public abstract class ASTNode implements TypeConstants, TypeIds { recipientTargetMask = TagBits.AnnotationForField; break; case Binding.METHOD: - recipientTargetMask = TagBits.AnnotationForMethod; + MethodBinding method = (MethodBinding) recipient; + recipientTargetMask = method.isConstructor() ? TagBits.AnnotationForConstructor : TagBits.AnnotationForMethod; break; default: return; @@ -1027,6 +1028,8 @@ public abstract class ASTNode implements TypeConstants, TypeIds { method.tagBits &= ~(se8nullBits); } } + } else { + method.setTypeAnnotations(se8Annotations); } break; } diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AbstractMethodDeclaration.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AbstractMethodDeclaration.java index 2058cbf4be..84a02b9189 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AbstractMethodDeclaration.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AbstractMethodDeclaration.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2015 IBM Corporation and others. + * Copyright (c) 2000, 2016 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 @@ -532,7 +532,7 @@ public abstract class AbstractMethodDeclaration resolveReceiver(); bindThrownExceptions(); resolveJavadoc(); - resolveAnnotations(this.scope, this.annotations, this.binding); + resolveAnnotations(this.scope, this.annotations, this.binding, this.isConstructor()); long sourceLevel = this.scope.compilerOptions().sourceLevel; if (sourceLevel < ClassFileConstants.JDK1_8) // otherwise already checked via Argument.createBinding diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AllocationExpression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AllocationExpression.java index 85dfc190c2..7960772d9e 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AllocationExpression.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AllocationExpression.java @@ -505,6 +505,10 @@ public TypeBinding resolveType(BlockScope scope) { } } } + if (compilerOptions.sourceLevel >= ClassFileConstants.JDK1_8 && + this.binding.getTypeAnnotations() != Binding.NO_ANNOTATIONS) { + this.resolvedType = scope.environment().createAnnotatedType(this.resolvedType, this.binding.getTypeAnnotations()); + } return this.resolvedType; } diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedAllocationExpression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedAllocationExpression.java index 4bca0f1fbf..9afc96ed3c 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedAllocationExpression.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedAllocationExpression.java @@ -300,6 +300,10 @@ public class QualifiedAllocationExpression extends AllocationExpression { } } } + if (compilerOptions.sourceLevel >= ClassFileConstants.JDK1_8 && + this.binding.getTypeAnnotations() != Binding.NO_ANNOTATIONS) { + this.resolvedType = scope.environment().createAnnotatedType(this.resolvedType, this.binding.getTypeAnnotations()); + } } return result; } diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodBinding.java index 7e7cc461fa..c7a0b5593d 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodBinding.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodBinding.java @@ -60,6 +60,8 @@ public class MethodBinding extends Binding { public TypeVariableBinding[] typeVariables = Binding.NO_TYPE_VARIABLES; char[] signature; public long tagBits; + // Used only for constructors + protected AnnotationBinding [] typeAnnotations = Binding.NO_ANNOTATIONS; /** Store nullness information from annotation (incl. applicable default). */ public Boolean[] parameterNonNullness; // TRUE means @NonNull declared, FALSE means @Nullable declared, null means nothing declared @@ -952,6 +954,13 @@ public char[] readableName() /* foo(int, Thread) */ { buffer.append(')'); return buffer.toString().toCharArray(); } +final public AnnotationBinding[] getTypeAnnotations() { + return this.typeAnnotations; +} + +public void setTypeAnnotations(AnnotationBinding[] annotations) { + this.typeAnnotations = annotations; +} public void setAnnotations(AnnotationBinding[] annotations) { this.declaringClass.storeAnnotations(this, annotations); } 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 cb2ff657c7..c4a5e723fe 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 @@ -1954,6 +1954,13 @@ public MethodBinding resolveTypesFor(MethodBinding method) { rejectTypeAnnotatedVoidMethod(methodDecl);
}
}
+ } else {
+ if (sourceLevel >= ClassFileConstants.JDK1_8) {
+ Annotation [] annotations = methodDecl.annotations;
+ if (annotations != null && annotations.length != 0) {
+ ASTNode.copySE8AnnotationsToType(methodDecl.scope, method, methodDecl.annotations, false);
+ }
+ }
}
if (foundArgProblem) {
methodDecl.binding = null;
|
