diff options
author | Stephan Herrmann | 2019-08-13 21:21:59 +0000 |
---|---|---|
committer | Stephan Herrmann | 2019-08-14 16:28:18 +0000 |
commit | 1f0f0840f8b9a727c507dfc44b762e9882693134 (patch) | |
tree | 605ffb8ca1757fa591a3d2a4c6bc3edde427ccfa | |
parent | bed796f498b19027a8ec3a769f0d1da3ce0c4807 (diff) | |
download | eclipse.jdt.core-1f0f0840f8b9a727c507dfc44b762e9882693134.tar.gz eclipse.jdt.core-1f0f0840f8b9a727c507dfc44b762e9882693134.tar.xz eclipse.jdt.core-1f0f0840f8b9a727c507dfc44b762e9882693134.zip |
Bug 549764 - [null] @NNBD on package is disabled by constant in class
annotation
Change-Id: I93fb437041e4ba02633770d15b66a78f153e3e2e
5 files changed, 95 insertions, 16 deletions
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 index d6777cb46d..54d85a1b65 100644 --- 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 @@ -30,6 +30,7 @@ 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.IPath; import org.eclipse.core.runtime.Platform; import org.eclipse.jdt.annotation.NonNull; import org.eclipse.jdt.core.IAnnotation; @@ -49,6 +50,7 @@ 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; +import org.eclipse.jdt.core.tests.util.Util; import org.osgi.framework.Bundle; @SuppressWarnings("rawtypes") @@ -1003,4 +1005,60 @@ public class NullAnnotationModelTests extends ReconcilerTests { deleteProject(client); } } + public void testBug549764() throws CoreException, IOException { + IJavaProject project = null; + try { + project = createJavaProject("Bug549764", new String[] {"src"}, new String[] {"JCL18_LIB", this.ANNOTATION_LIB}, "bin", "1.8"); + project.setOption(JavaCore.COMPILER_ANNOTATION_NULL_ANALYSIS, JavaCore.ENABLED); + + IPath libpath = project.getProject().getLocation().append("libann.jar"); + Util.createJar(new String[] { + "lib/MyGenerated.java", + "package lib;\n" + + "public @interface MyGenerated {\n" + + " String value();\n" + + "}"}, + libpath.toOSString(), + "1.8"); + addLibraryEntry(project, libpath, false); + + createFolder("Bug549764/src/nullAnalysis"); + createFile("Bug549764/src/nullAnalysis/package-info.java", + "@org.eclipse.jdt.annotation.NonNullByDefault\n" + + "package nullAnalysis;"); + String testSource = + "package nullAnalysis;\n" + + "\n" + + "import org.eclipse.jdt.annotation.NonNull;\n" + + "import lib.MyGenerated;\n" + + "\n" + + "@MyGenerated(Endpoint.COMMENT)\n" + + "public class Endpoint {\n" + + "\n" + + " public static final String COMMENT = \" comment\";\n" + + "\n" + + " public void method() {\n" + + " format(COMMENT, \"\");\n" + + " }\n" + + " native void format(@NonNull String comment, String arg);\n" + + "}\n"; + String testSourcePath = "Bug549764/src/nullAnalysis/Endpoint.java"; + createFile(testSourcePath, testSource); + char[] testSourceChars = testSource.toCharArray(); + this.problemRequestor.initialize(testSourceChars); + + getCompilationUnit(testSourcePath).getWorkingCopy(this.wcOwner, null); + assertProblems( + "Unexpected problems", + "----------\n" + + "1. WARNING in /Bug549764/src/nullAnalysis/Endpoint.java (at line 14)\n" + + " native void format(@NonNull String comment, String arg);\n" + + " ^^^^^^^^^^^^^^^^^^^^^^^\n" + + "The nullness annotation is redundant with a default that applies to this location\n" + + "----------\n" + ); + } finally { + deleteProject(project); + } + } } diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MemberValuePair.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MemberValuePair.java index 9b222c7177..b65a66745c 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MemberValuePair.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MemberValuePair.java @@ -109,7 +109,7 @@ public class MemberValuePair extends ASTNode { final TypeBinding leafType = requiredType.leafComponentType(); // the next check may need deferring: - final boolean[] shouldExit = new boolean[1]; + final boolean[] shouldExit = { false }; Runnable check = new Runnable() { @Override public void run() { diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BinaryTypeBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BinaryTypeBinding.java index 529913063f..e31e319b7f 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BinaryTypeBinding.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BinaryTypeBinding.java @@ -1913,6 +1913,9 @@ private void scanTypeForNullDefaultAnnotation(IBinaryType binaryType, PackageBin if (CharOperation.equals(CharOperation.splitOn('/', binaryType.getName()), nonNullByDefaultAnnotationName)) return; // don't recursively apply @NNBD on @NNBD, neither directly nor via the 'enclosing' package-info.java + for (String name : this.environment.globalOptions.nonNullByDefaultAnnotationSecondaryNames) + if (CharOperation.toString(this.compoundName).equals(name)) + return; IBinaryAnnotation[] annotations = binaryType.getAnnotations(); boolean isPackageInfo = CharOperation.equals(sourceName(), TypeConstants.PACKAGE_INFO_NAME); diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/PackageBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/PackageBinding.java index 282e542ab4..a43381f2d3 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/PackageBinding.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/PackageBinding.java @@ -38,8 +38,8 @@ public abstract class PackageBinding extends Binding implements TypeConstants { HashtableOfPackage<PackageBinding> knownPackages; // code representing the default that has been defined for this package (using @NonNullByDefault) - // one of Binding.{NO_NULL_DEFAULT,NULL_UNSPECIFIED_BY_DEFAULT,NONNULL_BY_DEFAULT} - private int defaultNullness = NO_NULL_DEFAULT; + // once initialized it will be one of Binding.{NO_NULL_DEFAULT,NULL_UNSPECIFIED_BY_DEFAULT,NONNULL_BY_DEFAULT} + private int defaultNullness = -1; public ModuleBinding enclosingModule; @@ -320,7 +320,23 @@ public final boolean isViewedAsDeprecated() { } return (this.tagBits & TagBits.AnnotationDeprecated) != 0; } +private void initDefaultNullness() { + if (this.defaultNullness == -1) { + ReferenceBinding packageInfo = getType(TypeConstants.PACKAGE_INFO_NAME, this.enclosingModule); + if (packageInfo != null) { + packageInfo.getAnnotationTagBits(); + if (packageInfo instanceof SourceTypeBinding) { + this.defaultNullness = ((SourceTypeBinding) packageInfo).defaultNullness; + } else { + this.defaultNullness = ((BinaryTypeBinding) packageInfo).defaultNullness; + } + } else { + this.defaultNullness = NO_NULL_DEFAULT; + } + } +} public int getDefaultNullness() { + initDefaultNullness(); if (this.defaultNullness == NO_NULL_DEFAULT) return this.enclosingModule.getDefaultNullness(); return this.defaultNullness; @@ -333,6 +349,7 @@ public void setDefaultNullness(int nullness) { * where 'defaultNullness' matches the given predicate. */ public Binding findDefaultNullnessTarget(Predicate<Integer> predicate) { + initDefaultNullness(); if (predicate.test(this.defaultNullness)) return this; if (this.defaultNullness == NO_NULL_DEFAULT) 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 de31d2ace7..71ba1a2cb7 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 @@ -1035,6 +1035,19 @@ public long getAnnotationTagBits() { if (!isPrototype()) return this.prototype.getAnnotationTagBits(); + if ((this.tagBits & TagBits.EndHierarchyCheck) == 0) { + CompilationUnitScope pkgCUS = this.scope.compilationUnitScope(); + boolean current = pkgCUS.connectingHierarchy; + pkgCUS.connectingHierarchy = true; + try { + return internalGetAnnotationTagBits(); + } finally { + pkgCUS.connectingHierarchy = current; + } + } + return internalGetAnnotationTagBits(); +} +private long internalGetAnnotationTagBits() { if ((this.tagBits & TagBits.AnnotationResolved) == 0 && this.scope != null) { TypeDeclaration typeDecl = this.scope.referenceContext; boolean old = typeDecl.staticInitializerScope.insideTypeAnnotation; @@ -2198,19 +2211,7 @@ public void evaluateNullAnnotations() { pkg.setDefaultNullness(NULL_UNSPECIFIED_BY_DEFAULT); } else { // if pkgInfo has no default annot. - complain - if (packageInfo instanceof SourceTypeBinding - && (packageInfo.tagBits & TagBits.EndHierarchyCheck) == 0) { - CompilationUnitScope pkgCUS = ((SourceTypeBinding) packageInfo).scope.compilationUnitScope(); - boolean current = pkgCUS.connectingHierarchy; - pkgCUS.connectingHierarchy = true; - try { - packageInfo.getAnnotationTagBits(); - } finally { - pkgCUS.connectingHierarchy = current; - } - } else { - packageInfo.getAnnotationTagBits(); - } + packageInfo.getAnnotationTagBits(); } } } |