View | Details | Raw Unified | Return to bug 186342 | Differences between
and this patch

Collapse All | Expand All

(-)batch/org/eclipse/jdt/internal/compiler/batch/Main.java (-3 / +26 lines)
Lines 1-5 Link Here
1
/*******************************************************************************
1
/*******************************************************************************
2
 * Copyright (c) 2000, 2010 IBM Corporation and others.
2
 * Copyright (c) 2000, 2011 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
5
 * which accompanies this distribution, and is available at
Lines 10-17 Link Here
10
 *     Tom Tromey - Contribution for bug 125961
10
 *     Tom Tromey - Contribution for bug 125961
11
 *     Tom Tromey - Contribution for bug 159641
11
 *     Tom Tromey - Contribution for bug 159641
12
 *     Benjamin Muskalla - Contribution for bug 239066
12
 *     Benjamin Muskalla - Contribution for bug 239066
13
 *     Stephan Herrmann  - Contribution for bug 236385
13
 *     Stephan Herrmann  - Contributions for 
14
 *     Stephan Herrmann  - Contribution for bug 295551
14
 *     							bug 236385 - [compiler] Warn for potential programming problem if an object is created but not used
15
 *     							bug 295551 - Add option to automatically promote all warnings to errors 
16
 *     							bug 186342 - [compiler][null]Using annotations for null checking
15
 *******************************************************************************/
17
 *******************************************************************************/
16
package org.eclipse.jdt.internal.compiler.batch;
18
package org.eclipse.jdt.internal.compiler.batch;
17
19
Lines 2388-2393 Link Here
2388
					mode = INSIDE_WARNINGS_PROPERTIES;
2390
					mode = INSIDE_WARNINGS_PROPERTIES;
2389
					continue;
2391
					continue;
2390
				}
2392
				}
2393
				if (currentArg.startsWith("-nullAnnotations:")) { //$NON-NLS-1$
2394
					StringTokenizer tokenizer =
2395
						new StringTokenizer(currentArg.substring("-nullAnnotations:".length()), ","); //$NON-NLS-1$ //$NON-NLS-2$
2396
					while (tokenizer.hasMoreTokens()) {
2397
						String token = tokenizer.nextToken();
2398
						if (token.startsWith("nullable=")) { //$NON-NLS-1$
2399
							this.options.put(CompilerOptions.OPTION_NullableAnnotationName, token.substring("nullable=".length())); //$NON-NLS-1$
2400
						} else if (token.startsWith("nonnull=")) { //$NON-NLS-1$
2401
							this.options.put(CompilerOptions.OPTION_NonNullAnnotationName, token.substring("nonnull=".length())); //$NON-NLS-1$
2402
						} else if (token.equals("emulate")) { //$NON-NLS-1$
2403
							this.options.put(CompilerOptions.OPTION_EmulateNullAnnotationTypes, CompilerOptions.ENABLED);
2404
						} else if (token.equals("import")) { //$NON-NLS-1$
2405
							this.options.put(CompilerOptions.OPTION_DefaultImportNullAnnotationTypes, CompilerOptions.ENABLED);
2406
						} else {
2407
							throw new IllegalArgumentException(
2408
								this.bind("configure.unrecognized.nullannotation.option", token)); //$NON-NLS-1$
2409
						}
2410
					}
2411
					mode = DEFAULT;
2412
					continue;
2413
				}
2391
				break;
2414
				break;
2392
			case INSIDE_TARGET :
2415
			case INSIDE_TARGET :
2393
				if (this.didSpecifyTarget) {
2416
				if (this.didSpecifyTarget) {
(-)batch/org/eclipse/jdt/internal/compiler/batch/messages.properties (+18 lines)
Lines 8-13 Link Here
8
# Contributors:
8
# Contributors:
9
#     IBM Corporation - initial API and implementation
9
#     IBM Corporation - initial API and implementation
10
#		Benjamin Muskalla - Contribution for bug 239066
10
#		Benjamin Muskalla - Contribution for bug 239066
11
#       Stephan Herrmann  - Contribution for bug 186342 - [compiler][null]Using annotations for null checking
11
###############################################################################
12
###############################################################################
12
### JavaBatchCompiler messages.
13
### JavaBatchCompiler messages.
13
14
Lines 71-76 Link Here
71
72
72
## configure.directoryNotExist = directory does not exist: {0}
73
## configure.directoryNotExist = directory does not exist: {0}
73
configure.unrecognizedOption = Unrecognized option : {0}
74
configure.unrecognizedOption = Unrecognized option : {0}
75
configure.unrecognized.nullannotation.option = Unrecognized sub-option of -nullAnnotations: {0},\nlegal values are 'nullable=..', 'nonnull=..', 'emulate' and 'import'
74
configure.noClasspath = no classpath defined, using default directory instead
76
configure.noClasspath = no classpath defined, using default directory instead
75
configure.incorrectClasspath = incorrect classpath: {0}
77
configure.incorrectClasspath = incorrect classpath: {0}
76
configure.invalidexpansionargumentname = expansion argument file {0} does not exist or cannot be read
78
configure.invalidexpansionargumentname = expansion argument file {0} does not exist or cannot be read
Lines 222-227 Link Here
222
\    -classNames <className1[,className2,...]>\n\
224
\    -classNames <className1[,className2,...]>\n\
223
\                         qualified names of binary classes to process\n\
225
\                         qualified names of binary classes to process\n\
224
\ \n\
226
\ \n\
227
\ Null annotation options:\n\
228
\    -nullAnnotations:<suboptions>\n\
229
\                      enable use of annotations for specifying null contracts;\n\
230
\                      <suboptions> is a non-empty, comma-separated list of:\n\
231
\        nullable=<typename>\n\
232
\                      specifies the fully qualified name of an annotation type\n\
233
\                      to be used for marking types whose values include null\n\
234
\        nonnull=<typename>\n\
235
\                      specifies the fully qualified name of an annotation type\n\
236
\                      to be used for marking types whose values cannot be null\n\
237
\        emulate       tells the compiler to emulate the above annotation types\n\
238
\                      although they do not exist on the classpath\n\
239
\        import        tells the compiler to import the above annotation types\n\
240
\                      without specific mention in the sources such that their\n\
241
\                      simple names can be used without explicit imports\n\
242
\ \n\
225
\ Advanced options:\n\
243
\ Advanced options:\n\
226
\    @<file>            read command line arguments from file\n\
244
\    @<file>            read command line arguments from file\n\
227
\    -maxProblems <n>   max number of problems per compilation unit (100 by\n\
245
\    -maxProblems <n>   max number of problems per compilation unit (100 by\n\
(-)compiler/org/eclipse/jdt/core/compiler/IProblem.java (-2 / +48 lines)
Lines 1-5 Link Here
1
/*******************************************************************************
1
/*******************************************************************************
2
 * Copyright (c) 2000, 2010 IBM Corporation and others.
2
 * Copyright (c) 2000, 2011 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
5
 * which accompanies this distribution, and is available at
Lines 116-122 Link Here
116
 *		Benjamin Muskalla - added the following constants
116
 *		Benjamin Muskalla - added the following constants
117
 *									MissingSynchronizedModifierInInheritedMethod
117
 *									MissingSynchronizedModifierInInheritedMethod
118
 *		Stephan Herrmann  - added the following constants
118
 *		Stephan Herrmann  - added the following constants
119
 *									UnusedObjectAllocation									
119
 *									UnusedObjectAllocation
120
 *									DefiniteNullFromNonNullMethod
121
 *									PotentialNullFromNonNullMethod
122
 *									NonNullReturnInsufficientInfo
123
 *									DefiniteNullToNonNullParameter
124
 *									PotentialNullToNonNullParameter
125
 *									NonNullParameterInsufficientInfo
126
 *									DefiniteNullToNonNullLocal
127
 *									PotentialNullToNonNullLocal
128
 *									NonNullLocalInsufficientInfo
129
 *									ConflictingTypeEmulation
130
 *									MissingNullAnnotationType
131
 *									IllegalRedefinitionToNullableReturn
132
 *									IllegalRedefinitionToNonNullParameter
133
 *									IllegalDefinitionToNonNullParameter
120
 *******************************************************************************/
134
 *******************************************************************************/
121
package org.eclipse.jdt.core.compiler;
135
package org.eclipse.jdt.core.compiler;
122
136
Lines 1340-1345 Link Here
1340
	int JavadocTypeArgumentsForRawGenericConstructor = Javadoc + Internal + 859;
1354
	int JavadocTypeArgumentsForRawGenericConstructor = Javadoc + Internal + 859;
1341
1355
1342
	/**
1356
	/**
1357
	 * Null Annotations
1358
	 */
1359
	/** @since 3.7 */
1360
	int DefiniteNullFromNonNullMethod = MethodRelated + 880;
1361
	/** @since 3.7 */
1362
	int PotentialNullFromNonNullMethod = MethodRelated + 881;
1363
	/** @since 3.7 */
1364
	int NonNullReturnInsufficientInfo = MethodRelated + 882;
1365
	/** @since 3.7 */
1366
	int DefiniteNullToNonNullParameter = MethodRelated + 883;
1367
	/** @since 3.7 */
1368
	int PotentialNullToNonNullParameter = MethodRelated + 884;
1369
	/** @since 3.7 */
1370
	int NonNullParameterInsufficientInfo = MethodRelated + 885;
1371
	/** @since 3.7 */
1372
	int DefiniteNullToNonNullLocal = Internal + 886;
1373
	/** @since 3.7 */
1374
	int PotentialNullToNonNullLocal = Internal + 887;
1375
	/** @since 3.7 */
1376
	int NonNullLocalInsufficientInfo = Internal + 888;
1377
	/** @since 3.7 */
1378
	int ConflictingTypeEmulation = ImportRelated + 889;
1379
	/** @since 3.7 */
1380
	int MissingNullAnnotationType = ImportRelated + 890;
1381
	/** @since 3.7 */
1382
	int IllegalRedefinitionToNullableReturn = MethodRelated + 891;
1383
	/** @since 3.7 */
1384
	int IllegalRedefinitionToNonNullParameter = MethodRelated + 892;
1385
	/** @since 3.7 */
1386
	int IllegalDefinitionToNonNullParameter = MethodRelated + 893;
1387
1388
	/**
1343
	 * External problems -- These are problems defined by other plugins
1389
	 * External problems -- These are problems defined by other plugins
1344
	 */
1390
	 */
1345
1391
(-)compiler/org/eclipse/jdt/internal/compiler/ast/AbstractMethodDeclaration.java (-2 / +14 lines)
Lines 1-5 Link Here
1
/*******************************************************************************
1
/*******************************************************************************
2
 * Copyright (c) 2000, 2010 IBM Corporation and others.
2
 * Copyright (c) 2000, 2011 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
5
 * which accompanies this distribution, and is available at
Lines 7-12 Link Here
7
 *
7
 *
8
 * Contributors:
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
9
 *     IBM Corporation - initial API and implementation
10
 *     Stephan Herrmann - Contribution for Bug 186342 - [compiler][null]Using annotations for null checking
10
 *******************************************************************************/
11
 *******************************************************************************/
11
package org.eclipse.jdt.internal.compiler.ast;
12
package org.eclipse.jdt.internal.compiler.ast;
12
13
Lines 75-81 Link Here
75
	 * Bind and add argument's binding into the scope of the method
76
	 * Bind and add argument's binding into the scope of the method
76
	 */
77
	 */
77
	public void bindArguments() {
78
	public void bindArguments() {
78
79
		if (this.binding != null) {
80
			if ((this.binding.tagBits & TagBits.HasBoundArguments) != 0)
81
				return;
82
			this.binding.tagBits |= TagBits.HasBoundArguments;
83
		}
84
		
79
		if (this.arguments != null) {
85
		if (this.arguments != null) {
80
			// by default arguments in abstract/native methods are considered to be used (no complaint is expected)
86
			// by default arguments in abstract/native methods are considered to be used (no complaint is expected)
81
			if (this.binding == null) {
87
			if (this.binding == null) {
Lines 100-105 Link Here
100
				} else if (paramAnnotations != null) {
106
				} else if (paramAnnotations != null) {
101
					paramAnnotations[i] = Binding.NO_ANNOTATIONS;
107
					paramAnnotations[i] = Binding.NO_ANNOTATIONS;
102
				}
108
				}
109
				// transfer nullness info from the argument to the method:
110
				if ((argument.binding.tagBits & (TagBits.AnnotationNonNull|TagBits.AnnotationNullable)) != 0) {
111
					if (this.binding.parameterNonNullness == null)
112
						this.binding.parameterNonNullness = new Boolean[this.arguments.length];
113
					this.binding.parameterNonNullness[i] = Boolean.valueOf((argument.binding.tagBits & TagBits.AnnotationNonNull) != 0);
114
				}
103
			}
115
			}
104
			if (paramAnnotations != null)
116
			if (paramAnnotations != null)
105
				this.binding.setParameterAnnotations(paramAnnotations);
117
				this.binding.setParameterAnnotations(paramAnnotations);
(-)compiler/org/eclipse/jdt/internal/compiler/ast/Annotation.java (-1 / +8 lines)
Lines 1-5 Link Here
1
/*******************************************************************************
1
/*******************************************************************************
2
 * Copyright (c) 2000, 2010 IBM Corporation and others.
2
 * Copyright (c) 2000, 2011 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
5
 * which accompanies this distribution, and is available at
Lines 7-12 Link Here
7
 *
7
 *
8
 * Contributors:
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
9
 *     IBM Corporation - initial API and implementation
10
 *     Stephan Herrmann - Contribution for Bug 186342 - [compiler][null]Using annotations for null checking
10
 *******************************************************************************/
11
 *******************************************************************************/
11
package org.eclipse.jdt.internal.compiler.ast;
12
package org.eclipse.jdt.internal.compiler.ast;
12
13
Lines 161-166 Link Here
161
			case TypeIds.T_JavaLangSuppressWarnings :
162
			case TypeIds.T_JavaLangSuppressWarnings :
162
				tagBits |= TagBits.AnnotationSuppressWarnings;
163
				tagBits |= TagBits.AnnotationSuppressWarnings;
163
				break;
164
				break;
165
			case TypeIds.T_ConfiguredAnnotationNullable :
166
				tagBits |= TagBits.AnnotationNullable;
167
				break;
168
			case TypeIds.T_ConfiguredAnnotationNonNull :
169
				tagBits |= TagBits.AnnotationNonNull;
170
				break;
164
		}
171
		}
165
		return tagBits;
172
		return tagBits;
166
	}
173
	}
(-)compiler/org/eclipse/jdt/internal/compiler/ast/Assignment.java (-3 / +13 lines)
Lines 1-5 Link Here
1
/*******************************************************************************
1
/*******************************************************************************
2
 * Copyright (c) 2000, 2010 IBM Corporation and others.
2
 * Copyright (c) 2000, 2011 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
5
 * which accompanies this distribution, and is available at
Lines 8-15 Link Here
8
 * Contributors:
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
9
 *     IBM Corporation - initial API and implementation
10
 *     Genady Beriozkin - added support for reporting assignment with no effect
10
 *     Genady Beriozkin - added support for reporting assignment with no effect
11
 *     Stephan Herrmann <stephan@cs.tu-berlin.de> - Contribution for bug 319201 - [null] no warning when unboxing SingleNameReference causes NPE
11
 *     Stephan Herrmann <stephan@cs.tu-berlin.de> - Contributions for 
12
 *     												and bug 292478 - Report potentially null across variable assignment
12
 * 							bug 319201 - [null] no warning when unboxing SingleNameReference causes NPE
13
 * 							bug 292478 - Report potentially null across variable assignment
14
 *     						bug 186342 - [compiler][null]Using annotations for null checking
13
 *******************************************************************************/
15
 *******************************************************************************/
14
package org.eclipse.jdt.internal.compiler.ast;
16
package org.eclipse.jdt.internal.compiler.ast;
15
17
Lines 52-57 Link Here
52
	flowInfo = ((Reference) this.lhs)
54
	flowInfo = ((Reference) this.lhs)
53
		.analyseAssignment(currentScope, flowContext, flowInfo, this, false)
55
		.analyseAssignment(currentScope, flowContext, flowInfo, this, false)
54
		.unconditionalInits();
56
		.unconditionalInits();
57
	if (   local != null 
58
		&& (local.tagBits & TagBits.AnnotationNonNull) != 0
59
		&& nullStatus != FlowInfo.NON_NULL) 
60
	{
61
		currentScope.problemReporter().possiblyNullToNonNullLocal(local.name, this.expression, 
62
				nullStatus,	currentScope.environment().globalOptions.nonNullAnnotationName);
63
		nullStatus = FlowInfo.NON_NULL; // from now on assume we adhere to the contract
64
	}
55
	if (local != null && (local.type.tagBits & TagBits.IsBaseType) == 0) {
65
	if (local != null && (local.type.tagBits & TagBits.IsBaseType) == 0) {
56
		flowInfo.markNullStatus(local, nullStatus);
66
		flowInfo.markNullStatus(local, nullStatus);
57
		if (flowContext.initsOnFinally != null)
67
		if (flowContext.initsOnFinally != null)
(-)compiler/org/eclipse/jdt/internal/compiler/ast/LocalDeclaration.java (-3 / +12 lines)
Lines 1-5 Link Here
1
/*******************************************************************************
1
/*******************************************************************************
2
 * Copyright (c) 2000, 2010 IBM Corporation and others.
2
 * Copyright (c) 2000, 2011 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
5
 * which accompanies this distribution, and is available at
Lines 7-14 Link Here
7
 *
7
 *
8
 * Contributors:
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
9
 *     IBM Corporation - initial API and implementation
10
 *     Stephan Herrmann <stephan@cs.tu-berlin.de> - Contribution for bug 319201 - [null] no warning when unboxing SingleNameReference causes NPE
10
 *     Stephan Herrmann <stephan@cs.tu-berlin.de> - Contributions for 
11
 *     												and bug 292478 - Report potentially null across variable assignment
11
 *     						bug 319201 - [null] no warning when unboxing SingleNameReference causes NPE
12
 *     						bug 292478 - Report potentially null across variable assignment
13
 *     						bug 186342 - [compiler][null]Using annotations for null checking
12
 *******************************************************************************/
14
 *******************************************************************************/
13
package org.eclipse.jdt.internal.compiler.ast;
15
package org.eclipse.jdt.internal.compiler.ast;
14
16
Lines 80-85 Link Here
80
		this.bits &= ~FirstAssignmentToLocal;  // int i = (i = 0);
82
		this.bits &= ~FirstAssignmentToLocal;  // int i = (i = 0);
81
	}
83
	}
82
	flowInfo.markAsDefinitelyAssigned(this.binding);
84
	flowInfo.markAsDefinitelyAssigned(this.binding);
85
	if (   (this.binding.tagBits & TagBits.AnnotationNonNull) != 0
86
		&& nullStatus != FlowInfo.NON_NULL)
87
	{
88
		currentScope.problemReporter().possiblyNullToNonNullLocal(this.name, this.initialization, 
89
					nullStatus, currentScope.environment().globalOptions.nonNullAnnotationName);
90
		nullStatus = FlowInfo.NON_NULL; // from now on assume we adhere to the contract
91
	}		
83
	if ((this.binding.type.tagBits & TagBits.IsBaseType) == 0) {
92
	if ((this.binding.type.tagBits & TagBits.IsBaseType) == 0) {
84
		flowInfo.markNullStatus(this.binding, nullStatus);
93
		flowInfo.markNullStatus(this.binding, nullStatus);
85
		// no need to inform enclosing try block since its locals won't get
94
		// no need to inform enclosing try block since its locals won't get
(-)compiler/org/eclipse/jdt/internal/compiler/ast/MessageSend.java (-2 / +21 lines)
Lines 1-5 Link Here
1
/*******************************************************************************
1
/*******************************************************************************
2
 * Copyright (c) 2000, 2010 IBM Corporation and others.
2
 * Copyright (c) 2000, 2011 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
5
 * which accompanies this distribution, and is available at
Lines 8-14 Link Here
8
 * Contributors:
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
9
 *     IBM Corporation - initial API and implementation
10
 *     Nick Teryaev - fix for bug (https://bugs.eclipse.org/bugs/show_bug.cgi?id=40752)
10
 *     Nick Teryaev - fix for bug (https://bugs.eclipse.org/bugs/show_bug.cgi?id=40752)
11
 *     Stephan Herrmann - Contribution for bug 319201 - [null] no warning when unboxing SingleNameReference causes NPE
11
 *     Stephan Herrmann - Contributions for
12
 *     						bug 319201 - [null] no warning when unboxing SingleNameReference causes NPE
13
 *     						bug 186342 - [compiler][null]Using annotations for null checking
12
 *******************************************************************************/
14
 *******************************************************************************/
13
package org.eclipse.jdt.internal.compiler.ast;
15
package org.eclipse.jdt.internal.compiler.ast;
14
16
Lines 80-85 Link Here
80
				this.arguments[i].checkNPE(currentScope, flowContext, flowInfo);
82
				this.arguments[i].checkNPE(currentScope, flowContext, flowInfo);
81
			}
83
			}
82
			flowInfo = this.arguments[i].analyseCode(currentScope, flowContext, flowInfo).unconditionalInits();
84
			flowInfo = this.arguments[i].analyseCode(currentScope, flowContext, flowInfo).unconditionalInits();
85
			// compare actual null-status against parameter annotations of the called method:
86
			int nullStatus = this.arguments[i].nullStatus(flowInfo);
87
			if (nullStatus != FlowInfo.NON_NULL 
88
					&& this.binding.parameterNonNullness != null
89
					&& this.binding.parameterNonNullness[i].booleanValue()) // if @NonNull is required
90
			{
91
				char[][] annotationName = currentScope.environment().globalOptions.nonNullAnnotationName;
92
				currentScope.problemReporter().possiblyNullToNonNullParameter(this.arguments[i], nullStatus, annotationName[annotationName.length-1]);
93
			}
83
		}
94
		}
84
	}
95
	}
85
	ReferenceBinding[] thrownExceptions;
96
	ReferenceBinding[] thrownExceptions;
Lines 250-255 Link Here
250
	}
261
	}
251
}
262
}
252
public int nullStatus(FlowInfo flowInfo) {
263
public int nullStatus(FlowInfo flowInfo) {
264
	if (this.binding.isValidBinding()) {
265
		// try to retrieve null status of this message send from an annotation of the called method:
266
		long tagBits = this.binding.tagBits;
267
		if ((tagBits & TagBits.AnnotationNonNull) != 0)
268
			return FlowInfo.NON_NULL;
269
		if ((tagBits & TagBits.AnnotationNullable) != 0)
270
			return FlowInfo.POTENTIALLY_NULL;
271
	}
253
	return FlowInfo.UNKNOWN;
272
	return FlowInfo.UNKNOWN;
254
}
273
}
255
274
(-)compiler/org/eclipse/jdt/internal/compiler/ast/MethodDeclaration.java (-1 / +8 lines)
Lines 1-5 Link Here
1
/*******************************************************************************
1
/*******************************************************************************
2
 * Copyright (c) 2000, 2010 IBM Corporation and others.
2
 * Copyright (c) 2000, 2011 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
5
 * which accompanies this distribution, and is available at
Lines 7-12 Link Here
7
 *
7
 *
8
 * Contributors:
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
9
 *     IBM Corporation - initial API and implementation
10
 *     Stephan Herrmann - Contribution for Bug 186342 - [compiler][null]Using annotations for null checking
10
 *******************************************************************************/
11
 *******************************************************************************/
