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

Collapse All | Expand All

(-)a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullAnnotationTest.java (-1 / +64 lines)
Lines 1915-1921 Link Here
1915
		"Type mismatch: required \'@NonNull Object\' but the provided value can be null\n" +
1915
		"Type mismatch: required \'@NonNull Object\' but the provided value can be null\n" +
1916
		"----------\n");
1916
		"----------\n");
1917
}
1917
}
1918
// package level default is consumed from package-info.class
1918
// package level default is consumed from package-info.class, similarly for type level default
1919
public void test_default_nullness_003a() {
1919
public void test_default_nullness_003a() {
1920
	Map customOptions = getCompilerOptions();
1920
	Map customOptions = getCompilerOptions();
1921
//	customOptions.put(CompilerOptions.OPTION_ReportPotentialNullSpecViolation, JavaCore.ERROR);
1921
//	customOptions.put(CompilerOptions.OPTION_ReportPotentialNullSpecViolation, JavaCore.ERROR);
Lines 1972-1977 Link Here
1972
		"Type mismatch: required \'@NonNull Object\' but the provided value can be null\n" +
1972
		"Type mismatch: required \'@NonNull Object\' but the provided value can be null\n" +
1973
		"----------\n");
1973
		"----------\n");
1974
}
1974
}
1975
// same as test_default_nullness_003b, but default-induced annotations are combined with explicit ones (not null related)
1976
public void test_default_nullness_003b() {
1977
	Map customOptions = getCompilerOptions();
1978
	runConformTestWithLibs(
1979
		new String[] {
1980
	"p1/Annot.java",
1981
			"package p1;\n" +
1982
			"import static java.lang.annotation.ElementType.*;\n" +
1983
			"import java.lang.annotation.*;\n" +
1984
			"@Retention(RetentionPolicy.CLASS)\n" +
1985
			"@Target({METHOD,PARAMETER})\n" +
1986
			"public @interface Annot {}\n",
1987
	"p1/X.java",
1988
			"package p1;\n" +
1989
			"import org.eclipse.jdt.annotation.*;\n" +
1990
			"@NonNullByDefault\n" +
1991
			"public class X {\n" +
1992
			"    protected @Annot Object getObject(@Annot @Nullable Object o) {\n" +
1993
			"        return new Object();\n" +
1994
			"    }\n" +
1995
			"	 protected @Annot void bar(@Annot Object o2) { }\n" + // parameter is nonnull per type default
1996
			"}\n",
1997
	"p2/package-info.java",
1998
			"@org.eclipse.jdt.annotation.NonNullByDefault\n" +
1999
			"package p2;\n",
2000
			},
2001
			customOptions,
2002
			"");
2003
	// check if default is visible from package-info.class.
2004
	runNegativeTestWithLibs(
2005
		false, // don't flush
2006
		new String[] {
2007
	"p2/Y.java",
2008
			"package p2;\n" +
2009
			"import org.eclipse.jdt.annotation.*;\n" +
2010
			"public class Y extends p1.X {\n" +
2011
			"    @Override\n" +
2012
			"    protected @Nullable Object getObject(@Nullable Object o) {\n" + // can't override inherited default nonnull
2013
			"        bar(o);\n" + // parameter is nonnull in super class's .class file
2014
			"        accept(o);\n" +
2015
			"        return o;\n" +
2016
			"    }\n" +
2017
			"    void accept(@p1.Annot Object a) {}\n" + // governed by package level default
2018
			"}\n"
2019
		},
2020
		customOptions,
2021
		"----------\n" +
2022
		"1. ERROR in p2\\Y.java (at line 5)\n" +
2023
		"	protected @Nullable Object getObject(@Nullable Object o) {\n" +
2024
		"	          ^^^^^^^^^^^^^^^^\n" +
2025
		"The return type is incompatible with the @NonNull return from X.getObject(Object)\n" +
2026
		"----------\n" +
2027
		"2. ERROR in p2\\Y.java (at line 6)\n" +
2028
		"	bar(o);\n" +
2029
		"	    ^\n" +
2030
		"Type mismatch: required \'@NonNull Object\' but the provided value can be null\n" +
2031
		"----------\n" +
2032
		"3. ERROR in p2\\Y.java (at line 7)\n" +
2033
		"	accept(o);\n" +
2034
		"	       ^\n" +
2035
		"Type mismatch: required \'@NonNull Object\' but the provided value can be null\n" +
2036
		"----------\n");
2037
}
1975
// don't apply type-level default to non-reference type
2038
// don't apply type-level default to non-reference type
1976
public void test_default_nullness_004() {
2039
public void test_default_nullness_004() {
1977
	Map customOptions = getCompilerOptions();
2040
	Map customOptions = getCompilerOptions();
(-)a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ClassFile.java (-32 / +83 lines)
Lines 53-58 Link Here
53
import org.eclipse.jdt.internal.compiler.impl.Constant;
53
import org.eclipse.jdt.internal.compiler.impl.Constant;
54
import org.eclipse.jdt.internal.compiler.impl.StringConstant;
54
import org.eclipse.jdt.internal.compiler.impl.StringConstant;
55
import org.eclipse.jdt.internal.compiler.lookup.Binding;
55
import org.eclipse.jdt.internal.compiler.lookup.Binding;
56
import org.eclipse.jdt.internal.compiler.lookup.ExtraCompilerModifiers;
56
import org.eclipse.jdt.internal.compiler.lookup.FieldBinding;
57
import org.eclipse.jdt.internal.compiler.lookup.FieldBinding;
57
import org.eclipse.jdt.internal.compiler.lookup.LocalTypeBinding;
58
import org.eclipse.jdt.internal.compiler.lookup.LocalTypeBinding;
58
import org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding;
59
import org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding;
Lines 324-330 Link Here
324
			if (typeDeclaration != null) {
325
			if (typeDeclaration != null) {
325
				final Annotation[] annotations = typeDeclaration.annotations;
326
				final Annotation[] annotations = typeDeclaration.annotations;
326
				if (annotations != null) {
327
				if (annotations != null) {
327
					attributesNumber += generateRuntimeAnnotations(annotations);
328
					attributesNumber += generateRuntimeAnnotations(annotations, 0);
328
				}
329
				}
329
			}
330
			}
330
		}
331
		}
