Download
Getting Started
Members
Projects
Community
Marketplace
Events
Planet Eclipse
Newsletter
Videos
Participate
Report a Bug
Forums
Mailing Lists
Wiki
IRC
How to Contribute
Working Groups
Automotive
Internet of Things
LocationTech
Long-Term Support
PolarSys
Science
OpenMDM
More
Community
Marketplace
Events
Planet Eclipse
Newsletter
Videos
Participate
Report a Bug
Forums
Mailing Lists
Wiki
IRC
How to Contribute
Working Groups
Automotive
Internet of Things
LocationTech
Long-Term Support
PolarSys
Science
OpenMDM
Toggle navigation
Bugzilla – Attachment 184335 Details for
Bug 186342
[compiler][null] Using annotations for null checking
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
Log In
[x]
|
Terms of Use
|
Copyright Agent
[patch]
experiment in configurability
Bug_186342_v1.patch (text/plain), 19.30 KB, created by
Stephan Herrmann
on 2010-12-02 06:03:37 EST
(
hide
)
Description:
experiment in configurability
Filename:
MIME Type:
Creator:
Stephan Herrmann
Created:
2010-12-02 06:03:37 EST
Size:
19.30 KB
patch
obsolete
>### Eclipse Workspace Patch 1.0 >#P org.eclipse.jdt.core >Index: compiler/org/eclipse/jdt/internal/compiler/ast/Annotation.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Annotation.java,v >retrieving revision 1.67 >diff -u -r1.67 Annotation.java >--- compiler/org/eclipse/jdt/internal/compiler/ast/Annotation.java 20 Jul 2010 20:23:19 -0000 1.67 >+++ compiler/org/eclipse/jdt/internal/compiler/ast/Annotation.java 2 Dec 2010 10:30:29 -0000 >@@ -161,6 +161,12 @@ > case TypeIds.T_JavaLangSuppressWarnings : > tagBits |= TagBits.AnnotationSuppressWarnings; > break; >+ case TypeIds.T_ConfiguredAnnotationNullable : >+ tagBits |= TagBits.AnnotationNullable; >+ break; >+ case TypeIds.T_ConfiguredAnnotationNonNull : >+ tagBits |= TagBits.AnnotationNonNull; >+ break; > } > return tagBits; > } >Index: compiler/org/eclipse/jdt/internal/compiler/ast/MethodDeclaration.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MethodDeclaration.java,v >retrieving revision 1.76 >diff -u -r1.76 MethodDeclaration.java >--- compiler/org/eclipse/jdt/internal/compiler/ast/MethodDeclaration.java 3 Nov 2009 15:37:46 -0000 1.76 >+++ compiler/org/eclipse/jdt/internal/compiler/ast/MethodDeclaration.java 2 Dec 2010 10:30:29 -0000 >@@ -78,6 +78,11 @@ > if (this.arguments != null) { > for (int i = 0, count = this.arguments.length; i < count; i++) { > flowInfo.markAsDefinitelyAssigned(this.arguments[i].binding); >+ long argumentTagBits = this.arguments[i].binding.tagBits; >+ if ((argumentTagBits & TagBits.AnnotationNullable) != 0) >+ flowInfo.markPotentiallyNullBit(this.arguments[i].binding); >+ else if ((argumentTagBits & TagBits.AnnotationNonNull) != 0) >+ flowInfo.markAsDefinitelyNonNull(this.arguments[i].binding); > } > } > // propagate to statements >Index: compiler/org/eclipse/jdt/internal/compiler/impl/CompilerOptions.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/CompilerOptions.java,v >retrieving revision 1.235 >diff -u -r1.235 CompilerOptions.java >--- compiler/org/eclipse/jdt/internal/compiler/impl/CompilerOptions.java 21 Oct 2010 19:59:58 -0000 1.235 >+++ compiler/org/eclipse/jdt/internal/compiler/impl/CompilerOptions.java 2 Dec 2010 10:30:33 -0000 >@@ -138,6 +138,11 @@ > public static final String OPTION_ReportMissingAnnotation = "org.eclipse.jdt.core.compiler.problem.missingAnnotation"; //$NON-NLS-1$ > public static final String OPTION_ReportMissingJavadoc = "org.eclipse.jdt.core.compiler.problem.missingJavadoc"; //$NON-NLS-1$ > >+ public static final String OPTION_NullableAnnotationNames = "org.eclipse.jdt.core.compiler.annotation.nullable"; //$NON-NLS-1$ >+ public static final String OPTION_NonNullAnnotationNames = "org.eclipse.jdt.core.compiler.annotation.nonnull"; //$NON-NLS-1$ >+ public static final String OPTION_EmulateNullAnnotationTypes = "org.eclipse.jdt.core.compiler.annotation.emulate"; //$NON-NLS-1$ >+ public static final String OPTION_DefaultImportNullAnnotationTypes = "org.eclipse.jdt.core.compiler.annotation.defaultImport"; //$NON-NLS-1$ >+ > /** > * Possible values for configurable options > */ >@@ -357,6 +362,14 @@ > public boolean ignoreMethodBodies; > /** Raise null related warnings for variables tainted inside an assert statement (java 1.4 and above)*/ > public boolean includeNullInfoFromAsserts; >+ /** List of fully qualified annotation names to use as marker for nullable types. */ >+ public char[][][] nullableAnnotationNames; >+ /** List of fully qualified annotation names to use as marker for nonnull types. */ >+ public char[][][] nonNullAnnotationNames; >+ /** Should null annotation types be emulated by synthetic bindings? */ >+ public boolean emulateNullAnnotationTypes; >+ /** Should null annotation types be imported by default? */ >+ public boolean defaultImportNullAnnotationTypes; > > // keep in sync with warningTokenToIrritant and warningTokenFromIrritant > public final static String[] warningTokens = { >@@ -921,6 +934,22 @@ > optionsMap.put(OPTION_ReportTasks, getSeverityString(Tasks)); > optionsMap.put(OPTION_ReportUnusedObjectAllocation, getSeverityString(UnusedObjectAllocation)); > optionsMap.put(OPTION_IncludeNullInfoFromAsserts, this.includeNullInfoFromAsserts ? ENABLED : DISABLED); >+ if (this.nullableAnnotationNames != null) { >+ char[][] compoundNames = new char[this.nullableAnnotationNames.length][]; >+ for (int i = 0; i < this.nullableAnnotationNames.length; i++) >+ compoundNames[i] = CharOperation.concatWith(this.nullableAnnotationNames[i], '.'); >+ char[] allNames = CharOperation.concatWith(compoundNames, ','); >+ optionsMap.put(OPTION_NullableAnnotationNames, String.valueOf(allNames)); >+ } >+ if (this.nonNullAnnotationNames != null) { >+ char[][] compoundNames = new char[this.nonNullAnnotationNames.length][]; >+ for (int i = 0; i < this.nonNullAnnotationNames.length; i++) >+ compoundNames[i] = CharOperation.concatWith(this.nonNullAnnotationNames[i], '.'); >+ char[] allNames = CharOperation.concatWith(compoundNames, ','); >+ optionsMap.put(OPTION_NonNullAnnotationNames, String.valueOf(allNames)); >+ } >+ optionsMap.put(OPTION_EmulateNullAnnotationTypes, this.emulateNullAnnotationTypes ? ENABLED : DISABLED); >+ optionsMap.put(OPTION_DefaultImportNullAnnotationTypes, this.defaultImportNullAnnotationTypes ? ENABLED : DISABLED); > return optionsMap; > } > >@@ -1452,6 +1481,32 @@ > this.storeAnnotations = false; > } > } >+ if ((optionValue = optionsMap.get(OPTION_NullableAnnotationNames)) != null) { >+ String[] allNames = ((String)optionValue).split(","); //$NON-NLS-1$ >+ this.nullableAnnotationNames = new char[allNames.length][][]; >+ for (int i = 0; i < allNames.length; i++) >+ this.nullableAnnotationNames[i] = CharOperation.splitAndTrimOn('.', allNames[i].toCharArray()); >+ } >+ if ((optionValue = optionsMap.get(OPTION_NonNullAnnotationNames)) != null) { >+ String[] allNames = ((String)optionValue).split(","); //$NON-NLS-1$ >+ this.nonNullAnnotationNames = new char[allNames.length][][]; >+ for (int i = 0; i < allNames.length; i++) >+ this.nonNullAnnotationNames[i] = CharOperation.splitAndTrimOn('.', allNames[i].toCharArray()); >+ } >+ if ((optionValue = optionsMap.get(OPTION_EmulateNullAnnotationTypes)) != null) { >+ if (ENABLED.equals(optionValue)) { >+ this.emulateNullAnnotationTypes = true; >+ } else if (DISABLED.equals(optionValue)) { >+ this.emulateNullAnnotationTypes = false; >+ } >+ } >+ if ((optionValue = optionsMap.get(OPTION_DefaultImportNullAnnotationTypes)) != null) { >+ if (ENABLED.equals(optionValue)) { >+ this.defaultImportNullAnnotationTypes = true; >+ } else if (DISABLED.equals(optionValue)) { >+ this.defaultImportNullAnnotationTypes = false; >+ } >+ } > } > public String toString() { > StringBuffer buf = new StringBuffer("CompilerOptions:"); //$NON-NLS-1$ >Index: compiler/org/eclipse/jdt/internal/compiler/lookup/CompilationUnitScope.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/CompilationUnitScope.java,v >retrieving revision 1.128 >diff -u -r1.128 CompilationUnitScope.java >--- compiler/org/eclipse/jdt/internal/compiler/lookup/CompilationUnitScope.java 12 Aug 2010 08:51:55 -0000 1.128 >+++ compiler/org/eclipse/jdt/internal/compiler/lookup/CompilationUnitScope.java 2 Dec 2010 10:30:36 -0000 >@@ -303,6 +303,13 @@ > return; // can be called when a field constant is resolved before static imports > if (this.referenceContext.imports == null) { > this.typeOrPackageCache = new HashtableOfObject(1); >+ for (int i = 0; i < this.imports.length; i++) { >+ // cache default-imported null annotation types: >+ if (!this.imports[i].onDemand) { >+ char[][] importName = this.imports[i].compoundName; >+ this.typeOrPackageCache.put(importName[importName.length-1], this.imports[i].resolvedImport); >+ } >+ } > return; > } > >@@ -612,8 +619,19 @@ > BinaryTypeBinding missingObject = this.environment.createMissingType(null, TypeConstants.JAVA_LANG_OBJECT); > importBinding = missingObject.fPackage; > } >- >- return this.environment.defaultImports = new ImportBinding[] {new ImportBinding(TypeConstants.JAVA_LANG, true, importBinding, null)}; >+ ImportBinding javaLangImport = new ImportBinding(TypeConstants.JAVA_LANG, true, importBinding, null); >+ ImportBinding[] nullAnnotationImports = this.environment.makeNullAnnotationTypeImports(); // trigger regardless of option below >+ if (this.environment.globalOptions.defaultImportNullAnnotationTypes) { >+ ImportBinding[] allDefaultImports = new ImportBinding[nullAnnotationImports.length+1]; >+ allDefaultImports[0] = javaLangImport; >+ System.arraycopy(nullAnnotationImports, 0, >+ allDefaultImports, 1, >+ nullAnnotationImports.length); >+ this.environment.defaultImports = allDefaultImports; >+ } else { >+ this.environment.defaultImports = new ImportBinding[] {javaLangImport}; >+ } >+ return this.environment.defaultImports; > } > // NOT Public API > public final Binding getImport(char[][] compoundName, boolean onDemand, boolean isStaticImport) { >Index: compiler/org/eclipse/jdt/internal/compiler/lookup/LookupEnvironment.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/LookupEnvironment.java,v >retrieving revision 1.109 >diff -u -r1.109 LookupEnvironment.java >--- compiler/org/eclipse/jdt/internal/compiler/lookup/LookupEnvironment.java 1 Nov 2010 14:15:47 -0000 1.109 >+++ compiler/org/eclipse/jdt/internal/compiler/lookup/LookupEnvironment.java 2 Dec 2010 10:30:38 -0000 >@@ -1314,6 +1314,53 @@ > return this.nameEnvironment.isPackage(null, name); > return this.nameEnvironment.isPackage(compoundName, name); > } >+ >+private ReferenceBinding makeNullAnnotationType(char[][] compoundName) { >+ if (!this.globalOptions.emulateNullAnnotationTypes) >+ return getType(compoundName); >+ BinaryTypeBinding emulatedType = new BinaryTypeBinding(); >+ emulatedType.compoundName = compoundName; >+ emulatedType.modifiers = ClassFileConstants.AccAnnotation | ClassFileConstants.AccPublic; >+ emulatedType.fields = Binding.NO_FIELDS; >+ emulatedType.methods = Binding.NO_METHODS; >+ emulatedType.memberTypes = Binding.NO_MEMBER_TYPES; >+ emulatedType.superclass = getType(TypeConstants.JAVA_LANG_OBJECT); >+ emulatedType.superInterfaces = Binding.NO_SUPERINTERFACES; >+ emulatedType.fPackage = new PackageBinding(CharOperation.subarray(compoundName, 0, compoundName.length-2), null, this); >+ emulatedType.typeVariables = Binding.NO_TYPE_VARIABLES; >+ emulatedType.tagBits = TagBits.AreFieldsComplete | TagBits.AreFieldsSorted >+ | TagBits.AreMethodsComplete | TagBits.AreMethodsSorted >+ | TagBits.HasNoMemberTypes | TagBits.TypeVariablesAreConnected >+ | TagBits.AnnotationClassRetention >+ | TagBits.AnnotationForMethod | TagBits.AnnotationForParameter ; >+ >+ // TODO(SH): make emulated type visible via knownPackages, too >+ return emulatedType; >+} >+ >+protected ImportBinding[] makeNullAnnotationTypeImports() { >+ char[][][] nullableAnnotationNames = this.globalOptions.nullableAnnotationNames; >+ char[][][] nonNullAnnotationNames = this.globalOptions.nonNullAnnotationNames; >+ if (nullableAnnotationNames == null || nonNullAnnotationNames == null) { >+ // TODO(SH): check and report inconsistency with other options >+ return new ImportBinding[0]; >+ } >+ int totalImports = nullableAnnotationNames.length + nonNullAnnotationNames.length; >+ ImportBinding[] emulatedNullAnnotationImports = new ImportBinding[totalImports]; >+ for (int i = 0; i < nullableAnnotationNames.length; i++) { >+ ReferenceBinding annotationType = makeNullAnnotationType(nullableAnnotationNames[i]); >+ annotationType.id = TypeIds.T_ConfiguredAnnotationNullable; >+ emulatedNullAnnotationImports[i] = new ImportBinding(nullableAnnotationNames[i], false, annotationType, null); >+ } >+ int offset = nullableAnnotationNames.length; >+ for (int i = 0; i < nonNullAnnotationNames.length; i++) { >+ ReferenceBinding annotationType = makeNullAnnotationType(nonNullAnnotationNames[i]); >+ annotationType.id = TypeIds.T_ConfiguredAnnotationNonNull; >+ emulatedNullAnnotationImports[i+offset] = new ImportBinding(nonNullAnnotationNames[i], false, annotationType, null); >+ } >+ return emulatedNullAnnotationImports; >+} >+ > // The method verifier is lazily initialized to guarantee the receiver, the compiler & the oracle are ready. > public MethodVerifier methodVerifier() { > if (this.verifier == null) >Index: compiler/org/eclipse/jdt/internal/compiler/lookup/TagBits.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TagBits.java,v >retrieving revision 1.44 >diff -u -r1.44 TagBits.java >--- compiler/org/eclipse/jdt/internal/compiler/lookup/TagBits.java 21 Sep 2010 14:02:58 -0000 1.44 >+++ compiler/org/eclipse/jdt/internal/compiler/lookup/TagBits.java 2 Dec 2010 10:30:38 -0000 >@@ -116,10 +116,13 @@ > long AnnotationInherited = ASTNode.Bit49L; > long AnnotationOverride = ASTNode.Bit50L; > long AnnotationSuppressWarnings = ASTNode.Bit51L; >- long AllStandardAnnotationsMask = AnnotationTargetMASK | AnnotationRetentionMASK | AnnotationDeprecated | AnnotationDocumented | AnnotationInherited | AnnotationOverride | AnnotationSuppressWarnings; >+ long AnnotationNullable = ASTNode.Bit52L; >+ long AnnotationNonNull = ASTNode.Bit53L; >+ long AllStandardAnnotationsMask = AnnotationTargetMASK | AnnotationRetentionMASK | AnnotationDeprecated | AnnotationDocumented >+ | AnnotationInherited | AnnotationOverride | AnnotationSuppressWarnings | AnnotationNullable | AnnotationNonNull; > >- long DefaultValueResolved = ASTNode.Bit52L; >+ long DefaultValueResolved = ASTNode.Bit54L; > > // set when type contains non-private constructor(s) >- long HasNonPrivateConstructor = ASTNode.Bit53L; >+ long HasNonPrivateConstructor = ASTNode.Bit55L; > } >Index: compiler/org/eclipse/jdt/internal/compiler/lookup/TypeIds.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeIds.java,v >retrieving revision 1.34 >diff -u -r1.34 TypeIds.java >--- compiler/org/eclipse/jdt/internal/compiler/lookup/TypeIds.java 7 Mar 2009 01:08:09 -0000 1.34 >+++ compiler/org/eclipse/jdt/internal/compiler/lookup/TypeIds.java 2 Dec 2010 10:30:38 -0000 >@@ -89,6 +89,9 @@ > > final int T_JavaUtilCollection = 59; > >+ final int T_ConfiguredAnnotationNullable = 60; >+ final int T_ConfiguredAnnotationNonNull = 61; >+ > final int NoId = Integer.MAX_VALUE; > > public static final int IMPLICIT_CONVERSION_MASK = 0xFF; >#P org.eclipse.jdt.core.tests.compiler >Index: src/org/eclipse/jdt/core/tests/compiler/regression/NullAnnotationTest.java >=================================================================== >RCS file: src/org/eclipse/jdt/core/tests/compiler/regression/NullAnnotationTest.java >diff -N src/org/eclipse/jdt/core/tests/compiler/regression/NullAnnotationTest.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/jdt/core/tests/compiler/regression/NullAnnotationTest.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,114 @@ >+/******************************************************************************* >+ * Copyright (c) 2010 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 >+ * http://www.eclipse.org/legal/epl-v10.html >+ * >+ * Contributors: >+ * Stephan Herrmann <stephan@cs.tu-berlin.de> - initial API and implementation >+ *******************************************************************************/ >+package org.eclipse.jdt.core.tests.compiler.regression; >+ >+import java.util.Map; >+ >+import junit.framework.Test; >+ >+import org.eclipse.jdt.internal.compiler.impl.CompilerOptions; >+ >+public class NullAnnotationTest extends AbstractComparableTest { >+ >+public NullAnnotationTest(String name) { >+ super(name); >+} >+ >+// Static initializer to specify tests subset using TESTS_* static variables >+// All specified tests which does not belong to the class are skipped... >+// Only the highest compliance level is run; add the VM argument >+// -Dcompliance=1.4 (for example) to lower it if needed >+static { >+// TESTS_NAMES = new String[] { "testBug325229" }; >+// TESTS_NUMBERS = new int[] { 561 }; >+// TESTS_RANGE = new int[] { 1, 2049 }; >+} >+ >+public static Test suite() { >+ return buildComparableTestSuite(testClass()); >+} >+ >+public static Class testClass() { >+ return NullAnnotationTest.class; >+} >+ >+// Conditionally augment problem detection settings >+static boolean setNullRelatedOptions = true; >+protected Map getCompilerOptions() { >+ Map defaultOptions = super.getCompilerOptions(); >+ if (setNullRelatedOptions) { >+ defaultOptions.put(CompilerOptions.OPTION_ReportNullReference, CompilerOptions.ERROR); >+ defaultOptions.put(CompilerOptions.OPTION_ReportPotentialNullReference, CompilerOptions.ERROR); >+ defaultOptions.put(CompilerOptions.OPTION_ReportRedundantNullCheck, CompilerOptions.ERROR); >+ defaultOptions.put(CompilerOptions.OPTION_ReportRawTypeReference, CompilerOptions.IGNORE); >+ defaultOptions.put(CompilerOptions.OPTION_IncludeNullInfoFromAsserts, CompilerOptions.ENABLED); >+ >+ defaultOptions.put(CompilerOptions.OPTION_NullableAnnotationNames, "org.eclipse.jdt.annotation.Nullable"); >+ defaultOptions.put(CompilerOptions.OPTION_NonNullAnnotationNames, "org.eclipse.jdt.annotation.NonNull"); >+ defaultOptions.put(CompilerOptions.OPTION_EmulateNullAnnotationTypes, CompilerOptions.ENABLED); >+ defaultOptions.put(CompilerOptions.OPTION_DefaultImportNullAnnotationTypes, CompilerOptions.ENABLED); >+ } >+ return defaultOptions; >+} >+ >+// >+public void test0001_nonnull_parameter() { >+ runNegativeTest( >+ new String[] { >+ "X.java", >+ "public class X {\n" + >+ " void foo(@NonNull Object o) {\n" + >+ " if (o != null)\n" + >+ " System.out.print(o.toString());\n" + >+ " }\n" + >+ "}\n"}, >+ "----------\n" + >+ "1. ERROR in X.java (at line 3)\n" + >+ " if (o != null)\n" + >+ " ^\n" + >+ "Redundant null check: The variable o cannot be null at this location\n" + >+ "----------\n", >+ JavacTestOptions.Excuse.EclipseWarningConfiguredAsError); >+} >+// >+public void test0002_nonnull_parameter() { >+ runConformTest( >+ new String[] { >+ "X.java", >+ "public class X {\n" + >+ " void foo(@NonNull Object o) {\n" + >+ " System.out.print(o.toString());\n" + >+ " }\n" + >+ " public static void main(String... args) {\n" + >+ " new X().foo(\"OK\");\n" + >+ " }\n" + >+ "}\n"}, >+ "OK"); >+} >+// >+public void test0003_nullable_paramter() { >+ runNegativeTest( >+ new String[] { >+ "X.java", >+ "public class X {\n" + >+ " void foo(@Nullable Object o) {\n" + >+ " System.out.print(o.toString());\n" + >+ " }\n" + >+ "}\n"}, >+ "----------\n" + >+ "1. ERROR in X.java (at line 3)\n" + >+ " System.out.print(o.toString());\n" + >+ " ^\n" + >+ "Potential null pointer access: The variable o may be null at this location\n" + >+ "----------\n", >+ JavacTestOptions.Excuse.EclipseWarningConfiguredAsError); >+} >+}
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 186342
:
74851
|
86246
|
86247
|
89354
|
184335
|
185507
|
186796
|
186798
|
186872
|
186876
|
186889
|
186890
|
206525
|
206557
|
207270
|
207308
|
207478
|
207565
|
207567
|
207573
|
207592
|
207604
|
207635
|
207637
|
207639
|
207657
|
207659
|
207672
|
207677
|
207685