Lines 25-35
Link Here
|
25 |
import org.eclipse.jdt.core.dom.AST; |
25 |
import org.eclipse.jdt.core.dom.AST; |
26 |
import org.eclipse.jdt.core.dom.ASTNode; |
26 |
import org.eclipse.jdt.core.dom.ASTNode; |
27 |
import org.eclipse.jdt.core.dom.Annotation; |
27 |
import org.eclipse.jdt.core.dom.Annotation; |
28 |
import org.eclipse.jdt.core.dom.BodyDeclaration; |
|
|
29 |
import org.eclipse.jdt.core.dom.CompilationUnit; |
28 |
import org.eclipse.jdt.core.dom.CompilationUnit; |
30 |
import org.eclipse.jdt.core.dom.IAnnotationBinding; |
29 |
import org.eclipse.jdt.core.dom.IAnnotationBinding; |
31 |
import org.eclipse.jdt.core.dom.IBinding; |
30 |
import org.eclipse.jdt.core.dom.IBinding; |
32 |
import org.eclipse.jdt.core.dom.IExtendedModifier; |
31 |
import org.eclipse.jdt.core.dom.IExtendedModifier; |
|
|
32 |
import org.eclipse.jdt.core.dom.IMemberValuePairBinding; |
33 |
import org.eclipse.jdt.core.dom.IMethodBinding; |
33 |
import org.eclipse.jdt.core.dom.IMethodBinding; |
34 |
import org.eclipse.jdt.core.dom.ITypeBinding; |
34 |
import org.eclipse.jdt.core.dom.ITypeBinding; |
35 |
import org.eclipse.jdt.core.dom.IVariableBinding; |
35 |
import org.eclipse.jdt.core.dom.IVariableBinding; |
Lines 69-74
Link Here
|
69 |
String fAnnotationToAdd; |
69 |
String fAnnotationToAdd; |
70 |
String fAnnotationToRemove; |
70 |
String fAnnotationToRemove; |
71 |
boolean fAllowRemove; |
71 |
boolean fAllowRemove; |
|
|
72 |
boolean fRemoveIfNonNullByDefault; |
73 |
String fNonNullByDefaultName; |
72 |
CompilationUnit fUnit; |
74 |
CompilationUnit fUnit; |
73 |
protected String fKey; |
75 |
protected String fKey; |
74 |
protected String fMessage; |
76 |
protected String fMessage; |
Lines 104-109
Link Here
|
104 |
return true; |
106 |
return true; |
105 |
} |
107 |
} |
106 |
|
108 |
|
|
|
109 |
/* Is the given element affected by a @NonNullByDefault. */ |
110 |
boolean hasNonNullDefault(IBinding enclosingElement) { |
111 |
if (!fRemoveIfNonNullByDefault) return false; |
112 |
IAnnotationBinding[] annotations = enclosingElement.getAnnotations(); |
113 |
for (int i= 0; i < annotations.length; i++) { |
114 |
IAnnotationBinding annot = annotations[i]; |
115 |
if (annot.getAnnotationType().getQualifiedName().equals(fNonNullByDefaultName)) { |
116 |
IMemberValuePairBinding[] pairs= annot.getDeclaredMemberValuePairs(); |
117 |
if (pairs.length > 0) { |
118 |
// is default cancelled by "false" or "value=false" ? |
119 |
for (int j= 0; j < pairs.length; j++) |
120 |
if (pairs[j].getKey() == null || pairs[j].getKey().equals("value")) //$NON-NLS-1$ |
121 |
return (pairs[j].getValue() != Boolean.FALSE); |
122 |
} |
123 |
return true; |
124 |
} |
125 |
} |
126 |
if (enclosingElement instanceof IMethodBinding) { |
127 |
return hasNonNullDefault(((IMethodBinding)enclosingElement).getDeclaringClass()); |
128 |
} else if (enclosingElement instanceof ITypeBinding) { |
129 |
ITypeBinding typeBinding= (ITypeBinding)enclosingElement; |
130 |
if (typeBinding.isLocal()) |
131 |
return hasNonNullDefault(typeBinding.getDeclaringMethod()); |
132 |
else if (typeBinding.isMember()) |
133 |
return hasNonNullDefault(typeBinding.getDeclaringClass()); |
134 |
else |
135 |
return hasNonNullDefault(typeBinding.getPackage()); |
136 |
} |
137 |
return false; |
138 |
} |
139 |
|
107 |
public String getMessage() { |
140 |
public String getMessage() { |
108 |
return fMessage; |
141 |
return fMessage; |
109 |
} |
142 |
} |
Lines 116-122
Link Here
|
116 |
*/ |
149 |
*/ |
117 |
static class ReturnAnnotationRewriteOperation extends SignatureAnnotationRewriteOperation { |
150 |
static class ReturnAnnotationRewriteOperation extends SignatureAnnotationRewriteOperation { |
118 |
|
151 |
|
119 |
private final BodyDeclaration fBodyDeclaration; |
152 |
private final MethodDeclaration fBodyDeclaration; |
120 |
|
153 |
|
121 |
ReturnAnnotationRewriteOperation(CompilationUnit unit, MethodDeclaration method, String annotationToAdd, String annotationToRemove, boolean allowRemove, String message) { |
154 |
ReturnAnnotationRewriteOperation(CompilationUnit unit, MethodDeclaration method, String annotationToAdd, String annotationToRemove, boolean allowRemove, String message) { |
122 |
fUnit= unit; |
155 |
fUnit= unit; |
Lines 135-140
Link Here
|
135 |
TextEditGroup group= createTextEditGroup(fMessage, cuRewrite); |
168 |
TextEditGroup group= createTextEditGroup(fMessage, cuRewrite); |
136 |
if (!checkExisting(fBodyDeclaration.modifiers(), listRewrite, group)) |
169 |
if (!checkExisting(fBodyDeclaration.modifiers(), listRewrite, group)) |
137 |
return; |
170 |
return; |
|
|
171 |
if (hasNonNullDefault(fBodyDeclaration.resolveBinding())) |
172 |
return; // should be safe, as in this case checkExisting() should've already produced a change (remove existing annotation). |
138 |
Annotation newAnnotation= ast.newMarkerAnnotation(); |
173 |
Annotation newAnnotation= ast.newMarkerAnnotation(); |
139 |
ImportRewrite importRewrite= cuRewrite.getImportRewrite(); |
174 |
ImportRewrite importRewrite= cuRewrite.getImportRewrite(); |
140 |
String resolvableName= importRewrite.addImport(fAnnotationToAdd); |
175 |
String resolvableName= importRewrite.addImport(fAnnotationToAdd); |
Lines 248-254
Link Here
|
248 |
|
283 |
|
249 |
// Entry for QuickFixes: |
284 |
// Entry for QuickFixes: |
250 |
public static SignatureAnnotationRewriteOperation createAddAnnotationOperation(CompilationUnit compilationUnit, IProblemLocation problem, String annotationToAdd, String annotationToRemove, |
285 |
public static SignatureAnnotationRewriteOperation createAddAnnotationOperation(CompilationUnit compilationUnit, IProblemLocation problem, String annotationToAdd, String annotationToRemove, |
251 |
Set<String> handledPositions, boolean thisUnitOnly, boolean allowRemove, ChangeKind changeKind) { |
286 |
Set<String> handledPositions, boolean thisUnitOnly, boolean allowRemove, boolean isArgumentProblem, ChangeKind changeKind) { |
252 |
// precondition: |
287 |
// precondition: |
253 |
// thisUnitOnly => changeKind == LOCAL |
288 |
// thisUnitOnly => changeKind == LOCAL |
254 |
SignatureAnnotationRewriteOperation result; |
289 |
SignatureAnnotationRewriteOperation result; |
Lines 256-262
Link Here
|
256 |
result= createAddAnnotationToOverriddenOperation(compilationUnit, problem, annotationToAdd, annotationToRemove, allowRemove); |
291 |
result= createAddAnnotationToOverriddenOperation(compilationUnit, problem, annotationToAdd, annotationToRemove, allowRemove); |
257 |
else |
292 |
else |
258 |
result= createAddAnnotationOperation(compilationUnit, problem, annotationToAdd, annotationToRemove, changeKind == ChangeKind.TARGET, |
293 |
result= createAddAnnotationOperation(compilationUnit, problem, annotationToAdd, annotationToRemove, changeKind == ChangeKind.TARGET, |
259 |
thisUnitOnly, allowRemove); |
294 |
thisUnitOnly, allowRemove, isArgumentProblem); |
260 |
if (handledPositions != null && result != null) { |
295 |
if (handledPositions != null && result != null) { |
261 |
if (handledPositions.contains(result.getKey())) |
296 |
if (handledPositions.contains(result.getKey())) |
262 |
return null; |
297 |
return null; |
Lines 266-272
Link Here
|
266 |
} |
301 |
} |
267 |
|
302 |
|
268 |
private static SignatureAnnotationRewriteOperation createAddAnnotationOperation(CompilationUnit compilationUnit, IProblemLocation problem, String annotationToAdd, String annotationToRemove, |
303 |
private static SignatureAnnotationRewriteOperation createAddAnnotationOperation(CompilationUnit compilationUnit, IProblemLocation problem, String annotationToAdd, String annotationToRemove, |
269 |
boolean changeTargetMethod, boolean thisUnitOnly, boolean allowRemove) { |
304 |
boolean changeTargetMethod, boolean thisUnitOnly, boolean allowRemove, boolean isArgumentProblem) { |
270 |
ICompilationUnit cu= (ICompilationUnit) compilationUnit.getJavaElement(); |
305 |
ICompilationUnit cu= (ICompilationUnit) compilationUnit.getJavaElement(); |
271 |
if (!JavaModelUtil.is50OrHigher(cu.getJavaProject())) |
306 |
if (!JavaModelUtil.is50OrHigher(cu.getJavaProject())) |
272 |
return null; |
307 |
return null; |
Lines 298-306
Link Here
|
298 |
annotationNameLabel= BasicElementLabels.getJavaElementName(annotationNameLabel); |
333 |
annotationNameLabel= BasicElementLabels.getJavaElementName(annotationNameLabel); |
299 |
|
334 |
|
300 |
if (changeTargetMethod) { |
335 |
if (changeTargetMethod) { |
301 |
if (selectedNode.getParent() instanceof MethodInvocation) { |
336 |
MethodInvocation methodInvocation= null; |
|
|
337 |
if (isArgumentProblem) { |
338 |
if (selectedNode.getParent() instanceof MethodInvocation) |
339 |
methodInvocation= (MethodInvocation) selectedNode.getParent(); |
340 |
} else { |
341 |
if (selectedNode instanceof MethodInvocation) |
342 |
methodInvocation= (MethodInvocation) selectedNode; |
343 |
} |
344 |
if (methodInvocation != null) { |
302 |
// DefiniteNullToNonNullParameter || PotentialNullToNonNullParameter |
345 |
// DefiniteNullToNonNullParameter || PotentialNullToNonNullParameter |
303 |
MethodInvocation methodInvocation= (MethodInvocation) selectedNode.getParent(); |
|
|
304 |
int paramIdx= methodInvocation.arguments().indexOf(selectedNode); |
346 |
int paramIdx= methodInvocation.arguments().indexOf(selectedNode); |
305 |
IMethodBinding methodBinding= methodInvocation.resolveMethodBinding(); |
347 |
IMethodBinding methodBinding= methodInvocation.resolveMethodBinding(); |
306 |
compilationUnit= findCUForMethod(compilationUnit, cu, methodBinding); |
348 |
compilationUnit= findCUForMethod(compilationUnit, cu, methodBinding); |
Lines 311-319
Link Here
|
311 |
ASTNode methodDecl= compilationUnit.findDeclaringNode(methodBinding.getKey()); |
353 |
ASTNode methodDecl= compilationUnit.findDeclaringNode(methodBinding.getKey()); |
312 |
if (methodDecl == null) |
354 |
if (methodDecl == null) |
313 |
return null; |
355 |
return null; |
314 |
String message= Messages.format(FixMessages.NullAnnotationsRewriteOperations_change_target_method_parameter_nullness, |
356 |
if (isArgumentProblem) { |
315 |
new Object[] {methodInvocation.getName(), annotationNameLabel}); |
357 |
String message= Messages.format(FixMessages.NullAnnotationsRewriteOperations_change_target_method_parameter_nullness, |
316 |
return new ParameterAnnotationRewriteOperation(compilationUnit, (MethodDeclaration) methodDecl, annotationToAdd, annotationToRemove, paramIdx, allowRemove, message); |
358 |
new Object[] {methodInvocation.getName(), annotationNameLabel}); |
|
|
359 |
return new ParameterAnnotationRewriteOperation(compilationUnit, (MethodDeclaration) methodDecl, annotationToAdd, annotationToRemove, paramIdx, allowRemove, message); |
360 |
} else { |
361 |
MethodDeclaration declaration = (MethodDeclaration) methodDecl; |
362 |
String message= Messages.format(FixMessages.NullAnnotationsRewriteOperations_change_method_return_nullness, |
363 |
new String[] { declaration.getName().getIdentifier(), annotationNameLabel }); |
364 |
return new ReturnAnnotationRewriteOperation(compilationUnit, declaration, annotationToAdd, annotationToRemove, allowRemove, message); |
365 |
} |
317 |
} |
366 |
} |
318 |
} else if (declaringNode instanceof MethodDeclaration) { |
367 |
} else if (declaringNode instanceof MethodDeclaration) { |
319 |
// complaint is in signature of this method |
368 |
// complaint is in signature of this method |
Lines 325-331
Link Here
|
325 |
case IProblem.IllegalRedefinitionToNonNullParameter: |
374 |
case IProblem.IllegalRedefinitionToNonNullParameter: |
326 |
case IProblem.SpecdNonNullLocalVariableComparisonYieldsFalse: |
375 |
case IProblem.SpecdNonNullLocalVariableComparisonYieldsFalse: |
327 |
case IProblem.RedundantNullCheckOnSpecdNonNullLocalVariable: |
376 |
case IProblem.RedundantNullCheckOnSpecdNonNullLocalVariable: |
328 |
// statements suggest changing parameters: |
377 |
// problems regarding the argument declaration: |
329 |
if (declaration.getNodeType() == ASTNode.METHOD_DECLARATION) { |
378 |
if (declaration.getNodeType() == ASTNode.METHOD_DECLARATION) { |
330 |
String paramName= findAffectedParameterName(selectedNode); |
379 |
String paramName= findAffectedParameterName(selectedNode); |
331 |
if (paramName != null) { |
380 |
if (paramName != null) { |
Lines 341-349
Link Here
|
341 |
case IProblem.RequiredNonNullButProvidedUnknown: |
390 |
case IProblem.RequiredNonNullButProvidedUnknown: |
342 |
case IProblem.ConflictingNullAnnotations: |
391 |
case IProblem.ConflictingNullAnnotations: |
343 |
case IProblem.ConflictingInheritedNullAnnotations: |
392 |
case IProblem.ConflictingInheritedNullAnnotations: |
344 |
if (NullAnnotationsFix.isComplainingAboutArgument(selectedNode)) { |
393 |
if (isArgumentProblem) { |
345 |
//TODO: duplication (consider chaining isArgumentProblem also into this method) |
394 |
// statement suggests changing parameters: |
346 |
// statements suggest changing parameters: |
|
|
347 |
if (declaration.getNodeType() == ASTNode.METHOD_DECLARATION && selectedNode instanceof SimpleName) { |
395 |
if (declaration.getNodeType() == ASTNode.METHOD_DECLARATION && selectedNode instanceof SimpleName) { |
348 |
// don't call findAffectedParameterName(), in this branch we're not interested in any target method |
396 |
// don't call findAffectedParameterName(), in this branch we're not interested in any target method |
349 |
String paramName= ((SimpleName) selectedNode).getIdentifier(); |
397 |
String paramName= ((SimpleName) selectedNode).getIdentifier(); |