Lines 413-419 Link Here
413
			if (fieldDeclaration != null) {
414
			if (fieldDeclaration != null) {
414
				Annotation[] annotations = fieldDeclaration.annotations;
415
				Annotation[] annotations = fieldDeclaration.annotations;
415
				if (annotations != null) {
416
				if (annotations != null) {
416
					attributesNumber += generateRuntimeAnnotations(annotations);
417
					attributesNumber += generateRuntimeAnnotations(annotations, 0);
417
				}
418
				}
418
			}
419
			}
419
		}
420
		}
Lines 2683-2690 Link Here
2683
			AbstractMethodDeclaration methodDeclaration = methodBinding.sourceMethod();
2684
			AbstractMethodDeclaration methodDeclaration = methodBinding.sourceMethod();
2684
			if (methodDeclaration != null) {
2685
			if (methodDeclaration != null) {
2685
				Annotation[] annotations = methodDeclaration.annotations;
2686
				Annotation[] annotations = methodDeclaration.annotations;
2686
				if (annotations != null) {
2687
				int modifiers = methodBinding.modifiers;
2687
					attributesNumber += generateRuntimeAnnotations(annotations);
2688
				if (annotations != null || (modifiers & ExtraCompilerModifiers.AccImplicitlyNonNull) != 0) {
2689
					attributesNumber += generateRuntimeAnnotations(annotations, methodBinding.modifiers);
2688
				}
2690
				}
2689
				if ((methodBinding.tagBits & TagBits.HasParameterAnnotations) != 0) {
2691
				if ((methodBinding.tagBits & TagBits.HasParameterAnnotations) != 0) {
2690
					Argument[] arguments = methodDeclaration.arguments;
2692
					Argument[] arguments = methodDeclaration.arguments;
Lines 2868-2890 Link Here
2868
		}
2870
		}
2869
	}
2871
	}
2870
2872
2873
	private int generateNonNullAttribute() {
2874
		TypeBinding nonNullAnnotation;
2875
		try {
2876
			nonNullAnnotation = this.referenceBinding.fPackage.environment.getNullAnnotationBinding(TagBits.AnnotationNonNull, true);
2877
		} catch (NullPointerException npe) {
2878
			return 0; // above chain of dereferencing is quite long, difficult to analyse if all are safe
2879
		}
2880
		int localContentsOffset = this.contentsOffset;
2881
		if (localContentsOffset + 6 >= this.contents.length) {
2882
			resizeContents(6);
2883
		}
2884
		int nonNullAttributeNameIndex = this.constantPool.literalIndex(nonNullAnnotation);
2885
		this.contents[localContentsOffset++] = (byte) (nonNullAttributeNameIndex >> 8);
2886
		this.contents[localContentsOffset++] = (byte) nonNullAttributeNameIndex;
2887
		// the length of a nonNull attribute is equals to 0
2888
		this.contents[localContentsOffset++] = 0;
2889
		this.contents[localContentsOffset++] = 0;
2890
		this.contents[localContentsOffset++] = 0;
2891
		this.contents[localContentsOffset++] = 0;
2892
		this.contentsOffset = localContentsOffset;
2893
		return 1;
2894
	}
2895
2871
	/**
2896
	/**
2872
	 * @param annotations
2897
	 * @param annotations
2898
	 * @param modifiers modifiers that could trigger generating an implicit annotation
2873
	 * @return the number of attributes created while dumping the annotations in the .class file
2899
	 * @return the number of attributes created while dumping the annotations in the .class file
2874
	 */
2900
	 */
2875
	private int generateRuntimeAnnotations(final Annotation[] annotations) {
2901
	private int generateRuntimeAnnotations(final Annotation[] annotations, int modifiers) {
2876
		int attributesNumber = 0;
2902
		int attributesNumber = 0;
2877
		final int length = annotations.length;
2878
		int visibleAnnotationsCounter = 0;
2903
		int visibleAnnotationsCounter = 0;
2879
		int invisibleAnnotationsCounter = 0;
2904
		int invisibleAnnotationsCounter = 0;
2880
2905
		
2881
		for (int i = 0; i < length; i++) {
2906
		if (annotations != null) {
2882
			Annotation annotation = annotations[i];
2907
			final int length = annotations.length;
2883
			if (annotation.isRuntimeInvisible()) {
2908
			for (int i = 0; i < length; i++) {
2884
				invisibleAnnotationsCounter++;
2909
				Annotation annotation = annotations[i];
2885
			} else if (annotation.isRuntimeVisible()) {
2910
				if (annotation.isRuntimeInvisible()) {
2886
				visibleAnnotationsCounter++;
2911
					invisibleAnnotationsCounter++;
2912
				} else if (annotation.isRuntimeVisible()) {
2913
					visibleAnnotationsCounter++;
2914
				}
2887
			}
2915
			}
2916
		}
2917
		boolean isImplicitlyNonNull = (modifiers & ExtraCompilerModifiers.AccImplicitlyNonNull) != 0;
2918
		if (isImplicitlyNonNull) {
2919
			visibleAnnotationsCounter++;
2888
		}
2920
		}
2889
2921
2890
		int annotationAttributeOffset = this.contentsOffset;
2922
		int annotationAttributeOffset = this.contentsOffset;
Lines 2905-2919 Link Here
2905
			this.contentsOffset += 2; // leave space for the annotations length
2937
			this.contentsOffset += 2; // leave space for the annotations length
2906
2938
2907
			int counter = 0;
2939
			int counter = 0;
2908
			loop: for (int i = 0; i < length; i++) {
2940
			if (annotations != null) {
2909
				if (invisibleAnnotationsCounter == 0) break loop;
2941
				final int length = annotations.length;
2910
				Annotation annotation = annotations[i];
2942
				loop: for (int i = 0; i < length; i++) {
2911
				if (annotation.isRuntimeInvisible()) {
2943
					if (invisibleAnnotationsCounter == 0) break loop;
2912
					int currentAnnotationOffset = this.contentsOffset;
2944
					Annotation annotation = annotations[i];
2913
					generateAnnotation(annotation, currentAnnotationOffset);
2945
					if (annotation.isRuntimeInvisible()) {
2914
					invisibleAnnotationsCounter--;
2946
						int currentAnnotationOffset = this.contentsOffset;
2915
					if (this.contentsOffset != currentAnnotationOffset) {
2947
						generateAnnotation(annotation, currentAnnotationOffset);
2916
						counter++;
2948
						invisibleAnnotationsCounter--;
2949
						if (this.contentsOffset != currentAnnotationOffset) {
2950
							counter++;
2951
						}
2917
					}
2952
					}
2918
				}
2953
				}
2919
			}
2954
			}
Lines 2952-2966 Link Here
2952
			this.contentsOffset += 2; // leave space for the annotations length
2987
			this.contentsOffset += 2; // leave space for the annotations length
2953
2988
2954
			int counter = 0;
2989
			int counter = 0;
2955
			loop: for (int i = 0; i < length; i++) {
2990
			if (isImplicitlyNonNull) {
2956
				if (visibleAnnotationsCounter == 0) break loop;
2991
				counter += generateNonNullAttribute();
2957
				Annotation annotation = annotations[i];
2992
				visibleAnnotationsCounter--;
2958
				if (annotation.isRuntimeVisible()) {
2993
			}
2959
					visibleAnnotationsCounter--;
2994
			if (annotations != null) {
2960
					int currentAnnotationOffset = this.contentsOffset;
2995
				final int length = annotations.length;
2961
					generateAnnotation(annotation, currentAnnotationOffset);
2996
				loop: for (int i = 0; i < length; i++) {
2962
					if (this.contentsOffset != currentAnnotationOffset) {
2997
					if (visibleAnnotationsCounter == 0) break loop;
2963
						counter++;
2998
					Annotation annotation = annotations[i];
2999
					if (annotation.isRuntimeVisible()) {
3000
						visibleAnnotationsCounter--;
3001
						int currentAnnotationOffset = this.contentsOffset;
3002
						generateAnnotation(annotation, currentAnnotationOffset);
3003
						if (this.contentsOffset != currentAnnotationOffset) {
3004
							counter++;
3005
						}
2964
					}
3006
					}
2965
				}
3007
				}
2966
			}
3008
			}
Lines 3002-3007 Link Here
3002
						visibleParametersAnnotationsCounter++;
3044
						visibleParametersAnnotationsCounter++;
3003
					}
3045
					}
