diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/AllocationExpression.java b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/AllocationExpression.java index 0c449802e4c..6af8af020cd 100644 --- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/AllocationExpression.java +++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/AllocationExpression.java @@ -529,7 +529,7 @@ public TypeBinding resolveType(BlockScope scope) { for (int i = 0; i < this.typeArguments.length; i++) this.typeArguments[i].checkNullConstraints(scope, (ParameterizedGenericMethodBinding) this.binding, typeVariables, i); } - this.resolvedType = scope.environment().createAnnotatedType(this.resolvedType, new AnnotationBinding[] {scope.environment().getNonNullAnnotation()}); + this.resolvedType = scope.environment().createNonNullAnnotatedType(this.resolvedType); } } if (compilerOptions.sourceLevel >= ClassFileConstants.JDK1_8 && diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/ArrayTypeReference.java b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/ArrayTypeReference.java index 66e270b41dc..9535c415a12 100644 --- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/ArrayTypeReference.java +++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/ArrayTypeReference.java @@ -218,15 +218,13 @@ static TypeBinding maybeMarkArrayContentsNonNull(Scope scope, TypeBinding typeBi LookupEnvironment environment = scope.environment(); if (environment.usesNullTypeAnnotations() && scope.hasDefaultNullnessFor(Binding.DefaultLocationArrayContents, sourceStart)) { - AnnotationBinding nonNullAnnotation = environment.getNonNullAnnotation(); - typeBinding = addNonNullToDimensions(scope, typeBinding, nonNullAnnotation, dimensions); + typeBinding = addNonNullToDimensions(scope, typeBinding, environment.getNonNullAnnotation(), dimensions); TypeBinding leafComponentType = typeBinding.leafComponentType(); if ((leafComponentType.tagBits & TagBits.AnnotationNullMASK) == 0 && leafComponentType.acceptsNonNullDefault()) { if (leafConsumer != null) leafConsumer.accept(leafComponentType); - TypeBinding nonNullLeafComponentType = scope.environment().createAnnotatedType(leafComponentType, - new AnnotationBinding[] { nonNullAnnotation }); + TypeBinding nonNullLeafComponentType = scope.environment().createNonNullAnnotatedType(leafComponentType); typeBinding = scope.createArrayType(nonNullLeafComponentType, typeBinding.dimensions(), typeBinding.getTypeAnnotations()); } diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/ClassLiteralAccess.java b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/ClassLiteralAccess.java index 909b66c2dc9..a51c5e257de 100644 --- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/ClassLiteralAccess.java +++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/ClassLiteralAccess.java @@ -119,7 +119,7 @@ class literals exist only for the raw underlying type. boxedType = scope.boxing(this.targetType); } if (environment.usesNullTypeAnnotations()) - boxedType = environment.createAnnotatedType(boxedType, new AnnotationBinding[] { environment.getNonNullAnnotation() }); + boxedType = environment.createNonNullAnnotatedType(boxedType); this.resolvedType = environment.createParameterizedType(classType, new TypeBinding[]{ boxedType }, null/*not a member*/); } else { this.resolvedType = classType; diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/QualifiedAllocationExpression.java b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/QualifiedAllocationExpression.java index 981b8178842..3b1fce6f6a6 100644 --- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/QualifiedAllocationExpression.java +++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/QualifiedAllocationExpression.java @@ -49,7 +49,6 @@ import org.eclipse.jdt.internal.compiler.flow.FlowInfo; import org.eclipse.jdt.internal.compiler.impl.CompilerOptions; import org.eclipse.jdt.internal.compiler.impl.Constant; -import org.eclipse.jdt.internal.compiler.lookup.AnnotationBinding; import org.eclipse.jdt.internal.compiler.lookup.Binding; import org.eclipse.jdt.internal.compiler.lookup.BlockScope; import org.eclipse.jdt.internal.compiler.lookup.ExtraCompilerModifiers; @@ -312,7 +311,7 @@ public TypeBinding resolveType(BlockScope scope) { this.typeArguments[i].checkNullConstraints(scope, (ParameterizedGenericMethodBinding) this.binding, typeVariables, i); } if (this.resolvedType.isValidBinding()) { - this.resolvedType = scope.environment().createAnnotatedType(this.resolvedType, new AnnotationBinding[] {scope.environment().getNonNullAnnotation()}); + this.resolvedType = scope.environment().createNonNullAnnotatedType(this.resolvedType); } } } diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/ReferenceExpression.java b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/ReferenceExpression.java index 6423d1009e2..41c1a5f57a0 100644 --- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/ReferenceExpression.java +++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/ReferenceExpression.java @@ -908,8 +908,7 @@ protected void checkNullAnnotations(BlockScope scope) { TypeBinding descriptorParameter = this.descriptor.parameters[0]; if((descriptorParameter.tagBits & TagBits.AnnotationNullable) != 0) { // Note: normal dereferencing of 'unchecked' values is not reported, either - final TypeBinding receiver = scope.environment().createAnnotatedType(this.binding.declaringClass, - new AnnotationBinding[] { scope.environment().getNonNullAnnotation() }); + final TypeBinding receiver = scope.environment().createNonNullAnnotatedType(this.binding.declaringClass); scope.problemReporter().referenceExpressionArgumentNullityMismatch(this, receiver, descriptorParameter, this.descriptor, -1, NullAnnotationMatching.NULL_ANNOTATIONS_MISMATCH); } } diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/Statement.java b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/Statement.java index 9501d7e9734..754e01f4d78 100644 --- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/Statement.java +++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/Statement.java @@ -222,7 +222,7 @@ void internalAnalyseOneArgument18(BlockScope currentScope, FlowContext flowConte if (!expectedType.hasNullTypeAnnotations() && expectedNonNullness == Boolean.TRUE) { // improve problem rendering when using a declaration annotation in a 1.8 setting LookupEnvironment env = currentScope.environment(); - expectedType = env.createAnnotatedType(expectedType, new AnnotationBinding[] {env.getNonNullAnnotation()}); + expectedType = env.createNonNullAnnotatedType(expectedType); } flowContext.recordNullityMismatch(currentScope, argument, argument.resolvedType, expectedType, flowInfo, nullStatus, annotationStatus); } diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/TypeParameter.java b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/TypeParameter.java index 9c5cd58d68e..09b37f5201c 100644 --- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/TypeParameter.java +++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/TypeParameter.java @@ -154,9 +154,8 @@ public void resolveAnnotations(Scope scope) { if ((this.binding.tagBits & TagBits.AnnotationNonNull) != 0) scope.problemReporter().nullAnnotationIsRedundant(this); } else { // no explicit type annos, add the default: - AnnotationBinding[] annots = new AnnotationBinding[] { environment.getNonNullAnnotation() }; TypeVariableBinding previousBinding = this.binding; - this.binding = (TypeVariableBinding) environment.createAnnotatedType(this.binding, annots); + this.binding = (TypeVariableBinding) environment.createNonNullAnnotatedType(this.binding); if (scope instanceof MethodScope) { /* diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/TypeReference.java b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/TypeReference.java index 3a53c7242ba..2daaab99676 100644 --- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/TypeReference.java +++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/TypeReference.java @@ -52,13 +52,11 @@ import org.eclipse.jdt.internal.compiler.flow.FlowInfo; import org.eclipse.jdt.internal.compiler.impl.CompilerOptions; import org.eclipse.jdt.internal.compiler.impl.Constant; -import org.eclipse.jdt.internal.compiler.lookup.AnnotationBinding; import org.eclipse.jdt.internal.compiler.lookup.ArrayBinding; import org.eclipse.jdt.internal.compiler.lookup.Binding; import org.eclipse.jdt.internal.compiler.lookup.BlockScope; import org.eclipse.jdt.internal.compiler.lookup.ClassScope; import org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding; -import org.eclipse.jdt.internal.compiler.lookup.LookupEnvironment; import org.eclipse.jdt.internal.compiler.lookup.ParameterizedTypeBinding; import org.eclipse.jdt.internal.compiler.lookup.ProblemReasons; import org.eclipse.jdt.internal.compiler.lookup.ProblemReferenceBinding; @@ -749,9 +747,7 @@ protected void resolveAnnotations(Scope scope, int location) { if (location == Binding.DefaultLocationTypeBound && this.resolvedType.id == TypeIds.T_JavaLangObject) { scope.problemReporter().implicitObjectBoundNoNullDefault(this); } else { - LookupEnvironment environment = scope.environment(); - AnnotationBinding[] annots = new AnnotationBinding[]{environment.getNonNullAnnotation()}; - this.resolvedType = environment.createAnnotatedType(this.resolvedType, annots); + this.resolvedType = scope.environment().createNonNullAnnotatedType(this.resolvedType); } } else if (nullTagBits == TagBits.AnnotationNonNull) { if (location != Binding.DefaultLocationParameter) { // parameters are handled in MethodBinding.fillInDefaultNonNullness18() diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/ArrayBinding.java b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/ArrayBinding.java index 6b01bf81331..15c33a4878c 100644 --- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/ArrayBinding.java +++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/ArrayBinding.java @@ -562,7 +562,7 @@ public char[] signature(ClassFile classFile) { method.returnType = this.environment.globalOptions.sourceLevel >= ClassFileConstants.JDK1_5 ? this : originalMethod.returnType; if (this.environment.globalOptions.isAnnotationBasedNullAnalysisEnabled) { if (this.environment.usesNullTypeAnnotations()) - method.returnType = this.environment.createAnnotatedType(method.returnType, new AnnotationBinding[] { this.environment.getNonNullAnnotation() }); + method.returnType = this.environment.createNonNullAnnotatedType(method.returnType); else method.tagBits |= TagBits.AnnotationNonNull; } diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/BinaryTypeBinding.java b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/BinaryTypeBinding.java index c40e1f466bb..68325ce6772 100644 --- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/BinaryTypeBinding.java +++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/BinaryTypeBinding.java @@ -2038,8 +2038,7 @@ private void scanFieldForNullAnnotation(IBinaryField field, VariableBinding fiel if (nullDefaultFromField == Binding.NO_NULL_DEFAULT ? hasNonNullDefaultForType(fieldType, DefaultLocationField, -1) : (nullDefaultFromField & DefaultLocationField) != 0) { - fieldBinding.type = this.environment.createAnnotatedType(fieldType, - new AnnotationBinding[] { this.environment.getNonNullAnnotation() }); + fieldBinding.type = this.environment.createNonNullAnnotatedType(fieldType); } } return; // not using fieldBinding.tagBits when we have type annotations. @@ -2124,8 +2123,7 @@ private void scanMethodForNullAnnotation(IBinaryMethod method, MethodBinding met methodBinding.tagBits |= TagBits.AnnotationNonNull; if (this.environment.usesNullTypeAnnotations()) { if (methodBinding.returnType != null && !methodBinding.returnType.hasNullTypeAnnotations()) { - methodBinding.returnType = this.environment.createAnnotatedType(methodBinding.returnType, - new AnnotationBinding[] { this.environment.getNonNullAnnotation() }); + methodBinding.returnType = this.environment.createNonNullAnnotatedType(methodBinding.returnType); } } } else if (typeBit == TypeIds.BitNullableAnnotation) { diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/ConstraintExpressionFormula.java b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/ConstraintExpressionFormula.java index adfb15a1238..5748d77e6cd 100644 --- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/ConstraintExpressionFormula.java +++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/ConstraintExpressionFormula.java @@ -340,6 +340,8 @@ private Object reduceReferenceExpressionCompatibility(ReferenceExpression refere TypeBinding rPrime = compileTimeDecl.isConstructor() ? compileTimeDecl.declaringClass : compileTimeDecl.returnType.capture(inferenceContext.scope, reference.sourceStart(), reference.sourceEnd()); if (rPrime.id == TypeIds.T_void) return FALSE; + if (compileTimeDecl.isConstructor() && inferenceContext.environment.usesNullTypeAnnotations()) + rPrime = inferenceContext.environment.createNonNullAnnotatedType(rPrime); return ConstraintTypeFormula.create(rPrime, r, COMPATIBLE, this.isSoft); } } diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/FieldBinding.java b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/FieldBinding.java index 8cf3150d25f..36dc2fb140b 100644 --- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/FieldBinding.java +++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/FieldBinding.java @@ -263,7 +263,7 @@ public void fillInDefaultNonNullness(FieldDeclaration sourceField, Scope scope) if (!this.type.acceptsNonNullDefault()) return; if ( (this.type.tagBits & TagBits.AnnotationNullMASK) == 0) { - this.type = environment.createAnnotatedType(this.type, new AnnotationBinding[]{environment.getNonNullAnnotation()}); + this.type = environment.createNonNullAnnotatedType(this.type); } else if ((this.type.tagBits & TagBits.AnnotationNonNull) != 0) { scope.problemReporter().nullAnnotationIsRedundant(sourceField); } diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/LookupEnvironment.java b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/LookupEnvironment.java index 645ce13b116..22dfef0d58f 100644 --- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/LookupEnvironment.java +++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/LookupEnvironment.java @@ -1431,6 +1431,11 @@ public TypeBinding createAnnotatedType(TypeBinding type, AnnotationBinding[] new return this.typeSystem.getAnnotatedType(type, new AnnotationBinding [][] { newbies }); } +// convenience: +public TypeBinding createNonNullAnnotatedType(TypeBinding type) { + return createAnnotatedType(type, new AnnotationBinding[] { getNonNullAnnotation() } ); +} + public RawTypeBinding createRawType(ReferenceBinding genericType, ReferenceBinding enclosingType) { AnnotationBinding[] annotations = genericType.typeAnnotations; if (annotations != Binding.NO_ANNOTATIONS) diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/MethodBinding.java b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/MethodBinding.java index 2ae3b811ff2..fba73503306 100644 --- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/MethodBinding.java +++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/MethodBinding.java @@ -577,7 +577,7 @@ protected void fillInDefaultNonNullness18(AbstractMethodDeclaration sourceMethod if (existing == 0L) { added = true; if (!parameter.isBaseType()) { - this.parameters[i] = env.createAnnotatedType(parameter, new AnnotationBinding[]{env.getNonNullAnnotation()}); + this.parameters[i] = env.createNonNullAnnotatedType(parameter); if (sourceMethod != null) sourceMethod.arguments[i].binding.type = this.parameters[i]; } diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/ParameterizedMethodBinding.java b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/ParameterizedMethodBinding.java index 872fc44ba83..1c1bb7f8619 100644 --- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/ParameterizedMethodBinding.java +++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/ParameterizedMethodBinding.java @@ -316,14 +316,14 @@ public static ParameterizedMethodBinding instantiateGetClass(TypeBinding receive LookupEnvironment environment = scope.environment(); TypeBinding rawType = environment.convertToRawType(receiverType.erasure(), false /*do not force conversion of enclosing types*/); if (environment.usesNullTypeAnnotations()) - rawType = environment.createAnnotatedType(rawType, new AnnotationBinding[] { environment.getNonNullAnnotation() }); + rawType = environment.createNonNullAnnotatedType(rawType); method.returnType = environment.createParameterizedType( genericClassType, new TypeBinding[] { environment.createWildcard(genericClassType, 0, rawType, null /*no extra bound*/, Wildcard.EXTENDS) }, null); if (environment.globalOptions.isAnnotationBasedNullAnalysisEnabled) { if (environment.usesNullTypeAnnotations()) - method.returnType = environment.createAnnotatedType(method.returnType, new AnnotationBinding[] { environment.getNonNullAnnotation() }); + method.returnType = environment.createNonNullAnnotatedType(method.returnType); else method.tagBits |= TagBits.AnnotationNonNull; } diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/SyntheticMethodBinding.java b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/SyntheticMethodBinding.java index 826f4955d37..668797d2d0e 100644 --- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/SyntheticMethodBinding.java +++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/SyntheticMethodBinding.java @@ -372,7 +372,7 @@ public SyntheticMethodBinding(int purpose, ArrayBinding arrayType, char [] selec if (environment.globalOptions.isAnnotationBasedNullAnalysisEnabled) { // mark X[]::new and X[]::clone as returning 'X @NonNull' (don't wait (cf. markNonNull()), because we're called as late as codeGen): if (environment.usesNullTypeAnnotations()) - this.returnType = environment.createAnnotatedType(this.returnType, new AnnotationBinding[]{ environment.getNonNullAnnotation() }); + this.returnType = environment.createNonNullAnnotatedType(this.returnType); else this.tagBits |= TagBits.AnnotationNonNull; } @@ -686,7 +686,7 @@ static void markNonNull(MethodBinding method, int purpose, LookupEnvironment env if (environment.usesNullTypeAnnotations()) { TypeBinding elementType = ((ArrayBinding)method.returnType).leafComponentType(); AnnotationBinding nonNullAnnotation = environment.getNonNullAnnotation(); - elementType = environment.createAnnotatedType(elementType, new AnnotationBinding[]{ environment.getNonNullAnnotation() }); + elementType = environment.createNonNullAnnotatedType(elementType); method.returnType = environment.createArrayType(elementType, 1, new AnnotationBinding[]{ nonNullAnnotation, null }); } else { method.tagBits |= TagBits.AnnotationNonNull; @@ -694,7 +694,7 @@ static void markNonNull(MethodBinding method, int purpose, LookupEnvironment env return; case EnumValueOf: if (environment.usesNullTypeAnnotations()) { - method.returnType = environment.createAnnotatedType(method.returnType, new AnnotationBinding[]{ environment.getNonNullAnnotation() }); + method.returnType = environment.createNonNullAnnotatedType(method.returnType); } else { method.tagBits |= TagBits.AnnotationNonNull; } diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullAnnotationTests21.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullAnnotationTests21.java index 39b5f00aece..7d403d7bb81 100644 --- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullAnnotationTests21.java +++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullAnnotationTests21.java @@ -945,4 +945,35 @@ public abstract static class InnerBlah extends Blah options = getCompilerOptions(); + options.put(CompilerOptions.OPTION_ReportAnnotatedTypeArgumentToUnannotated, CompilerOptions.ERROR); + runner.customOptions = options; + runner.testFiles = new String[] { + "UnsafeNullTypeConversionFalsePositive.java", + """ + import java.util.ArrayList; + import java.util.List; + import java.util.stream.Collectors; + + import org.eclipse.jdt.annotation.NonNull; + + public class UnsafeNullTypeConversionFalsePositive { + + public static void main(final String[] args) { + final List<@NonNull StringBuffer> someList = new ArrayList<>(); + List<@NonNull String> results; + // was buggy: + results = someList.stream().map(String::new).collect(Collectors.toList()); + // was OK: + results = someList.stream().map(buff -> new String(buff)).collect(Collectors.toList()); + results = someList.stream().<@NonNull String>map(String::new).collect(Collectors.toList()); + } + } + """ + }; + runner.classLibraries = this.LIBS; + runner.runConformTest(); + } }