11
package org.eclipse.jdt.internal.compiler.ast;
12
package org.eclipse.jdt.internal.compiler.ast;
12
13
Lines 89-94 Link Here
89
						if (this.binding != null && this.binding.declaringClass == declaringElement)
90
						if (this.binding != null && this.binding.declaringClass == declaringElement)
90
							this.bits &= ~ASTNode.CanBeStatic;
91
							this.bits &= ~ASTNode.CanBeStatic;
91
					}
92
					}
93
					// leverage null-info from parameter annotations:
94
					long argumentTagBits = this.arguments[i].binding.tagBits;
95
					if ((argumentTagBits & TagBits.AnnotationNullable) != 0)
96
						flowInfo.markPotentiallyNullBit(this.arguments[i].binding);
97
					else if ((argumentTagBits & TagBits.AnnotationNonNull) != 0)
98
						flowInfo.markAsDefinitelyNonNull(this.arguments[i].binding);
92
				}
99
				}
93
			}
100
			}
94
			if (this.binding.declaringClass instanceof MemberTypeBinding && !this.binding.declaringClass.isStatic()) {
101
			if (this.binding.declaringClass instanceof MemberTypeBinding && !this.binding.declaringClass.isStatic()) {
(-)compiler/org/eclipse/jdt/internal/compiler/ast/ReturnStatement.java (-2 / +16 lines)
Lines 1-5 Link Here
1
/*******************************************************************************
1
/*******************************************************************************
2
 * Copyright (c) 2000, 2010 IBM Corporation and others.
2
 * Copyright (c) 2000, 2011 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
5
 * which accompanies this distribution, and is available at
Lines 7-13 Link Here
7
 *
7
 *
8
 * Contributors:
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
9
 *     IBM Corporation - initial API and implementation
10
 *     Stephan Herrmann - Contribution for bug 319201 - [null] no warning when unboxing SingleNameReference causes NPE
10
 *     Stephan Herrmann - Contributions for 
11
 *     						bug 319201 - [null] no warning when unboxing SingleNameReference causes NPE
12
 *     						bug 186342 - [compiler][null]Using annotations for null checking
11
 *******************************************************************************/
13
 *******************************************************************************/
12
package org.eclipse.jdt.internal.compiler.ast;
14
package org.eclipse.jdt.internal.compiler.ast;
13
15
Lines 40-45 Link Here
40
		if ((this.expression.implicitConversion & TypeIds.UNBOXING) != 0) {
42
		if ((this.expression.implicitConversion & TypeIds.UNBOXING) != 0) {
41
			this.expression.checkNPE(currentScope, flowContext, flowInfo);
43
			this.expression.checkNPE(currentScope, flowContext, flowInfo);
42
		}
44
		}
45
		if (this.expression.nullStatus(flowInfo) != FlowInfo.NON_NULL) {
46
			// if we can't prove non-null check against declared null-ness of the enclosing method:
47
			AbstractMethodDeclaration referenceMethod = currentScope.methodScope().referenceMethod();
48
			if (referenceMethod != null) {
49
				MethodBinding method = referenceMethod.binding;
50
				if ((method.tagBits & TagBits.AnnotationNonNull) != 0) {
51
					char[][] annotationName = currentScope.environment().globalOptions.nonNullAnnotationName;
52
					currentScope.problemReporter().possiblyNullFromNonNullMethod(this, this.expression.nullStatus(flowInfo), 
53
																				 annotationName[annotationName.length-1]);
54
				}
55
			}
56
		}
43
	}
57
	}
44
	this.initStateIndex =
58
	this.initStateIndex =
45
		currentScope.methodScope().recordInitializationStates(flowInfo);
59
		currentScope.methodScope().recordInitializationStates(flowInfo);
(-)compiler/org/eclipse/jdt/internal/compiler/impl/CompilerOptions.java (-2 / +83 lines)
Lines 8-15 Link Here
8
 * Contributors:
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
9
 *     IBM Corporation - initial API and implementation
10
 *     Benjamin Muskalla - Contribution for bug 239066
10
 *     Benjamin Muskalla - Contribution for bug 239066
11
 *     Stephan Herrmann  - Contribution for bug 236385
11
 *     Stephan Herrmann  - Contributions for 
12
 *     Stephan Herrmann  - Contribution for bug 295551
12
 *     							bug 236385 - [compiler] Warn for potential programming problem if an object is created but not used 
13
 *     							bug 295551 - Add option to automatically promote all warnings to errors
14
 *     							bug 186342 - [compiler][null]Using annotations for null checking
13
 *******************************************************************************/
15
 *******************************************************************************/
14
package org.eclipse.jdt.internal.compiler.impl;
16
package org.eclipse.jdt.internal.compiler.impl;
15
17
Lines 106-111 Link Here
106
	public static final String OPTION_ReportNullReference = "org.eclipse.jdt.core.compiler.problem.nullReference"; //$NON-NLS-1$
108
	public static final String OPTION_ReportNullReference = "org.eclipse.jdt.core.compiler.problem.nullReference"; //$NON-NLS-1$
107
	public static final String OPTION_ReportPotentialNullReference = "org.eclipse.jdt.core.compiler.problem.potentialNullReference"; //$NON-NLS-1$
109
	public static final String OPTION_ReportPotentialNullReference = "org.eclipse.jdt.core.compiler.problem.potentialNullReference"; //$NON-NLS-1$
108
	public static final String OPTION_ReportRedundantNullCheck = "org.eclipse.jdt.core.compiler.problem.redundantNullCheck"; //$NON-NLS-1$
110
	public static final String OPTION_ReportRedundantNullCheck = "org.eclipse.jdt.core.compiler.problem.redundantNullCheck"; //$NON-NLS-1$
111
	public static final String OPTION_ReportNullContractViolation = "org.eclipse.jdt.core.compiler.problem.nullContractViolation";  //$NON-NLS-1$
112
	public static final String OPTION_ReportPotentialNullContractViolation = "org.eclipse.jdt.core.compiler.problem.potentialNullContractViolation";  //$NON-NLS-1$
113
	public static final String OPTION_ReportNullContractInsufficientInfo = "org.eclipse.jdt.core.compiler.problem.nullContractInsufficientInfo";  //$NON-NLS-1$
109
	public static final String OPTION_ReportAutoboxing = "org.eclipse.jdt.core.compiler.problem.autoboxing"; //$NON-NLS-1$
114
	public static final String OPTION_ReportAutoboxing = "org.eclipse.jdt.core.compiler.problem.autoboxing"; //$NON-NLS-1$
110
	public static final String OPTION_ReportAnnotationSuperInterface = "org.eclipse.jdt.core.compiler.problem.annotationSuperInterface"; //$NON-NLS-1$
115
	public static final String OPTION_ReportAnnotationSuperInterface = "org.eclipse.jdt.core.compiler.problem.annotationSuperInterface"; //$NON-NLS-1$
111
	public static final String OPTION_ReportMissingOverrideAnnotation = "org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation"; //$NON-NLS-1$
116
	public static final String OPTION_ReportMissingOverrideAnnotation = "org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation"; //$NON-NLS-1$
Lines 136-141 Link Here
136
	public static final String OPTION_IncludeNullInfoFromAsserts = "org.eclipse.jdt.core.compiler.problem.includeNullInfoFromAsserts";  //$NON-NLS-1$
141
	public static final String OPTION_IncludeNullInfoFromAsserts = "org.eclipse.jdt.core.compiler.problem.includeNullInfoFromAsserts";  //$NON-NLS-1$
137
	public static final String OPTION_ReportMethodCanBeStatic = "org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic";  //$NON-NLS-1$
142
	public static final String OPTION_ReportMethodCanBeStatic = "org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic";  //$NON-NLS-1$
138
	public static final String OPTION_ReportMethodCanBePotentiallyStatic = "org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic";  //$NON-NLS-1$
143
	public static final String OPTION_ReportMethodCanBePotentiallyStatic = "org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic";  //$NON-NLS-1$
144
	public static final String OPTION_NullableAnnotationName = "org.eclipse.jdt.core.compiler.annotation.nullable"; //$NON-NLS-1$
145
	public static final String OPTION_NonNullAnnotationName = "org.eclipse.jdt.core.compiler.annotation.nonnull"; //$NON-NLS-1$
146
	public static final String OPTION_EmulateNullAnnotationTypes = "org.eclipse.jdt.core.compiler.annotation.emulate"; //$NON-NLS-1$
147
	public static final String OPTION_DefaultImportNullAnnotationTypes = "org.eclipse.jdt.core.compiler.annotation.defaultImport"; //$NON-NLS-1$
139
	/**
148
	/**
140
	 * Possible values for configurable options
149
	 * Possible values for configurable options
141
	 */
150
	 */
Lines 165-170 Link Here
165
	public static final String NO_TAG = "no_tag";	//$NON-NLS-1$
174
	public static final String NO_TAG = "no_tag";	//$NON-NLS-1$
166
	public static final String ALL_STANDARD_TAGS = "all_standard_tags";	//$NON-NLS-1$
175
	public static final String ALL_STANDARD_TAGS = "all_standard_tags";	//$NON-NLS-1$
167
176
177
	private static final char[][] DEFAULT_NONNULL_ANNOTATION_NAME = CharOperation.splitOn('.', "org.eclipse.jdt.annotation.NonNull".toCharArray()); //$NON-NLS-1$
178
	private static final char[][] DEFAULT_NULLABLE_ANNOTATION_NAME = CharOperation.splitOn('.', "org.eclipse.jdt.annotation.Nullable".toCharArray()); //$NON-NLS-1$
179
168
	/**
180
	/**
169
	 * Bit mask for configurable problems (error/warning threshold)
181
	 * Bit mask for configurable problems (error/warning threshold)
170
	 * Note: bitmask assumes 3 highest bits to denote irritant group (to allow storing 8 groups of 29 bits each
182
	 * Note: bitmask assumes 3 highest bits to denote irritant group (to allow storing 8 groups of 29 bits each
Lines 238-243 Link Here
238
	public static final int UnusedObjectAllocation = IrritantSet.GROUP2 | ASTNode.Bit4;
250
	public static final int UnusedObjectAllocation = IrritantSet.GROUP2 | ASTNode.Bit4;
239
	public static final int MethodCanBeStatic = IrritantSet.GROUP2 | ASTNode.Bit5;
251
	public static final int MethodCanBeStatic = IrritantSet.GROUP2 | ASTNode.Bit5;
240
	public static final int MethodCanBePotentiallyStatic = IrritantSet.GROUP2 | ASTNode.Bit6;
252
	public static final int MethodCanBePotentiallyStatic = IrritantSet.GROUP2 | ASTNode.Bit6;
253
	public static final int NullContractViolation = IrritantSet.GROUP2 | ASTNode.Bit7;
254
	public static final int PotentialNullContractViolation = IrritantSet.GROUP2 | ASTNode.Bit8;
255
	public static final int NullContractInsufficientInfo = IrritantSet.GROUP2 | ASTNode.Bit9;
241
256
242
	// Severity level for handlers
257
	// Severity level for handlers
243
	/** 
258
	/** 
Lines 359-364 Link Here
359
	public boolean includeNullInfoFromAsserts;
374
	public boolean includeNullInfoFromAsserts;
360
	/** Controls whether forced generic type problems get reported  */
375
	/** Controls whether forced generic type problems get reported  */
361
	public boolean reportUnavoidableGenericTypeProblems;
376
	public boolean reportUnavoidableGenericTypeProblems;
377
	/** Fully qualified name of annotation to use as marker for nullable types. */
378
	public char[][] nullableAnnotationName;
379
	/** Fully qualified name of annotation to use as marker for nonnull types. */
380
	public char[][] nonNullAnnotationName;
381
	/** Should null annotation types be emulated by synthetic bindings? */
382
	public boolean emulateNullAnnotationTypes;
383
	/** Should null annotation types be imported by default? */
384
	public boolean defaultImportNullAnnotationTypes;
362
385
363
	// keep in sync with warningTokenToIrritant and warningTokenFromIrritant
386
	// keep in sync with warningTokenToIrritant and warningTokenFromIrritant
364
	public final static String[] warningTokens = {
387
	public final static String[] warningTokens = {
Lines 498-503 Link Here
498
				return OPTION_ReportPotentialNullReference;
521
				return OPTION_ReportPotentialNullReference;
499
			case RedundantNullCheck :
522
			case RedundantNullCheck :
500
				return OPTION_ReportRedundantNullCheck;
523
				return OPTION_ReportRedundantNullCheck;
524
			case NullContractViolation :
525
				return OPTION_ReportNullContractViolation;
526
			case PotentialNullContractViolation :
527
				return OPTION_ReportPotentialNullContractViolation;
528
			case NullContractInsufficientInfo :
529
				return OPTION_ReportNullContractInsufficientInfo;
501
			case AutoBoxing :
530
			case AutoBoxing :
502
				return OPTION_ReportAutoboxing;
531
				return OPTION_ReportAutoboxing;
503
			case AnnotationSuperInterface :
532
			case AnnotationSuperInterface :
Lines 769-774 Link Here
769
			case NullReference :
798
			case NullReference :
770
			case PotentialNullReference :
799
			case PotentialNullReference :
771
			case RedundantNullCheck :
800
			case RedundantNullCheck :
801
			case NullContractViolation :
802
			case PotentialNullContractViolation :
803
			case NullContractInsufficientInfo :
772
				return "null"; //$NON-NLS-1$
804
				return "null"; //$NON-NLS-1$
773
			case FallthroughCase :
805
			case FallthroughCase :
774
				return "fallthrough"; //$NON-NLS-1$
806
				return "fallthrough"; //$NON-NLS-1$
Lines 944-949 Link Here
944
		optionsMap.put(OPTION_ReportNullReference, getSeverityString(NullReference));
976
		optionsMap.put(OPTION_ReportNullReference, getSeverityString(NullReference));
945
		optionsMap.put(OPTION_ReportPotentialNullReference, getSeverityString(PotentialNullReference));
977
		optionsMap.put(OPTION_ReportPotentialNullReference, getSeverityString(PotentialNullReference));
946
		optionsMap.put(OPTION_ReportRedundantNullCheck, getSeverityString(RedundantNullCheck));
978
		optionsMap.put(OPTION_ReportRedundantNullCheck, getSeverityString(RedundantNullCheck));
979
		optionsMap.put(OPTION_ReportNullContractViolation, getSeverityString(NullContractViolation));
980
		optionsMap.put(OPTION_ReportPotentialNullContractViolation, getSeverityString(PotentialNullContractViolation));
981
		optionsMap.put(OPTION_ReportNullContractInsufficientInfo, getSeverityString(NullContractInsufficientInfo));
947
		optionsMap.put(OPTION_SuppressWarnings, this.suppressWarnings ? ENABLED : DISABLED);
982
		optionsMap.put(OPTION_SuppressWarnings, this.suppressWarnings ? ENABLED : DISABLED);
948
		optionsMap.put(OPTION_SuppressOptionalErrors, this.suppressOptionalErrors ? ENABLED : DISABLED);
983
		optionsMap.put(OPTION_SuppressOptionalErrors, this.suppressOptionalErrors ? ENABLED : DISABLED);
949
		optionsMap.put(OPTION_ReportUnhandledWarningToken, getSeverityString(UnhandledWarningToken));
984
		optionsMap.put(OPTION_ReportUnhandledWarningToken, getSeverityString(UnhandledWarningToken));
Lines 964-969 Link Here
964
		optionsMap.put(OPTION_IncludeNullInfoFromAsserts, this.includeNullInfoFromAsserts ? ENABLED : DISABLED);
999
		optionsMap.put(OPTION_IncludeNullInfoFromAsserts, this.includeNullInfoFromAsserts ? ENABLED : DISABLED);
965
		optionsMap.put(OPTION_ReportMethodCanBeStatic, getSeverityString(MethodCanBeStatic));
1000
		optionsMap.put(OPTION_ReportMethodCanBeStatic, getSeverityString(MethodCanBeStatic));
966
		optionsMap.put(OPTION_ReportMethodCanBePotentiallyStatic, getSeverityString(MethodCanBePotentiallyStatic));
1001
		optionsMap.put(OPTION_ReportMethodCanBePotentiallyStatic, getSeverityString(MethodCanBePotentiallyStatic));
1002
		if (this.nullableAnnotationName != null) {
1003
			char[] compoundName = CharOperation.concatWith(this.nullableAnnotationName, '.');
1004
			optionsMap.put(OPTION_NullableAnnotationName, String.valueOf(compoundName));
1005
		}
1006
		if (this.nonNullAnnotationName != null) {
1007
			char[] compoundName = CharOperation.concatWith(this.nonNullAnnotationName, '.');
1008
			optionsMap.put(OPTION_NonNullAnnotationName, String.valueOf(compoundName));
1009
		}
1010
		optionsMap.put(OPTION_EmulateNullAnnotationTypes, this.emulateNullAnnotationTypes ? ENABLED : DISABLED);
1011
		optionsMap.put(OPTION_DefaultImportNullAnnotationTypes, this.defaultImportNullAnnotationTypes ? ENABLED : DISABLED);
967
		return optionsMap;
1012
		return optionsMap;
968
	}
1013
	}
969
1014
Lines 1372-1377 Link Here
1372
		if ((optionValue = optionsMap.get(OPTION_ReportNullReference)) != null) updateSeverity(NullReference, optionValue);
1417
		if ((optionValue = optionsMap.get(OPTION_ReportNullReference)) != null) updateSeverity(NullReference, optionValue);
1373
		if ((optionValue = optionsMap.get(OPTION_ReportPotentialNullReference)) != null) updateSeverity(PotentialNullReference, optionValue);
1418
		if ((optionValue = optionsMap.get(OPTION_ReportPotentialNullReference)) != null) updateSeverity(PotentialNullReference, optionValue);
1374
		if ((optionValue = optionsMap.get(OPTION_ReportRedundantNullCheck)) != null) updateSeverity(RedundantNullCheck, optionValue);
1419
		if ((optionValue = optionsMap.get(OPTION_ReportRedundantNullCheck)) != null) updateSeverity(RedundantNullCheck, optionValue);
1420
		if ((optionValue = optionsMap.get(OPTION_ReportNullContractViolation)) != null) updateSeverity(NullContractViolation, optionValue);
1421
		if ((optionValue = optionsMap.get(OPTION_ReportPotentialNullContractViolation)) != null) updateSeverity(PotentialNullContractViolation, optionValue);
1422
		if ((optionValue = optionsMap.get(OPTION_ReportNullContractInsufficientInfo)) != null) updateSeverity(NullContractInsufficientInfo, optionValue);
1375
		if ((optionValue = optionsMap.get(OPTION_ReportAutoboxing)) != null) updateSeverity(AutoBoxing, optionValue);
1423
		if ((optionValue = optionsMap.get(OPTION_ReportAutoboxing)) != null) updateSeverity(AutoBoxing, optionValue);
1376
		if ((optionValue = optionsMap.get(OPTION_ReportAnnotationSuperInterface)) != null) updateSeverity(AnnotationSuperInterface, optionValue);
1424
		if ((optionValue = optionsMap.get(OPTION_ReportAnnotationSuperInterface)) != null) updateSeverity(AnnotationSuperInterface, optionValue);
1377
		if ((optionValue = optionsMap.get(OPTION_ReportMissingOverrideAnnotation)) != null) updateSeverity(MissingOverrideAnnotation, optionValue);
1425
		if ((optionValue = optionsMap.get(OPTION_ReportMissingOverrideAnnotation)) != null) updateSeverity(MissingOverrideAnnotation, optionValue);
Lines 1506-1511 Link Here
1506
				this.storeAnnotations = false;
1554
				this.storeAnnotations = false;
1507
			}
1555
			}
1508
		}
1556
		}
1557
		if ((optionValue = optionsMap.get(OPTION_NullableAnnotationName)) != null) {
1558
			this.nullableAnnotationName = CharOperation.splitAndTrimOn('.', ((String)optionValue).toCharArray());
1559
		}
1560
		if ((optionValue = optionsMap.get(OPTION_NonNullAnnotationName)) != null) {
1561
			this.nonNullAnnotationName = CharOperation.splitAndTrimOn('.', ((String)optionValue).toCharArray());
1562
		}
1563
		if ((optionValue = optionsMap.get(OPTION_EmulateNullAnnotationTypes)) != null) {
1564
			if (ENABLED.equals(optionValue)) {
1565
				this.emulateNullAnnotationTypes = true;
1566
				// ensure that we actually have annotation names to emulate:
1567
				if (this.nullableAnnotationName == null)
1568
					this.nullableAnnotationName = DEFAULT_NULLABLE_ANNOTATION_NAME;
1569
				if (this.nonNullAnnotationName == null)
1570
					this.nonNullAnnotationName = DEFAULT_NONNULL_ANNOTATION_NAME;
1571
			} else if (DISABLED.equals(optionValue)) {
1572
				this.emulateNullAnnotationTypes = false;
1573
			}
1574
		}
1575
		if ((optionValue = optionsMap.get(OPTION_DefaultImportNullAnnotationTypes)) != null) {
1576
			if (ENABLED.equals(optionValue)) {
1577
				this.defaultImportNullAnnotationTypes = true;
1578
				// ensure that we actually have annotation names to be used for default imports:
1579
				if (this.nullableAnnotationName == null)
1580
					this.nullableAnnotationName = DEFAULT_NULLABLE_ANNOTATION_NAME;
1581
				if (this.nonNullAnnotationName == null)
1582
					this.nonNullAnnotationName = DEFAULT_NONNULL_ANNOTATION_NAME;
1583
			} else if (DISABLED.equals(optionValue)) {
1584
				this.defaultImportNullAnnotationTypes = false;
1585
			}
1586
		}
1509
	}
1587
	}