3004
				}
3046
				}
3047
			}
3048
			if ((argument.binding.modifiers & ExtraCompilerModifiers.AccImplicitlyNonNull) != 0) {
3049
				visibleParametersAnnotationsCounter++;
3005
			}
3050
			}
3006
		}
3051
		}
3007
		int attributesNumber = 0;
3052
		int attributesNumber = 0;
Lines 3085-3097 Link Here
3085
					this.contents[this.contentsOffset++] = (byte) 0;
3130
					this.contents[this.contentsOffset++] = (byte) 0;
3086
					this.contents[this.contentsOffset++] = (byte) 0;
3131
					this.contents[this.contentsOffset++] = (byte) 0;
3087
				} else {
3132
				} else {
3133
					Argument argument = arguments[i];
3088
					final int numberOfVisibleAnnotations = annotationsCounters[i][VISIBLE_INDEX];
3134
					final int numberOfVisibleAnnotations = annotationsCounters[i][VISIBLE_INDEX];
3089
					int visibleAnnotationsOffset = this.contentsOffset;
3135
					int visibleAnnotationsOffset = this.contentsOffset;
3090
					// leave space for number of annotations
3136
					// leave space for number of annotations
3091
					this.contentsOffset += 2;
3137
					this.contentsOffset += 2;
3092
					int counter = 0;
3138
					int counter = 0;
3093
					if (numberOfVisibleAnnotations != 0) {
3139
					if (numberOfVisibleAnnotations != 0) {
3094
						Argument argument = arguments[i];
3095
						Annotation[] annotations = argument.annotations;
3140
						Annotation[] annotations = argument.annotations;
3096
						for (int j = 0, max = annotations.length; j < max; j++) {
3141
						for (int j = 0, max = annotations.length; j < max; j++) {
3097
							Annotation annotation = annotations[j];
3142
							Annotation annotation = annotations[j];
Lines 3106-3111 Link Here
3106
							}
3151
							}
3107
						}
3152
						}
3108
					}
3153
					}
3154
					if ((argument.binding.modifiers & ExtraCompilerModifiers.AccImplicitlyNonNull) != 0) {
3155
						int generated = generateNonNullAttribute();
3156
						counter+=generated;
3157
						globalCounter+=generated;
3158
						visibleParametersAnnotationsCounter--;
3159
					}
3109
					this.contents[visibleAnnotationsOffset++] = (byte) (counter >> 8);
3160
					this.contents[visibleAnnotationsOffset++] = (byte) (counter >> 8);
3110
					this.contents[visibleAnnotationsOffset] = (byte) counter;
3161
					this.contents[visibleAnnotationsOffset] = (byte) counter;
3111
				}
3162
				}
(-)a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ASTNode.java (-2 lines)
Lines 256-263 Link Here
256
	// this is only used for method invocation as the expression inside an expression statement
256
	// this is only used for method invocation as the expression inside an expression statement
257
	public static final int InsideExpressionStatement = Bit5;
257
	public static final int InsideExpressionStatement = Bit5;
258
258
259
	// for annotation reference, signal if annotation was created from a default:
260
	public static final int IsSynthetic = ASTNode.Bit7;
261
	// for name reference within a memberValuePair of an annotation:
259
	// for name reference within a memberValuePair of an annotation:
262
	public static final int IsMemberValueReference = ASTNode.Bit15;
260
	public static final int IsMemberValueReference = ASTNode.Bit15;
263
261
(-)a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AbstractMethodDeclaration.java (-38 lines)
Lines 11-18 Link Here
11
 *******************************************************************************/
11
 *******************************************************************************/
12
package org.eclipse.jdt.internal.compiler.ast;
12
package org.eclipse.jdt.internal.compiler.ast;
13
13
14
import java.util.Arrays;
15
16
import org.eclipse.jdt.core.compiler.*;
14
import org.eclipse.jdt.core.compiler.*;
17
import org.eclipse.jdt.internal.compiler.*;
15
import org.eclipse.jdt.internal.compiler.*;
18
import org.eclipse.jdt.internal.compiler.flow.FlowInfo;
16
import org.eclipse.jdt.internal.compiler.flow.FlowInfo;
Lines 69-110 Link Here
69
			default :
67
			default :
70
				throw new AbortMethod(this.compilationResult, problem);
68
				throw new AbortMethod(this.compilationResult, problem);
71
		}
69
		}
72
	}
73
74
	/**
75
	 * Materialize a null annotation that has been added from the current default,
76
	 * in order to ensure that this annotation will be generated into the .class file, too.
77
	 */
