Lines 20-25
Link Here
|
20 |
import org.eclipse.jdt.internal.compiler.impl.CompilerOptions; |
20 |
import org.eclipse.jdt.internal.compiler.impl.CompilerOptions; |
21 |
import org.eclipse.jdt.internal.compiler.lookup.ClassScope; |
21 |
import org.eclipse.jdt.internal.compiler.lookup.ClassScope; |
22 |
import org.eclipse.jdt.internal.compiler.lookup.ExtraCompilerModifiers; |
22 |
import org.eclipse.jdt.internal.compiler.lookup.ExtraCompilerModifiers; |
|
|
23 |
import org.eclipse.jdt.internal.compiler.lookup.MethodBinding; |
24 |
import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding; |
23 |
import org.eclipse.jdt.internal.compiler.lookup.TagBits; |
25 |
import org.eclipse.jdt.internal.compiler.lookup.TagBits; |
24 |
import org.eclipse.jdt.internal.compiler.lookup.TypeBinding; |
26 |
import org.eclipse.jdt.internal.compiler.lookup.TypeBinding; |
25 |
import org.eclipse.jdt.internal.compiler.lookup.TypeConstants; |
27 |
import org.eclipse.jdt.internal.compiler.lookup.TypeConstants; |
Lines 67-72
Link Here
|
67 |
if (binding.isAbstract() || binding.isNative()) |
69 |
if (binding.isAbstract() || binding.isNative()) |
68 |
return; |
70 |
return; |
69 |
|
71 |
|
|
|
72 |
boolean[] argumentIsNonNull = null; |
73 |
if (arguments != null) |
74 |
argumentIsNonNull = new boolean[arguments.length]; |
75 |
|
76 |
ReferenceBinding declaringClassRef = binding.declaringClass; |
77 |
|
78 |
if ((returnType.bits & TagBits.IsBaseType) == 0) { |
79 |
|
80 |
ReferenceBinding type = isOverriddenMethodNonNullAnnotated(declaringClassRef, -1, classScope); |
81 |
if (type != null && !isNonNullAnnotated(classScope, binding.getAnnotations())) |
82 |
classScope.problemReporter().nonNullAnnotationIsMissingForOverridingMethod(type, binding, this); |
83 |
} |
84 |
|
85 |
if (arguments != null) { |
86 |
for (int i = 0; i < arguments.length; i++) { |
87 |
ReferenceBinding type = isOverriddenMethodNonNullAnnotated(declaringClassRef, i, classScope); |
88 |
boolean argIsNonNull = isNonNullAnnotated(classScope, binding.getParameterAnnotations(i)); |
89 |
if (type != null && !argIsNonNull) |
90 |
classScope.problemReporter().nonNullAnnotationIsMissingForArgumentInOverridingMethod(type, binding, arguments[i]); |
91 |
|
92 |
argumentIsNonNull[i] = type != null || argIsNonNull; |
93 |
} |
94 |
} |
95 |
|
96 |
if (argumentIsNonNull != null) { |
97 |
for (int i = 0; i < argumentIsNonNull.length; i++) { |
98 |
if (!argumentIsNonNull[i] && isNonNullAnnotated(classScope, binding.getParameterAnnotations(i))) |
99 |
argumentIsNonNull[i] = true; |
100 |
} |
101 |
} |
102 |
|
70 |
ExceptionHandlingFlowContext methodContext = |
103 |
ExceptionHandlingFlowContext methodContext = |
71 |
new ExceptionHandlingFlowContext( |
104 |
new ExceptionHandlingFlowContext( |
72 |
initializationContext, |
105 |
initializationContext, |
Lines 79-84
Link Here
|
79 |
if (this.arguments != null) { |
112 |
if (this.arguments != null) { |
80 |
for (int i = 0, count = this.arguments.length; i < count; i++) { |
113 |
for (int i = 0, count = this.arguments.length; i < count; i++) { |
81 |
flowInfo.markAsDefinitelyAssigned(this.arguments[i].binding); |
114 |
flowInfo.markAsDefinitelyAssigned(this.arguments[i].binding); |
|
|
115 |
if (argumentIsNonNull[i]) |
116 |
flowInfo.markAsDefinitelyNonNull(this.arguments[i].binding); |
82 |
} |
117 |
} |
83 |
} |
118 |
} |
84 |
// propagate to statements |
119 |
// propagate to statements |
Lines 111-116
Link Here
|
111 |
} |
146 |
} |
112 |
} |
147 |
} |
113 |
|
148 |
|
|
|
149 |
|
150 |
/** |
151 |
* Check all the overridden methods (super classes and interfaces) |
152 |
* searching for NonNull annotation. Return the first type which |
153 |
* contains an annotated overridden method. |
154 |
* |
155 |
* @param declaringClassRef the base type |
156 |
* @param argument if positive, search annotations on parameters, else |
157 |
* search on method |
158 |
* @param classScope |
159 |
* @return the type containing the overridden and annotated method |
160 |
* or null |
161 |
*/ |
162 |
public ReferenceBinding isOverriddenMethodNonNullAnnotated(ReferenceBinding declaringClassRef, int argument, ClassScope classScope) { |
163 |
if (declaringClassRef == null) |
164 |
return null; |
165 |
|
166 |
if (binding.isPrivate() || binding.isConstructor()) |
167 |
return null; |
168 |
|
169 |
ReferenceBinding superClassRef = declaringClassRef.superclass(); |
170 |
if (superClassRef != null) { |
171 |
MethodBinding mb = superClassRef.getExactMethod(selector, binding.parameters, classScope.compilationUnitScope()); |
172 |
|
173 |
if (mb != null) { |
174 |
boolean nonNullAnnotated; |
175 |
if (argument < 0) |
176 |
nonNullAnnotated = isNonNullAnnotated(classScope, mb.getAnnotations()); |
177 |
else |
178 |
nonNullAnnotated = isNonNullAnnotated(classScope, mb.getParameterAnnotations(argument)); |
179 |
|
180 |
// if an annotation is found, returns |
181 |
if (nonNullAnnotated) |
182 |
return superClassRef; |
183 |
} else { |
184 |
ReferenceBinding type = isOverriddenMethodNonNullAnnotated(superClassRef, argument, classScope); |
185 |
if (type != null) |
186 |
return type; |
187 |
} |
188 |
} |
189 |
|
190 |
// if an overridden method have been found, but it was not annotated |
191 |
// the check continues through the interfaces |
192 |
|
193 |
ReferenceBinding[] superInterfacesRef = declaringClassRef.superInterfaces(); |
194 |
if (superInterfacesRef != null) { |
195 |
for (int i = 0; i < superInterfacesRef.length; i++) { |
196 |
if (superInterfacesRef[i] != null) { |
197 |
MethodBinding mb = superInterfacesRef[i].getExactMethod(selector, binding.parameters, classScope.compilationUnitScope()); |
198 |
|
199 |
if (mb != null) { |
200 |
boolean nonNullAnnotated; |
201 |
if (argument < 0) |
202 |
nonNullAnnotated = isNonNullAnnotated(classScope, mb.getAnnotations()); |
203 |
else |
204 |
nonNullAnnotated = isNonNullAnnotated(classScope, mb.getParameterAnnotations(argument)); |
205 |
|
206 |
if (nonNullAnnotated) |
207 |
return superInterfacesRef[i]; |
208 |
} else { |
209 |
ReferenceBinding type = isOverriddenMethodNonNullAnnotated(superInterfacesRef[i], argument, classScope); |
210 |
if (type != null) |
211 |
return type; |
212 |
} |
213 |
} |
214 |
} |
215 |
} |
216 |
|
217 |
return null; |
218 |
} |
219 |
|
114 |
public boolean isMethod() { |
220 |
public boolean isMethod() { |
115 |
|
221 |
|
116 |
return true; |
222 |
return true; |