1510
	public String toString() {
1588
	public String toString() {
1511
		StringBuffer buf = new StringBuffer("CompilerOptions:"); //$NON-NLS-1$
1589
		StringBuffer buf = new StringBuffer("CompilerOptions:"); //$NON-NLS-1$
Lines 1581-1586 Link Here
1581
		buf.append("\n\t- null reference: ").append(getSeverityString(NullReference)); //$NON-NLS-1$
1659
		buf.append("\n\t- null reference: ").append(getSeverityString(NullReference)); //$NON-NLS-1$
1582
		buf.append("\n\t- potential null reference: ").append(getSeverityString(PotentialNullReference)); //$NON-NLS-1$
1660
		buf.append("\n\t- potential null reference: ").append(getSeverityString(PotentialNullReference)); //$NON-NLS-1$
1583
		buf.append("\n\t- redundant null check: ").append(getSeverityString(RedundantNullCheck)); //$NON-NLS-1$
1661
		buf.append("\n\t- redundant null check: ").append(getSeverityString(RedundantNullCheck)); //$NON-NLS-1$
1662
		buf.append("\n\t- null contract violation: ").append(getSeverityString(NullContractViolation)); //$NON-NLS-1$
1663
		buf.append("\n\t- potential null contract vialotation: ").append(getSeverityString(PotentialNullContractViolation)); //$NON-NLS-1$
1664
		buf.append("\n\t- insufficient information for checking null contract: ").append(getSeverityString(NullContractInsufficientInfo)); //$NON-NLS-1$
1584
		buf.append("\n\t- autoboxing: ").append(getSeverityString(AutoBoxing)); //$NON-NLS-1$
1665
		buf.append("\n\t- autoboxing: ").append(getSeverityString(AutoBoxing)); //$NON-NLS-1$
1585
		buf.append("\n\t- annotation super interface: ").append(getSeverityString(AnnotationSuperInterface)); //$NON-NLS-1$
1666
		buf.append("\n\t- annotation super interface: ").append(getSeverityString(AnnotationSuperInterface)); //$NON-NLS-1$
1586
		buf.append("\n\t- missing @Override annotation: ").append(getSeverityString(MissingOverrideAnnotation)); //$NON-NLS-1$
1667
		buf.append("\n\t- missing @Override annotation: ").append(getSeverityString(MissingOverrideAnnotation)); //$NON-NLS-1$
(-)compiler/org/eclipse/jdt/internal/compiler/impl/IrritantSet.java (-4 / +12 lines)
Lines 1-5 Link Here
1
/*******************************************************************************
1
/*******************************************************************************
2
 * Copyright (c) 2000, 2010 IBM Corporation and others.
2
 * Copyright (c) 2000, 2011 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
5
 * which accompanies this distribution, and is available at
Lines 7-12 Link Here
7
 *
7
 *
8
 * Contributors:
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
9
 *     IBM Corporation - initial API and implementation
10
 *     Stephan Herrmann - Contribution for Bug 186342 - [compiler][null]Using annotations for null checking
10
 *******************************************************************************/
11
 *******************************************************************************/
11
12
12
package org.eclipse.jdt.internal.compiler.impl;
13
package org.eclipse.jdt.internal.compiler.impl;
Lines 58-66 Link Here
58
	public static final IrritantSet UNCHECKED = new IrritantSet(CompilerOptions.UncheckedTypeOperation);
59
	public static final IrritantSet UNCHECKED = new IrritantSet(CompilerOptions.UncheckedTypeOperation);
59
	public static final IrritantSet UNQUALIFIED_FIELD_ACCESS = new IrritantSet(CompilerOptions.UnqualifiedFieldAccess);
60
	public static final IrritantSet UNQUALIFIED_FIELD_ACCESS = new IrritantSet(CompilerOptions.UnqualifiedFieldAccess);
60
61
61
	public static final IrritantSet COMPILER_DEFAULT_ERRORS = new IrritantSet(0); // no optional error by default	
62
	public static final IrritantSet COMPILER_DEFAULT_ERRORS = new IrritantSet(0); // see static initializer below	
62
	public static final IrritantSet COMPILER_DEFAULT_WARNINGS = new IrritantSet(0); // see static initializer below
63
	public static final IrritantSet COMPILER_DEFAULT_WARNINGS = new IrritantSet(0); // see static initializer below
63
	static {
64
	static {
65
		COMPILER_DEFAULT_ERRORS
66
			.set(CompilerOptions.NullContractViolation
67
				 | CompilerOptions.PotentialNullContractViolation);
64
		COMPILER_DEFAULT_WARNINGS
68
		COMPILER_DEFAULT_WARNINGS
65
			// group-0 warnings enabled by default
69
			// group-0 warnings enabled by default
66
			.set(
70
			.set(
Lines 98-104 Link Here
98
			// group-2 warnings enabled by default
102
			// group-2 warnings enabled by default
99
			.set(
103
			.set(
100
				CompilerOptions.DeadCode
104
				CompilerOptions.DeadCode
101
				|CompilerOptions.Tasks);
105
				| CompilerOptions.Tasks
106
				| CompilerOptions.NullContractInsufficientInfo);
102
			
107
			
103
		ALL.setAll();
108
		ALL.setAll();
104
		HIDING
109
		HIDING
Lines 107-113 Link Here
107
			.set(CompilerOptions.TypeHiding);
112
			.set(CompilerOptions.TypeHiding);
108
		NULL
113
		NULL
109
			.set(CompilerOptions.PotentialNullReference)
114
			.set(CompilerOptions.PotentialNullReference)
110
			.set(CompilerOptions.RedundantNullCheck);
115
			.set(CompilerOptions.RedundantNullCheck)
116
			.set(CompilerOptions.NullContractViolation)
117
			.set(CompilerOptions.PotentialNullContractViolation)
118
			.set(CompilerOptions.NullContractInsufficientInfo);
111
		RESTRICTION.set(CompilerOptions.DiscouragedReference);
119
		RESTRICTION.set(CompilerOptions.DiscouragedReference);
112
		STATIC_ACCESS.set(CompilerOptions.NonStaticAccessToStatic);
120
		STATIC_ACCESS.set(CompilerOptions.NonStaticAccessToStatic);
113
		UNUSED
121
		UNUSED
(-)compiler/org/eclipse/jdt/internal/compiler/lookup/BinaryTypeBinding.java (+50 lines)
Lines 7-12 Link Here
7
 *
7
 *
8
 * Contributors:
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
9
 *     IBM Corporation - initial API and implementation
10
 *     Stephan Herrmann - Contribution for Bug 186342 - [compiler][null]Using annotations for null checking
10
 *******************************************************************************/
11
 *******************************************************************************/
11
package org.eclipse.jdt.internal.compiler.lookup;
12
package org.eclipse.jdt.internal.compiler.lookup;
12
13
Lines 553-558 Link Here
553
			isAnnotationType() ? convertMemberValue(method.getDefaultValue(), this.environment, missingTypeNames) : null,
554
			isAnnotationType() ? convertMemberValue(method.getDefaultValue(), this.environment, missingTypeNames) : null,
554
			this.environment);
555
			this.environment);
555
556
557
	scanForNullAnnotation(method, result);
558
556
	if (use15specifics)
559
	if (use15specifics)
557
		result.tagBits |= method.getTagBits();
560
		result.tagBits |= method.getTagBits();
558
	result.typeVariables = typeVars;
561
	result.typeVariables = typeVars;
Lines 1092-1097 Link Here
1092
AnnotationBinding[] retrieveAnnotations(Binding binding) {
1095
AnnotationBinding[] retrieveAnnotations(Binding binding) {
1093
	return AnnotationBinding.addStandardAnnotations(super.retrieveAnnotations(binding), binding.getAnnotationTagBits(), this.environment);
1096
	return AnnotationBinding.addStandardAnnotations(super.retrieveAnnotations(binding), binding.getAnnotationTagBits(), this.environment);
1094
}
1097
}
1098
private void scanForNullAnnotation(IBinaryMethod method, MethodBinding result) {
1099
	char[][] nullableAnnotationName = this.environment.globalOptions.nullableAnnotationName;
1100
	char[][] nonNullAnnotationName = this.environment.globalOptions.nonNullAnnotationName;
1101
	if (nullableAnnotationName == null || nonNullAnnotationName == null)
1102
		return; // not configured to use null annotations
1103
1104
	IBinaryAnnotation[] annotations = method.getAnnotations();
1105
	if (annotations != null) {
1106
		for (int i = 0; i < annotations.length; i++) {
1107
			char[] annotationTypeName = annotations[i].getTypeName();
1108
			if (annotationTypeName[0] != 'L')
1109
				continue;
1110
			char[][] typeName = CharOperation.splitOn('/', annotationTypeName, 1, annotationTypeName.length-1); // cut of leading 'L' and trailing ';'
1111
			if (CharOperation.equals(typeName, nonNullAnnotationName)) {
1112
				result.tagBits |= TagBits.AnnotationNonNull;
1113
				return;
1114
			}
1115
			if (CharOperation.equals(typeName, nullableAnnotationName)) {
1116
				result.tagBits |= TagBits.AnnotationNullable;
1117
				return;
1118
			}
1119
		}
1120
	}
1121
1122
	for (int j = 0; j < result.parameters.length; j++) {
1123
		IBinaryAnnotation[] paramAnnotations = method.getParameterAnnotations(j); 
1124
		if (paramAnnotations != null) {
1125
			for (int i = 0; i < paramAnnotations.length; i++) {
1126
				char[] annotationTypeName = paramAnnotations[i].getTypeName();
1127
				if (annotationTypeName[0] != 'L')
1128
					continue;
1129
				char[][] typeName = CharOperation.splitOn('/', annotationTypeName, 1, annotationTypeName.length-1); // cut of leading 'L' and trailing ';'
1130
				if (CharOperation.equals(typeName, nonNullAnnotationName)) {
1131
					if (result.parameterNonNullness == null)
1132
						result.parameterNonNullness = new Boolean[result.parameters.length];
1133
					result.parameterNonNullness[j] = Boolean.TRUE;
1134
					break;
1135
				} else if (CharOperation.equals(typeName, nullableAnnotationName)) {
1136
					if (result.parameterNonNullness == null)
1137
						result.parameterNonNullness = new Boolean[result.parameters.length];
1138
					result.parameterNonNullness[j] = Boolean.FALSE;
1139
					break;
1140
				}
1141
			}
1142
		}
1143
	}
1144
}
1095
SimpleLookupTable storedAnnotations(boolean forceInitialize) {
1145
SimpleLookupTable storedAnnotations(boolean forceInitialize) {
1096
	if (forceInitialize && this.storedAnnotations == null) {
1146
	if (forceInitialize && this.storedAnnotations == null) {
1097
		if (!this.environment.globalOptions.storeAnnotations)
1147
		if (!this.environment.globalOptions.storeAnnotations)
(-)compiler/org/eclipse/jdt/internal/compiler/lookup/CompilationUnitScope.java (-8 / +43 lines)
Lines 1-5 Link Here
1
/*******************************************************************************
1
/*******************************************************************************
2
 * Copyright (c) 2000, 2010 IBM Corporation and others.
2
 * Copyright (c) 2000, 2011 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
5
 * which accompanies this distribution, and is available at
Lines 7-13 Link Here
7
 *
7
 *
8
 * Contributors:
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
9
 *     IBM Corporation - initial API and implementation
10
 *     Erling Ellingsen -  patch for bug 125570
10
 *     Erling Ellingsen - patch for bug 125570
11
 *     Stephan Herrmann - Contribution for Bug 186342 - [compiler][null]Using annotations for null checking
11
 *******************************************************************************/
12
 *******************************************************************************/
12
package org.eclipse.jdt.internal.compiler.lookup;
13
package org.eclipse.jdt.internal.compiler.lookup;
13
14
Lines 160-166 Link Here
160
161
161
	// allocate the import array, add java.lang.* by default
162
	// allocate the import array, add java.lang.* by default
162
	int numberOfStatements = this.referenceContext.imports.length;
163
	int numberOfStatements = this.referenceContext.imports.length;
163
	int numberOfImports = numberOfStatements + 1;
164
	int numberOfDefaultImports = 1;
165
	if (this.environment.globalOptions.defaultImportNullAnnotationTypes)
166
		numberOfDefaultImports += 2;
167
	int numberOfImports = numberOfStatements + numberOfDefaultImports;
164
	for (int i = 0; i < numberOfStatements; i++) {
168
	for (int i = 0; i < numberOfStatements; i++) {
165
		ImportReference importReference = this.referenceContext.imports[i];
169
		ImportReference importReference = this.referenceContext.imports[i];
166
		if (((importReference.bits & ASTNode.OnDemand) != 0) && CharOperation.equals(TypeConstants.JAVA_LANG, importReference.tokens) && !importReference.isStatic()) {
170
		if (((importReference.bits & ASTNode.OnDemand) != 0) && CharOperation.equals(TypeConstants.JAVA_LANG, importReference.tokens) && !importReference.isStatic()) {
Lines 169-176 Link Here
169
		}
173
		}
170
	}
174
	}
171
	ImportBinding[] resolvedImports = new ImportBinding[numberOfImports];
175
	ImportBinding[] resolvedImports = new ImportBinding[numberOfImports];
172
	resolvedImports[0] = getDefaultImports()[0];
176
	ImportBinding[] defaultImports = getDefaultImports(); // consistent number of default imports is ensured in LookupEnvironment.makeNullAnnotationTypeImports()
173
	int index = 1;
177
	for (int i = 0; i < numberOfDefaultImports; i++) {
178
		resolvedImports[i] = defaultImports[i];
179
	}
180
	int index = numberOfDefaultImports;
174
181
175
	nextImport : for (int i = 0; i < numberOfStatements; i++) {
182
	nextImport : for (int i = 0; i < numberOfStatements; i++) {
176
		ImportReference importReference = this.referenceContext.imports[i];
183
		ImportReference importReference = this.referenceContext.imports[i];
Lines 303-308 Link Here
303
		return; // can be called when a field constant is resolved before static imports
310
		return; // can be called when a field constant is resolved before static imports
304
	if (this.referenceContext.imports == null) {
311
	if (this.referenceContext.imports == null) {
305
		this.typeOrPackageCache = new HashtableOfObject(1);
312
		this.typeOrPackageCache = new HashtableOfObject(1);
313
		for (int i = 0; i < this.imports.length; i++) {
314
			// cache default-imported null annotation types:
315
			if (!this.imports[i].onDemand) {
316
				char[][] importName = this.imports[i].compoundName;
317
				this.typeOrPackageCache.put(importName[importName.length-1], this.imports[i].resolvedImport);
318
			}
319
		}
306
		return;
320
		return;
307
	}
321
	}
308
322
Lines 327-335 Link Here
327
			break;
341
			break;
328
		}
342
		}
329
	}
343
	}
344
	int numberOfDefaultImports = 1;
345
	if (this.environment.globalOptions.defaultImportNullAnnotationTypes) {
346
		numberOfDefaultImports += 2;
347
		numberOfImports += 2;
348
	}
330
	ImportBinding[] resolvedImports = new ImportBinding[numberOfImports];
349
	ImportBinding[] resolvedImports = new ImportBinding[numberOfImports];
331
	resolvedImports[0] = getDefaultImports()[0];
350
	ImportBinding[] defaultImports = getDefaultImports(); // consistent number of default imports is ensured in LookupEnvironment.makeNullAnnotationTypeImports()
332
	int index = 1;
351
	for (int i = 0; i < numberOfDefaultImports; i++) {
352
		resolvedImports[i] = defaultImports[i];
353
	}
354
355
	int index = numberOfDefaultImports;
333
356
334
	// keep static imports with normal imports until there is a reason to split them up
357
	// keep static imports with normal imports until there is a reason to split them up
335
	// on demand imports continue to be packages & types. need to check on demand type imports for fields/methods
358
	// on demand imports continue to be packages & types. need to check on demand type imports for fields/methods
Lines 613-619 Link Here
613
		importBinding = missingObject.fPackage;
636
		importBinding = missingObject.fPackage;
614
	}
637
	}
615
638
616
	return this.environment.defaultImports = new ImportBinding[] {new ImportBinding(TypeConstants.JAVA_LANG, true, importBinding, null)};
639
	ImportBinding javaLangImport = new ImportBinding(TypeConstants.JAVA_LANG, true, importBinding, null);
640
	ImportBinding[] nullAnnotationImports = this.environment.makeNullAnnotationTypeImports(); // trigger regardless of option below
641
	if (this.environment.globalOptions.defaultImportNullAnnotationTypes) {
642
		ImportBinding[] allDefaultImports = new ImportBinding[nullAnnotationImports.length+1];// java.lang.* + null-annotations
643
		allDefaultImports[0] = javaLangImport;
644
		System.arraycopy(nullAnnotationImports, 0,
645
						 allDefaultImports, 1,
646
						 nullAnnotationImports.length);
647
		this.environment.defaultImports = allDefaultImports;
648
	} else {
649
		this.environment.defaultImports = new ImportBinding[] {javaLangImport};
650
	}
651
	return this.environment.defaultImports;
617
}
652
}
618
// NOT Public API
653
// NOT Public API
619
public final Binding getImport(char[][] compoundName, boolean onDemand, boolean isStaticImport) {
654
public final Binding getImport(char[][] compoundName, boolean onDemand, boolean isStaticImport) {
(-)compiler/org/eclipse/jdt/internal/compiler/lookup/LookupEnvironment.java (-1 / +70 lines)
Lines 1-5 Link Here
1
/*******************************************************************************
1
/*******************************************************************************
2
 * Copyright (c) 2000, 2010 IBM Corporation and others.
2
 * Copyright (c) 2000, 2011 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
5
 * which accompanies this distribution, and is available at
Lines 7-12 Link Here
7
 *
7
 *
8
 * Contributors:
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
9
 *     IBM Corporation - initial API and implementation
10
 *     Stephan Herrmann - Contribution for Bug 186342 - [compiler][null]Using annotations for null checking
10
 *******************************************************************************/
11
 *******************************************************************************/
11
package org.eclipse.jdt.internal.compiler.lookup;
12
package org.eclipse.jdt.internal.compiler.lookup;
12
13
Lines 1314-1319 Link Here
1314
		return this.nameEnvironment.isPackage(null, name);
1315
		return this.nameEnvironment.isPackage(null, name);
1315
	return this.nameEnvironment.isPackage(compoundName, name);
1316
	return this.nameEnvironment.isPackage(compoundName, name);
1316
}
1317
}
1318
1319
private ReferenceBinding makeNullAnnotationType(char[][] compoundName, int typeId) {
1320
	char[][] packageName = CharOperation.subarray(compoundName, 0, compoundName.length-1);
1321
	PackageBinding packageBinding = createPackage(packageName);
1322
	ReferenceBinding typeBinding = packageBinding.getType(compoundName[compoundName.length-1]);
1323
	if (typeBinding != null && typeBinding.isValidBinding())
1324
		this.problemReporter.conflictingTypeEmulation(compoundName); // does not return
1325
1326
	BinaryTypeBinding emulatedType = new BinaryTypeBinding();
1327
	emulatedType.compoundName = compoundName;
1328
	emulatedType.sourceName = compoundName[compoundName.length-1];
1329
	emulatedType.modifiers = ClassFileConstants.AccAnnotation | ClassFileConstants.AccPublic;
1330
	emulatedType.fields = Binding.NO_FIELDS;
1331
	emulatedType.methods = Binding.NO_METHODS;
1332
	emulatedType.memberTypes = Binding.NO_MEMBER_TYPES;
1333
	emulatedType.superclass = getType(TypeConstants.JAVA_LANG_OBJECT);
1334
	emulatedType.superInterfaces = Binding.NO_SUPERINTERFACES;
1335
	emulatedType.fPackage = packageBinding;
1336
	emulatedType.typeVariables = Binding.NO_TYPE_VARIABLES;
1337
	emulatedType.tagBits = TagBits.AreFieldsComplete | TagBits.AreFieldsSorted 
1338
							| TagBits.AreMethodsComplete | TagBits.AreMethodsSorted 
1339
							| TagBits.HasNoMemberTypes | TagBits.TypeVariablesAreConnected
1340
							| TagBits.AnnotationClassRetention 
1341
							| TagBits.AnnotationForMethod | TagBits.AnnotationForParameter 
1342
							| TagBits.AnnotationForLocalVariable ;
1343
	emulatedType.id = typeId;
1344
	
1345
	packageBinding.addType(emulatedType);
1346
1347
	return emulatedType;
1348
}
1349
1350
protected ImportBinding[] makeNullAnnotationTypeImports() {
1351
	char[][] nullableAnnotationName = this.globalOptions.nullableAnnotationName;
1352
	char[][] nonNullAnnotationName = this.globalOptions.nonNullAnnotationName;
1353
	if (nullableAnnotationName == null || nonNullAnnotationName == null) {
1354
		if (this.globalOptions.emulateNullAnnotationTypes || this.globalOptions.defaultImportNullAnnotationTypes)
1355
			// shouldn't happen by construction of CompilerOptions.set(Map)
1356
			this.problemReporter.abortDueToInternalError("Inconsistent null annotation options"); //$NON-NLS-1$
1357
		return new ImportBinding[0];
1358
	}
1359
	// fetch annotation types for emulation and/or default import:
1360
	ReferenceBinding nullableAnnotationType = null;
1361
	ReferenceBinding nonNullAnnotationType = null;
1362
	if (this.globalOptions.emulateNullAnnotationTypes) {
1363
		nullableAnnotationType = makeNullAnnotationType(nullableAnnotationName, TypeIds.T_ConfiguredAnnotationNullable);
1364
		nonNullAnnotationType  = makeNullAnnotationType(nonNullAnnotationName, TypeIds.T_ConfiguredAnnotationNonNull);
1365
	} else { // not emulated means those types should exist (and need to be marked):
1366
		nullableAnnotationType = getType(nullableAnnotationName);
1367
		if (nullableAnnotationType != null && nullableAnnotationType.isValidBinding())
1368
			nullableAnnotationType.id = TypeIds.T_ConfiguredAnnotationNullable;
1369
		else if (this.globalOptions.defaultImportNullAnnotationTypes)
1370
			this.problemReporter.missingNullAnnotationType(nullableAnnotationName);
1371
1372
		nonNullAnnotationType  = getType(nonNullAnnotationName);
1373
		if (nonNullAnnotationType != null && nonNullAnnotationType.isValidBinding())
1374
			nonNullAnnotationType.id = TypeIds.T_ConfiguredAnnotationNonNull;
1375
		else if (this.globalOptions.defaultImportNullAnnotationTypes)
1376
			this.problemReporter.missingNullAnnotationType(nonNullAnnotationName);
1377
	}
1378
	if (this.globalOptions.defaultImportNullAnnotationTypes)
1379
		return new ImportBinding[] {
1380
				new ImportBinding(nullableAnnotationName, false, nullableAnnotationType, null),
1381
				new ImportBinding(nonNullAnnotationName, false, nonNullAnnotationType, null)
1382
		};
1383
	return new ImportBinding[0];
1384
}
1385
1317
// The method verifier is lazily initialized to guarantee the receiver, the compiler & the oracle are ready.
1386
// The method verifier is lazily initialized to guarantee the receiver, the compiler & the oracle are ready.
1318
public MethodVerifier methodVerifier() {
1387
public MethodVerifier methodVerifier() {
1319
	if (this.verifier == null)
1388
	if (this.verifier == null)
(-)compiler/org/eclipse/jdt/internal/compiler/lookup/MethodBinding.java (-1 / +3 lines)
Lines 1-5 Link Here
1
/*******************************************************************************
1
/*******************************************************************************
2
 * Copyright (c) 2000, 2010 IBM Corporation and others.
2
 * Copyright (c) 2000, 2011 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
5
 * which accompanies this distribution, and is available at
Lines 7-12 Link Here
7
 *
7
 *
8
 * Contributors:
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
9
 *     IBM Corporation - initial API and implementation
10
 *     Stephan Herrmann - Contribution for Bug 186342 - [compiler][null]Using annotations for null checking
10
 *******************************************************************************/
11
 *******************************************************************************/
11
package org.eclipse.jdt.internal.compiler.lookup;
12
package org.eclipse.jdt.internal.compiler.lookup;
12
13
Lines 28-33 Link Here
28
	public char[] selector;
29
	public char[] selector;
29
	public TypeBinding returnType;
30
	public TypeBinding returnType;
30
	public TypeBinding[] parameters;
31
	public TypeBinding[] parameters;
32
	public Boolean[] parameterNonNullness; // TRUE means @NonNull declared, FALSE means @Nullable declared, null means nothing declared
31
	public ReferenceBinding[] thrownExceptions;
33
	public ReferenceBinding[] thrownExceptions;
32
	public ReferenceBinding declaringClass;
34
	public ReferenceBinding declaringClass;
33
	public TypeVariableBinding[] typeVariables = Binding.NO_TYPE_VARIABLES;
35
	public TypeVariableBinding[] typeVariables = Binding.NO_TYPE_VARIABLES;
(-)compiler/org/eclipse/jdt/internal/compiler/lookup/MethodVerifier.java (-2 / +11 lines)
Lines 1-5 Link Here
1
/*******************************************************************************
1
/*******************************************************************************
2
 * Copyright (c) 2000, 2010 IBM Corporation and others.
2
 * Copyright (c) 2000, 2011 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
5
 * which accompanies this distribution, and is available at
Lines 8-13 Link Here
8
 * Contributors:
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
9
 *     IBM Corporation - initial API and implementation
10
 *     Benjamin Muskalla - Contribution for bug 239066
10
 *     Benjamin Muskalla - Contribution for bug 239066
11
 *     Stephan Herrmann  - Contribution for Bug 186342 - [compiler][null]Using annotations for null checking
11
 *******************************************************************************/
12
 *******************************************************************************/
12
package org.eclipse.jdt.internal.compiler.lookup;
13
package org.eclipse.jdt.internal.compiler.lookup;
13
14
Lines 152-157 Link Here
152
				// interface I { @Override Object clone(); } does not override Object#clone()
153
				// interface I { @Override Object clone(); } does not override Object#clone()
153
				currentMethod.modifiers |= ExtraCompilerModifiers.AccOverriding;
154
				currentMethod.modifiers |= ExtraCompilerModifiers.AccOverriding;
154
			}
155
			}
156
			if (!currentMethod.isStatic())
157
				checkNullContractInheritance(currentMethod, inheritedMethod);
155
158
156
			if (!areReturnTypesCompatible(currentMethod, inheritedMethod)
159
			if (!areReturnTypesCompatible(currentMethod, inheritedMethod)
157
					&& (currentMethod.returnType.tagBits & TagBits.HasMissingType) == 0) {
160
					&& (currentMethod.returnType.tagBits & TagBits.HasMissingType) == 0) {
Lines 184-190 Link Here
184
		checkForBridgeMethod(currentMethod, inheritedMethod, allInheritedMethods);
187
		checkForBridgeMethod(currentMethod, inheritedMethod, allInheritedMethods);
185
	}
188
	}
186
}
189
}
187
190
protected void checkNullContractInheritance(MethodBinding currentMethod, MethodBinding inheritedMethod) {
191
	// nothing to do here. Real action happens at 1.5+
192
}
188
public void reportRawReferences(MethodBinding currentMethod, MethodBinding inheritedMethod) {
193
public void reportRawReferences(MethodBinding currentMethod, MethodBinding inheritedMethod) {
189
	// nothing to do here. Real action happens at 1.5+
194
	// nothing to do here. Real action happens at 1.5+
190
}
195
}
Lines 725-730 Link Here
725
	this.currentMethods = new HashtableOfObject(size == 0 ? 1 : size); // maps method selectors to an array of methods... must search to match paramaters & return type