78
	public void addNullnessAnnotation(ReferenceBinding annotationBinding) {
79
		this.annotations = addAnnotation(this, this.annotations, annotationBinding);
80
	}
81
82
	/**
83
	 * Materialize a null parameter annotation that has been added from the current default,
84
	 * in order to ensure that this annotation will be generated into the .class file, too.
85
	 */
86
	public void addParameterNonNullAnnotation(int i, ReferenceBinding annotationBinding) {
87
		Argument argument = this.arguments[i];
88
		if (argument.type != null) // null happens for constructors of anonymous classes
89
			argument.annotations = addAnnotation(argument.type, argument.annotations, annotationBinding);
90
	}
91
92
	private Annotation[] addAnnotation(ASTNode location, Annotation[] oldAnnotations, ReferenceBinding annotationBinding) {
93
		long pos = ((long)location.sourceStart<<32) + location.sourceEnd;
94
		long[] poss = new long[annotationBinding.compoundName.length];
95
		Arrays.fill(poss, pos);
96
		MarkerAnnotation annotation = new MarkerAnnotation(new QualifiedTypeReference(annotationBinding.compoundName, poss), location.sourceStart);
97
		annotation.declarationSourceEnd = location.sourceEnd;
98
		annotation.resolvedType = annotationBinding;
99
		annotation.bits = IsSynthetic;
100
		if (oldAnnotations == null) {
101
			oldAnnotations = new Annotation[] {annotation};
102
		} else {
103
			int len = oldAnnotations.length;
104
			System.arraycopy(oldAnnotations, 0, oldAnnotations=new Annotation[len+1], 1, len);
105
			oldAnnotations[0] = annotation;
106
		}
107
		return oldAnnotations;
108
	}
70
	}
109
71
110
	/**
72
	/**
(-)a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BinaryTypeBinding.java (-4 / +4 lines)
Lines 1218-1224 Link Here
1218
	IBinaryAnnotation[] annotations = binaryType.getAnnotations();
1218
	IBinaryAnnotation[] annotations = binaryType.getAnnotations();
1219
	if (annotations != null) {
1219
	if (annotations != null) {
1220
		long annotationBit = 0L;
1220
		long annotationBit = 0L;
1221
		TypeBinding defaultNullness = null;
1221
		int defaultNullness = NO_NULL_DEFAULT;
1222
		for (int i = 0; i < annotations.length; i++) {
1222
		for (int i = 0; i < annotations.length; i++) {
1223
			char[] annotationTypeName = annotations[i].getTypeName();
1223
			char[] annotationTypeName = annotations[i].getTypeName();
1224
			if (annotationTypeName[0] != Util.C_RESOLVED)
1224
			if (annotationTypeName[0] != Util.C_RESOLVED)
Lines 1233-1251 Link Here
1233
					{
1233
					{
1234
						// parameter is 'false': this means we cancel defaults from outer scopes:
1234
						// parameter is 'false': this means we cancel defaults from outer scopes:
1235
						annotationBit = TagBits.AnnotationNullUnspecifiedByDefault;
1235
						annotationBit = TagBits.AnnotationNullUnspecifiedByDefault;
1236
						defaultNullness = ReferenceBinding.NULL_UNSPECIFIED;
1236
						defaultNullness = NULL_UNSPECIFIED_BY_DEFAULT;
1237
						break;
1237
						break;
1238
					}
1238
					}
1239
				}
1239
				}
1240
				annotationBit = TagBits.AnnotationNonNullByDefault;
1240
				annotationBit = TagBits.AnnotationNonNullByDefault;
1241
				defaultNullness = this.environment.getNullAnnotationBinding(TagBits.AnnotationNonNull, false/*resolve*/);
1241
				defaultNullness = NONNULL_BY_DEFAULT;
1242
				break;
1242
				break;
1243
			}
1243
			}
1244
		}
1244
		}
1245
		if (annotationBit != 0L) {
1245
		if (annotationBit != 0L) {
1246
			this.tagBits |= annotationBit;
1246
			this.tagBits |= annotationBit;
1247
			if (CharOperation.equals(this.sourceName(), TypeConstants.PACKAGE_INFO_NAME))
1247
			if (CharOperation.equals(this.sourceName(), TypeConstants.PACKAGE_INFO_NAME))
1248
				this.getPackage().nullnessDefaultAnnotation = defaultNullness;
1248
				this.getPackage().defaultNullness = defaultNullness;
1249
		}
1249
		}
1250
	}
1250
	}
1251
}
1251
}
(-)a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/Binding.java (+5 lines)
Lines 48-53 Link Here
48
	public static final MethodBinding[] UNINITIALIZED_METHODS = new MethodBinding[0];
48
	public static final MethodBinding[] UNINITIALIZED_METHODS = new MethodBinding[0];
49
	public static final ReferenceBinding[] UNINITIALIZED_REFERENCE_TYPES = new ReferenceBinding[0];
49
	public static final ReferenceBinding[] UNINITIALIZED_REFERENCE_TYPES = new ReferenceBinding[0];
50
50
51
	// Nullness defaults:
52
	public static final int NO_NULL_DEFAULT = 0;
53
	public static final int NULL_UNSPECIFIED_BY_DEFAULT = 1;
54
	public static final int NONNULL_BY_DEFAULT = 2;
55
51
	/*
56
	/*
52
	* Answer the receiver's binding type from Binding.BindingID.
57
	* Answer the receiver's binding type from Binding.BindingID.
53
	*/
58
	*/
(-)a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ExtraCompilerModifiers.java (+1 lines)
Lines 41-44 Link Here
41
	final int AccOverriding = ASTNode.Bit29; // record fact a method overrides another one
41
	final int AccOverriding = ASTNode.Bit29; // record fact a method overrides another one
42
	final int AccImplementing = ASTNode.Bit30; // record fact a method implements another one (it is concrete and overrides an abstract one)
42
	final int AccImplementing = ASTNode.Bit30; // record fact a method implements another one (it is concrete and overrides an abstract one)
43
	final int AccGenericSignature = ASTNode.Bit31; // record fact a type/method/field involves generics in its signature (and need special signature attr)
43
	final int AccGenericSignature = ASTNode.Bit31; // record fact a type/method/field involves generics in its signature (and need special signature attr)
44
	final int AccImplicitlyNonNull = ASTNode.Bit32; // record fact that a method/argument should be seen as NonNull due to an applicable default
