diff options
Diffstat (limited to 'org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast')
7 files changed, 106 insertions, 61 deletions
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 80e2e1b9c..9fc88ae55 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 @@ -750,8 +750,11 @@ public abstract class ASTNode implements TypeConstants, TypeIds { } else { updatedArgumentType = argument.resolveType(scope); } - if (updatedArgumentType != null && updatedArgumentType.kind() != Binding.POLY_TYPE) + if (updatedArgumentType != null && updatedArgumentType.kind() != Binding.POLY_TYPE) { argumentTypes[i] = updatedArgumentType; + if (candidateMethod.isPolymorphic()) + candidateMethod.parameters[i] = updatedArgumentType; + } } } } diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Annotation.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Annotation.java index 828fa15f1..dfb613a58 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Annotation.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Annotation.java @@ -654,7 +654,7 @@ public abstract class Annotation extends Expression { // no need to check annotation usage if missing return; } - if (! isAnnotationTargetAllowed(repeatingAnnotation, scope, containerAnnotationType, repeatingAnnotation.recipient.kind())) { + if (isAnnotationTargetAllowed(repeatingAnnotation, scope, containerAnnotationType, repeatingAnnotation.recipient.kind()) != AnnotationTargetAllowed.YES) { scope.problemReporter().disallowedTargetForContainerAnnotation(repeatingAnnotation, containerAnnotationType); } } @@ -987,75 +987,83 @@ public abstract class Annotation extends Expression { return this.resolvedType; } - private static boolean isAnnotationTargetAllowed(Binding recipient, BlockScope scope, TypeBinding annotationType, int kind, long metaTagBits) { + public enum AnnotationTargetAllowed { + YES, TYPE_ANNOTATION_ON_QUALIFIED_NAME, NO; + } + + private static AnnotationTargetAllowed isAnnotationTargetAllowed(Binding recipient, BlockScope scope, TypeBinding annotationType, int kind, long metaTagBits) { switch (kind) { case Binding.PACKAGE : if ((metaTagBits & TagBits.AnnotationForPackage) != 0) - return true; + return AnnotationTargetAllowed.YES; else if (scope.compilerOptions().sourceLevel <= ClassFileConstants.JDK1_6) { SourceTypeBinding sourceType = (SourceTypeBinding) recipient; if (CharOperation.equals(sourceType.sourceName, TypeConstants.PACKAGE_INFO_NAME)) - return true; + return AnnotationTargetAllowed.YES; } break; case Binding.TYPE_USE : if ((metaTagBits & TagBits.AnnotationForTypeUse) != 0) { // jsr 308 - return true; + return AnnotationTargetAllowed.YES; } if (scope.compilerOptions().sourceLevel < ClassFileConstants.JDK1_8) { // already reported as syntax error; don't report secondary problems - return true; + return AnnotationTargetAllowed.YES; } break; case Binding.TYPE : case Binding.GENERIC_TYPE : if (((ReferenceBinding)recipient).isAnnotationType()) { if ((metaTagBits & (TagBits.AnnotationForAnnotationType | TagBits.AnnotationForType | TagBits.AnnotationForTypeUse)) != 0) - return true; + return AnnotationTargetAllowed.YES; } else if ((metaTagBits & (TagBits.AnnotationForType | TagBits.AnnotationForTypeUse)) != 0) { - return true; + return AnnotationTargetAllowed.YES; } else if ((metaTagBits & TagBits.AnnotationForPackage) != 0) { if (CharOperation.equals(((ReferenceBinding) recipient).sourceName, TypeConstants.PACKAGE_INFO_NAME)) - return true; + return AnnotationTargetAllowed.YES; } //{ObjectTeams: allow @Override for roles: if ( (((ReferenceBinding)recipient).isRole()) && (annotationType.id == TypeIds.T_JavaLangOverride)) - return true; + return AnnotationTargetAllowed.YES; //SH} break; //{ObjectTeams: method mappings // TODO(SH): should annotations for method mappings be controlled separately? case Binding.BINDING : if ((metaTagBits & TagBits.AnnotationForMethod) != 0) - return true; + return AnnotationTargetAllowed.YES; break; //SH} case Binding.METHOD : MethodBinding methodBinding = (MethodBinding) recipient; if (methodBinding.isConstructor()) { if ((metaTagBits & (TagBits.AnnotationForConstructor | TagBits.AnnotationForTypeUse)) != 0) - return true; + return AnnotationTargetAllowed.YES; } else if ((metaTagBits & TagBits.AnnotationForMethod) != 0) { - return true; + return AnnotationTargetAllowed.YES; } else if ((metaTagBits & TagBits.AnnotationForTypeUse) != 0) { SourceTypeBinding sourceType = (SourceTypeBinding) methodBinding.declaringClass; MethodDeclaration methodDecl = (MethodDeclaration) sourceType.scope.referenceContext.declarationOf(methodBinding); if (isTypeUseCompatible(methodDecl.returnType, scope)) { - return true; + return AnnotationTargetAllowed.YES; + } else { + return AnnotationTargetAllowed.TYPE_ANNOTATION_ON_QUALIFIED_NAME; } } break; case Binding.FIELD : if ((metaTagBits & TagBits.AnnotationForField) != 0) { - return true; + return AnnotationTargetAllowed.YES; } else if ((metaTagBits & TagBits.AnnotationForTypeUse) != 0) { FieldBinding sourceField = (FieldBinding) recipient; SourceTypeBinding sourceType = (SourceTypeBinding) sourceField.declaringClass; FieldDeclaration fieldDeclaration = sourceType.scope.referenceContext.declarationOf(sourceField); if (isTypeUseCompatible(fieldDeclaration.type, scope)) { - return true; + return AnnotationTargetAllowed.YES; + } else { + return AnnotationTargetAllowed.TYPE_ANNOTATION_ON_QUALIFIED_NAME; } } break; @@ -1063,27 +1071,31 @@ public abstract class Annotation extends Expression { LocalVariableBinding localVariableBinding = (LocalVariableBinding) recipient; if ((localVariableBinding.tagBits & TagBits.IsArgument) != 0) { if ((metaTagBits & TagBits.AnnotationForParameter) != 0) { - return true; + return AnnotationTargetAllowed.YES; } else if ((metaTagBits & TagBits.AnnotationForTypeUse) != 0) { if (isTypeUseCompatible(localVariableBinding.declaration.type, scope)) { - return true; + return AnnotationTargetAllowed.YES; + } else { + return AnnotationTargetAllowed.TYPE_ANNOTATION_ON_QUALIFIED_NAME; } } } else if ((annotationType.tagBits & TagBits.AnnotationForLocalVariable) != 0) { - return true; + return AnnotationTargetAllowed.YES; } else if ((metaTagBits & TagBits.AnnotationForTypeUse) != 0) { if (isTypeUseCompatible(localVariableBinding.declaration.type, scope)) { - return true; + return AnnotationTargetAllowed.YES; + } else { + return AnnotationTargetAllowed.TYPE_ANNOTATION_ON_QUALIFIED_NAME; } } break; case Binding.TYPE_PARAMETER : // jsr308 // https://bugs.eclipse.org/bugs/show_bug.cgi?id=391196 if ((metaTagBits & (TagBits.AnnotationForTypeParameter | TagBits.AnnotationForTypeUse)) != 0) { - return true; + return AnnotationTargetAllowed.YES; } } - return false; + return AnnotationTargetAllowed.NO; } public static boolean isAnnotationTargetAllowed(BlockScope scope, TypeBinding annotationType, Binding recipient) { @@ -1091,10 +1103,10 @@ public abstract class Annotation extends Expression { if ((metaTagBits & TagBits.AnnotationTargetMASK) == 0) { return true; } - return isAnnotationTargetAllowed(recipient, scope, annotationType, recipient.kind(), metaTagBits); + return isAnnotationTargetAllowed(recipient, scope, annotationType, recipient.kind(), metaTagBits)==AnnotationTargetAllowed.YES; } - static boolean isAnnotationTargetAllowed(Annotation annotation, BlockScope scope, TypeBinding annotationType, int kind) { + static AnnotationTargetAllowed isAnnotationTargetAllowed(Annotation annotation, BlockScope scope, TypeBinding annotationType, int kind) { long metaTagBits = annotationType.getAnnotationTagBits(); // could be forward reference if ((metaTagBits & TagBits.AnnotationTargetMASK) == 0) { @@ -1102,7 +1114,7 @@ public abstract class Annotation extends Expression { if (kind == Binding.TYPE_PARAMETER || kind == Binding.TYPE_USE) { scope.problemReporter().explitAnnotationTargetRequired(annotation); } - return true; + return AnnotationTargetAllowed.YES; } // https://bugs.eclipse.org/bugs/show_bug.cgi?id=391201 @@ -1129,8 +1141,13 @@ public abstract class Annotation extends Expression { // no need to check annotation usage if missing return; } - if (! isAnnotationTargetAllowed(annotation, scope, annotationType, kind)) { + AnnotationTargetAllowed annotationTargetAllowed = isAnnotationTargetAllowed(annotation, scope, annotationType, kind); + if (annotationTargetAllowed != AnnotationTargetAllowed.YES) { + if(annotationTargetAllowed == AnnotationTargetAllowed.TYPE_ANNOTATION_ON_QUALIFIED_NAME) { + scope.problemReporter().typeAnnotationAtQualifiedName(annotation); + } else { scope.problemReporter().disallowedTargetForAnnotation(annotation); + } if (recipient instanceof TypeBinding) ((TypeBinding)recipient).tagBits &= ~tagBitsToRevert; } @@ -1199,7 +1216,7 @@ public abstract class Annotation extends Expression { continue nextAnnotation; } else { if (annotation.hasNullBit(TypeIds.BitNonNullAnnotation|TypeIds.BitNullableAnnotation)) { - scope.problemReporter().nullAnnotationUnsupportedLocation(annotation); + scope.problemReporter().nullAnnotationAtQualifyingType(annotation); continue nextAnnotation; } } diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CastExpression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CastExpression.java index 13f06d9e1..bf50c2a28 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CastExpression.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CastExpression.java @@ -360,6 +360,9 @@ public static void checkNeedForArgumentCasts(BlockScope scope, int operator, int } public boolean checkNPE(BlockScope scope, FlowContext flowContext, FlowInfo flowInfo, int ttlForFieldCheck) { + if((this.resolvedType.tagBits & TagBits.AnnotationNonNull) != 0) { + return true; + } checkNPEbyUnboxing(scope, flowContext, flowInfo); return this.expression.checkNPE(scope, flowContext, flowInfo, ttlForFieldCheck); } diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CompilationUnitDeclaration.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CompilationUnitDeclaration.java index 98e3208cb..04287d411 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CompilationUnitDeclaration.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CompilationUnitDeclaration.java @@ -376,22 +376,28 @@ public void finalizeProblems() { Constant cst = inits[iToken].constant; if (cst != Constant.NotAConstant && cst.typeID() == TypeIds.T_JavaLangString) { IrritantSet tokenIrritants = CompilerOptions.warningTokenToIrritants(cst.stringValue()); - if (tokenIrritants != null - && !tokenIrritants.areAllSet() // no complaint against @SuppressWarnings("all") - && options.isAnyEnabled(tokenIrritants) // if irritant is effectively enabled - && (foundIrritants[iSuppress] == null || !foundIrritants[iSuppress].isAnySet(tokenIrritants))) { // if irritant had no matching problem - if (unusedWarningTokenIsWarning) { - int start = value.sourceStart, end = value.sourceEnd; - nextSuppress: for (int jSuppress = iSuppress - 1; jSuppress >= 0; jSuppress--) { - long position = this.suppressWarningScopePositions[jSuppress]; - int startSuppress = (int) (position >>> 32); - int endSuppress = (int) position; - if (start < startSuppress) continue nextSuppress; - if (end > endSuppress) continue nextSuppress; - if (this.suppressWarningIrritants[jSuppress].areAllSet()) break pairLoop; // suppress all? + if (tokenIrritants != null) { + if (!tokenIrritants.areAllSet() // no complaint against @SuppressWarnings("all") + && (foundIrritants[iSuppress] == null || !foundIrritants[iSuppress].isAnySet(tokenIrritants))) { // if irritant had no matching problem + if (unusedWarningTokenIsWarning) { + int start = value.sourceStart, end = value.sourceEnd; + nextSuppress: for (int jSuppress = iSuppress - 1; jSuppress >= 0; jSuppress--) { + long position = this.suppressWarningScopePositions[jSuppress]; + int startSuppress = (int) (position >>> 32); + int endSuppress = (int) position; + if (start < startSuppress) continue nextSuppress; + if (end > endSuppress) continue nextSuppress; + if (this.suppressWarningIrritants[jSuppress].areAllSet()) break pairLoop; // suppress all? + } + } + int id = options.getIgnoredIrritant(tokenIrritants); + if (id > 0) { + String key = CompilerOptions.optionKeyFromIrritant(id); + this.scope.problemReporter().problemNotAnalysed(inits[iToken], key); + } else { + this.scope.problemReporter().unusedWarningToken(inits[iToken]); } } - this.scope.problemReporter().unusedWarningToken(inits[iToken]); } } } @@ -400,22 +406,28 @@ public void finalizeProblems() { Constant cst = value.constant; if (cst != Constant.NotAConstant && cst.typeID() == T_JavaLangString) { IrritantSet tokenIrritants = CompilerOptions.warningTokenToIrritants(cst.stringValue()); - if (tokenIrritants != null - && !tokenIrritants.areAllSet() // no complaint against @SuppressWarnings("all") - && options.isAnyEnabled(tokenIrritants) // if irritant is effectively enabled - && (foundIrritants[iSuppress] == null || !foundIrritants[iSuppress].isAnySet(tokenIrritants))) { // if irritant had no matching problem - if (unusedWarningTokenIsWarning) { - int start = value.sourceStart, end = value.sourceEnd; - nextSuppress: for (int jSuppress = iSuppress - 1; jSuppress >= 0; jSuppress--) { - long position = this.suppressWarningScopePositions[jSuppress]; - int startSuppress = (int) (position >>> 32); - int endSuppress = (int) position; - if (start < startSuppress) continue nextSuppress; - if (end > endSuppress) continue nextSuppress; - if (this.suppressWarningIrritants[jSuppress].areAllSet()) break pairLoop; // suppress all? + if (tokenIrritants != null) { + if (!tokenIrritants.areAllSet() // no complaint against @SuppressWarnings("all") + && (foundIrritants[iSuppress] == null || !foundIrritants[iSuppress].isAnySet(tokenIrritants))) { // if irritant had no matching problem + if (unusedWarningTokenIsWarning) { + int start = value.sourceStart, end = value.sourceEnd; + nextSuppress: for (int jSuppress = iSuppress - 1; jSuppress >= 0; jSuppress--) { + long position = this.suppressWarningScopePositions[jSuppress]; + int startSuppress = (int) (position >>> 32); + int endSuppress = (int) position; + if (start < startSuppress) continue nextSuppress; + if (end > endSuppress) continue nextSuppress; + if (this.suppressWarningIrritants[jSuppress].areAllSet()) break pairLoop; // suppress all? + } + } + int id = options.getIgnoredIrritant(tokenIrritants); + if (id > 0) { + String key = CompilerOptions.optionKeyFromIrritant(id); + this.scope.problemReporter().problemNotAnalysed(value, key); + } else { + this.scope.problemReporter().unusedWarningToken(value); } } - this.scope.problemReporter().unusedWarningToken(value); } } } diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MessageSend.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MessageSend.java index d6a97919f..0b3762cd8 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MessageSend.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MessageSend.java @@ -867,8 +867,11 @@ public TypeBinding resolveType(BlockScope scope) { // MW,JH,SH} if (receiverCast && this.actualReceiverType != null) { // due to change of declaring class with receiver type, only identity cast should be notified - if (TypeBinding.equalsEquals(((CastExpression)this.receiver).expression.resolvedType, this.actualReceiverType)) { - scope.problemReporter().unnecessaryCast((CastExpression)this.receiver); + TypeBinding resolvedType2 = ((CastExpression)this.receiver).expression.resolvedType; + if (TypeBinding.equalsEquals(resolvedType2, this.actualReceiverType)) { + if (!scope.environment().usesNullTypeAnnotations() || !NullAnnotationMatching.analyse(this.actualReceiverType, resolvedType2, -1).isAnyMismatch()) { + scope.problemReporter().unnecessaryCast((CastExpression) this.receiver); + } } } // resolve type arguments (for generic constructor call) diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedTypeReference.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedTypeReference.java index b7095550b..ae21034c6 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedTypeReference.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedTypeReference.java @@ -128,8 +128,15 @@ public class QualifiedTypeReference extends TypeReference { for (int j = 0; j < i; j++) { Annotation[] qualifierAnnot = this.annotations[j]; if (qualifierAnnot != null && qualifierAnnot.length > 0) { - scope.problemReporter().misplacedTypeAnnotations(qualifierAnnot[0], qualifierAnnot[qualifierAnnot.length - 1]); - this.annotations[j] = null; + if (j == 0) { + for (int k = 0; k < qualifierAnnot.length; k++) { + scope.problemReporter().typeAnnotationAtQualifiedName(qualifierAnnot[k]); + } + } else { + scope.problemReporter().misplacedTypeAnnotations(qualifierAnnot[0], + qualifierAnnot[qualifierAnnot.length - 1]); + this.annotations[j] = null; + } } } } diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ReferenceExpression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ReferenceExpression.java index 004ddafbd..3a2af2c64 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ReferenceExpression.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ReferenceExpression.java @@ -239,7 +239,7 @@ public class ReferenceExpression extends FunctionalExpression implements IPolyEx } // Process the lambda, taking care not to double report diagnostics. Don't expect any from resolve, Any from code generation should surface, but not those from flow analysis. - implicitLambda.resolve(currentScope); + implicitLambda.resolveType(currentScope, true); IErrorHandlingPolicy oldPolicy = currentScope.problemReporter().switchErrorHandlingPolicy(silentErrorHandlingPolicy); try { implicitLambda.analyseCode(currentScope, |