730
	this.currentMethods = new HashtableOfObject(size == 0 ? 1 : size); // maps method selectors to an array of methods... must search to match paramaters & return type
726
	for (int m = size; --m >= 0;) {
731
	for (int m = size; --m >= 0;) {
727
		MethodBinding method = methods[m];
732
		MethodBinding method = methods[m];
733
		// binding arguments is required for null contract checking, which needs argument annotations
734
		AbstractMethodDeclaration decl = method.sourceMethod();
735
		if (decl != null) // happens for synthetic methods
736
			decl.bindArguments();
728
		if (!(method.isConstructor() || method.isDefaultAbstract())) { // keep all methods which are NOT constructors or default abstract
737
		if (!(method.isConstructor() || method.isDefaultAbstract())) { // keep all methods which are NOT constructors or default abstract
729
			MethodBinding[] existingMethods = (MethodBinding[]) this.currentMethods.get(method.selector);
738
			MethodBinding[] existingMethods = (MethodBinding[]) this.currentMethods.get(method.selector);
730
			if (existingMethods == null)
739
			if (existingMethods == null)
(-)compiler/org/eclipse/jdt/internal/compiler/lookup/MethodVerifier15.java (-1 / +58 lines)
Lines 1-5 Link Here
1
/*******************************************************************************
1
/*******************************************************************************
2
 * Copyright (c) 2000, 2010 IBM Corporation and others.
2
 * Copyright (c) 2000, 2011 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
5
 * which accompanies this distribution, and is available at
Lines 7-12 Link Here
7
 *
7
 *
8
 * Contributors:
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
9
 *     IBM Corporation - initial API and implementation
10
 *     Stephan Herrmann - Contribution for Bug 186342 - [compiler][null]Using annotations for null checking
10
 *******************************************************************************/
11
 *******************************************************************************/
11
package org.eclipse.jdt.internal.compiler.lookup;
12
package org.eclipse.jdt.internal.compiler.lookup;
12
13
Lines 407-412 Link Here
407
	return false;
408
	return false;
408
}
409
}
409
410
411
protected void checkNullContractInheritance(MethodBinding currentMethod, MethodBinding inheritedMethod) {
412
	// return type:
413
	if ((inheritedMethod.tagBits & TagBits.AnnotationNonNull) != 0) {
414
		if ((currentMethod.tagBits & TagBits.AnnotationNullable) != 0) {
415
			AbstractMethodDeclaration methodDecl = currentMethod.sourceMethod();
416
			this.type.scope.problemReporter().illegalRedefinitionToNullableReturn(methodDecl, inheritedMethod.declaringClass, 
417
																			this.environment.globalOptions.nonNullAnnotationName);
418
		}
419
	}
420
	if ((currentMethod.tagBits & (TagBits.AnnotationNonNull|TagBits.AnnotationNullable)) == 0)
421
		currentMethod.tagBits |= (inheritedMethod.tagBits & (TagBits.AnnotationNonNull|TagBits.AnnotationNullable));
422
423
	// parameters:
424
	if (inheritedMethod.parameterNonNullness != null) {
425
		// inherited method has null-annotations, check and possibly transfer:
426
		
427
		// prepare for transfering (contract inheritance):
428
		if (currentMethod.parameterNonNullness == null)
429
			currentMethod.parameterNonNullness = new Boolean[currentMethod.parameters.length];
430
		
431
		for (int i = 0; i < inheritedMethod.parameterNonNullness.length; i++) {
432
			
433
			Boolean inheritedNonNullNess = inheritedMethod.parameterNonNullness[i];
434
			if (inheritedNonNullNess != Boolean.TRUE) { 	 				 // super parameter is not restricted to @NonNull
435
				if (currentMethod.parameterNonNullness[i] == Boolean.TRUE) { // current parameter is restricted to @NonNull
436
					this.type.scope.problemReporter().illegalRedefinitionToNonNullParameter(
437
																	currentMethod.sourceMethod().arguments[i],
438
																	inheritedMethod.declaringClass,
439
																	inheritedNonNullNess == null
440
																	? null
441
																	: this.environment.globalOptions.nullableAnnotationName);
442
					continue;
443
				} 
444
			}
445
			
446
			if (currentMethod.parameterNonNullness[i] == null && inheritedNonNullNess != null) {
447
				// inherit this annotation as the current method has no annotation:
448
				currentMethod.parameterNonNullness[i] = inheritedNonNullNess;
449
				VariableBinding argumentBinding = currentMethod.sourceMethod().arguments[i].binding;
450
				argumentBinding.tagBits |= inheritedNonNullNess.booleanValue()
451
												? TagBits.AnnotationNonNull : TagBits.AnnotationNullable;
452
			}
453
		}
454
	} else if (currentMethod.parameterNonNullness != null) {
455
		// super method has no annotations but current has
456
		for (int i = 0; i < currentMethod.parameterNonNullness.length; i++) {
457
			if (currentMethod.parameterNonNullness[i] == Boolean.TRUE) { // tightening from unconstrained to @NonNull
458
				this.type.scope.problemReporter().illegalRedefinitionToNonNullParameter(
459
																currentMethod.sourceMethod().arguments[i],
460
																inheritedMethod.declaringClass,
461
																null);
462
			}
463
		}
464
	}
465
}
466
410
void reportRawReferences() {
467
void reportRawReferences() {
411
	CompilerOptions compilerOptions = this.type.scope.compilerOptions();
468
	CompilerOptions compilerOptions = this.type.scope.compilerOptions();
412
	if (compilerOptions.sourceLevel < ClassFileConstants.JDK1_5 // shouldn't whine at all
469
	if (compilerOptions.sourceLevel < ClassFileConstants.JDK1_5 // shouldn't whine at all
(-)compiler/org/eclipse/jdt/internal/compiler/lookup/TagBits.java (-4 / +10 lines)
Lines 1-5 Link Here
1
/*******************************************************************************
1
/*******************************************************************************
2
 * Copyright (c) 2000, 2010 IBM Corporation and others.
2
 * Copyright (c) 2000, 2011 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
5
 * which accompanies this distribution, and is available at
Lines 7-12 Link Here
7
 *
7
 *
8
 * Contributors:
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
9
 *     IBM Corporation - initial API and implementation
10
 *     Stephan Herrmann - Contribution for Bug 186342 - [compiler][null]Using annotations for null checking
10
 *******************************************************************************/
11
 *******************************************************************************/
11
package org.eclipse.jdt.internal.compiler.lookup;
12
package org.eclipse.jdt.internal.compiler.lookup;
12
13
Lines 67-72 Link Here
67
	// test bit to identify if the type's hierarchy is inconsistent
68
	// test bit to identify if the type's hierarchy is inconsistent
68
	long HierarchyHasProblems = ASTNode.Bit18;
69
	long HierarchyHasProblems = ASTNode.Bit18;
69
70
71
	long HasBoundArguments = ASTNode.Bit13; // for method bindings to avoid duplicate invocation of bindArguments()
72
70
	// test bit to identify if the type's type variables have been connected
73
	// test bit to identify if the type's type variables have been connected
71
	long TypeVariablesAreConnected = ASTNode.Bit19;
74
	long TypeVariablesAreConnected = ASTNode.Bit19;
72
75
Lines 119-128 Link Here
119
	long AnnotationInherited = ASTNode.Bit49L;
122
	long AnnotationInherited = ASTNode.Bit49L;
120
	long AnnotationOverride = ASTNode.Bit50L;
123
	long AnnotationOverride = ASTNode.Bit50L;
121
	long AnnotationSuppressWarnings = ASTNode.Bit51L;
124
	long AnnotationSuppressWarnings = ASTNode.Bit51L;
122
	long AllStandardAnnotationsMask = AnnotationTargetMASK | AnnotationRetentionMASK | AnnotationDeprecated | AnnotationDocumented | AnnotationInherited |  AnnotationOverride | AnnotationSuppressWarnings;
125
	long AnnotationNullable = ASTNode.Bit52L;
126
	long AnnotationNonNull = ASTNode.Bit53L;
127
	long AllStandardAnnotationsMask = AnnotationTargetMASK | AnnotationRetentionMASK | AnnotationDeprecated | AnnotationDocumented 
128
				| AnnotationInherited |  AnnotationOverride | AnnotationSuppressWarnings | AnnotationNullable | AnnotationNonNull;
123
129
124
	long DefaultValueResolved = ASTNode.Bit52L;
130
	long DefaultValueResolved = ASTNode.Bit54L;
125
131
126
	// set when type contains non-private constructor(s)
132
	// set when type contains non-private constructor(s)
127
	long HasNonPrivateConstructor = ASTNode.Bit53L;
133
	long HasNonPrivateConstructor = ASTNode.Bit55L;
128
}
134
}
(-)compiler/org/eclipse/jdt/internal/compiler/lookup/TypeIds.java (-1 / +5 lines)
Lines 1-5 Link Here
1
/*******************************************************************************
1
/*******************************************************************************
2
 * Copyright (c) 2000, 2009 IBM Corporation and others.
2
 * Copyright (c) 2000, 2011 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
5
 * which accompanies this distribution, and is available at
Lines 7-12 Link Here
7
 *
7
 *
8
 * Contributors:
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
9
 *     IBM Corporation - initial API and implementation
10
 *     Stephan Herrmann - Contribution for Bug 186342 - [compiler][null]Using annotations for null checking
10
 *******************************************************************************/
11
 *******************************************************************************/
11
package org.eclipse.jdt.internal.compiler.lookup;
12
package org.eclipse.jdt.internal.compiler.lookup;
12
13
Lines 89-94 Link Here
89
	
90
	
90
	final int T_JavaUtilCollection = 59;
91
	final int T_JavaUtilCollection = 59;
91
92
93
	final int T_ConfiguredAnnotationNullable = 60;
94
	final int T_ConfiguredAnnotationNonNull = 61;
95
92
	final int NoId = Integer.MAX_VALUE;
96
	final int NoId = Integer.MAX_VALUE;
93
97
94
	public static final int IMPLICIT_CONVERSION_MASK = 0xFF;
98
	public static final int IMPLICIT_CONVERSION_MASK = 0xFF;
(-)compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java (-2 / +111 lines)
Lines 1-5 Link Here
1
/*******************************************************************************
1
/*******************************************************************************
2
 * Copyright (c) 2000, 2010 IBM Corporation and others.
2
 * Copyright (c) 2000, 2011 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
5
 * which accompanies this distribution, and is available at
Lines 8-14 Link Here
8
 * Contributors:
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
9
 *     IBM Corporation - initial API and implementation
10
 *     Benjamin Muskalla - Contribution for bug 239066
10
 *     Benjamin Muskalla - Contribution for bug 239066
11
 *     Stephan Herrmann  - Contribution for bug 236385
11
 *     Stephan Herrmann  - Contributions for 
12
 *     							bug 236385 - [compiler] Warn for potential programming problem if an object is created but not used
13
 *     							bug 186342 - [compiler][null]Using annotations for null checking
12
 *******************************************************************************/
14
 *******************************************************************************/
13
package org.eclipse.jdt.internal.compiler.problem;
15
package org.eclipse.jdt.internal.compiler.problem;
14
16
Lines 81-86 Link Here
81
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
83
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
82
import org.eclipse.jdt.internal.compiler.env.AccessRestriction;
84
import org.eclipse.jdt.internal.compiler.env.AccessRestriction;
83
import org.eclipse.jdt.internal.compiler.env.ICompilationUnit;
85
import org.eclipse.jdt.internal.compiler.env.ICompilationUnit;
86
import org.eclipse.jdt.internal.compiler.flow.FlowInfo;
84
import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
87
import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
85
import org.eclipse.jdt.internal.compiler.impl.ReferenceContext;
88
import org.eclipse.jdt.internal.compiler.impl.ReferenceContext;
86
import org.eclipse.jdt.internal.compiler.lookup.ArrayBinding;
89
import org.eclipse.jdt.internal.compiler.lookup.ArrayBinding;
Lines 293-298 Link Here
293
		case IProblem.NullLocalVariableInstanceofYieldsFalse:
296
		case IProblem.NullLocalVariableInstanceofYieldsFalse:
294
			return CompilerOptions.RedundantNullCheck;
297
			return CompilerOptions.RedundantNullCheck;
295
298
299
		case IProblem.DefiniteNullFromNonNullMethod:
300
		case IProblem.DefiniteNullToNonNullLocal:
301
		case IProblem.DefiniteNullToNonNullParameter:
302
		case IProblem.IllegalRedefinitionToNullableReturn:
303
		case IProblem.IllegalRedefinitionToNonNullParameter:
304
		case IProblem.IllegalDefinitionToNonNullParameter:
305
			return CompilerOptions.NullContractViolation;
306
		case IProblem.PotentialNullFromNonNullMethod:
307
		case IProblem.PotentialNullToNonNullLocal:
308
		case IProblem.PotentialNullToNonNullParameter:
309
			return CompilerOptions.PotentialNullContractViolation;
310
		case IProblem.NonNullLocalInsufficientInfo:
311
		case IProblem.NonNullParameterInsufficientInfo:
312
		case IProblem.NonNullReturnInsufficientInfo:
313
			return CompilerOptions.NullContractInsufficientInfo;
314
296
		case IProblem.BoxingConversion :
315
		case IProblem.BoxingConversion :
297
		case IProblem.UnboxingConversion :
316
		case IProblem.UnboxingConversion :
298
			return CompilerOptions.AutoBoxing;
317
			return CompilerOptions.AutoBoxing;
Lines 469-474 Link Here
469
			case CompilerOptions.NullReference :
488
			case CompilerOptions.NullReference :
470
			case CompilerOptions.PotentialNullReference :
489
			case CompilerOptions.PotentialNullReference :
471
			case CompilerOptions.RedundantNullCheck :
490
			case CompilerOptions.RedundantNullCheck :
491
			case CompilerOptions.NullContractViolation :
492
			case CompilerOptions.PotentialNullContractViolation :
493
			case CompilerOptions.NullContractInsufficientInfo :
472
			case CompilerOptions.IncompleteEnumSwitch :
494
			case CompilerOptions.IncompleteEnumSwitch :
473
			case CompilerOptions.FallthroughCase :
495
			case CompilerOptions.FallthroughCase :
474
			case CompilerOptions.OverridingMethodWithoutSuperInvocation :
496
			case CompilerOptions.OverridingMethodWithoutSuperInvocation :
Lines 530-535 Link Here
530
	switch (problemID) {
552
	switch (problemID) {
531
		case IProblem.IsClassPathCorrect :
553
		case IProblem.IsClassPathCorrect :
532
		case IProblem.CorruptedSignature :
554
		case IProblem.CorruptedSignature :
555
		case IProblem.ConflictingTypeEmulation :
556
		case IProblem.MissingNullAnnotationType :
533
			return CategorizedProblem.CAT_BUILDPATH;
557
			return CategorizedProblem.CAT_BUILDPATH;
534
558
535
		default :
559
		default :
Lines 1331-1336 Link Here
1331
		importRef.sourceStart,
1355
		importRef.sourceStart,
1332
		importRef.sourceEnd);
1356
		importRef.sourceEnd);
1333
}
1357
}
1358
public void conflictingTypeEmulation(char[][] compoundName) {
1359
	String[] arguments = new String[] {CharOperation.toString(compoundName)};
1360
	this.handle(
1361
		IProblem.ConflictingTypeEmulation,
1362
		arguments,
1363
		arguments,
1364
		ProblemSeverities.Error | ProblemSeverities.Abort | ProblemSeverities.Fatal, // not configurable
1365
		0, 0);	
1366
}
1334
public void constantOutOfRange(Literal literal, TypeBinding literalType) {
1367
public void constantOutOfRange(Literal literal, TypeBinding literalType) {
1335
	String[] arguments = new String[] {new String(literalType.readableName()), new String(literal.source())};
1368
	String[] arguments = new String[] {new String(literalType.readableName()), new String(literal.source())};
1336
	this.handle(
1369
	this.handle(
Lines 2437-2442 Link Here
2437
		qualifiedTypeReference.sourceStart,
2470
		qualifiedTypeReference.sourceStart,
2438
		qualifiedTypeReference.sourceEnd);
2471
		qualifiedTypeReference.sourceEnd);
2439
}
2472
}
2473
public void illegalRedefinitionToNonNullParameter(Argument argument, ReferenceBinding declaringClass, char[][] inheritedAnnotationName) {
2474
	if (inheritedAnnotationName == null) {
2475
		this.handle(
2476
			IProblem.IllegalDefinitionToNonNullParameter, 
2477
			new String[] { new String(argument.name), new String(declaringClass.readableName()) },
2478
			new String[] { new String(argument.name), new String(declaringClass.shortReadableName()) },
2479
			argument.sourceStart, 
2480
			argument.sourceEnd);
2481
		
2482
	} else {
2483
		this.handle(
2484
			IProblem.IllegalRedefinitionToNonNullParameter, 
2485
			new String[] { new String(argument.name), new String(declaringClass.readableName()), CharOperation.toString(inheritedAnnotationName)},
2486
			new String[] { new String(argument.name), new String(declaringClass.shortReadableName()), new String(inheritedAnnotationName[inheritedAnnotationName.length-1])},
2487
			argument.sourceStart, 
2488
			argument.sourceEnd);
2489
	}
2490
}
2491
public void illegalRedefinitionToNullableReturn(AbstractMethodDeclaration methodDecl, ReferenceBinding declaringClass, char[][] nonNullAnnotationName) {
2492
	this.handle(
2493
		IProblem.IllegalRedefinitionToNullableReturn, 
2494
		new String[] { new String(declaringClass.readableName()), CharOperation.toString(nonNullAnnotationName)},
2495
		new String[] { new String(declaringClass.shortReadableName()), new String(nonNullAnnotationName[nonNullAnnotationName.length-1])},
2496
		methodDecl.sourceStart, 
2497
		methodDecl.sourceEnd);	
2498
}
2440
public void illegalStaticModifierForMemberType(SourceTypeBinding type) {
2499
public void illegalStaticModifierForMemberType(SourceTypeBinding type) {
2441
	String[] arguments = new String[] {new String(type.sourceName())};
2500
	String[] arguments = new String[] {new String(type.sourceName())};
2442
	this.handle(
2501
	this.handle(
Lines 5116-5121 Link Here
5116
		switchStatement.expression.sourceStart,
5175
		switchStatement.expression.sourceStart,
5117
		switchStatement.expression.sourceEnd);
5176
		switchStatement.expression.sourceEnd);
5118
}
5177
}
5178
5179
public void missingNullAnnotationType(char[][] nullAnnotationName) {
5180
	String[] args = { new String(CharOperation.concatWith(nullAnnotationName, '.')) };
5181
	this.handle(IProblem.MissingNullAnnotationType, args, args, 0, 0);	
5182
}
5119
public void missingOverrideAnnotation(AbstractMethodDeclaration method) {
5183
public void missingOverrideAnnotation(AbstractMethodDeclaration method) {
5120
	int severity = computeSeverity(IProblem.MissingOverrideAnnotation);
5184
	int severity = computeSeverity(IProblem.MissingOverrideAnnotation);
5121
	if (severity == ProblemSeverities.Ignore) return;
5185
	if (severity == ProblemSeverities.Ignore) return;
Lines 6078-6083 Link Here
6078
		caseStatement.sourceStart,
6142
		caseStatement.sourceStart,
6079
		caseStatement.sourceEnd);
6143
		caseStatement.sourceEnd);
6080
}
6144
}
6145
public void possiblyNullFromNonNullMethod(ReturnStatement returnStatement, int nullStatus, char[] annotationName) {
6146
	int problemId = IProblem.NonNullReturnInsufficientInfo;
6147
	if ((nullStatus & FlowInfo.NULL) != 0)
6148
		problemId = IProblem.DefiniteNullFromNonNullMethod;
6149
	if ((nullStatus & FlowInfo.POTENTIALLY_NULL) != 0)
6150
		problemId = IProblem.PotentialNullFromNonNullMethod;
6151
	String[] arguments = new String[] { String.valueOf(annotationName) };
6152
	this.handle(
6153
		problemId,
6154
		arguments,
6155
		arguments,
6156
		returnStatement.sourceStart,
6157
		returnStatement.sourceEnd);
6158
}
6159
public void possiblyNullToNonNullLocal(char[] variableName, Expression expression, int nullStatus, char[][] annotationName) {
6160
	int problemId = IProblem.NonNullLocalInsufficientInfo;
6161
	if ((nullStatus & FlowInfo.NULL) != 0)
6162
		problemId = IProblem.DefiniteNullToNonNullLocal;
6163
	else if ((nullStatus & FlowInfo.POTENTIALLY_NULL) != 0)
6164
		problemId = IProblem.PotentialNullToNonNullLocal;
6165
	String[] arguments = new String[] {
6166
			String.valueOf(variableName),
6167
			String.valueOf(annotationName[annotationName.length-1]) 
6168
	};
6169
	this.handle(
6170
		problemId,
6171
		arguments,
6172
		arguments,
6173
		expression.sourceStart,
6174
		expression.sourceEnd);
6175
}
6176
public void possiblyNullToNonNullParameter(Expression argument, int nullStatus, char[] annotationName) {
6177
	int problemId = IProblem.NonNullParameterInsufficientInfo;
6178
	if ((nullStatus & FlowInfo.NULL) != 0)
6179
		problemId = IProblem.DefiniteNullToNonNullParameter;
6180
	else if ((nullStatus & FlowInfo.POTENTIALLY_NULL) != 0)
6181
		problemId = IProblem.PotentialNullToNonNullParameter;
6182
	String[] arguments = new String[] { String.valueOf(annotationName) };
6183
	this.handle(
6184
		problemId,
6185
		arguments,
6186
		arguments,
6187
		argument.sourceStart,
6188
		argument.sourceEnd);
6189
}
6081
public void publicClassMustMatchFileName(CompilationUnitDeclaration compUnitDecl, TypeDeclaration typeDecl) {
6190
public void publicClassMustMatchFileName(CompilationUnitDeclaration compUnitDecl, TypeDeclaration typeDecl) {
6082
	this.referenceContext = typeDecl; // report the problem against the type not the entire compilation unit
6191
	this.referenceContext = typeDecl; // report the problem against the type not the entire compilation unit
6083
	String[] arguments = new String[] {new String(compUnitDecl.getFileName()), new String(typeDecl.name)};
6192
	String[] arguments = new String[] {new String(compUnitDecl.getFileName()), new String(typeDecl.name)};
(-)compiler/org/eclipse/jdt/internal/compiler/problem/messages.properties (-2 / +20 lines)
Lines 1-5 Link Here
1
###############################################################################
1
###############################################################################
2
# Copyright (c) 2000, 2010 IBM Corporation and others.
2
# Copyright (c) 2000, 2011 IBM Corporation and others.
3
# All rights reserved. This program and the accompanying materials
3
# All rights reserved. This program and the accompanying materials
4
# are made available under the terms of the Eclipse Public License v1.0
4
# are made available under the terms of the Eclipse Public License v1.0
5
# which accompanies this distribution, and is available at
5
# which accompanies this distribution, and is available at
Lines 8-14 Link Here
8
# Contributors:
8
# Contributors:
9
#     IBM Corporation - initial API and implementation
9
#     IBM Corporation - initial API and implementation
10
#		Benjamin Muskalla - Contribution for bug 239066
10
#		Benjamin Muskalla - Contribution for bug 239066
11
#		Stephan Herrmann <stephan@cs.tu-berlin.de> - Contribution for bug 185682 - Increment/decrement operators mark local variables as read
11
#		Stephan Herrmann <stephan@cs.tu-berlin.de> - Contributions for
12
#						bug 185682 - Increment/decrement operators mark local variables as read
13
#				 		bug 186342 - [compiler][null]Using annotations for null checking
12
###############################################################################
14
###############################################################################
13
0 = {0}
15
0 = {0}
14
1 = super cannot be used in java.lang.Object
16
1 = super cannot be used in java.lang.Object
Lines 619-624 Link Here
619
858 = The parameterized constructor <{3}>{0}({1}) of type {2} is not applicable for the arguments ({4})
621
858 = The parameterized constructor <{3}>{0}({1}) of type {2} is not applicable for the arguments ({4})
620
859 = The constructor {0}({1}) of raw type {2} is no longer generic; it cannot be parameterized with arguments <{3}>
622
859 = The constructor {0}({1}) of raw type {2} is no longer generic; it cannot be parameterized with arguments <{3}>
621
623
624
### NULL ANNOTATIONS
625
880 = Null contract violation: returning null from a method declared as @{0}.
626
881 = Null contract violation: return value can be null but method is declared as @{0}.
627
882 = Potential null contract violation: insufficient nullness information regarding return value while the method is declared as @{0}.
628
883 = Null contract violation: passing null to a parameter declared as @{0}.
629
884 = Null contract violation: potentially passing null to a parameter declared as @{0}.
630
885 = Potential null contract violation: insufficient nullness information regarding a value that is passed to a parameter declared as @{0}.
631
886 = Null contract violation: assigning null to local variable {0}, which is declared as @{1}.
632
887 = Null contract violation: potentially assigning null to local variable {0}, which is declared as @{1}.
633
888 = Potential null contract violation: insufficient nullness information regarding a value that is assigned to local variable {0}, which is declared as @{1}.
634
889 = Buildpath problem: emulation of type {0} is requested (for null annotations) but a type of this name exists on the build path.
635
890 = Buildpath problem: the type {0} which is configured as a null annotation type cannot be resolved.
636
891 = Cannot relax null contract for method return, inherited method from {0} is declared as @{1}.
637
892 = Cannot tighten null contract for parameter {0}, inherited method from {1} declares this parameter as @{2}.
638
893 = Cannot tighten null contract for parameter {0}, inherited method from {1} does not constrain this parameter.
639
622
### ELABORATIONS
640
### ELABORATIONS
623
## Access restrictions
641
## Access restrictions
624
78592 = The type {1} is not accessible due to restriction on classpath entry {0}
642
78592 = The type {1} is not accessible due to restriction on classpath entry {0}
(-)model/org/eclipse/jdt/core/JavaCore.java (-3 / +177 lines)
Lines 1-5 Link Here
1
/*******************************************************************************
1
/*******************************************************************************
2
 * Copyright (c) 2000, 2010 IBM Corporation and others.
2
 * Copyright (c) 2000, 2011 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
5
 * which accompanies this distribution, and is available at
Lines 81-88 Link Here
81
 *                                 COMPILER_PB_UNUSED_DECLARED_THROWN_EXCEPTION_EXEMPT_EXCEPTION_AND_THROWABLE
81
 *                                 COMPILER_PB_UNUSED_DECLARED_THROWN_EXCEPTION_EXEMPT_EXCEPTION_AND_THROWABLE
82
 *     IBM Corporation - added getOptionForConfigurableSeverity(int)
82
 *     IBM Corporation - added getOptionForConfigurableSeverity(int)
83
 *     Benjamin Muskalla - added COMPILER_PB_MISSING_SYNCHRONIZED_ON_INHERITED_METHOD
83
 *     Benjamin Muskalla - added COMPILER_PB_MISSING_SYNCHRONIZED_ON_INHERITED_METHOD
84
 *     Stephan Herrmann  - added COMPILER_PB_UNUSED_OBJECT_ALLOCATION
84
 *     Stephan Herrmann  - added the following constants:
85
 *     Stephan Herrmann  - added COMPILER_PB_SUPPRESS_OPTIONAL_ERRORS
85
 *     								COMPILER_PB_UNUSED_OBJECT_ALLOCATION
86
 *     								COMPILER_PB_SUPPRESS_OPTIONAL_ERRORS
87
 *     								COMPILER_NULLABLE_ANNOTATION_NAME
88
 *     								COMPILER_NONNULL_ANNOTATION_NAME
89
 *     								COMPILER_EMULATE_NULL_ANNOTATION_TYPES
90
 *     								COMPILER_DEFAULT_IMPORT_NULL_ANNOTATION_TYPES
91
 *     								COMPILER_PB_NULL_CONTRACT_VIOLATION
92
 *     							 	COMPILER_PB_POTENTIAL_NULL_CONTRACT_VIOLATION
93
 *     							 	COMPILER_PB_NULL_CONTRACT_INSUFFICIENT_INFO
86
 *******************************************************************************/
94
 *******************************************************************************/
87
95
88
package org.eclipse.jdt.core;
96
package org.eclipse.jdt.core;
Lines 1576-1581 Link Here
1576
	 */
1584
	 */
1577
	public static final String COMPILER_PB_POTENTIAL_NULL_REFERENCE = PLUGIN_ID + ".compiler.problem.potentialNullReference"; //$NON-NLS-1$
1585
	public static final String COMPILER_PB_POTENTIAL_NULL_REFERENCE = PLUGIN_ID + ".compiler.problem.potentialNullReference"; //$NON-NLS-1$
1578
	/**
1586
	/**
1587
	 * Compiler option ID: Name of Annotation Type for Nullable Types.
1588
	 * <p>This option defines a fully qualified Java type name that the compiler may use
1589
	 *    to perform special null analysis.</p>
1590
	 * <p>If the annotation specified by this option is applied to a type in a method
1591
	 *    signature or variable declaration this will be interpreted as a contract that 
1592
	 *    <code>null</code> is a legal value in that position. Currently supported
1593
	 *    positions are: method parameters, method return type and local variables.</p>
1594
	 * <p>If a value whose type
1595
	 *    is annotated with this annotation is dereferenced without checking for null
1596
	 *    the compiler will trigger a diagnostic as further controlled by 
1597
	 *    {@link #COMPILER_PB_POTENTIAL_NULL_REFERENCE}.</p>
1598
	 * <p>The compiler may furthermore check adherence to the null contract as further
1599
	 *    controlled by {@link #COMPILER_PB_NULL_CONTRACT_VIOLATION}, 
1600
	 *    {@link #COMPILER_PB_POTENTIAL_NULL_CONTRACT_VIOLATION} and
1601
	 *    {@link #COMPILER_PB_NULL_CONTRACT_INSUFFICIENT_INFO}.
1602
	 * </p>
1603
	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.annotation.nullable"</code></dd>
1604
	 * <dt>Possible values:</dt><dd>any legal Java type name</dd>
1605
	 * <dt>Default:</dt><dd><code>"org.eclipse.jdt.annotation.Nullable"</code></dd>
1606
	 * @since 3.7
1607
	 * @category CompilerOptionID
1608
	 */
1609
	public static final String COMPILER_NULLABLE_ANNOTATION_NAME = PLUGIN_ID + ".compiler.annotation.nullable"; //$NON-NLS-1$
1610
	/**
1611
	 * Compiler option ID: Name of Annotation Type for Non-Null Types.
1612
	 * <p>This option defines a fully qualified Java type name that the compiler may use
1613
	 *    to perform special null analysis.</p>
1614
	 * <p>If the annotation specified by this option is applied to a type in a method
1615
	 *    signature or variable declaration this will be interpreted as a contract that 
1616
	 *    <code>null</code> is <b>not</b> a legal value in that position. Currently 
1617
	 *    supported positions are: method parameters, method return type and local variables.</p>
1618
	 * <p>For values declared with this annotation the compiler will never trigger a null
1619
	 *    reference diagnostic (as controlled by {@link #COMPILER_PB_POTENTIAL_NULL_REFERENCE}
1620
	 *    and {@link #COMPILER_PB_NULL_REFERENCE}), because the assumption is made that null
1621
	 *    will never occur at runtime in these positions.</p>
1622
	 * <p>The compiler may furthermore check adherence to the null contract as further
1623
	 *    controlled by {@link #COMPILER_PB_NULL_CONTRACT_VIOLATION}, 
1624
	 *    {@link #COMPILER_PB_POTENTIAL_NULL_CONTRACT_VIOLATION} and
1625
	 *    {@link #COMPILER_PB_NULL_CONTRACT_INSUFFICIENT_INFO}.
1626
	 * </p>
1627
	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.annotation.nonnull"</code></dd>
1628
	 * <dt>Possible values:</dt><dd>any legal Java type name</dd>
1629
	 * <dt>Default:</dt><dd><code>"org.eclipse.jdt.annotation.NonNull"</code></dd>
1630
	 * @since 3.7
1631
	 * @category CompilerOptionID
1632
	 */
1633
	public static final String COMPILER_NONNULL_ANNOTATION_NAME = PLUGIN_ID + ".compiler.annotation.nonnull"; //$NON-NLS-1$
1634
	/**
1635
	 * Compiler option ID: Emulate Null Annotation Types.
1636
	 * <p>When enabled, the compiler will use the annotation types specified in
1637
	 *    {@link #COMPILER_NONNULL_ANNOTATION_NAME} and {@link #COMPILER_NULLABLE_ANNOTATION_NAME}
1638
	 *    without searching for a corresponding type definition, ie., these annotation
1639
	 *    types don't have to actually exist.</p>
1640
	 * <p>This option is used to make null contract analysis independent of any additional
1641
	 *    classes that would otherwise need to be supplied at compile time.</p>
1642
	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.annotation.emulate"</code></dd>
1643
	 * <dt>Possible values:</dt><dd>{ "disabled", "enabled" }</dd>
1644
	 * <dt>Default:</dt><dd><code>"disabled"</code></dd>
1645
	 * @since 3.7
1646
	 * @category CompilerOptionID
1647
	 */
1648
	public static final String COMPILER_EMULATE_NULL_ANNOTATION_TYPES = PLUGIN_ID + ".compiler.annotation.emulate"; //$NON-NLS-1$
1649
	/**
1650
	 * Compiler option ID: Default Import of Null Annotation Types.
1651
	 * <p>When enabled, the compiler will be able to resolve the annotation types specified in
1652
	 *    {@link #COMPILER_NONNULL_ANNOTATION_NAME} and {@link #COMPILER_NULLABLE_ANNOTATION_NAME}
1653
	 *    by their simple names without an explicit import statement.</p>
1654
	 * <p>This option is used to avoid mentioning the fully qualified annotation names
1655
	 *    in any source files, as to facility the migration from one set of annotations
1656
	 *    to another, e.g., when standard annotations for this purpose will be defined
1657
	 *    in the future.
1658
	 * </p> 
1659
	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.annotation.defaultImport"</code></dd>
1660
	 * <dt>Possible values:</dt><dd>{ "disabled", "enabled" }</dd>
1661
	 * <dt>Default:</dt><dd><code>"disabled"</code></dd>
1662
	 * @since 3.7
1663
	 * @category CompilerOptionID
1664
	 */
1665
	public static final String COMPILER_DEFAULT_IMPORT_NULL_ANNOTATION_TYPES = PLUGIN_ID + ".compiler.annotation.defaultImport"; //$NON-NLS-1$
1666
	/**
1667
	 * Compiler option ID: Reporting Violations of Null Contracts.
1668
	 * <p>When enabled, the compiler will issue an error or a warning whenever one of the 
1669
	 *    following situations is detected:
1670
	 *    <ol>
1671
	 *    <li>A method declared with a nonnull annotation returns an expression that is 
1672
	 *    	  statically known to evaluate to a null value.</li>
1673
	 *    <li>An expression that is statically known to evaluate to a null value is passed 
1674
	 *        as an argument in a method call where the corresponding parameter of the called
1675
	 *        method is declared with a nonnull annotation.</li>
1676
	 *    <li>A method that overrides or implements an inherited method declared with a nonnull
1677
	 *        annotation tries to relax that contract by specifying a nullable annotation
1678
	 *        (prohibition of contravariant return).</li>
1679
	 *    <li>A method that overrides or implements an inherited method which has a nullable
1680
	 *        declaration for at least one of its parameters, tries to tighten that null contract
1681
	 *        by specifying a nonnull annotation for its corresponding parameter
1682
	 *        (prohibition of covariant parameters).</li>
1683
	 *    </ol>         
1684
	 * </p>
1685
	 * <p>The compiler options {@link #COMPILER_NONNULL_ANNOTATION_NAME} and
1686
	 *    {@link #COMPILER_NULLABLE_ANNOTATION_NAME} control which annotations the compiler
1687
	 *    shall interpret as nonnull or nullable annotations, respectively.
1688
	 * </p>
1689
	 * <dl>
1690
	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.problem.nullContractViolation"</code></dd>
1691
	 * <dt>Possible values:</dt><dd><code>{ "error", "warning", "ignore" }</code></dd>
1692
	 * <dt>Default:</dt><dd><code>"error"</code></dd>
1693
	 * </dl>
1694
	 * @since 3.7
1695
	 * @category CompilerOptionID
1696
	 */
1697
	public static final String COMPILER_PB_NULL_CONTRACT_VIOLATION = PLUGIN_ID + ".compiler.problem.nullContractViolation"; //$NON-NLS-1$
1698
	/**
1699
	 * Compiler option ID: Reporting Violations of Null Contracts with Potential Null Value.
1700
	 * <p>When enabled, the compiler will issue an error or a warning whenever one of the 
1701
	 *    following situations is detected:
1702
	 *    <ol>
1703
	 *    <li>A method declared with a nonnull annotation returns an expression that is 
1704
	 *    	  statically known to evaluate to a null value on some flow.</li>
1705
	 *    <li>An expression that is statically known to evaluate to a null value on some flow
1706
	 *        is passed as an argument in a method call where the corresponding parameter of 
1707
	 *        the called method is declared with a nonnull annotation.</li>
1708
	 *    </ol>         
1709
	 * </p>
1710
	 * <p>The compiler options {@link #COMPILER_NONNULL_ANNOTATION_NAME} and
1711
	 *    {@link #COMPILER_NULLABLE_ANNOTATION_NAME} control which annotations the compiler
1712
	 *    shall interpret as nonnull or nullable annotations, respectively.
1713
	 * </p>
1714
	 * <dl>
1715
	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.problem.potentialNullContractViolation"</code></dd>
1716
	 * <dt>Possible values:</dt><dd><code>{ "error", "warning", "ignore" }</code></dd>
1717
	 * <dt>Default:</dt><dd><code>"error"</code></dd>
1718
	 * </dl>
1719
	 * @since 3.7
1720
	 * @category CompilerOptionID
1721
	 */
1722
	public static final String COMPILER_PB_POTENTIAL_NULL_CONTRACT_VIOLATION = PLUGIN_ID + ".compiler.problem.potentialNullContractViolation"; //$NON-NLS-1$
1723
	/**
1724
	 * Compiler option ID: Reporting Insufficient Information for Analysing Adherence to Null Contracts.
1725
	 * <p>When enabled, the compiler will issue an error or a warning whenever one of the 
1726
	 *    following situations is detected:
1727
	 *    <ol>
1728
	 *    <li>A method declared with a nonnull annotation returns an expression for which 
1729
	 *        insufficient nullness information is available for statically proving that no
1730
	 *        flow will pass a null value at runtime.</li>
1731
	 *    <li>An expression for which insufficient nullness information is available for 
1732
	 *        statically proving that it will never evaluate to a null value at runtime
1733
	 *        is passed as an argument in a method call where the corresponding parameter of 
1734
	 *        the called method is declared with a nonnull annotation.</li>
1735
	 *    </ol>
1736
	 *    Insufficient nullness information is usually a consequence of using other unannotated
1737
	 *    variables or methods.
1738
	 * </p>
1739
	 * <p>The compiler options {@link #COMPILER_NONNULL_ANNOTATION_NAME} and
1740
	 *    {@link #COMPILER_NULLABLE_ANNOTATION_NAME} control which annotations the compiler
1741
	 *    shall interpret as nonnull or nullable annotations, respectively.
1742
	 * </p>
1743
	 * <dl>
1744
	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.problem.nullContractInsufficientInfo"</code></dd>
1745
	 * <dt>Possible values:</dt><dd><code>{ "error", "warning", "ignore" }</code></dd>
1746
	 * <dt>Default:</dt><dd><code>"warning"</code></dd>
1747
	 * </dl>
1748
	 * @since 3.7
1749
	 * @category CompilerOptionID
1750
	 */
1751
	public static final String COMPILER_PB_NULL_CONTRACT_INSUFFICIENT_INFO = PLUGIN_ID + ".compiler.problem.nullContractInsufficientInfo"; //$NON-NLS-1$
1752
	/**
1579
	 * Compiler option ID: Reporting Redundant Null Check.
1753
	 * Compiler option ID: Reporting Redundant Null Check.
1580
	 * <p>When enabled, the compiler will issue an error or a warning whenever a
1754
	 * <p>When enabled, the compiler will issue an error or a warning whenever a
1581
	 *    variable that is statically known to hold a null or a non-null value
1755
	 *    variable that is statically known to hold a null or a non-null value
(-)src/org/eclipse/jdt/core/tests/compiler/regression/BatchCompilerTest.java (-3 / +90 lines)
Lines 1-5 Link Here
1
/*******************************************************************************
1
/*******************************************************************************
2
 * Copyright (c) 2000, 2010 IBM Corporation and others.
2
 * Copyright (c) 2000, 2011 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
5
 * which accompanies this distribution, and is available at
Lines 10-16 Link Here
10
 *     Benjamin Muskalla - Contribution for bug 239066
10
 *     Benjamin Muskalla - Contribution for bug 239066
11
 *     Stephan Herrmann  - Contribution for bug 236385
11
 *     Stephan Herrmann  - Contribution for bug 236385
12
 *     Stephan Herrmann  - Contribution for bug 295551
12
 *     Stephan Herrmann  - Contribution for bug 295551
13
 *     Stephan Herrmann <stephan@cs.tu-berlin.de> - Contribution for bug 185682 - Increment/decrement operators mark local variables as read
13
 *     Stephan Herrmann <stephan@cs.tu-berlin.de> - Contributions for 
14
 *     						bug 185682 - Increment/decrement operators mark local variables as read
15
 *     						bug 186342 - [compiler][null]Using annotations for null checking
14
 *******************************************************************************/
16
 *******************************************************************************/
15
package org.eclipse.jdt.core.tests.compiler.regression;
17
package org.eclipse.jdt.core.tests.compiler.regression;
16
18
Lines 48-54 Link Here
48
	private static final Main MAIN = new Main(null/*outWriter*/, null/*errWriter*/, false/*systemExit*/, null/*options*/, null/*progress*/);
50
	private static final Main MAIN = new Main(null/*outWriter*/, null/*errWriter*/, false/*systemExit*/, null/*options*/, null/*progress*/);
49
51
50
	static {
52
	static {
51
//		TESTS_NAMES = new String[] { "test295_warn_options" };
53
//		TESTS_NAMES = new String[] { "testNullAnnotations" };
52
//		TESTS_NUMBERS = new int[] { 306 };
54
//		TESTS_NUMBERS = new int[] { 306 };
53
//		TESTS_RANGE = new int[] { 298, -1 };
55
//		TESTS_RANGE = new int[] { 298, -1 };
54
	}
56
	}
Lines 1589-1594 Link Here
1589
        "    -classNames <className1[,className2,...]>\n" +
1591
        "    -classNames <className1[,className2,...]>\n" +
1590
        "                         qualified names of binary classes to process\n" +
1592
        "                         qualified names of binary classes to process\n" +
1591
        " \n" +
1593
        " \n" +
1594
        " Null annotation options:\n" +
1595
		"    -nullAnnotations:<suboptions>\n" +
1596
		"                      enable use of annotations for specifying null contracts;\n" +
1597
		"                      <suboptions> is a non-empty, comma-separated list of:\n" +
1598
		"        nullable=<typename>\n" +
1599
		"                      specifies the fully qualified name of an annotation type\n" +
1600
		"                      to be used for marking types whose values include null\n" +
1601
		"        nonnull=<typename>\n" +
1602
		"                      specifies the fully qualified name of an annotation type\n" +
1603
		"                      to be used for marking types whose values cannot be null\n" +
1604
		"        emulate       tells the compiler to emulate the above annotation types\n" +
1605
		"                      although they do not exist on the classpath\n" +
1606
		"        import        tells the compiler to import the above annotation types\n" +
1607
		"                      without specific mention in the sources such that their\n" +
1608
		"                      simple names can be used without explicit imports\n" +
1609
		" \n" +
1592
        " Advanced options:\n" +
1610
        " Advanced options:\n" +
1593
        "    @<file>            read command line arguments from file\n" +
1611
        "    @<file>            read command line arguments from file\n" +
1594
        "    -maxProblems <n>   max number of problems per compilation unit (100 by\n" +
1612
        "    -maxProblems <n>   max number of problems per compilation unit (100 by\n" +
Lines 1793-1798 Link Here
1793
			"		<argument value=\"---OUTPUT_DIR_PLACEHOLDER---\"/>\n" + 
1811
			"		<argument value=\"---OUTPUT_DIR_PLACEHOLDER---\"/>\n" + 
1794
			"	</command_line>\n" + 
1812
			"	</command_line>\n" + 
1795
			"	<options>\n" + 
1813
			"	<options>\n" + 
1814
			"		<option key=\"org.eclipse.jdt.core.compiler.annotation.defaultImport\" value=\"disabled\"/>\n" + 
1815
			"		<option key=\"org.eclipse.jdt.core.compiler.annotation.emulate\" value=\"disabled\"/>\n" + 
1796
			"		<option key=\"org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode\" value=\"disabled\"/>\n" + 
1816
			"		<option key=\"org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode\" value=\"disabled\"/>\n" + 
1797
			"		<option key=\"org.eclipse.jdt.core.compiler.codegen.targetPlatform\" value=\"1.5\"/>\n" + 
1817
			"		<option key=\"org.eclipse.jdt.core.compiler.codegen.targetPlatform\" value=\"1.5\"/>\n" + 
1798
			"		<option key=\"org.eclipse.jdt.core.compiler.codegen.unusedLocal\" value=\"optimize out\"/>\n" + 
1818
			"		<option key=\"org.eclipse.jdt.core.compiler.codegen.unusedLocal\" value=\"optimize out\"/>\n" + 
Lines 1850-1860 Link Here
1850
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.noEffectAssignment\" value=\"warning\"/>\n" + 
1870
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.noEffectAssignment\" value=\"warning\"/>\n" + 
1851
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion\" value=\"warning\"/>\n" + 
1871
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion\" value=\"warning\"/>\n" + 
1852
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral\" value=\"ignore\"/>\n" + 
1872
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral\" value=\"ignore\"/>\n" + 
1873
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.nullContractInsufficientInfo\" value=\"warning\"/>\n" + 
1874
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.nullContractViolation\" value=\"error\"/>\n" + 
1853
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.nullReference\" value=\"warning\"/>\n" + 
1875
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.nullReference\" value=\"warning\"/>\n" + 
1854
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.overridingMethodWithoutSuperInvocation\" value=\"ignore\"/>\n" + 
1876
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.overridingMethodWithoutSuperInvocation\" value=\"ignore\"/>\n" + 
1855
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod\" value=\"warning\"/>\n" + 
1877
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod\" value=\"warning\"/>\n" + 
1856
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.parameterAssignment\" value=\"ignore\"/>\n" + 
1878
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.parameterAssignment\" value=\"ignore\"/>\n" + 
1857
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment\" value=\"ignore\"/>\n" + 
1879
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment\" value=\"ignore\"/>\n" + 
1880
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.potentialNullContractViolation\" value=\"error\"/>\n" + 
1858
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.potentialNullReference\" value=\"ignore\"/>\n" + 
1881
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.potentialNullReference\" value=\"ignore\"/>\n" + 
1859
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.rawTypeReference\" value=\"warning\"/>\n" + 
1882
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.rawTypeReference\" value=\"warning\"/>\n" + 
1860
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.redundantNullCheck\" value=\"ignore\"/>\n" + 
1883
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.redundantNullCheck\" value=\"ignore\"/>\n" + 
Lines 12264-12267 Link Here
12264
		"3 problems (1 error, 2 warnings)",
12287
		"3 problems (1 error, 2 warnings)",
12265
		true);
12288
		true);