44
}
45
}
(-)a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/LookupEnvironment.java (-15 lines)
Lines 1113-1133 Link Here
1113
		return getTypeFromCompoundName(name, false, false);
1113
		return getTypeFromCompoundName(name, false, false);
1114
}
1114
}
1115
1115
1116
/**
1117
 * Inspect the given tag bits and answer a corresponding null annotation type binding
1118
 * @param defaultTagBit tag bits representing the default applicable at the current code location
1119
 * @param resolve should the resulting type binding be resolved?
1120
 * @return the corresponding concrete annotation type binding (<code>@NonNull</code> or <code>@Nullable</code>)
1121
 * 		or <code>null</code> if no bits of a default-annotation are contained in the given tag bits.
1122
 */
1123
public TypeBinding getNullAnnotationBindingFromDefault(long defaultTagBit, boolean resolve) {
1124
	if ((defaultTagBit & TagBits.AnnotationNullUnspecifiedByDefault) != 0)
1125
		return ReferenceBinding.NULL_UNSPECIFIED;
1126
	if ((defaultTagBit & TagBits.AnnotationNonNullByDefault) != 0)
1127
		return getNullAnnotationBinding(TagBits.AnnotationNonNull, resolve);
1128
	return null;
1129
}
1130
1131
TypeBinding getNullAnnotationResolved(TypeBinding nullAnnotation, Scope scope) {
1116
TypeBinding getNullAnnotationResolved(TypeBinding nullAnnotation, Scope scope) {
1132
	// avoid unspecific error "The type in.valid cannot be resolved. It is indirectly referenced from required .class files"
1117
	// avoid unspecific error "The type in.valid cannot be resolved. It is indirectly referenced from required .class files"
1133
	boolean tolerateMissing = this.mayTolerateMissingType;
1118
	boolean tolerateMissing = this.mayTolerateMissingType;
(-)a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodBinding.java (-10 / +5 lines)
Lines 444-478 Link Here
444
}
444
}
445
445
446
/**
446
/**
447
 * After method verifier has finished, fill in missing nullness values from the applicable default.
447
 * After method verifier has finished, fill in missing @NonNull specification from the applicable default.
448
 * @param annotationBinding the null annotation specified to be the default at the current code location.
449
 */
448
 */
450
protected void fillInDefaultNonNullness(TypeBinding annotationBinding) {
449
protected void fillInDefaultNonNullness() {
451
	if (this.parameterNonNullness == null)
450
	if (this.parameterNonNullness == null)
452
		this.parameterNonNullness = new Boolean[this.parameters.length];
451
		this.parameterNonNullness = new Boolean[this.parameters.length];
453
	AbstractMethodDeclaration sourceMethod = sourceMethod();
452
	AbstractMethodDeclaration sourceMethod = sourceMethod();
454
	for (int i = 0; i < this.parameterNonNullness.length; i++) {
453
	for (int i = 0; i < this.parameterNonNullness.length; i++) {
455
		if (this.parameters[i].isBaseType())
454
		if (this.parameters[i].isBaseType())
456
			continue;
455
			continue;
457
		boolean added = false;
458
		if (this.parameterNonNullness[i] == null) {
456
		if (this.parameterNonNullness[i] == null) {
459
			added = true;
460
			this.parameterNonNullness[i] = Boolean.TRUE;
457
			this.parameterNonNullness[i] = Boolean.TRUE;
461
			if (sourceMethod != null)
458
			if (sourceMethod != null)
462
				sourceMethod.addParameterNonNullAnnotation(i, (ReferenceBinding)annotationBinding);
459
				sourceMethod.arguments[i].binding.modifiers |= ExtraCompilerModifiers.AccImplicitlyNonNull; 
460
			this.tagBits |= TagBits.HasParameterAnnotations;
463
		} else if (this.parameterNonNullness[i].booleanValue()) {
461
		} else if (this.parameterNonNullness[i].booleanValue()) {
464
			sourceMethod.scope.problemReporter().nullAnnotationIsRedundant(sourceMethod, i);
462
			sourceMethod.scope.problemReporter().nullAnnotationIsRedundant(sourceMethod, i);
465
		}
463
		}
466
		if (added)
467
			this.tagBits |= TagBits.HasParameterAnnotations;
468
	}
464
	}
469
	if (   this.returnType != null
465
	if (   this.returnType != null
470
		&& !this.returnType.isBaseType()
466
		&& !this.returnType.isBaseType()
471
		&& (this.tagBits & (TagBits.AnnotationNonNull|TagBits.AnnotationNullable)) == 0)
467
		&& (this.tagBits & (TagBits.AnnotationNonNull|TagBits.AnnotationNullable)) == 0)
472
	{
468
	{
473
		this.tagBits |= TagBits.AnnotationNonNull;
469
		this.tagBits |= TagBits.AnnotationNonNull;
474
		if (sourceMethod != null)
470
		this.modifiers |= ExtraCompilerModifiers.AccImplicitlyNonNull;
475
			sourceMethod.addNullnessAnnotation((ReferenceBinding)annotationBinding);
476
	} else if ((this.tagBits & TagBits.AnnotationNonNull) != 0) {
471
	} else if ((this.tagBits & TagBits.AnnotationNonNull) != 0) {
477
		sourceMethod.scope.problemReporter().nullAnnotationIsRedundant(sourceMethod, -1/*signifies method return*/);
472
		sourceMethod.scope.problemReporter().nullAnnotationIsRedundant(sourceMethod, -1/*signifies method return*/);
478
	}
473
	}
(-)a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/PackageBinding.java (-11 / +9 lines)
Lines 24-31 Link Here
24
	HashtableOfType knownTypes;
24
	HashtableOfType knownTypes;
25
	HashtableOfPackage knownPackages;
25
	HashtableOfPackage knownPackages;
26
26
27
	// annotation type binding representing the default that has been defined for this package (using @NonNullByDefault)
27
	// code representing the default that has been defined for this package (using @NonNullByDefault)
28
	protected TypeBinding nullnessDefaultAnnotation;
28
	// one of Binding.{NO_NULL_DEFAULT,NULL_UNSPECIFIED_BY_DEFAULT,NONNULL_BY_DEFAULT}
29
	protected int defaultNullness = NO_NULL_DEFAULT;
29
30
30
protected PackageBinding() {
31
protected PackageBinding() {
31
	// for creating problem package
32
	// for creating problem package
Lines 267-288 Link Here
267
	if (this.environment.nullableAnnotationPackage == this
268
	if (this.environment.nullableAnnotationPackage == this
268
			&& CharOperation.equals(type.compoundName, this.environment.getNullableAnnotationName())) {
269
			&& CharOperation.equals(type.compoundName, this.environment.getNullableAnnotationName())) {
269
		type.id = TypeIds.T_ConfiguredAnnotationNullable;
270
		type.id = TypeIds.T_ConfiguredAnnotationNullable;
270
		this.environment.nullableAnnotationPackage = null; // don't check again
271
		if (!(type instanceof UnresolvedReferenceBinding)) // unresolved type will come back here
272
			this.environment.nullableAnnotationPackage = null; // don't check again
271
	} else if (this.environment.nonnullAnnotationPackage == this
273
	} else if (this.environment.nonnullAnnotationPackage == this
272
			&& CharOperation.equals(type.compoundName, this.environment.getNonNullAnnotationName())) {
274
			&& CharOperation.equals(type.compoundName, this.environment.getNonNullAnnotationName())) {
273
		type.id = TypeIds.T_ConfiguredAnnotationNonNull;
275
		type.id = TypeIds.T_ConfiguredAnnotationNonNull;
274
		this.environment.nonnullAnnotationPackage = null; // don't check again
276
		if (!(type instanceof UnresolvedReferenceBinding)) // unresolved type will come back here
277
			this.environment.nonnullAnnotationPackage = null; // don't check again
275
	} else if (this.environment.nonnullByDefaultAnnotationPackage == this
278
	} else if (this.environment.nonnullByDefaultAnnotationPackage == this
276
			&& CharOperation.equals(type.compoundName, this.environment.getNonNullByDefaultAnnotationName())) {
279
			&& CharOperation.equals(type.compoundName, this.environment.getNonNullByDefaultAnnotationName())) {
277
		type.id = TypeIds.T_ConfiguredAnnotationNonNullByDefault;
280
		type.id = TypeIds.T_ConfiguredAnnotationNonNullByDefault;
278
		this.environment.nonnullByDefaultAnnotationPackage = null; // don't check again
281
		if (!(type instanceof UnresolvedReferenceBinding)) // unresolved type will come back here
282
			this.environment.nonnullByDefaultAnnotationPackage = null; // don't check again
279
	}
283
	}
280
}
281
282
public TypeBinding getNullnessDefaultAnnotation(Scope scope) {
283
	if (this.nullnessDefaultAnnotation instanceof UnresolvedReferenceBinding)
284
		return this.nullnessDefaultAnnotation = this.environment.getNullAnnotationResolved(this.nullnessDefaultAnnotation, scope);
285
	return this.nullnessDefaultAnnotation;
286
}
284
}
287
285
288
public char[] readableName() /*java.lang*/ {
286
public char[] readableName() /*java.lang*/ {
(-)a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ReferenceBinding.java (-8 lines)
Lines 50-63 Link Here
50
		public boolean hasTypeBit(int bit) { return false; }
50
		public boolean hasTypeBit(int bit) { return false; }
51
	};
51
	};
52
52
53
	/**
54
	 * This faked annotation type binding marks types with unspecified nullness.
55
	 * For use in {@link PackageBinding#nullnessDefaultAnnotation} and SourceTypeBinding#nullnessDefaultAnnotation
56
	 */
57
	final static ReferenceBinding NULL_UNSPECIFIED = new ReferenceBinding() { /* faked type binding */
58
		public boolean hasTypeBit(int bit) { return false; }
59
	};
60
61
	private static final Comparator FIELD_COMPARATOR = new Comparator() {
53
	private static final Comparator FIELD_COMPARATOR = new Comparator() {
62
		public int compare(Object o1, Object o2) {
54
		public int compare(Object o1, Object o2) {
63
			char[] n1 = ((FieldBinding) o1).name;
55
			char[] n1 = ((FieldBinding) o1).name;
(-)a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SourceTypeBinding.java (-46 / +43 lines)
Lines 56-62 Link Here
56
56
57
	private SimpleLookupTable storedAnnotations = null; // keys are this ReferenceBinding & its fields and methods, value is an AnnotationHolder
57
	private SimpleLookupTable storedAnnotations = null; // keys are this ReferenceBinding & its fields and methods, value is an AnnotationHolder
58
58
59
	private TypeBinding nullnessDefaultAnnotation;
59
	private int defaultNullness;
60
	private int nullnessDefaultInitialized = 0; // 0: nothing; 1: type; 2: package
60
	private int nullnessDefaultInitialized = 0; // 0: nothing; 1: type; 2: package
61
61
62
public SourceTypeBinding(char[][] compoundName, PackageBinding fPackage, ClassScope scope) {
62
public SourceTypeBinding(char[][] compoundName, PackageBinding fPackage, ClassScope scope) {
Lines 1618-1626 Link Here
1618
	if (methodDecl != null) {
1618
	if (methodDecl != null) {
1619
		if (method.parameters != Binding.NO_PARAMETERS)
1619
		if (method.parameters != Binding.NO_PARAMETERS)
1620
			methodDecl.createArgumentBindings();
1620
			methodDecl.createArgumentBindings();
1621
		TypeBinding annotationBinding = findDefaultNullness(method, methodDecl.scope.environment());
1621
		if (hasNonNullDefault(method, methodDecl.scope.environment())) {
1622
		if (annotationBinding != null && annotationBinding.id == TypeIds.T_ConfiguredAnnotationNonNull)
1622
			method.fillInDefaultNonNullness();
1623
			method.fillInDefaultNonNullness(annotationBinding);
1623
		}
1624
	}
1624
	}
1625
}
1625
}
1626
private void evaluateNullAnnotations(long annotationTagBits) {
1626
private void evaluateNullAnnotations(long annotationTagBits) {
Lines 1628-1696 Link Here
1628
		return;
1628
		return;
1629
	this.nullnessDefaultInitialized = 1;
1629
	this.nullnessDefaultInitialized = 1;
1630
	// transfer nullness info from tagBits to this.nullnessDefaultAnnotation
1630
	// transfer nullness info from tagBits to this.nullnessDefaultAnnotation
1631
	TypeBinding defaultAnnotation = getPackage().environment
1631
	int newDefaultNullness = NO_NULL_DEFAULT;
1632
						.getNullAnnotationBindingFromDefault(annotationTagBits, false/*resolve*/);
1632
	if ((annotationTagBits & TagBits.AnnotationNullUnspecifiedByDefault) != 0)
1633
	if (defaultAnnotation != null) {
1633
		newDefaultNullness = NULL_UNSPECIFIED_BY_DEFAULT;
1634
	else if ((annotationTagBits & TagBits.AnnotationNonNullByDefault) != 0)
1635
		newDefaultNullness = NONNULL_BY_DEFAULT;
1636
	if (newDefaultNullness != NO_NULL_DEFAULT) {
1634
		if (CharOperation.equals(this.sourceName, TypeConstants.PACKAGE_INFO_NAME)) {
1637
		if (CharOperation.equals(this.sourceName, TypeConstants.PACKAGE_INFO_NAME)) {
1635
			getPackage().nullnessDefaultAnnotation = defaultAnnotation;
1638
			getPackage().defaultNullness = newDefaultNullness;
1636
		} else {
1639
		} else {
1637
			this.nullnessDefaultAnnotation = defaultAnnotation;
1640
			this.defaultNullness = newDefaultNullness;
1638
		}
1641
		}
1639
	}
1642
	}
1640
}
1643
}
1641
private TypeBinding getNullnessDefaultAnnotation() {
1642
	if (this.nullnessDefaultAnnotation instanceof UnresolvedReferenceBinding)
1643
		this.nullnessDefaultAnnotation = this.scope.environment().getNullAnnotationResolved(this.nullnessDefaultAnnotation, this.scope);
1644
	return this.nullnessDefaultAnnotation;
1645
}
1646
/**
1644
/**
1647
 * Answer the nullness default applicable at the given method binding.
1645
 * Answer whether the given method binding is subject to a @NonNull default
1648
 * Possible values:<ul>
1649
 * <li>the type binding for @NonNulByDefault</li>
1650
 * <li>the synthetic type {@link ReferenceBinding#NULL_UNSPECIFIED} if a default from outer scope has been canceled</li>
1651
 * <li>null if no default has been defined</li>
1652
 * </ul>
1653
 */
1646
 */
1654
private TypeBinding findDefaultNullness(MethodBinding methodBinding, LookupEnvironment environment) {
1647
private boolean hasNonNullDefault(MethodBinding methodBinding, LookupEnvironment environment) {
1648
	int foundDefaultNullness = findNonNullDefault(methodBinding, environment);
1649
	if (foundDefaultNullness == NONNULL_BY_DEFAULT) {
1650
		// requesting implicit use of @NonNull, check if the annotation type is present:
1651
		if (environment.getNullAnnotationBinding(TagBits.AnnotationNonNull, true) == null) {
1652
			this.scope.problemReporter().missingNullAnnotationType(environment.getNonNullAnnotationName());
1653
			environment.globalOptions.defaultNonNullness = 0;
1654
			return false;
1655
		}
1656
		return true;
1657
	}
1658
	return false;
1659
}
1660
private int findNonNullDefault(MethodBinding methodBinding, LookupEnvironment environment) {
1655
	// find the applicable default inside->out:
1661
	// find the applicable default inside->out:
1656
1662
1657
	// method
1663
	// method
1658
	TypeBinding annotationBinding = environment.getNullAnnotationBindingFromDefault(methodBinding.tagBits, true/*resolve*/);
1664
	if ((methodBinding.tagBits & TagBits.AnnotationNonNullByDefault) != 0)
1659
	if (annotationBinding != null)
1665
		return NONNULL_BY_DEFAULT;
1660
		return annotationBinding;
1666
	if ((methodBinding.tagBits & TagBits.AnnotationNullUnspecifiedByDefault) != 0)
1667
		return NULL_UNSPECIFIED_BY_DEFAULT;
1661
1668
1662
	// type
1669
	// type
1663
	ReferenceBinding type = methodBinding.declaringClass;
1670
	ReferenceBinding type = methodBinding.declaringClass;
1664
	ReferenceBinding currentType = type;
1671
	ReferenceBinding currentType = type;
1672
	int foundDefaultNullness = NO_NULL_DEFAULT;
1665
	while (currentType instanceof SourceTypeBinding) {
1673
	while (currentType instanceof SourceTypeBinding) {
1666
		annotationBinding = ((SourceTypeBinding) currentType).getNullnessDefaultAnnotation();
1674
		foundDefaultNullness = ((SourceTypeBinding)currentType).defaultNullness;
1667
		if (annotationBinding != null)
1675
		if (foundDefaultNullness != NO_NULL_DEFAULT) {
1668
			return annotationBinding;
1676
			return foundDefaultNullness;
1677
		}
1669
		currentType = currentType.enclosingType();
1678
		currentType = currentType.enclosingType();
1670
	}
1679
	}
1671
1680
1672
	// package
1681
	// package
1673
	annotationBinding = type.getPackage().getNullnessDefaultAnnotation(this.scope);
1682
	foundDefaultNullness = type.getPackage().defaultNullness;
1674
	if (annotationBinding != null)
1683
	if (foundDefaultNullness != NO_NULL_DEFAULT) {
1675
		return annotationBinding;
1684
		return foundDefaultNullness;
1685
	}
1676
1686
1677
	// global
1687
	// global
1678
	long defaultNullness = environment.globalOptions.defaultNonNullness;
1688
	if (environment.globalOptions.defaultNonNullness == TagBits.AnnotationNonNull)
1679
	if (defaultNullness != 0) {
1689
		return NONNULL_BY_DEFAULT;
1680
		// we have a default, so we need an annotation type to record this during compile and in the byte code
1690
	return NO_NULL_DEFAULT;
1681
		annotationBinding = environment.getNullAnnotationBinding(defaultNullness, true/*resolve*/);
1682
		if (annotationBinding != null)
1683
			return annotationBinding;
1684
1685
		// on this branch default was not defined using an annotation, thus annotation type can still be missing
1686
		if (defaultNullness == TagBits.AnnotationNonNull)
1687
			this.scope.problemReporter().missingNullAnnotationType(environment.getNonNullAnnotationName());
1688
		else
1689
			this.scope.problemReporter().abortDueToInternalError("Illegal default nullness value: "+defaultNullness); //$NON-NLS-1$
1690
		// reset default to avoid duplicate errors:
1691
		environment.globalOptions.defaultNonNullness = 0;
1692
	}
1693
	return null;
1694
}
1691
}
1695
1692
1696
public AnnotationHolder retrieveAnnotationHolder(Binding binding, boolean forceInitialization) {
1693
public AnnotationHolder retrieveAnnotationHolder(Binding binding, boolean forceInitialization) {
(-)a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTConverter.java (-19 / +2 lines)
Lines 4361-4367 Link Here
4361
			int indexInAnnotations = 0;
4361
			int indexInAnnotations = 0;
4362
			while ((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF) {
4362
			while ((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF) {
4363
				IExtendedModifier modifier = null;
4363
				IExtendedModifier modifier = null;
4364
				switchToken:
4365
				switch(token) {
4364
				switch(token) {
4366
					case TerminalTokens.TokenNameabstract:
4365
					case TerminalTokens.TokenNameabstract:
4367
						modifier = createModifier(Modifier.ModifierKeyword.ABSTRACT_KEYWORD);
4366
						modifier = createModifier(Modifier.ModifierKeyword.ABSTRACT_KEYWORD);
Lines 4399-4411 Link Here
4399
					case TerminalTokens.TokenNameAT :
4398
					case TerminalTokens.TokenNameAT :
4400
						// we have an annotation
4399
						// we have an annotation
4401
						if (annotations != null && indexInAnnotations < annotations.length) {
4400
						if (annotations != null && indexInAnnotations < annotations.length) {
4402
							// method may have synthetic annotations, skip them:
4401
							org.eclipse.jdt.internal.compiler.ast.Annotation annotation = annotations[indexInAnnotations++];
4403
							org.eclipse.jdt.internal.compiler.ast.Annotation annotation;
4404
							do {
4405
								if (indexInAnnotations == annotations.length)
4406
									break switchToken;
4407
								annotation = annotations[indexInAnnotations++];
4408
							} while ((annotation.bits & org.eclipse.jdt.internal.compiler.ast.ASTNode.IsSynthetic) != 0);
4409
							modifier = convert(annotation);
4402
							modifier = convert(annotation);
4410
							this.scanner.resetTo(annotation.declarationSourceEnd + 1, modifiersEnd);
4403
							this.scanner.resetTo(annotation.declarationSourceEnd + 1, modifiersEnd);
4411
						}
4404
						}
Lines 4519-4525 Link Here
4519
					int token;
4512
					int token;
4520
					while ((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF) {
4513
					while ((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF) {
4521
						IExtendedModifier modifier = null;
4514
						IExtendedModifier modifier = null;
4522
						switchToken:
4523
						switch(token) {
4515
						switch(token) {
4524
							case TerminalTokens.TokenNameabstract:
4516
							case TerminalTokens.TokenNameabstract:
4525
								modifier = createModifier(Modifier.ModifierKeyword.ABSTRACT_KEYWORD);
4517
								modifier = createModifier(Modifier.ModifierKeyword.ABSTRACT_KEYWORD);
Lines 4557-4569 Link Here
4557
							case TerminalTokens.TokenNameAT :
4549
							case TerminalTokens.TokenNameAT :
4558
								// we have an annotation
4550
								// we have an annotation
4559
								if (annotations != null && indexInAnnotations < annotations.length) {
4551
								if (annotations != null && indexInAnnotations < annotations.length) {
4560
									// argument may have synthetic annotations, skip them:
4552
									org.eclipse.jdt.internal.compiler.ast.Annotation annotation = annotations[indexInAnnotations++];
4561
									org.eclipse.jdt.internal.compiler.ast.Annotation annotation;
4562
									do {
4563
										if (indexInAnnotations == annotations.length)
4564
											break switchToken;
4565
										annotation = annotations[indexInAnnotations++];
4566
									} while ((annotation.bits & org.eclipse.jdt.internal.compiler.ast.ASTNode.IsSynthetic) != 0);
4567
									modifier = convert(annotation);
4553
									modifier = convert(annotation);
4568
									this.scanner.resetTo(annotation.declarationSourceEnd + 1, this.compilationUnitSourceLength);
4554
									this.scanner.resetTo(annotation.declarationSourceEnd + 1, this.compilationUnitSourceLength);
4569
								}
4555
								}
Lines 4637-4643 Link Here
4637
							break;
4623
							break;
4638
						case TerminalTokens.TokenNameAT :
4624
						case TerminalTokens.TokenNameAT :
4639
							// we have an annotation
4625
							// we have an annotation
4640
							// (local variable has no synthetic annotations, no need to skip them)
4641
							if (annotations != null && indexInAnnotations < annotations.length) {
4626
							if (annotations != null && indexInAnnotations < annotations.length) {
4642
								org.eclipse.jdt.internal.compiler.ast.Annotation annotation = annotations[indexInAnnotations++];
4627
								org.eclipse.jdt.internal.compiler.ast.Annotation annotation = annotations[indexInAnnotations++];
4643
								modifier = convert(annotation);
4628
								modifier = convert(annotation);
Lines 4740-4746 Link Here
4740
								break;
4725
								break;
4741
							case TerminalTokens.TokenNameAT :
4726
							case TerminalTokens.TokenNameAT :
4742
								// we have an annotation
4727
								// we have an annotation
4743
								// (local variable has no synthetic annotations, no need to skip them)
4744
								if (annotations != null && indexInAnnotations < annotations.length) {
4728
								if (annotations != null && indexInAnnotations < annotations.length) {
4745
									org.eclipse.jdt.internal.compiler.ast.Annotation annotation = annotations[indexInAnnotations++];
4729
									org.eclipse.jdt.internal.compiler.ast.Annotation annotation = annotations[indexInAnnotations++];
4746
									modifier = convert(annotation);
4730
									modifier = convert(annotation);
Lines 4822-4828 Link Here
4822
								break;
4806
								break;
4823
							case TerminalTokens.TokenNameAT :
4807
							case TerminalTokens.TokenNameAT :
4824
								// we have an annotation
4808
								// we have an annotation
4825
								// (local variable has no synthetic annotations, no need to skip them)
4826
								if (annotations != null && indexInAnnotations < annotations.length) {
4809
								if (annotations != null && indexInAnnotations < annotations.length) {
4827
									org.eclipse.jdt.internal.compiler.ast.Annotation annotation = annotations[indexInAnnotations++];
4810
									org.eclipse.jdt.internal.compiler.ast.Annotation annotation = annotations[indexInAnnotations++];
4828
									modifier = convert(annotation);
4811
									modifier = convert(annotation);

Return to bug 186342