12266
}
12289
}
12290
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=186342  -- minimal options passed
12291
public void testNullAnnotations1() {
12292
	this.runNegativeTest(
12293
		new String[] {
12294
			"X.java",
12295
			"public class X {\n" +
12296
			"    @org.eclipse.jdt.annotation.NonNull Object foo(boolean b) {\n" +
12297
			"          return null;\n" +
12298
			"    }\n" +
12299
			"}\n"
12300
		},
12301
		"\"" + OUTPUT_DIR +  File.separator + "X.java\""
12302
		+ " -1.5 -nullAnnotations:emulate -d \"" + OUTPUT_DIR + "\"",
12303
		"",
12304
		"----------\n" + 
12305
		"1. ERROR in ---OUTPUT_DIR_PLACEHOLDER---/X.java (at line 3)\n" + 
12306
		"	return null;\n" + 
12307
		"	^^^^^^^^^^^^\n" + 
12308
		"Null contract violation: returning null from a method declared as @NonNull.\n" +
12309
		"----------\n" + 
12310
		"1 problem (1 error)",
12311
		true);
12312
}
12313
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=186342  -- full options passed
12314
public void testNullAnnotations2() {
12315
	this.runNegativeTest(
12316
		new String[] {
12317
			"X.java",
12318
			"public class X {\n" +
12319
			"    @NichtNull Object foo(boolean b) {\n" +
12320
			"          return null;\n" +
12321
			"    }\n" +
12322
			"}\n"
12323
		},
12324
		"\"" + OUTPUT_DIR +  File.separator + "X.java\""
12325
		+ " -1.5 -nullAnnotations:nullable=org.foo.Nullish,emulate,import,nonnull=de.foo.NichtNull -d \"" + OUTPUT_DIR + "\"",
12326
		"",
12327
		"----------\n" + 
12328
		"1. ERROR in ---OUTPUT_DIR_PLACEHOLDER---/X.java (at line 3)\n" + 
12329
		"	return null;\n" + 
12330
		"	^^^^^^^^^^^^\n" + 
12331
		"Null contract violation: returning null from a method declared as @NichtNull.\n" +
12332
		"----------\n" + 
12333
		"1 problem (1 error)",
12334
		true);
12335
}
12336
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=186342  -- unrecognized sub-option
12337
public void testNullAnnotations3() {
12338
	this.runNegativeTest(
12339
		new String[] {
12340
			"X.java",
12341
			"public class X {\n" +
12342
			"    @NichtNull Object foo(boolean b) {\n" +
12343
			"          return null;\n" +
12344
			"    }\n" +
12345
			"}\n"
12346
		},
12347
		"\"" + OUTPUT_DIR +  File.separator + "X.java\""
12348
		+ " -1.5 -nullAnnotations:wrong -d \"" + OUTPUT_DIR + "\"",
12349
		"",
12350
		"Unrecognized sub-option of -nullAnnotations: wrong,\n" + 
12351
		"legal values are nullable=.., nonnull=.., emulate and import\n",
12352
		true);
12353
}
12267
}
12354
}
(-)src/org/eclipse/jdt/core/tests/compiler/regression/CompilerInvocationTests.java (-2 / +32 lines)
Lines 1-5 Link Here
1
/*******************************************************************************
1
/*******************************************************************************
2
 * Copyright (c) 2006, 2010 IBM Corporation and others.
2
 * Copyright (c) 2006, 2011 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
5
 * which accompanies this distribution, and is available at
Lines 8-14 Link Here
8
 * Contributors:
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
9
 *     IBM Corporation - initial API and implementation
10
 *     Benjamin Muskalla - Contribution for bug 239066
10
 *     Benjamin Muskalla - Contribution for bug 239066
11
 *     Stephan Herrmann  - Contribution for bug 236385
11
 *     Stephan Herrmann  - Contributions for 
12
 *     							bug 236385 - [compiler] Warn for potential programming problem if an object is created but not used
13
 *     							bug 186342 - [compiler][null]Using annotations for null checking
12
 *******************************************************************************/
14
 *******************************************************************************/
13
package org.eclipse.jdt.core.tests.compiler.regression;
15
package org.eclipse.jdt.core.tests.compiler.regression;
14
16
Lines 386-394 Link Here
386
		expectedProblemAttributes.put("CodeSnippetMissingMethod", new ProblemAttributes(CategorizedProblem.CAT_INTERNAL));
388
		expectedProblemAttributes.put("CodeSnippetMissingMethod", new ProblemAttributes(CategorizedProblem.CAT_INTERNAL));
387
		expectedProblemAttributes.put("ComparingIdentical", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM));
389
		expectedProblemAttributes.put("ComparingIdentical", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM));
388
		expectedProblemAttributes.put("ConflictingImport", new ProblemAttributes(CategorizedProblem.CAT_IMPORT));
390
		expectedProblemAttributes.put("ConflictingImport", new ProblemAttributes(CategorizedProblem.CAT_IMPORT));
391
		expectedProblemAttributes.put("ConflictingTypeEmulation", new ProblemAttributes(CategorizedProblem.CAT_BUILDPATH));
389
		expectedProblemAttributes.put("ConstructorVarargsArgumentNeedCast", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM));
392
		expectedProblemAttributes.put("ConstructorVarargsArgumentNeedCast", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM));
390
		expectedProblemAttributes.put("CorruptedSignature", new ProblemAttributes(CategorizedProblem.CAT_BUILDPATH));
393
		expectedProblemAttributes.put("CorruptedSignature", new ProblemAttributes(CategorizedProblem.CAT_BUILDPATH));
391
		expectedProblemAttributes.put("DeadCode", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM));
394
		expectedProblemAttributes.put("DeadCode", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM));
395
		expectedProblemAttributes.put("DefiniteNullFromNonNullMethod", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM));
396
		expectedProblemAttributes.put("DefiniteNullToNonNullParameter", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM));
397
		expectedProblemAttributes.put("DefiniteNullToNonNullLocal", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM));
392
		expectedProblemAttributes.put("DirectInvocationOfAbstractMethod", new ProblemAttributes(CategorizedProblem.CAT_MEMBER));
398
		expectedProblemAttributes.put("DirectInvocationOfAbstractMethod", new ProblemAttributes(CategorizedProblem.CAT_MEMBER));
393
		expectedProblemAttributes.put("DisallowedTargetForAnnotation", new ProblemAttributes(CategorizedProblem.CAT_TYPE));
399
		expectedProblemAttributes.put("DisallowedTargetForAnnotation", new ProblemAttributes(CategorizedProblem.CAT_TYPE));
394
		expectedProblemAttributes.put("DiscouragedReference", new ProblemAttributes(CategorizedProblem.CAT_RESTRICTION));
400
		expectedProblemAttributes.put("DiscouragedReference", new ProblemAttributes(CategorizedProblem.CAT_RESTRICTION));
Lines 491-496 Link Here
491
		expectedProblemAttributes.put("IllegalPrimitiveOrArrayTypeForEnclosingInstance", new ProblemAttributes(CategorizedProblem.CAT_TYPE));
497
		expectedProblemAttributes.put("IllegalPrimitiveOrArrayTypeForEnclosingInstance", new ProblemAttributes(CategorizedProblem.CAT_TYPE));
492
		expectedProblemAttributes.put("IllegalQualifiedEnumConstantLabel", new ProblemAttributes(CategorizedProblem.CAT_MEMBER));
498
		expectedProblemAttributes.put("IllegalQualifiedEnumConstantLabel", new ProblemAttributes(CategorizedProblem.CAT_MEMBER));
493
		expectedProblemAttributes.put("IllegalQualifiedParameterizedTypeAllocation", new ProblemAttributes(CategorizedProblem.CAT_TYPE));
499
		expectedProblemAttributes.put("IllegalQualifiedParameterizedTypeAllocation", new ProblemAttributes(CategorizedProblem.CAT_TYPE));
500
		expectedProblemAttributes.put("IllegalDefinitionToNonNullParameter", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM));
501
		expectedProblemAttributes.put("IllegalRedefinitionToNullableReturn", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM));
502
		expectedProblemAttributes.put("IllegalRedefinitionToNonNullParameter", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM));
494
		expectedProblemAttributes.put("IllegalStaticModifierForMemberType", new ProblemAttributes(CategorizedProblem.CAT_TYPE));
503
		expectedProblemAttributes.put("IllegalStaticModifierForMemberType", new ProblemAttributes(CategorizedProblem.CAT_TYPE));
495
		expectedProblemAttributes.put("IllegalTypeVariableSuperReference", new ProblemAttributes(CategorizedProblem.CAT_INTERNAL));
504
		expectedProblemAttributes.put("IllegalTypeVariableSuperReference", new ProblemAttributes(CategorizedProblem.CAT_INTERNAL));
496
		expectedProblemAttributes.put("IllegalUsageOfQualifiedTypeReference", new ProblemAttributes(CategorizedProblem.CAT_SYNTAX));
505
		expectedProblemAttributes.put("IllegalUsageOfQualifiedTypeReference", new ProblemAttributes(CategorizedProblem.CAT_SYNTAX));
Lines 669-674 Link Here
669
		expectedProblemAttributes.put("MissingEnclosingInstance", new ProblemAttributes(CategorizedProblem.CAT_TYPE));
678
		expectedProblemAttributes.put("MissingEnclosingInstance", new ProblemAttributes(CategorizedProblem.CAT_TYPE));
670
		expectedProblemAttributes.put("MissingEnclosingInstanceForConstructorCall", new ProblemAttributes(CategorizedProblem.CAT_TYPE));
679
		expectedProblemAttributes.put("MissingEnclosingInstanceForConstructorCall", new ProblemAttributes(CategorizedProblem.CAT_TYPE));
671
		expectedProblemAttributes.put("MissingEnumConstantCase", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM));
680
		expectedProblemAttributes.put("MissingEnumConstantCase", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM));
681
		expectedProblemAttributes.put("MissingNullAnnotationType", new ProblemAttributes(CategorizedProblem.CAT_BUILDPATH));
672
		expectedProblemAttributes.put("MissingOverrideAnnotation", new ProblemAttributes(CategorizedProblem.CAT_CODE_STYLE));
682
		expectedProblemAttributes.put("MissingOverrideAnnotation", new ProblemAttributes(CategorizedProblem.CAT_CODE_STYLE));
673
		expectedProblemAttributes.put("MissingOverrideAnnotationForInterfaceMethodImplementation", new ProblemAttributes(CategorizedProblem.CAT_CODE_STYLE));
683
		expectedProblemAttributes.put("MissingOverrideAnnotationForInterfaceMethodImplementation", new ProblemAttributes(CategorizedProblem.CAT_CODE_STYLE));
674
		expectedProblemAttributes.put("MissingReturnType", new ProblemAttributes(CategorizedProblem.CAT_TYPE));
684
		expectedProblemAttributes.put("MissingReturnType", new ProblemAttributes(CategorizedProblem.CAT_TYPE));
Lines 697-702 Link Here
697
		expectedProblemAttributes.put("NonGenericMethod", new ProblemAttributes(CategorizedProblem.CAT_TYPE));
707
		expectedProblemAttributes.put("NonGenericMethod", new ProblemAttributes(CategorizedProblem.CAT_TYPE));
698
		expectedProblemAttributes.put("NonGenericType", new ProblemAttributes(CategorizedProblem.CAT_TYPE));
708
		expectedProblemAttributes.put("NonGenericType", new ProblemAttributes(CategorizedProblem.CAT_TYPE));
699
		expectedProblemAttributes.put("NonNullLocalVariableComparisonYieldsFalse", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM));
709
		expectedProblemAttributes.put("NonNullLocalVariableComparisonYieldsFalse", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM));
710
		expectedProblemAttributes.put("NonNullLocalInsufficientInfo", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM));
711
		expectedProblemAttributes.put("NonNullParameterInsufficientInfo", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM));
712
		expectedProblemAttributes.put("NonNullReturnInsufficientInfo", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM));
700
		expectedProblemAttributes.put("NonStaticAccessToStaticField", new ProblemAttributes(CategorizedProblem.CAT_CODE_STYLE));
713
		expectedProblemAttributes.put("NonStaticAccessToStaticField", new ProblemAttributes(CategorizedProblem.CAT_CODE_STYLE));
701
		expectedProblemAttributes.put("NonStaticAccessToStaticMethod", new ProblemAttributes(CategorizedProblem.CAT_CODE_STYLE));
714
		expectedProblemAttributes.put("NonStaticAccessToStaticMethod", new ProblemAttributes(CategorizedProblem.CAT_CODE_STYLE));
702
		expectedProblemAttributes.put("NonStaticContextForEnumMemberType", new ProblemAttributes(CategorizedProblem.CAT_INTERNAL));
715
		expectedProblemAttributes.put("NonStaticContextForEnumMemberType", new ProblemAttributes(CategorizedProblem.CAT_INTERNAL));
Lines 746-751 Link Here
746
		expectedProblemAttributes.put("ParsingErrorUnexpectedEOF", new ProblemAttributes(CategorizedProblem.CAT_SYNTAX));
759
		expectedProblemAttributes.put("ParsingErrorUnexpectedEOF", new ProblemAttributes(CategorizedProblem.CAT_SYNTAX));
747
		expectedProblemAttributes.put("PossibleAccidentalBooleanAssignment", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM));
760
		expectedProblemAttributes.put("PossibleAccidentalBooleanAssignment", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM));
748
		expectedProblemAttributes.put("PotentialNullLocalVariableReference", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM));
761
		expectedProblemAttributes.put("PotentialNullLocalVariableReference", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM));
762
		expectedProblemAttributes.put("PotentialNullFromNonNullMethod", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM));
763
		expectedProblemAttributes.put("PotentialNullToNonNullLocal", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM));
764
		expectedProblemAttributes.put("PotentialNullToNonNullParameter", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM));
749
		expectedProblemAttributes.put("PublicClassMustMatchFileName", new ProblemAttributes(CategorizedProblem.CAT_TYPE));
765
		expectedProblemAttributes.put("PublicClassMustMatchFileName", new ProblemAttributes(CategorizedProblem.CAT_TYPE));
750
		expectedProblemAttributes.put("RawMemberTypeCannotBeParameterized", new ProblemAttributes(CategorizedProblem.CAT_TYPE));
766
		expectedProblemAttributes.put("RawMemberTypeCannotBeParameterized", new ProblemAttributes(CategorizedProblem.CAT_TYPE));
751
		expectedProblemAttributes.put("RawTypeReference", new ProblemAttributes(CategorizedProblem.CAT_UNCHECKED_RAW));
767
		expectedProblemAttributes.put("RawTypeReference", new ProblemAttributes(CategorizedProblem.CAT_UNCHECKED_RAW));
Lines 1023-1031 Link Here
1023
		expectedProblemAttributes.put("CodeSnippetMissingMethod", SKIP);
1039
		expectedProblemAttributes.put("CodeSnippetMissingMethod", SKIP);
1024
		expectedProblemAttributes.put("ComparingIdentical", new ProblemAttributes(JavaCore.COMPILER_PB_COMPARING_IDENTICAL));
1040
		expectedProblemAttributes.put("ComparingIdentical", new ProblemAttributes(JavaCore.COMPILER_PB_COMPARING_IDENTICAL));
1025
		expectedProblemAttributes.put("ConflictingImport", SKIP);
1041
		expectedProblemAttributes.put("ConflictingImport", SKIP);
1042
		expectedProblemAttributes.put("ConflictingTypeEmulation", SKIP);
1026
		expectedProblemAttributes.put("ConstructorVarargsArgumentNeedCast", new ProblemAttributes(JavaCore.COMPILER_PB_VARARGS_ARGUMENT_NEED_CAST));
1043
		expectedProblemAttributes.put("ConstructorVarargsArgumentNeedCast", new ProblemAttributes(JavaCore.COMPILER_PB_VARARGS_ARGUMENT_NEED_CAST));
1027
		expectedProblemAttributes.put("CorruptedSignature", SKIP);
1044
		expectedProblemAttributes.put("CorruptedSignature", SKIP);
1028
		expectedProblemAttributes.put("DeadCode", new ProblemAttributes(JavaCore.COMPILER_PB_DEAD_CODE));
1045
		expectedProblemAttributes.put("DeadCode", new ProblemAttributes(JavaCore.COMPILER_PB_DEAD_CODE));
1046
		expectedProblemAttributes.put("DefiniteNullFromNonNullMethod", new ProblemAttributes(JavaCore.COMPILER_PB_NULL_CONTRACT_VIOLATION));
1047
		expectedProblemAttributes.put("DefiniteNullToNonNullLocal", new ProblemAttributes(JavaCore.COMPILER_PB_NULL_CONTRACT_VIOLATION));
1048
		expectedProblemAttributes.put("DefiniteNullToNonNullParameter", new ProblemAttributes(JavaCore.COMPILER_PB_NULL_CONTRACT_VIOLATION));
1029
		expectedProblemAttributes.put("DirectInvocationOfAbstractMethod", SKIP);
1049
		expectedProblemAttributes.put("DirectInvocationOfAbstractMethod", SKIP);
1030
		expectedProblemAttributes.put("DisallowedTargetForAnnotation", SKIP);
1050
		expectedProblemAttributes.put("DisallowedTargetForAnnotation", SKIP);
1031
		expectedProblemAttributes.put("DiscouragedReference", new ProblemAttributes(JavaCore.COMPILER_PB_DISCOURAGED_REFERENCE));
1051
		expectedProblemAttributes.put("DiscouragedReference", new ProblemAttributes(JavaCore.COMPILER_PB_DISCOURAGED_REFERENCE));
Lines 1128-1133 Link Here
1128
		expectedProblemAttributes.put("IllegalPrimitiveOrArrayTypeForEnclosingInstance", SKIP);
1148
		expectedProblemAttributes.put("IllegalPrimitiveOrArrayTypeForEnclosingInstance", SKIP);
1129
		expectedProblemAttributes.put("IllegalQualifiedEnumConstantLabel", SKIP);
1149
		expectedProblemAttributes.put("IllegalQualifiedEnumConstantLabel", SKIP);
1130
		expectedProblemAttributes.put("IllegalQualifiedParameterizedTypeAllocation", SKIP);
1150
		expectedProblemAttributes.put("IllegalQualifiedParameterizedTypeAllocation", SKIP);
1151
		expectedProblemAttributes.put("IllegalDefinitionToNonNullParameter", new ProblemAttributes(JavaCore.COMPILER_PB_NULL_CONTRACT_VIOLATION));
1152
		expectedProblemAttributes.put("IllegalRedefinitionToNullableReturn", new ProblemAttributes(JavaCore.COMPILER_PB_NULL_CONTRACT_VIOLATION));
1153
		expectedProblemAttributes.put("IllegalRedefinitionToNonNullParameter", new ProblemAttributes(JavaCore.COMPILER_PB_NULL_CONTRACT_VIOLATION));
1131
		expectedProblemAttributes.put("IllegalStaticModifierForMemberType", SKIP);
1154
		expectedProblemAttributes.put("IllegalStaticModifierForMemberType", SKIP);
1132
		expectedProblemAttributes.put("IllegalTypeVariableSuperReference", SKIP);
1155
		expectedProblemAttributes.put("IllegalTypeVariableSuperReference", SKIP);
1133
		expectedProblemAttributes.put("IllegalUsageOfQualifiedTypeReference", SKIP);
1156
		expectedProblemAttributes.put("IllegalUsageOfQualifiedTypeReference", SKIP);
Lines 1306-1311 Link Here
1306
		expectedProblemAttributes.put("MissingEnclosingInstance", SKIP);
1329
		expectedProblemAttributes.put("MissingEnclosingInstance", SKIP);
1307
		expectedProblemAttributes.put("MissingEnclosingInstanceForConstructorCall", SKIP);
1330
		expectedProblemAttributes.put("MissingEnclosingInstanceForConstructorCall", SKIP);
1308
		expectedProblemAttributes.put("MissingEnumConstantCase", new ProblemAttributes(JavaCore.COMPILER_PB_INCOMPLETE_ENUM_SWITCH));
1331
		expectedProblemAttributes.put("MissingEnumConstantCase", new ProblemAttributes(JavaCore.COMPILER_PB_INCOMPLETE_ENUM_SWITCH));
1332
		expectedProblemAttributes.put("MissingNullAnnotationType", SKIP);
1309
		expectedProblemAttributes.put("MissingOverrideAnnotation", new ProblemAttributes(JavaCore.COMPILER_PB_MISSING_OVERRIDE_ANNOTATION));
1333
		expectedProblemAttributes.put("MissingOverrideAnnotation", new ProblemAttributes(JavaCore.COMPILER_PB_MISSING_OVERRIDE_ANNOTATION));
1310
		expectedProblemAttributes.put("MissingOverrideAnnotationForInterfaceMethodImplementation", SKIP);
1334
		expectedProblemAttributes.put("MissingOverrideAnnotationForInterfaceMethodImplementation", SKIP);
1311
		expectedProblemAttributes.put("MissingReturnType", SKIP);
1335
		expectedProblemAttributes.put("MissingReturnType", SKIP);
Lines 1334-1339 Link Here
1334
		expectedProblemAttributes.put("NonGenericMethod", SKIP);
1358
		expectedProblemAttributes.put("NonGenericMethod", SKIP);
1335
		expectedProblemAttributes.put("NonGenericType", SKIP);
1359
		expectedProblemAttributes.put("NonGenericType", SKIP);
1336
		expectedProblemAttributes.put("NonNullLocalVariableComparisonYieldsFalse", new ProblemAttributes(JavaCore.COMPILER_PB_REDUNDANT_NULL_CHECK));
1360
		expectedProblemAttributes.put("NonNullLocalVariableComparisonYieldsFalse", new ProblemAttributes(JavaCore.COMPILER_PB_REDUNDANT_NULL_CHECK));
1361
		expectedProblemAttributes.put("NonNullReturnInsufficientInfo", new ProblemAttributes(JavaCore.COMPILER_PB_NULL_CONTRACT_INSUFFICIENT_INFO));
1362
		expectedProblemAttributes.put("NonNullLocalInsufficientInfo", new ProblemAttributes(JavaCore.COMPILER_PB_NULL_CONTRACT_INSUFFICIENT_INFO));
1363
		expectedProblemAttributes.put("NonNullParameterInsufficientInfo", new ProblemAttributes(JavaCore.COMPILER_PB_NULL_CONTRACT_INSUFFICIENT_INFO));
1337
		expectedProblemAttributes.put("NonStaticAccessToStaticField", new ProblemAttributes(JavaCore.COMPILER_PB_STATIC_ACCESS_RECEIVER));
1364
		expectedProblemAttributes.put("NonStaticAccessToStaticField", new ProblemAttributes(JavaCore.COMPILER_PB_STATIC_ACCESS_RECEIVER));
1338
		expectedProblemAttributes.put("NonStaticAccessToStaticMethod", new ProblemAttributes(JavaCore.COMPILER_PB_STATIC_ACCESS_RECEIVER));
1365
		expectedProblemAttributes.put("NonStaticAccessToStaticMethod", new ProblemAttributes(JavaCore.COMPILER_PB_STATIC_ACCESS_RECEIVER));
1339
		expectedProblemAttributes.put("NonStaticContextForEnumMemberType", SKIP);
1366
		expectedProblemAttributes.put("NonStaticContextForEnumMemberType", SKIP);
Lines 1383-1388 Link Here
1383
		expectedProblemAttributes.put("ParsingErrorUnexpectedEOF", SKIP);
1410
		expectedProblemAttributes.put("ParsingErrorUnexpectedEOF", SKIP);
1384
		expectedProblemAttributes.put("PossibleAccidentalBooleanAssignment", new ProblemAttributes(JavaCore.COMPILER_PB_POSSIBLE_ACCIDENTAL_BOOLEAN_ASSIGNMENT));
1411
		expectedProblemAttributes.put("PossibleAccidentalBooleanAssignment", new ProblemAttributes(JavaCore.COMPILER_PB_POSSIBLE_ACCIDENTAL_BOOLEAN_ASSIGNMENT));
1385
		expectedProblemAttributes.put("PotentialNullLocalVariableReference", new ProblemAttributes(JavaCore.COMPILER_PB_POTENTIAL_NULL_REFERENCE));
1412
		expectedProblemAttributes.put("PotentialNullLocalVariableReference", new ProblemAttributes(JavaCore.COMPILER_PB_POTENTIAL_NULL_REFERENCE));
1413
		expectedProblemAttributes.put("PotentialNullFromNonNullMethod", new ProblemAttributes(JavaCore.COMPILER_PB_POTENTIAL_NULL_CONTRACT_VIOLATION));
1414
		expectedProblemAttributes.put("PotentialNullToNonNullLocal", new ProblemAttributes(JavaCore.COMPILER_PB_POTENTIAL_NULL_CONTRACT_VIOLATION));
1415
		expectedProblemAttributes.put("PotentialNullToNonNullParameter", new ProblemAttributes(JavaCore.COMPILER_PB_POTENTIAL_NULL_CONTRACT_VIOLATION));
1386
		expectedProblemAttributes.put("PublicClassMustMatchFileName", SKIP);
1416
		expectedProblemAttributes.put("PublicClassMustMatchFileName", SKIP);
1387
		expectedProblemAttributes.put("RawMemberTypeCannotBeParameterized", SKIP);
1417
		expectedProblemAttributes.put("RawMemberTypeCannotBeParameterized", SKIP);
1388
		expectedProblemAttributes.put("RawTypeReference", new ProblemAttributes(JavaCore.COMPILER_PB_RAW_TYPE_REFERENCE));
1418
		expectedProblemAttributes.put("RawTypeReference", new ProblemAttributes(JavaCore.COMPILER_PB_RAW_TYPE_REFERENCE));
(-)src/org/eclipse/jdt/core/tests/compiler/regression/NullAnnotationTest.java (+943 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2010, 2011 GK Software AG and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     Stephan Herrmann - initial API and implementation 
10
 *******************************************************************************/
11
package org.eclipse.jdt.core.tests.compiler.regression;
12
13
import java.util.Map;
14
15
import junit.framework.Test;
16
17
import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
18
19
public class NullAnnotationTest extends AbstractComparableTest {
20
21
public NullAnnotationTest(String name) {
22
	super(name);
23
}
24
25
// Static initializer to specify tests subset using TESTS_* static variables
26
// All specified tests which do not belong to the class are skipped...
27
static {
28
//		TESTS_NAMES = new String[] { "test_parameter_contract_inheritance_" };
29
//		TESTS_NUMBERS = new int[] { 561 };
30
//		TESTS_RANGE = new int[] { 1, 2049 };
31
}
32
33
public static Test suite() {
34
	return buildComparableTestSuite(testClass());
35
}
36
37
public static Class testClass() {
38
	return NullAnnotationTest.class;
39
}
40
41
// Conditionally augment problem detection settings
42
static boolean setNullRelatedOptions = true;
43
protected Map getCompilerOptions() {
44
    Map defaultOptions = super.getCompilerOptions();
45
    if (setNullRelatedOptions) {
46
	    defaultOptions.put(CompilerOptions.OPTION_ReportNullReference, CompilerOptions.ERROR);
47
	    defaultOptions.put(CompilerOptions.OPTION_ReportPotentialNullReference, CompilerOptions.ERROR);
48
	    defaultOptions.put(CompilerOptions.OPTION_ReportRedundantNullCheck, CompilerOptions.ERROR);
49
		defaultOptions.put(CompilerOptions.OPTION_ReportRawTypeReference, CompilerOptions.IGNORE);
50
		defaultOptions.put(CompilerOptions.OPTION_IncludeNullInfoFromAsserts, CompilerOptions.ENABLED);
51
		
52
		defaultOptions.put(CompilerOptions.OPTION_ReportMissingOverrideAnnotationForInterfaceMethodImplementation, CompilerOptions.DISABLED);
53
54
		// enable null annotations:
55
		defaultOptions.put(CompilerOptions.OPTION_EmulateNullAnnotationTypes, CompilerOptions.ENABLED);
56
		defaultOptions.put(CompilerOptions.OPTION_DefaultImportNullAnnotationTypes, CompilerOptions.ENABLED);
57
		// leave other new options at these defaults:
58
//		defaultOptions.put(CompilerOptions.OPTION_ReportNullContractViolation, CompilerOptions.ERROR);
59
//		defaultOptions.put(CompilerOptions.OPTION_ReportPotentialNullContractViolation, CompilerOptions.ERROR);
60
//		defaultOptions.put(CompilerOptions.OPTION_ReportNullContractInsufficientInfo, CompilerOptions.WARNING);
61
		
62
//		defaultOptions.put(CompilerOptions.OPTION_NullableAnnotationName, "org.eclipse.jdt.annotation.Nullable");
63
//		defaultOptions.put(CompilerOptions.OPTION_NonNullAnnotationName, "org.eclipse.jdt.annotation.NonNull");
64
    }
65
    return defaultOptions;
66
}
67
// a nullable argument is dereferenced without a check
68
public void test_nullable_paramter_001() {
69
	runNegativeTest(
70
		new String[] {
71
			"X.java",
72
			  "public class X {\n" +
73
			  "    void foo(@Nullable Object o) {\n" +
74
			  "        System.out.print(o.toString());\n" +
75
			  "    }\n" +
76
			  "}\n"},
77
	    "----------\n" + 
78
		"1. ERROR in X.java (at line 3)\n" + 
79
		"	System.out.print(o.toString());\n" + 
80
		"	                 ^\n" + 
81
		"Potential null pointer access: The variable o may be null at this location\n" + 
82
		"----------\n",
83
	    JavacTestOptions.Excuse.EclipseWarningConfiguredAsError);
84
}
85
86
// a null value is passed to a nullable argument
87
public void test_nullable_paramter_002() {
88
	runConformTest(
89
		new String[] {
90
			"X.java",
91
			  "public class X {\n" +
92
			  "    void foo(@Nullable Object o) {\n" +
93
			  "        // nop\n" +
94
			  "    }\n" +
95
			  "    void bar() {\n" +
96
			  "        foo(null);\n" +
97
			  "    }\n" +
98
			  "}\n"},
99
	    "");
100
}
101
102
// a non-null argument is checked for null
103
public void test_nonnull_parameter_001() {
104
	runNegativeTest(
105
		new String[] {
106
			"X.java",
107
			  "public class X {\n" +
108
			  "    void foo(@NonNull Object o) {\n" +
109
			  "        if (o != null)\n" +
110
			  "              System.out.print(o.toString());\n" +
111
			  "    }\n" +
112
			  "}\n"},
113
	    "----------\n" + 
114
		"1. ERROR in X.java (at line 3)\n" + 
115
		"	if (o != null)\n" + 
116
		"	    ^\n" + 
117
		"Redundant null check: The variable o cannot be null at this location\n" + 
118
		"----------\n",
119
	    JavacTestOptions.Excuse.EclipseWarningConfiguredAsError);
120
}
121
// a non-null argument is dereferenced without a check
122
public void test_nonnull_parameter_002() {
123
	runConformTest(
124
		new String[] {
125
			"X.java",
126
			  "public class X {\n" +
127
			  "    void foo(@NonNull Object o) {\n" +
128
			  "        System.out.print(o.toString());\n" +
129
			  "    }\n" +
130
			  "    public static void main(String... args) {\n" +
131
			  "        new X().foo(\"OK\");\n" +
132
			  "    }\n" +
133
			  "}\n"},
134
	    "OK");
135
}
136
// passing null to nonnull parameter 
137
public void test_nonnull_parameter_003() {
138
	runNegativeTest(
139
		new String[] {
140
			"X.java",
141
			  "public class X {\n" +
142
			  "    void foo(@NonNull Object o) {\n" +
143
			  "        System.out.print(o.toString());\n" +
144
			  "    }\n" +
145
			  "    void bar() {\n" +
146
			  "        foo(null);\n" +
147
			  "    }\n" +
148
			  "}\n"},
149
		"----------\n" + 
150
		"1. ERROR in X.java (at line 6)\n" + 
151
		"	foo(null);\n" + 
152
		"	    ^^^^\n" + 
153
		"Null contract violation: passing null to a parameter declared as @NonNull.\n" + 
154
		"----------\n",
155
	    JavacTestOptions.Excuse.EclipseWarningConfiguredAsError);
156
}
157
// passing potential null to nonnull parameter - target method is consumed from .class
158
public void test_nonnull_parameter_004() {
159
	runConformTest(
160
			new String[] {
161
				"Lib.java",
162
				"public class Lib {\n" +
163
				"    void setObject(@NonNull Object o) { }\n" +
164
				"}\n"
165
			});
166
	runNegativeTest(
167
		false /* flush output directory */,
168
		new String[] {
169
			"X.java",
170
			  "public class X {\n" +
171
			  "    void bar(Lib l, boolean b) {\n" +
172
			  "        Object o = null;\n" +
173
			  "        if (b) o = new Object();\n" +
174
			  "        l.setObject(o);\n" +
175
			  "    }\n" +
176
			  "}\n"},
177
		null /* no class libraries */,
178
		null /* no custom options */,
179
		"----------\n" + 
180
		"1. ERROR in X.java (at line 5)\n" + 
181
		"	l.setObject(o);\n" + 
182
		"	            ^\n" + 
183
		"Null contract violation: potentially passing null to a parameter declared as @NonNull.\n" + 
184
		"----------\n",
185
		"",/* expected output */
186
		"",/* expected error */
187
	    JavacTestOptions.Excuse.EclipseWarningConfiguredAsError);
188
}
189
// passing unknown value to nonnull parameter  - target method is consumed from .class
190
public void test_nonnull_parameter_005() {
191
	runConformTest(
192
			new String[] {
193
				"Lib.java",
194
				"public class Lib {\n" +
195
				"    void setObject(@NonNull Object o) { }\n" +
196
				"}\n"
197
			});
198
	runConformTest(
199
		false /* flush output directory */,
200
		new String[] {
201
			"X.java",
202
			  "public class X {\n" +
203
			  "    void bar(Lib l, Object o) {\n" +
204
			  "        l.setObject(o);\n" +
205
			  "    }\n" +
206
			  "}\n"},
207
		null /* no class libraries */,
208
		null /* no custom options */,
209
		"----------\n" + 
210
		"1. WARNING in X.java (at line 3)\n" + 
211
		"	l.setObject(o);\n" + 
212
		"	            ^\n" + 
213
		"Potential null contract violation: insufficient nullness information regarding a value that is passed to a parameter declared as @NonNull.\n" + 
214
		"----------\n",
215
		"",/* expected output */
216
		"",/* expected error */
217
	    JavacTestOptions.Excuse.EclipseWarningConfiguredAsError);
218
}
219
220
// assigning potential null to a nonnull local variable
221
public void test_nonnull_local_001() {
222
	runNegativeTest(
223
		new String[] {
224
			"X.java",
225
			  "public class X {\n" +
226
			  "    void foo(boolean b, Object p) {\n" +
227
			  "        @NonNull Object o1 = b ? null : new Object();\n" +
228
			  "        @NonNull String o2 = \"\";\n" +
229
			  "        o2 = null;\n" +
230
			  "        @NonNull Object o3 = p;\n" +
231
			  "    }\n" +
232
			  "}\n"},
233
		"----------\n" + 
234
		"1. ERROR in X.java (at line 3)\n" + 
235
		"	@NonNull Object o1 = b ? null : new Object();\n" + 
236
		"	                     ^^^^^^^^^^^^^^^^^^^^^^^\n" + 
237
		"Null contract violation: potentially assigning null to local variable o1, which is declared as @NonNull.\n" + 
238
		"----------\n" + 
239
		"2. ERROR in X.java (at line 5)\n" + 
240
		"	o2 = null;\n" + 
241
		"	     ^^^^\n" + 
242
		"Null contract violation: assigning null to local variable o2, which is declared as @NonNull.\n" + 
243
		"----------\n" + 
244
		"3. WARNING in X.java (at line 6)\n" + 
245
		"	@NonNull Object o3 = p;\n" + 
246
		"	                     ^\n" + 
247
		"Potential null contract violation: insufficient nullness information regarding a value that is assigned to local variable o3, which is declared as @NonNull.\n" + 
248
		"----------\n",
249
	    JavacTestOptions.Excuse.EclipseWarningConfiguredAsError);
250
}
251
252
// a method tries to tighten the null contract, super declares parameter o as @Nullable
253
// other parameters: s is redefined from not constrained to @Nullable which is OK
254
//                   third is redefined from not constrained to @NonNull which is bad, too
255
public void test_parameter_contract_inheritance_001() {
256
	runConformTest(
257
		new String[] {
258
			"Lib.java",
259
			"public class Lib {\n" +
260
			"    void foo(String s, @Nullable Object o, Object third) { }\n" +
261
			"}\n"
262
		});
263
	runNegativeTest(
264
		false /* flush output directory */,
265
		new String[] {
266
			"X.java",
267
			"public class X extends Lib {\n" +
268
			"    @Override\n" +
269
			"    void foo(@Nullable String s, @NonNull Object o, @NonNull Object third) { System.out.print(o.toString()); }\n" +
270
			"}\n"
271
		},
272
		// compiler options
273
		null /* no class libraries */,
274
		null /* no custom options */,
275
		"----------\n" + 
276
		"1. ERROR in X.java (at line 3)\n" + 
277
		"	void foo(@Nullable String s, @NonNull Object o, @NonNull Object third) { System.out.print(o.toString()); }\n" + 
278
		"	                                             ^\n" + 
279
		"Cannot tighten null contract for parameter o, inherited method from Lib declares this parameter as @Nullable.\n" + 
280
		"----------\n" + 
281
		"2. ERROR in X.java (at line 3)\n" + 
282
		"	void foo(@Nullable String s, @NonNull Object o, @NonNull Object third) { System.out.print(o.toString()); }\n" + 
283
		"	                                                                ^^^^^\n" + 
284
		"Cannot tighten null contract for parameter third, inherited method from Lib does not constrain this parameter.\n" + 
285
		"----------\n",
286
		JavacTestOptions.Excuse.EclipseWarningConfiguredAsError);
287
}
288
// a method body fails to handle the inherited null contract, super declares parameter as @Nullable
289
public void test_parameter_contract_inheritance_002() {
290
	runConformTest(
291
		new String[] {
292
			"Lib.java",
293
			"public class Lib {\n" +
294
			"    void foo(@Nullable Object o) { }\n" +
295
			"}\n"
296
		});
297
	runNegativeTest(
298
		false /* flush output directory */,
299
		new String[] {
300
			"X.java",
301
			"public class X extends Lib {\n" +
302
			"    @Override\n" +
303
			"    void foo(Object o) {\n" +
304
			"        System.out.print(o.toString());\n" +
305
			"    }\n" +
306
			"}\n"
307
		},
308
		// compiler options
309
		null /* no class libraries */,
310
		null /* no custom options */,
311
		"----------\n" + 
312
		"1. ERROR in X.java (at line 4)\n" + 
313
		"	System.out.print(o.toString());\n" + 
314
		"	                 ^\n" + 
315
		"Potential null pointer access: The variable o may be null at this location\n" + 
316
		"----------\n",
317
		JavacTestOptions.Excuse.EclipseWarningConfiguredAsError);
318
}
319
// a method relaxes the parameter null contract, super interface declares parameter o as @NonNull
320
// other (first) parameter just repeats the inherited @NonNull
321
public void test_parameter_contract_inheritance_003() {
322
	runConformTest(
323
		new String[] {
324
			"IX.java",
325
			"public interface IX {\n" +
326
			"    void foo(@NonNull String s, @NonNull Object o);\n" +
327
			"}\n",
328
			"X.java",
329
			"public class X implements IX {\n" +
330
			"    public void foo(@NonNull String s, @Nullable Object o) { ; }\n" +
331
			"    void bar() { foo(\"OK\", null); }\n" +
332
			"}\n"
333
		},
334
		"");
335
}
336
// a method adds a @NonNull annotation, super interface has no null annotation
337
// changing other from unconstrained to @Nullable is OK
338
public void test_parameter_contract_inheritance_004() {
339
	runConformTest(
340
		new String[] {
341
			"IX.java",
342
			"public interface IX {\n" +
343
			"    void foo(Object o, Object other);\n" +
344
			"}\n"
345
		});
346
	runNegativeTest(
347
		false /* flush output directory */,
348
		new String[] {
349
			"X.java",
350
			"public class X implements IX {\n" +
351
			"    public void foo(@NonNull Object o, @Nullable Object other) { System.out.print(o.toString()); }\n" +
352
			"}\n"
353
		},
354
		// compiler options
355
		null /* no class libraries */,
356
		null /* no custom options */,
357
		"----------\n" + 
358
		"1. ERROR in X.java (at line 2)\n" + 
359
		"	public void foo(@NonNull Object o, @Nullable Object other) { System.out.print(o.toString()); }\n" + 
360
		"	                                ^\n" + 
361
		"Cannot tighten null contract for parameter o, inherited method from IX does not constrain this parameter.\n" + 
362
		"----------\n",
363
		JavacTestOptions.Excuse.EclipseWarningConfiguredAsError);
364
}
365
// a method tries to relax the null contract, super declares @NonNull return
366
public void test_parameter_contract_inheritance_005() {
367
	runConformTest(
368
		new String[] {
369
			"Lib.java",
370
			"public class Lib {\n" +
371
			"    @NonNull Object getObject() { return new Object(); }\n" +
372
			"}\n"
373
		});
374
	runNegativeTest(
375
		false /* flush output directory */,
376
		new String[] {
377
			"X.java",
378
			"public class X extends Lib {\n" +
379
			"    @Override\n" +
380
			"    @Nullable Object getObject() { return null; }\n" +
381
			"}\n"
382
		},
383
		// compiler options
384
		null /* no class libraries */,
385
		null /* no custom options */,
386
		"----------\n" + 
387
		"1. ERROR in X.java (at line 3)\n" + 
388
		"	@Nullable Object getObject() { return null; }\n" + 
389
		"	                 ^^^^^^^^^^^\n" + 
390
		"Cannot relax null contract for method return, inherited method from Lib is declared as @NonNull.\n" + 
391
		"----------\n",
392
		JavacTestOptions.Excuse.EclipseWarningConfiguredAsError);
393
}
394
395
// super has no contraint for return, sub method confirms the null contract as @Nullable 
396
public void test_parameter_contract_inheritance_006() {
397
	runConformTest(
398
		new String[] {
399
			"Lib.java",
400
			"public class Lib {\n" +
401
			"    Object getObject() { return null; }\n" +
402
			"}\n"
403
		});
404
	runConformTest(
405
		new String[] {
406
			"X.java",
407
			"public class X extends Lib {\n" +
408
			"    @Override\n" +
409
			"    @Nullable Object getObject() { return null; }\n" +
410
			"}\n"
411
		},
412
		"",
413
		null/*classLibs*/,
414
		false /* flush output directory */,
415
		null/*vmArguments*/,
416
		null/*customOptions*/,
417
		null/*compilerRequestor*/);
418
}
419
// a method body violates the inherited null contract, super declares @NonNull return
420
public void test_parameter_contract_inheritance_007() {
421
	runConformTest(
422
		new String[] {
423
			"Lib.java",
424
			"public class Lib {\n" +
425
			"    @NonNull Object getObject() { return new Object(); }\n" +
426
			"}\n"
427
		});
428
	runNegativeTest(
429
		false /* flush output directory */,
430
		new String[] {
431
			"X.java",
432
			"public class X extends Lib {\n" +
433
			"    @Override\n" +
434
			"    Object getObject() { return null; }\n" +
435
			"}\n"
436
		},
437
		// compiler options
438
		null /* no class libraries */,
439
		null /* no custom options */,
440
		"----------\n" + 
441
		"1. ERROR in X.java (at line 3)\n" + 
442
		"	Object getObject() { return null; }\n" + 
443
		"	                     ^^^^^^^^^^^^\n" + 
444
		"Null contract violation: returning null from a method declared as @NonNull.\n" + 
445
		"----------\n",
446
		JavacTestOptions.Excuse.EclipseWarningConfiguredAsError);
447
}
448
// a client potentially violates the inherited null contract, super interface declares @NonNull parameter
449
public void test_parameter_contract_inheritance_008() {
450
	Map options = getCompilerOptions();
451
	options.put(CompilerOptions.OPTION_ReportNullContractInsufficientInfo, CompilerOptions.ERROR);
452
	runConformTest(
453
		new String[] {
454
			"IX.java",
455
			"public interface IX {\n" +
456
			"    void printObject(@NonNull Object o);\n" +
457
			"}\n"
458
		});
459
	runNegativeTest(
460
		false /* flush output directory */,
461
		new String[] {
462
			"X.java",
463
			"public class X implements IX {\n" +
464
			"    public void printObject(Object o) { System.out.print(o.toString()); }\n" +
465
			"}\n",
466
			"M.java",
467
			"public class M{\n" +
468
			"    void foo(X x, Object o) {\n" +
469
			"        x.printObject(o);\n" +
470
			"    }\n" +
471
			"}\n"
472
		},
473
		// compiler options
474
		null /* no class libraries */,
475
		options,
476
		"----------\n" + 
477
		"1. ERROR in M.java (at line 3)\n" + 
478
		"	x.printObject(o);\n" + 
479
		"	              ^\n" + 
480
		"Potential null contract violation: insufficient nullness information regarding a value that is passed to a parameter declared as @NonNull.\n" + 
481
		"----------\n",
482
		JavacTestOptions.Excuse.EclipseWarningConfiguredAsError);
483
}
484
// a static method has a more relaxed null contract than a like method in the super class, but no overriding.
485
public void test_parameter_contract_inheritance_009() {
486
	runConformTest(
487
		new String[] {
488
			"Lib.java",
489
			"public class Lib {\n" +
490
			"    @NonNull static Object getObject() { return new Object(); }\n" +
491
			"}\n",
492
			"X.java",
493
			"public class X extends Lib {\n" +
494
			"    @Nullable static Object getObject() { return null; }\n" +
495
			"}\n"
496
		},
497
		"");
498
}
499
// a nullable return value is dereferenced without a check
500
public void test_nullable_return_001() {
501
	runNegativeTest(
502
		new String[] {
503
			"X.java",
504
			"public class X {\n" +
505
			"    @Nullable Object getObject() { return null; }\n" +
506
			"    void foo() {\n" +
507
			"        Object o = getObject();\n" +
508
			"        System.out.print(o.toString());\n" +
509
			"    }\n" +
510
			"}\n"
511
		},
512
		"----------\n" + 
513
		"1. ERROR in X.java (at line 5)\n" + 
514
		"	System.out.print(o.toString());\n" + 
515
		"	                 ^\n" + 
516
		"Potential null pointer access: The variable o may be null at this location\n" + 
517
		"----------\n",
518
		JavacTestOptions.Excuse.EclipseWarningConfiguredAsError);
519
}
520
// a nullable return value is dereferenced without a check, method is read from .class file
521
public void test_nullable_return_002() {
522
	runConformTest(
523
		new String[] {
524
			"Lib.java",
525
			"public class Lib {\n" +
526
			"    @Nullable Object getObject() { return null; }\n" +
527
			"}\n"
528
		});
529
	runNegativeTest(
530
		false /* flush output directory */,
531
		new String[] {
532
			"X.java",
533
			"public class X {\n" +
534
			"    void foo(Lib l) {\n" +
535
			"        Object o = l.getObject();\n" +
536
			"        System.out.print(o.toString());\n" +
537
			"    }\n" +
538
			"}\n"
539
		},
540
		// compiler options
541
		null /* no class libraries */,
542
		null /* no custom options */,
543
		"----------\n" + 
544
		"1. ERROR in X.java (at line 4)\n" + 
545
		"	System.out.print(o.toString());\n" + 
546
		"	                 ^\n" + 
547
		"Potential null pointer access: The variable o may be null at this location\n" + 
548
		"----------\n",
549
		JavacTestOptions.Excuse.EclipseWarningConfiguredAsError);
550
}
551
// a non-null return value is checked for null, method is read from .class file
552
public void test_nonnull_return_001() {
553
	runConformTest(
554
		new String[] {
555
			"Lib.java",
556
			"public class Lib {\n" +
557
			"    @NonNull Object getObject() { return new Object(); }\n" +
558
			"}\n"
559
		});
560
	runNegativeTest(
561
		false /* flush output directory */,
562
		new String[] {
563
			"X.java",
564
			"public class X {\n" +
565
			"    void foo(Lib l) {\n" +
566
			"        Object o = l.getObject();\n" +
567
			"        if (o != null)\n" +
568
			"            System.out.print(o.toString());\n" +
569
			"    }\n" +
570
			"}\n"
571
		},
572
		// compiler options
573
		null /* no class libraries */,
574
		null /* no custom options */,
575
		"----------\n" + 
576
		"1. ERROR in X.java (at line 4)\n" + 
577
		"	if (o != null)\n" + 
578
		"	    ^\n" + 
579
		"Redundant null check: The variable o cannot be null at this location\n" + 
580
		"----------\n",
581
		JavacTestOptions.Excuse.EclipseWarningConfiguredAsError);
582
}
583
// a non-null method returns null
584
public void test_nonnull_return_003() {
585
	runNegativeTest(
586
		new String[] {
587
			"X.java",
588
			"public class X {\n" +
589
			"    @NonNull Object getObject(boolean b) {\n" +
590
			"        if (b)\n" +
591
			"            return null;\n" + // definite contract violation despite enclosing "if"
592
			"        return new Object();\n" +
593
			"    }\n" +
594
			"}\n"
595
		},
596
		"----------\n" + 
597
		"1. ERROR in X.java (at line 4)\n" + 
598
		"	return null;\n" + 
599
		"	^^^^^^^^^^^^\n" + 
600
		"Null contract violation: returning null from a method declared as @NonNull.\n" + 
601
		"----------\n",
602
		JavacTestOptions.Excuse.EclipseWarningConfiguredAsError);
603
}
604
// a non-null method potentially returns null
605
public void test_nonnull_return_004() {
606
	runNegativeTest(
607
		new String[] {
608
			"X.java",
609
			"public class X {\n" +
610
			"    @NonNull Object getObject(@Nullable Object o) {\n" +
611
			"        return o;\n" + // 'o' is only potentially null
612
			"    }\n" +
613
			"}\n"
614
		},
615
		"----------\n" + 
616
		"1. ERROR in X.java (at line 3)\n" + 
617
		"	return o;\n" + 
618
		"	^^^^^^^^^\n" + 
619
		"Null contract violation: return value can be null but method is declared as @NonNull.\n" + 
620
		"----------\n");
621
}
622
// a non-null method returns its non-null argument
623
public void test_nonnull_return_005() {
624
	Map customOptions = getCompilerOptions();
625
	customOptions.put(CompilerOptions.OPTION_ReportNullReference, CompilerOptions.ERROR);
626
	runConformTest(
627
		new String[] {
628
			"X.java",
629
			"public class X {\n" +
630
			"    @NonNull Object getObject(@NonNull Object o) {\n" +
631
			"        return o;\n" +
632
			"    }\n" +
633
			"}\n"
634
		},
635
		"",
636
		null/*classLibs*/,
637
		true/*shouldFlushOutputDirectory*/,
638
		null/*vmArguments*/,
639
		customOptions,
640
		null/*compilerRequestor*/);
641
}
642
//a non-null method has insufficient nullness info for its return value
643
public void test_nonnull_return_006() {
644
	runNegativeTest(
645
		new String[] {
646
			"X.java",
647
			"public class X {\n" +
648
			"    @NonNull Object getObject(Object o) {\n" +
649
			"        return o;\n" +
650
			"    }\n" +
651
			"}\n"
652
		},
653
		"----------\n" + 
654
		"1. WARNING in X.java (at line 3)\n" + 
655
		"	return o;\n" + 
656
		"	^^^^^^^^^\n" + 
657
		"Potential null contract violation: insufficient nullness information regarding return value while the method is declared as @NonNull.\n" + 
658
		"----------\n");
659
}
660
// mixed use of fully qualified name / explicit import
661
public void test_annotation_import_001() {
662
	Map customOptions = getCompilerOptions();
663
	customOptions.put(CompilerOptions.OPTION_ReportNullReference, CompilerOptions.ERROR);
664
	customOptions.put(CompilerOptions.OPTION_NullableAnnotationName, "org.foo.Nullable");
665
	customOptions.put(CompilerOptions.OPTION_NonNullAnnotationName, "org.foo.NonNull");
666
	customOptions.put(CompilerOptions.OPTION_DefaultImportNullAnnotationTypes, CompilerOptions.DISABLED);
667
	runConformTest(
668
		new String[] {
669
			"Lib.java",
670
			"public class Lib {\n" +
671
			"    @org.foo.NonNull Object getObject() { return new Object(); }\n" + 	// FQN
672
			"}\n",
673
			"X.java",
674
			"import org.foo.NonNull;\n" +											// explicit import
675
			"public class X {\n" +
676
			"    @NonNull Object getObject(@NonNull Lib l) {\n" +
677
			"        return l.getObject();\n" +
678
			"    }\n" +
679
			"}\n"
680
		},
681
		"",
682
		null/*classLibs*/,
683
		true/*shouldFlushOutputDirectory*/,
684
		null/*vmArguments*/,
685
		customOptions,
686
		null/*compilerRequestor*/);
687
}
688
689
// use of explicit imports throughout
690
public void test_annotation_import_002() {
691
	Map customOptions = getCompilerOptions();
692
	customOptions.put(CompilerOptions.OPTION_ReportNullReference, CompilerOptions.ERROR);
693
	customOptions.put(CompilerOptions.OPTION_NullableAnnotationName, "org.foo.Nullable");
694
	customOptions.put(CompilerOptions.OPTION_NonNullAnnotationName, "org.foo.NonNull");
695
	customOptions.put(CompilerOptions.OPTION_DefaultImportNullAnnotationTypes, CompilerOptions.DISABLED);
696
	runConformTest(
697
		new String[] {
698
			"Lib.java",
699
			"import org.foo.NonNull;\n" +
700
			"public class Lib {\n" +
701
			"    @NonNull Object getObject() { return new Object(); }\n" +
702
			"}\n",
703
			"X.java",
704
			"import org.foo.NonNull;\n" +
705
			"public class X {\n" +
706
			"    @NonNull Object getObject(@org.foo.Nullable String dummy, @NonNull Lib l) {\n" +
707
			"        Object o = l.getObject();" +
708
			"        return o;\n" +
709
			"    }\n" +
710
			"}\n"
711
		},
712
		"",
713
		null/*classLibs*/,
714
		true/*shouldFlushOutputDirectory*/,
715
		null/*vmArguments*/,
716
		customOptions,
717
		null/*compilerRequestor*/);
718
}
719
// default import plus explicit ones
720
public void test_annotation_import_003() {
721
	Map customOptions = getCompilerOptions();
722
	customOptions.put(CompilerOptions.OPTION_ReportNullReference, CompilerOptions.ERROR);
723
	customOptions.put(CompilerOptions.OPTION_NullableAnnotationName, "org.foo.Nullable");
724
	customOptions.put(CompilerOptions.OPTION_NonNullAnnotationName, "org.foo.NonNull");
725
	customOptions.put(CompilerOptions.OPTION_DefaultImportNullAnnotationTypes, CompilerOptions.ENABLED);
726
	runConformTest(
727
		new String[] {
728
			"libpack/Lib.java",
729
			"package libpack;\n" +
730
			"public class Lib {\n" +
731
			"    public @NonNull Object getObject() { return new Object(); }\n" +
732
			"}\n",
733
			"X.java",
734
			"import libpack.Lib;\n" +
735
			"public class X {\n" +
736
			"    @NonNull Object getObject(@NonNull Lib l) {\n" +
737
			"        return l.getObject();\n" +
738
			"    }\n" +
739
			"}\n"
740
		},
741
		"",
742
		null/*classLibs*/,
743
		true/*shouldFlushOutputDirectory*/,
744
		null/*vmArguments*/,
745
		customOptions,
746
		null/*compilerRequestor*/);
747
}
748
// default import but unspecified annotation names
749
public void test_annotation_import_004() {
750
	Map customOptions = getCompilerOptions();
751
	customOptions.put(CompilerOptions.OPTION_ReportNullReference, CompilerOptions.ERROR);
752
	customOptions.put(CompilerOptions.OPTION_NullableAnnotationName, null);
753
	customOptions.put(CompilerOptions.OPTION_NonNullAnnotationName, null);
754
	customOptions.put(CompilerOptions.OPTION_DefaultImportNullAnnotationTypes, CompilerOptions.ENABLED);
755
	runConformTest(
756
		new String[] {
757
			"libpack/Lib.java",
758
			"package libpack;\n" +
759
			"public class Lib {\n" +
760
			"    public @NonNull Object getObject() { return new Object(); }\n" +
761
			"}\n",
762
			"X.java",
763
			"import libpack.Lib;\n" +
764
			"public class X {\n" +
765
			"    @NonNull Object getObject(@NonNull Lib l) {\n" +
766
			"        return l.getObject();\n" +
767
			"    }\n" +
768
			"}\n"
769
		},
770
		"",
771
		null/*classLibs*/,
772
		true/*shouldFlushOutputDirectory*/,
773
		null/*vmArguments*/,
774
		customOptions,
775
		null/*compilerRequestor*/);
776
}
777
// default import of existing annotation types
778
public void test_annotation_import_005() {
779
	Map customOptions = getCompilerOptions();
780
	customOptions.put(CompilerOptions.OPTION_ReportNullReference, CompilerOptions.ERROR);
781
	customOptions.put(CompilerOptions.OPTION_ReportNullContractInsufficientInfo, CompilerOptions.ERROR);
782
	customOptions.put(CompilerOptions.OPTION_NullableAnnotationName, "org.foo.MayBeNull");
783
	customOptions.put(CompilerOptions.OPTION_NonNullAnnotationName, "org.foo.MustNotBeNull");
784
	customOptions.put(CompilerOptions.OPTION_DefaultImportNullAnnotationTypes, CompilerOptions.ENABLED);
785
	customOptions.put(CompilerOptions.OPTION_EmulateNullAnnotationTypes, CompilerOptions.DISABLED);
786
	runNegativeTest(
787
		true/*shouldFlushOutputDirectory*/,
788
		new String[] {
789
			"Lib.java",
790
			"public class Lib {\n" +
791
			"    Object getObject() { return new Object(); }\n" +
792
			"}\n",
793
			"X.java",
794
			"public class X {\n" +
795
			"    @MustNotBeNull Object getObject(@MustNotBeNull Lib l) {\n" +
796
			"        return l.getObject();\n" +
797
			"    }\n" +
798
			"}\n",
799
			
800
			"org/foo/MayBeNull.java",
801
			"package org.foo;\n" +
802
			"import java.lang.annotation.*;\n" +
803
			"@Retention(RetentionPolicy.CLASS)\n" +
804
			"public @interface MayBeNull {}\n",
805
			
806
			"org/foo/MustNotBeNull.java",
807
			"package org.foo;\n" +
808
			"import java.lang.annotation.*;\n" +
809
			"@Retention(RetentionPolicy.CLASS)\n" +
810
			"public @interface MustNotBeNull {}\n",
811
		},
812
		null/*classLibs*/,
813
		customOptions,
814
		"----------\n" + 
815
		"1. ERROR in X.java (at line 3)\n" + 
816
		"	return l.getObject();\n" + 
817
		"	^^^^^^^^^^^^^^^^^^^^^\n" + 
818
		"Potential null contract violation: insufficient nullness information regarding return value while the method is declared as @MustNotBeNull.\n" +
819
//		"Potential null contract violation: insufficient nullness information for checking return value against declaration as @MustNotBeNull.\n" + 
820
		"----------\n",
821
		JavacTestOptions.SKIP);
822
}
823
// a non-null method returns a value obtained from an unannotated method, default import of missing annotation types
824
public void test_annotation_import_006() {
825
	Map customOptions = getCompilerOptions();
826
	customOptions.put(CompilerOptions.OPTION_ReportNullReference, CompilerOptions.ERROR);
827
	customOptions.put(CompilerOptions.OPTION_ReportNullContractInsufficientInfo, CompilerOptions.ERROR);
828
	customOptions.put(CompilerOptions.OPTION_NullableAnnotationName, "org.foo.MayBeNull");
829
	customOptions.put(CompilerOptions.OPTION_NonNullAnnotationName, "org.foo.MustNotBeNull");
830
	customOptions.put(CompilerOptions.OPTION_DefaultImportNullAnnotationTypes, CompilerOptions.ENABLED);
831
	customOptions.put(CompilerOptions.OPTION_EmulateNullAnnotationTypes, CompilerOptions.DISABLED);
832
	runNegativeTest(
833
		true/*shouldFlushOutputDirectory*/,
834
		new String[] {
835
			"Lib.java",
836
			"public class Lib {\n" +
837
			"    Object getObject() { return new Object(); }\n" +
838
			"}\n",
839
			"X.java",
840
			"public class X {\n" +
841
			"    @MustNotBeNull Object getObject(@MustNotBeNull Lib l) {\n" +
842
			"        return l.getObject();\n" +
843
			"    }\n" +
844
			"}\n"
845
		},
846
		null/*classLibs*/,
847
		customOptions,
848
		"----------\n" + 
849
		"1. ERROR in Lib.java (at line 0)\n" + 
850
		"	public class Lib {\n" + 
851
		"	^\n" + 
852
		"Buildpath problem: the type org.foo.MayBeNull which is configured as a null annotation type cannot be resolved.\n" + 
853
		"----------\n",
854
		JavacTestOptions.SKIP);
855
}
856
// emulation names conflict with existing types
857
public void test_annotation_emulation_001() {
858
	Map customOptions = getCompilerOptions();
859
	customOptions.put(CompilerOptions.OPTION_ReportNullReference, CompilerOptions.ERROR);
860
	customOptions.put(CompilerOptions.OPTION_NullableAnnotationName, "libpack.Lib");
861
	customOptions.put(CompilerOptions.OPTION_NonNullAnnotationName, "libpack.Lib");
862
	customOptions.put(CompilerOptions.OPTION_DefaultImportNullAnnotationTypes, CompilerOptions.ENABLED);
863
	runNegativeTest(
864
		true/*shouldFlushOutputDirectory*/,
865
		new String[] {
866
			"libpack/Lib.java",
867
			"package libpack;\n" +
868
			"public class Lib {\n" +
869
			"}\n",
870
		},
871
		null/*classLibs*/,
872
		customOptions,
873
		"----------\n" + 
874
		"1. ERROR in libpack\\Lib.java (at line 0)\n" + 
875
		"	package libpack;\n" + 
876
		"	^\n" + 
877
		"Buildpath problem: emulation of type libpack.Lib is requested (for null annotations) but a type of this name exists on the build path.\n" + 
878
		"----------\n",
879
		JavacTestOptions.SKIP);
880
}
881
// regular use (explicit import/FQN) of existing annotation types (=no emulation)
882
public void test_annotation_emulation_002() {
883
	Map customOptions = getCompilerOptions();
884
	customOptions.put(CompilerOptions.OPTION_ReportNullReference, CompilerOptions.ERROR);
885
	customOptions.put(CompilerOptions.OPTION_ReportPotentialNullContractViolation, CompilerOptions.ERROR);
886
	customOptions.put(CompilerOptions.OPTION_NullableAnnotationName, "org.foo.MayBeNull");
887
	customOptions.put(CompilerOptions.OPTION_NonNullAnnotationName, "org.foo.MustNotBeNull");
888
	customOptions.put(CompilerOptions.OPTION_DefaultImportNullAnnotationTypes, CompilerOptions.DISABLED);
889
	customOptions.put(CompilerOptions.OPTION_EmulateNullAnnotationTypes, CompilerOptions.DISABLED);
890
	runNegativeTest(
891
		true/*shouldFlushOutputDirectory*/,
892
		new String[] {
893
			"Lib.java",
894
			"public class Lib {\n" +
895
			"    @org.foo.MayBeNull Object getObject() { return new Object(); }\n" + 	// FQN
896
			"}\n",
897
			"X.java",
898
			"import org.foo.MustNotBeNull;\n" +											// explicit import
899
			"public class X {\n" +
900
			"    @MustNotBeNull Object getObject(@MustNotBeNull Lib l) {\n" +
901
			"        return l.getObject();\n" +
902
			"    }\n" +
903
			"}\n",
904
905
			"org/foo/MayBeNull.java",
906
			"package org.foo;\n" +
907
			"import java.lang.annotation.*;\n" +
908
			"@Retention(RetentionPolicy.CLASS)\n" +
909
			"public @interface MayBeNull {}\n",
910
			
911
			"org/foo/MustNotBeNull.java",
912
			"package org.foo;\n" +
913
			"import java.lang.annotation.*;\n" +
914
			"@Retention(RetentionPolicy.CLASS)\n" +
915
			"public @interface MustNotBeNull {}\n",
916
		},
917
		null/*classLibs*/,
918
		customOptions,
919
		"----------\n" + 
920
		"1. ERROR in X.java (at line 4)\n" + 
921
		"	return l.getObject();\n" + 
922
		"	^^^^^^^^^^^^^^^^^^^^^\n" + 
923
		"Null contract violation: return value can be null but method is declared as @MustNotBeNull.\n" + 
924
		"----------\n",
925
		JavacTestOptions.SKIP);
926
}
927
928
// a default null annotation is illegally used on a class:
929
public void test_illegal_annotation_001() {
930
	runNegativeTest(
931
		new String[] {
932
			"X.java",
933
			"@NonNull public class X {\n" +
934
			"}\n"
935
		},
936
		"----------\n" + 
937
		"1. ERROR in X.java (at line 1)\n" + 
938
		"	@NonNull public class X {\n" + 
939
		"	^^^^^^^^\n" + 
940
		"The annotation @NonNull is disallowed for this location\n" + 
941
		"----------\n");	
942
}
943
}
(-)src/org/eclipse/jdt/core/tests/compiler/regression/TestAll.java (-1 / +3 lines)
Lines 1-5 Link Here
1
/*******************************************************************************
1
/*******************************************************************************
2
 * Copyright (c) 2000, 2010 IBM Corporation and others.
2
 * Copyright (c) 2000, 2011 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
5
 * which accompanies this distribution, and is available at
Lines 7-12 Link Here
7
 *
7
 *
8
 * Contributors:
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
9
 *     IBM Corporation - initial API and implementation
10
 *     Stephan Herrmann  - Contribution for bug 186342 - [compiler][null]Using annotations for null checking
10
 *******************************************************************************/
11
 *******************************************************************************/
11
package org.eclipse.jdt.core.tests.compiler.regression;
12
package org.eclipse.jdt.core.tests.compiler.regression;
12
13
Lines 96-101 Link Here
96
	since_1_5.add(InnerEmulationTest_1_5.class);
97
	since_1_5.add(InnerEmulationTest_1_5.class);
97
	since_1_5.add(AssignmentTest_1_5.class);
98
	since_1_5.add(AssignmentTest_1_5.class);
98
	since_1_5.add(InnerClass15Test.class);
99
	since_1_5.add(InnerClass15Test.class);
100
	since_1_5.add(NullAnnotationTest.class);
99
101
100
	// Tests to run when compliance is greater than 1.5
102
	// Tests to run when compliance is greater than 1.5
101
	ArrayList since_1_6 = new ArrayList();
103
	ArrayList since_1_6 = new ArrayList();

Return to bug 186342