KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > internal > ui > text > correction > ModifierCorrectionSubProcessor


1 /*******************************************************************************
2  * Copyright (c) 2000, 2007 IBM Corporation 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  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.jdt.internal.ui.text.correction;
12
13 import java.lang.reflect.InvocationTargetException JavaDoc;
14 import java.util.Collection JavaDoc;
15 import java.util.Hashtable JavaDoc;
16 import java.util.List JavaDoc;
17 import java.util.Map JavaDoc;
18
19 import org.eclipse.text.edits.MultiTextEdit;
20 import org.eclipse.text.edits.ReplaceEdit;
21 import org.eclipse.text.edits.TextEdit;
22
23 import org.eclipse.core.runtime.Assert;
24 import org.eclipse.core.runtime.CoreException;
25 import org.eclipse.core.runtime.IStatus;
26 import org.eclipse.core.runtime.Status;
27
28 import org.eclipse.swt.graphics.Image;
29 import org.eclipse.swt.widgets.Display;
30
31 import org.eclipse.jface.text.BadLocationException;
32 import org.eclipse.jface.text.IDocument;
33 import org.eclipse.jface.text.link.LinkedModeModel;
34 import org.eclipse.jface.text.link.LinkedPosition;
35
36 import org.eclipse.ui.IWorkbenchWindow;
37 import org.eclipse.ui.PlatformUI;
38
39 import org.eclipse.ltk.core.refactoring.RefactoringStatus;
40
41 import org.eclipse.jdt.core.Flags;
42 import org.eclipse.jdt.core.ICompilationUnit;
43 import org.eclipse.jdt.core.IField;
44 import org.eclipse.jdt.core.IJavaElement;
45 import org.eclipse.jdt.core.JavaModelException;
46 import org.eclipse.jdt.core.compiler.IProblem;
47 import org.eclipse.jdt.core.dom.AST;
48 import org.eclipse.jdt.core.dom.ASTNode;
49 import org.eclipse.jdt.core.dom.Annotation;
50 import org.eclipse.jdt.core.dom.Assignment;
51 import org.eclipse.jdt.core.dom.Block;
52 import org.eclipse.jdt.core.dom.CastExpression;
53 import org.eclipse.jdt.core.dom.ClassInstanceCreation;
54 import org.eclipse.jdt.core.dom.CompilationUnit;
55 import org.eclipse.jdt.core.dom.Expression;
56 import org.eclipse.jdt.core.dom.FieldAccess;
57 import org.eclipse.jdt.core.dom.IBinding;
58 import org.eclipse.jdt.core.dom.IMethodBinding;
59 import org.eclipse.jdt.core.dom.ITypeBinding;
60 import org.eclipse.jdt.core.dom.IVariableBinding;
61 import org.eclipse.jdt.core.dom.InfixExpression;
62 import org.eclipse.jdt.core.dom.Javadoc;
63 import org.eclipse.jdt.core.dom.MethodDeclaration;
64 import org.eclipse.jdt.core.dom.MethodInvocation;
65 import org.eclipse.jdt.core.dom.Modifier;
66 import org.eclipse.jdt.core.dom.Name;
67 import org.eclipse.jdt.core.dom.NumberLiteral;
68 import org.eclipse.jdt.core.dom.ParenthesizedExpression;
69 import org.eclipse.jdt.core.dom.PostfixExpression;
70 import org.eclipse.jdt.core.dom.PrefixExpression;
71 import org.eclipse.jdt.core.dom.PrimitiveType;
72 import org.eclipse.jdt.core.dom.QualifiedName;
73 import org.eclipse.jdt.core.dom.ReturnStatement;
74 import org.eclipse.jdt.core.dom.SimpleName;
75 import org.eclipse.jdt.core.dom.SimpleType;
76 import org.eclipse.jdt.core.dom.SuperConstructorInvocation;
77 import org.eclipse.jdt.core.dom.SuperFieldAccess;
78 import org.eclipse.jdt.core.dom.SuperMethodInvocation;
79 import org.eclipse.jdt.core.dom.TagElement;
80 import org.eclipse.jdt.core.dom.Type;
81 import org.eclipse.jdt.core.dom.TypeDeclaration;
82 import org.eclipse.jdt.core.dom.Assignment.Operator;
83 import org.eclipse.jdt.core.dom.Modifier.ModifierKeyword;
84 import org.eclipse.jdt.core.dom.rewrite.ASTRewrite;
85 import org.eclipse.jdt.core.formatter.IndentManipulation;
86
87 import org.eclipse.jdt.internal.corext.codemanipulation.GetterSetterUtil;
88 import org.eclipse.jdt.internal.corext.dom.ASTNodeFactory;
89 import org.eclipse.jdt.internal.corext.dom.ASTNodes;
90 import org.eclipse.jdt.internal.corext.dom.Bindings;
91 import org.eclipse.jdt.internal.corext.fix.CleanUpConstants;
92 import org.eclipse.jdt.internal.corext.fix.IFix;
93 import org.eclipse.jdt.internal.corext.fix.Java50Fix;
94 import org.eclipse.jdt.internal.corext.fix.LinkedProposalModel;
95 import org.eclipse.jdt.internal.corext.fix.LinkedProposalPositionGroup;
96 import org.eclipse.jdt.internal.corext.refactoring.RefactoringAvailabilityTester;
97 import org.eclipse.jdt.internal.corext.refactoring.sef.SelfEncapsulateFieldRefactoring;
98 import org.eclipse.jdt.internal.corext.util.JavaModelUtil;
99 import org.eclipse.jdt.internal.corext.util.JdtFlags;
100 import org.eclipse.jdt.internal.corext.util.Messages;
101
102 import org.eclipse.jdt.ui.JavaUI;
103 import org.eclipse.jdt.ui.text.java.IInvocationContext;
104 import org.eclipse.jdt.ui.text.java.IProblemLocation;
105
106 import org.eclipse.jdt.internal.ui.JavaPlugin;
107 import org.eclipse.jdt.internal.ui.JavaPluginImages;
108 import org.eclipse.jdt.internal.ui.fix.Java50CleanUp;
109 import org.eclipse.jdt.internal.ui.refactoring.RefactoringExecutionHelper;
110 import org.eclipse.jdt.internal.ui.refactoring.RefactoringSaveHelper;
111 import org.eclipse.jdt.internal.ui.refactoring.actions.RefactoringStarter;
112 import org.eclipse.jdt.internal.ui.refactoring.sef.SelfEncapsulateFieldWizard;
113 import org.eclipse.jdt.internal.ui.util.ExceptionHandler;
114
115 /**
116   */

117 public class ModifierCorrectionSubProcessor {
118
119
120     public static final int TO_STATIC= 1;
121     public static final int TO_VISIBLE= 2;
122     public static final int TO_NON_PRIVATE= 3;
123     public static final int TO_NON_STATIC= 4;
124     public static final int TO_NON_FINAL= 5;
125
126     public static void addNonAccessibleReferenceProposal(IInvocationContext context, IProblemLocation problem, Collection JavaDoc proposals, int kind, int relevance) throws CoreException {
127         ICompilationUnit cu= context.getCompilationUnit();
128
129         ASTNode selectedNode= problem.getCoveringNode(context.getASTRoot());
130         if (selectedNode == null) {
131             return;
132         }
133
134         IBinding binding=null;
135         switch (selectedNode.getNodeType()) {
136             case ASTNode.SIMPLE_NAME:
137                 binding= ((SimpleName) selectedNode).resolveBinding();
138                 break;
139             case ASTNode.QUALIFIED_NAME:
140                 binding= ((QualifiedName) selectedNode).resolveBinding();
141                 break;
142             case ASTNode.SIMPLE_TYPE:
143                 binding= ((SimpleType) selectedNode).resolveBinding();
144                 break;
145             case ASTNode.METHOD_INVOCATION:
146                 binding= ((MethodInvocation) selectedNode).getName().resolveBinding();
147                 break;
148             case ASTNode.SUPER_METHOD_INVOCATION:
149                 binding= ((SuperMethodInvocation) selectedNode).getName().resolveBinding();
150                 break;
151             case ASTNode.FIELD_ACCESS:
152                 binding= ((FieldAccess) selectedNode).getName().resolveBinding();
153                 break;
154             case ASTNode.SUPER_FIELD_ACCESS:
155                 binding= ((SuperFieldAccess) selectedNode).getName().resolveBinding();
156                 break;
157             case ASTNode.CLASS_INSTANCE_CREATION:
158                 binding= ((ClassInstanceCreation) selectedNode).resolveConstructorBinding();
159                 break;
160             case ASTNode.SUPER_CONSTRUCTOR_INVOCATION:
161                 binding= ((SuperConstructorInvocation) selectedNode).resolveConstructorBinding();
162                 break;
163             default:
164                 return;
165         }
166         ITypeBinding typeBinding= null;
167         String JavaDoc name;
168         IBinding bindingDecl;
169         boolean isLocalVar= false;
170         if (binding instanceof IMethodBinding) {
171             IMethodBinding methodDecl= (IMethodBinding) binding;
172             bindingDecl= methodDecl.getMethodDeclaration();
173             typeBinding= methodDecl.getDeclaringClass();
174             name= methodDecl.getName() + "()"; //$NON-NLS-1$
175
} else if (binding instanceof IVariableBinding) {
176             IVariableBinding varDecl= (IVariableBinding) binding;
177             typeBinding= varDecl.getDeclaringClass();
178             name= binding.getName();
179             isLocalVar= !varDecl.isField();
180             bindingDecl= varDecl.getVariableDeclaration();
181         } else if (binding instanceof ITypeBinding) {
182             typeBinding= (ITypeBinding) binding;
183             bindingDecl= typeBinding.getTypeDeclaration();
184             name= binding.getName();
185         } else {
186             return;
187         }
188         if (typeBinding != null && typeBinding.isFromSource() || isLocalVar) {
189             int includedModifiers= 0;
190             int excludedModifiers= 0;
191             String JavaDoc label;
192             switch (kind) {
193                 case TO_VISIBLE:
194                     excludedModifiers= Modifier.PRIVATE | Modifier.PROTECTED | Modifier.PUBLIC;
195                     includedModifiers= getNeededVisibility(selectedNode, typeBinding);
196                     label= Messages.format(CorrectionMessages.ModifierCorrectionSubProcessor_changevisibility_description, new String JavaDoc[] { name, getVisibilityString(includedModifiers) });
197                     break;
198                 case TO_STATIC:
199                     label= Messages.format(CorrectionMessages.ModifierCorrectionSubProcessor_changemodifiertostatic_description, name);
200                     includedModifiers= Modifier.STATIC;
201                     break;
202                 case TO_NON_STATIC:
203                     label= Messages.format(CorrectionMessages.ModifierCorrectionSubProcessor_changemodifiertononstatic_description, name);
204                     excludedModifiers= Modifier.STATIC;
205                     break;
206                 case TO_NON_PRIVATE:
207                     label= Messages.format(CorrectionMessages.ModifierCorrectionSubProcessor_changemodifiertodefault_description, name);
208                     excludedModifiers= Modifier.PRIVATE;
209                     break;
210                 case TO_NON_FINAL:
211                     label= Messages.format(CorrectionMessages.ModifierCorrectionSubProcessor_changemodifiertononfinal_description, name);
212                     excludedModifiers= Modifier.FINAL;
213                     break;
214                 default:
215                     throw new IllegalArgumentException JavaDoc("not supported"); //$NON-NLS-1$
216
}
217             ICompilationUnit targetCU= isLocalVar ? cu : ASTResolving.findCompilationUnitForBinding(cu, context.getASTRoot(), typeBinding.getTypeDeclaration());
218             if (targetCU != null) {
219                 Image image= JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_CHANGE);
220                 proposals.add(new ModifierChangeCompletionProposal(label, targetCU, bindingDecl, selectedNode, includedModifiers, excludedModifiers, relevance, image));
221             }
222         }
223         if (kind == TO_VISIBLE && bindingDecl.getKind() == IBinding.VARIABLE) {
224             UnresolvedElementsSubProcessor.getVariableProposals(context, problem, (IVariableBinding) bindingDecl, proposals);
225         }
226     }
227
228     public static void addChangeOverriddenModfierProposal(IInvocationContext context, IProblemLocation problem, Collection JavaDoc proposals, int kind) throws JavaModelException {
229         ICompilationUnit cu= context.getCompilationUnit();
230
231         ASTNode selectedNode= problem.getCoveringNode(context.getASTRoot());
232         if (!(selectedNode instanceof MethodDeclaration)) {
233             return;
234         }
235
236         IMethodBinding method= ((MethodDeclaration) selectedNode).resolveBinding();
237         ITypeBinding curr= method.getDeclaringClass();
238
239
240         if (kind == TO_VISIBLE && problem.getProblemId() != IProblem.OverridingNonVisibleMethod) {
241             IMethodBinding defining= Bindings.findOverriddenMethod(method, false);
242             if (defining != null) {
243                 int excludedModifiers= Modifier.PRIVATE | Modifier.PROTECTED | Modifier.PUBLIC;
244                 int includedModifiers= JdtFlags.getVisibilityCode(defining);
245                 String JavaDoc label= Messages.format(CorrectionMessages.ModifierCorrectionSubProcessor_changemethodvisibility_description, new String JavaDoc[] { getVisibilityString(includedModifiers) });
246                 Image image= JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_CHANGE);
247                 proposals.add(new ModifierChangeCompletionProposal(label, cu, method, selectedNode, includedModifiers, excludedModifiers, 8, image));
248             }
249         }
250
251         IMethodBinding overriddenInClass= null;
252         while (overriddenInClass == null && curr.getSuperclass() != null) {
253             curr= curr.getSuperclass();
254             overriddenInClass= Bindings.findOverriddenMethodInType(curr, method);
255         }
256         if (overriddenInClass != null) {
257             IMethodBinding overriddenDecl= overriddenInClass.getMethodDeclaration();
258             ICompilationUnit targetCU= ASTResolving.findCompilationUnitForBinding(cu, context.getASTRoot(), overriddenDecl.getDeclaringClass());
259             if (targetCU != null) {
260                 String JavaDoc methodName= curr.getName() + '.' + overriddenInClass.getName();
261                 String JavaDoc label;
262                 int excludedModifiers;
263                 int includedModifiers;
264                 switch (kind) {
265                     case TO_VISIBLE:
266                         excludedModifiers= Modifier.PRIVATE | Modifier.PROTECTED | Modifier.PUBLIC;
267                         includedModifiers= JdtFlags.getVisibilityCode(method);
268                         label= Messages.format(CorrectionMessages.ModifierCorrectionSubProcessor_changeoverriddenvisibility_description, new String JavaDoc[] { methodName, getVisibilityString(includedModifiers) });
269                         break;
270                     case TO_NON_FINAL:
271                         label= Messages.format(CorrectionMessages.ModifierCorrectionSubProcessor_changemethodtononfinal_description, methodName);
272                         excludedModifiers= Modifier.FINAL;
273                         includedModifiers= 0;
274                         break;
275                     case TO_NON_STATIC:
276                         label= Messages.format(CorrectionMessages.ModifierCorrectionSubProcessor_changemethodtononstatic_description, methodName);
277                         excludedModifiers= Modifier.STATIC;
278                         includedModifiers= 0;
279                         break;
280                     default:
281                         Assert.isTrue(false, "not supported"); //$NON-NLS-1$
282
return;
283                 }
284                 Image image= JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_CHANGE);
285                 proposals.add(new ModifierChangeCompletionProposal(label, targetCU, overriddenDecl, selectedNode, includedModifiers, excludedModifiers, 7, image));
286             }
287         }
288     }
289
290     public static void addNonFinalLocalProposal(IInvocationContext context, IProblemLocation problem, Collection JavaDoc proposals) {
291         ICompilationUnit cu= context.getCompilationUnit();
292
293         ASTNode selectedNode= problem.getCoveringNode(context.getASTRoot());
294         if (!(selectedNode instanceof SimpleName)) {
295             return;
296         }
297
298         IBinding binding= ((SimpleName) selectedNode).resolveBinding();
299         if (binding instanceof IVariableBinding) {
300             binding= ((IVariableBinding) binding).getVariableDeclaration();
301             Image image= JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_CHANGE);
302             String JavaDoc label= Messages.format(CorrectionMessages.ModifierCorrectionSubProcessor_changemodifiertofinal_description, binding.getName());
303             proposals.add(new ModifierChangeCompletionProposal(label, cu, binding, selectedNode, Modifier.FINAL, 0, 5, image));
304         }
305     }
306
307
308
309     public static void addRemoveInvalidModfiersProposal(IInvocationContext context, IProblemLocation problem, Collection JavaDoc proposals, int relevance) {
310         ICompilationUnit cu= context.getCompilationUnit();
311
312         ASTNode selectedNode= problem.getCoveringNode(context.getASTRoot());
313         if (selectedNode instanceof MethodDeclaration) {
314             selectedNode= ((MethodDeclaration) selectedNode).getName();
315         }
316
317         if (!(selectedNode instanceof SimpleName)) {
318             return;
319         }
320
321         IBinding binding= ((SimpleName) selectedNode).resolveBinding();
322         if (binding != null) {
323             String JavaDoc methodName= binding.getName();
324             String JavaDoc label= null;
325             int problemId= problem.getProblemId();
326
327             
328             int excludedModifiers= 0;
329             int includedModifiers= 0;
330
331             switch (problemId) {
332                 case IProblem.CannotHideAnInstanceMethodWithAStaticMethod:
333                 case IProblem.UnexpectedStaticModifierForMethod:
334                     excludedModifiers= Modifier.STATIC;
335                     label= Messages.format(CorrectionMessages.ModifierCorrectionSubProcessor_changemethodtononstatic_description, methodName);
336                     break;
337                 case IProblem.UnexpectedStaticModifierForField:
338                     excludedModifiers= Modifier.STATIC;
339                     label= Messages.format(CorrectionMessages.ModifierCorrectionSubProcessor_changefieldmodifiertononstatic_description, methodName);
340                     break;
341                 case IProblem.IllegalModifierCombinationFinalVolatileForField:
342                     excludedModifiers= Modifier.VOLATILE;
343                     label= CorrectionMessages.ModifierCorrectionSubProcessor_removevolatile_description;
344                     break;
345                 case IProblem.IllegalModifierForInterfaceMethod:
346                     excludedModifiers= ~(Modifier.PUBLIC | Modifier.ABSTRACT);
347                     break;
348                 case IProblem.IllegalModifierForInterface:
349                     excludedModifiers= ~(Modifier.PUBLIC | Modifier.ABSTRACT | Modifier.STRICTFP);
350                     break;
351                 case IProblem.IllegalModifierForClass:
352                     excludedModifiers= ~(Modifier.PUBLIC | Modifier.ABSTRACT | Modifier.FINAL | Modifier.STRICTFP);
353                     break;
354                 case IProblem.IllegalModifierForInterfaceField:
355                     excludedModifiers= ~(Modifier.PUBLIC | Modifier.ABSTRACT | Modifier.FINAL);
356                     break;
357                 case IProblem.IllegalModifierForMemberInterface:
358                 case IProblem.IllegalVisibilityModifierForInterfaceMemberType:
359                     excludedModifiers= ~(Modifier.PUBLIC | Modifier.STATIC | Modifier.STRICTFP);
360                     break;
361                 case IProblem.IllegalModifierForMemberClass:
362                     excludedModifiers= ~(Modifier.PUBLIC | Modifier.PROTECTED | Modifier.PRIVATE | Modifier.STATIC | Modifier.ABSTRACT | Modifier.FINAL | Modifier.STRICTFP);
363                     break;
364                 case IProblem.IllegalModifierForLocalClass:
365                     excludedModifiers= ~(Modifier.ABSTRACT | Modifier.FINAL | Modifier.STRICTFP);
366                     break;
367                 case IProblem.IllegalModifierForArgument:
368                     excludedModifiers= ~Modifier.FINAL;
369                     break;
370                 case IProblem.IllegalModifierForField:
371                     excludedModifiers= ~(Modifier.PUBLIC | Modifier.PROTECTED | Modifier.PRIVATE | Modifier.STATIC | Modifier.FINAL | Modifier.VOLATILE | Modifier.TRANSIENT);
372                     break;
373                 case IProblem.IllegalModifierForMethod:
374                     excludedModifiers= ~(Modifier.PUBLIC | Modifier.PROTECTED | Modifier.PRIVATE | Modifier.STATIC | Modifier.ABSTRACT | Modifier.FINAL | Modifier.NATIVE | Modifier.STRICTFP);
375                     if (((IMethodBinding) binding).isConstructor()) {
376                         excludedModifiers |= Modifier.STATIC;
377                     }
378                     break;
379                 case IProblem.IllegalModifierForVariable:
380                     excludedModifiers= ~Modifier.FINAL;
381                     break;
382                 default:
383                     Assert.isTrue(false, "not supported"); //$NON-NLS-1$
384
return;
385             }
386             
387             if (label == null)
388                 label= Messages.format(CorrectionMessages.ModifierCorrectionSubProcessor_removeinvalidmodifiers_description, methodName);
389
390             Image image= JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_CHANGE);
391             proposals.add(new ModifierChangeCompletionProposal(label, cu, binding, selectedNode, includedModifiers, excludedModifiers, relevance, image));
392             
393             if (problemId == IProblem.IllegalModifierCombinationFinalVolatileForField) {
394                 proposals.add(new ModifierChangeCompletionProposal(CorrectionMessages.ModifierCorrectionSubProcessor_removefinal_description, cu, binding, selectedNode, 0, Modifier.FINAL, relevance + 1, image));
395             }
396             
397             if (problemId == IProblem.UnexpectedStaticModifierForField && binding instanceof IVariableBinding) {
398                 ITypeBinding declClass= ((IVariableBinding) binding).getDeclaringClass();
399                 if (declClass.isMember()) {
400                     proposals.add(new ModifierChangeCompletionProposal(CorrectionMessages.ModifierCorrectionSubProcessor_changemodifiertostaticfinal_description, cu, binding, selectedNode, Modifier.FINAL, Modifier.VOLATILE, relevance + 1, image));
401                     ASTNode parentType= context.getASTRoot().findDeclaringNode(declClass);
402                     if (parentType != null) {
403                         proposals.add(new ModifierChangeCompletionProposal(CorrectionMessages.ModifierCorrectionSubProcessor_addstatictoparenttype_description, cu, declClass, parentType, Modifier.STATIC, 0, relevance - 1, image));
404                     }
405                 }
406             }
407             if (problemId == IProblem.UnexpectedStaticModifierForMethod && binding instanceof IMethodBinding) {
408                 ITypeBinding declClass= ((IMethodBinding) binding).getDeclaringClass();
409                 if (declClass.isMember()) {
410                     ASTNode parentType= context.getASTRoot().findDeclaringNode(declClass);
411                     if (parentType != null) {
412                         proposals.add(new ModifierChangeCompletionProposal(CorrectionMessages.ModifierCorrectionSubProcessor_addstatictoparenttype_description, cu, declClass, parentType, Modifier.STATIC, 0, relevance - 1, image));
413                     }
414                 }
415             }
416         }
417     }
418
419     private static String JavaDoc getVisibilityString(int code) {
420         if (Modifier.isPublic(code)) {
421             return "public"; //$NON-NLS-1$
422
} else if (Modifier.isProtected(code)) {
423             return "protected"; //$NON-NLS-1$
424
} else if (Modifier.isPrivate(code)) {
425             return "private"; //$NON-NLS-1$
426
}
427         return CorrectionMessages.ModifierCorrectionSubProcessor_default;
428     }
429
430
431     private static int getNeededVisibility(ASTNode currNode, ITypeBinding targetType) {
432         ITypeBinding currNodeBinding= Bindings.getBindingOfParentType(currNode);
433         if (currNodeBinding == null) { // import
434
return Modifier.PUBLIC;
435         }
436
437         if (Bindings.isSuperType(targetType, currNodeBinding)) {
438             return Modifier.PROTECTED;
439         }
440
441         if (currNodeBinding.getPackage().getKey().equals(targetType.getPackage().getKey())) {
442             return 0;
443         }
444         return Modifier.PUBLIC;
445     }
446
447     public static void addAbstractMethodProposals(IInvocationContext context, IProblemLocation problem, Collection JavaDoc proposals) {
448         ICompilationUnit cu= context.getCompilationUnit();
449
450         CompilationUnit astRoot= context.getASTRoot();
451
452         ASTNode selectedNode= problem.getCoveringNode(astRoot);
453         if (selectedNode == null) {
454             return;
455         }
456         MethodDeclaration decl;
457         if (selectedNode instanceof SimpleName) {
458             decl= (MethodDeclaration) selectedNode.getParent();
459         } else if (selectedNode instanceof MethodDeclaration) {
460             decl= (MethodDeclaration) selectedNode;
461         } else {
462             return;
463         }
464
465         ASTNode parentType= ASTResolving.findParentType(decl);
466         TypeDeclaration parentTypeDecl= null;
467         boolean parentIsAbstractClass= false;
468         if (parentType instanceof TypeDeclaration) {
469             parentTypeDecl= (TypeDeclaration) parentType;
470             parentIsAbstractClass= !parentTypeDecl.isInterface() && Modifier.isAbstract(parentTypeDecl.getModifiers());
471         }
472         boolean hasNoBody= (decl.getBody() == null);
473
474         if (problem.getProblemId() == IProblem.AbstractMethodInAbstractClass || parentIsAbstractClass) {
475             AST ast= astRoot.getAST();
476             ASTRewrite rewrite= ASTRewrite.create(ast);
477
478             Modifier modifierNode= ASTNodes.findModifierNode(Modifier.ABSTRACT, decl.modifiers());
479             if (modifierNode != null) {
480                 rewrite.remove(modifierNode, null);
481             }
482
483             if (hasNoBody) {
484                 Block newBody= ast.newBlock();
485                 rewrite.set(decl, MethodDeclaration.BODY_PROPERTY, newBody, null);
486
487                 Expression expr= ASTNodeFactory.newDefaultExpression(ast, decl.getReturnType2(), decl.getExtraDimensions());
488                 if (expr != null) {
489                     ReturnStatement returnStatement= ast.newReturnStatement();
490                     returnStatement.setExpression(expr);
491                     newBody.statements().add(returnStatement);
492                 }
493             }
494
495             String JavaDoc label= CorrectionMessages.ModifierCorrectionSubProcessor_removeabstract_description;
496             Image image= JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_CHANGE);
497             ASTRewriteCorrectionProposal proposal= new ASTRewriteCorrectionProposal(label, cu, rewrite, 6, image);
498             proposals.add(proposal);
499         }
500
501         if (!hasNoBody && problem.getProblemId() == IProblem.BodyForAbstractMethod) {
502             ASTRewrite rewrite= ASTRewrite.create(decl.getAST());
503             rewrite.remove(decl.getBody(), null);
504
505             String JavaDoc label= CorrectionMessages.ModifierCorrectionSubProcessor_removebody_description;
506             Image image= JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_CHANGE);
507             ASTRewriteCorrectionProposal proposal2= new ASTRewriteCorrectionProposal(label, cu, rewrite, 5, image);
508             proposals.add(proposal2);
509         }
510
511         if (problem.getProblemId() == IProblem.AbstractMethodInAbstractClass && (parentTypeDecl != null)) {
512             ASTRewriteCorrectionProposal proposal= getMakeTypeAbstractProposal(cu, parentTypeDecl, 5);
513             proposals.add(proposal);
514         }
515
516     }
517
518     public static void addNativeMethodProposals(IInvocationContext context, IProblemLocation problem, Collection JavaDoc proposals) {
519         ICompilationUnit cu= context.getCompilationUnit();
520
521         CompilationUnit astRoot= context.getASTRoot();
522
523         ASTNode selectedNode= problem.getCoveringNode(astRoot);
524         if (selectedNode == null) {
525             return;
526         }
527         MethodDeclaration decl;
528         if (selectedNode instanceof SimpleName) {
529             decl= (MethodDeclaration) selectedNode.getParent();
530         } else if (selectedNode instanceof MethodDeclaration) {
531             decl= (MethodDeclaration) selectedNode;
532         } else {
533             return;
534         }
535
536         {
537             AST ast= astRoot.getAST();
538             ASTRewrite rewrite= ASTRewrite.create(ast);
539
540             Modifier modifierNode= ASTNodes.findModifierNode(Modifier.NATIVE, decl.modifiers());
541             if (modifierNode != null) {
542                 rewrite.remove(modifierNode, null);
543             }
544
545             Block newBody= ast.newBlock();
546             rewrite.set(decl, MethodDeclaration.BODY_PROPERTY, newBody, null);
547
548             Expression expr= ASTNodeFactory.newDefaultExpression(ast, decl.getReturnType2(), decl.getExtraDimensions());
549             if (expr != null) {
550                 ReturnStatement returnStatement= ast.newReturnStatement();
551                 returnStatement.setExpression(expr);
552                 newBody.statements().add(returnStatement);
553             }
554
555             String JavaDoc label= CorrectionMessages.ModifierCorrectionSubProcessor_removenative_description;
556             Image image= JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_CHANGE);
557             ASTRewriteCorrectionProposal proposal= new ASTRewriteCorrectionProposal(label, cu, rewrite, 6, image);
558             proposals.add(proposal);
559         }
560
561         if (decl.getBody() != null) {
562             ASTRewrite rewrite= ASTRewrite.create(decl.getAST());
563             rewrite.remove(decl.getBody(), null);
564
565             String JavaDoc label= CorrectionMessages.ModifierCorrectionSubProcessor_removebody_description;
566             Image image= JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_CHANGE);
567             ASTRewriteCorrectionProposal proposal2= new ASTRewriteCorrectionProposal(label, cu, rewrite, 5, image);
568             proposals.add(proposal2);
569         }
570
571     }
572
573
574
575     public static ASTRewriteCorrectionProposal getMakeTypeAbstractProposal(ICompilationUnit cu, TypeDeclaration typeDeclaration, int relevance) {
576         AST ast= typeDeclaration.getAST();
577         ASTRewrite rewrite= ASTRewrite.create(ast);
578         Modifier newModifier= ast.newModifier(Modifier.ModifierKeyword.ABSTRACT_KEYWORD);
579         rewrite.getListRewrite(typeDeclaration, TypeDeclaration.MODIFIERS2_PROPERTY).insertLast(newModifier, null);
580
581         String JavaDoc label= Messages.format(CorrectionMessages.ModifierCorrectionSubProcessor_addabstract_description, typeDeclaration.getName().getIdentifier());
582         Image image= JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_CHANGE);
583         LinkedCorrectionProposal proposal= new LinkedCorrectionProposal(label, cu, rewrite, relevance, image);
584         proposal.addLinkedPosition(rewrite.track(newModifier), true, "modifier"); //$NON-NLS-1$
585
return proposal;
586     }
587
588     public static void addMethodRequiresBodyProposals(IInvocationContext context, IProblemLocation problem, Collection JavaDoc proposals) {
589         ICompilationUnit cu= context.getCompilationUnit();
590         AST ast= context.getASTRoot().getAST();
591
592         ASTNode selectedNode= problem.getCoveringNode(context.getASTRoot());
593         if (!(selectedNode instanceof MethodDeclaration)) {
594             return;
595         }
596         MethodDeclaration decl= (MethodDeclaration) selectedNode;
597         {
598             ASTRewrite rewrite= ASTRewrite.create(ast);
599
600             Modifier modifierNode= ASTNodes.findModifierNode(Modifier.ABSTRACT, decl.modifiers());
601             if (modifierNode != null) {
602                 rewrite.remove(modifierNode, null);
603             }
604
605             Block body= ast.newBlock();
606             rewrite.set(decl, MethodDeclaration.BODY_PROPERTY, body, null);
607
608
609             if (!decl.isConstructor()) {
610                 Type returnType= decl.getReturnType2();
611                 Expression expression= ASTNodeFactory.newDefaultExpression(ast, returnType, decl.getExtraDimensions());
612                 if (expression != null) {
613                     ReturnStatement returnStatement= ast.newReturnStatement();
614                     returnStatement.setExpression(expression);
615                     body.statements().add(returnStatement);
616                 }
617             }
618
619             String JavaDoc label= CorrectionMessages.ModifierCorrectionSubProcessor_addmissingbody_description;
620             Image image= JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_CHANGE);
621             ASTRewriteCorrectionProposal proposal= new ASTRewriteCorrectionProposal(label, cu, rewrite, 9, image);
622
623             proposals.add(proposal);
624         }
625         {
626             ASTRewrite rewrite= ASTRewrite.create(ast);
627
628             Modifier newModifier= ast.newModifier(Modifier.ModifierKeyword.ABSTRACT_KEYWORD);
629             rewrite.getListRewrite(decl, MethodDeclaration.MODIFIERS2_PROPERTY).insertLast(newModifier, null);
630
631             String JavaDoc label= CorrectionMessages.ModifierCorrectionSubProcessor_setmethodabstract_description;
632             Image image= JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_CHANGE);
633             LinkedCorrectionProposal proposal= new LinkedCorrectionProposal(label, cu, rewrite, 8, image);
634             proposal.addLinkedPosition(rewrite.track(newModifier), true, "modifier"); //$NON-NLS-1$
635

636             proposals.add(proposal);
637         }
638
639     }
640
641
642     public static void addNeedToEmulateProposal(IInvocationContext context, IProblemLocation problem, Collection JavaDoc proposals) {
643         ICompilationUnit cu= context.getCompilationUnit();
644
645         ASTNode selectedNode= problem.getCoveringNode(context.getASTRoot());
646         if (!(selectedNode instanceof SimpleName)) {
647             return;
648         }
649
650         IBinding binding= ((SimpleName) selectedNode).resolveBinding();
651         if (binding instanceof IVariableBinding) {
652             binding= ((IVariableBinding) binding).getVariableDeclaration();
653             Image image= JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_CHANGE);
654             String JavaDoc label= Messages.format(CorrectionMessages.ModifierCorrectionSubProcessor_changemodifiertofinal_description, binding.getName());
655             proposals.add(new ModifierChangeCompletionProposal(label, cu, binding, selectedNode, Modifier.FINAL, 0, 5, image));
656         }
657     }
658     
659     public static void addOverrideAnnotationProposal(IInvocationContext context, IProblemLocation problem, Collection JavaDoc proposals) throws CoreException {
660         IFix fix= Java50Fix.createAddOverrideAnnotationFix(context.getASTRoot(), problem);
661         if (fix != null) {
662             Image image= JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_CHANGE);
663             Map JavaDoc options= new Hashtable JavaDoc();
664             options.put(CleanUpConstants.ADD_MISSING_ANNOTATIONS, CleanUpConstants.TRUE);
665             options.put(CleanUpConstants.ADD_MISSING_ANNOTATIONS_OVERRIDE, CleanUpConstants.TRUE);
666             FixCorrectionProposal proposal= new FixCorrectionProposal(fix, new Java50CleanUp(options), 5, image, context);
667             proposals.add(proposal);
668         }
669     }
670     
671     public static void addDeprecatedAnnotationProposal(IInvocationContext context, IProblemLocation problem, Collection JavaDoc proposals) throws CoreException {
672         IFix fix= Java50Fix.createAddDeprectatedAnnotation(context.getASTRoot(), problem);
673         if (fix != null) {
674             Image image= JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_CHANGE);
675             Map JavaDoc options= new Hashtable JavaDoc();
676             options.put(CleanUpConstants.ADD_MISSING_ANNOTATIONS, CleanUpConstants.TRUE);
677             options.put(CleanUpConstants.ADD_MISSING_ANNOTATIONS_DEPRECATED, CleanUpConstants.TRUE);
678             FixCorrectionProposal proposal= new FixCorrectionProposal(fix, new Java50CleanUp(options), 5, image, context);
679             proposals.add(proposal);
680         }
681     }
682     
683     public static void addOverridingDeprecatedMethodProposal(IInvocationContext context, IProblemLocation problem, Collection JavaDoc proposals) throws CoreException {
684         
685         ICompilationUnit cu= context.getCompilationUnit();
686
687         ASTNode selectedNode= problem.getCoveringNode(context.getASTRoot());
688         if (!(selectedNode instanceof MethodDeclaration)) {
689             return;
690         }
691         boolean is50OrHigher= JavaModelUtil.is50OrHigher(cu.getJavaProject());
692         MethodDeclaration methodDecl= (MethodDeclaration) selectedNode;
693         AST ast= methodDecl.getAST();
694         ASTRewrite rewrite= ASTRewrite.create(ast);
695         if (is50OrHigher) {
696             Annotation annot= ast.newMarkerAnnotation();
697             annot.setTypeName(ast.newName("Deprecated")); //$NON-NLS-1$
698
rewrite.getListRewrite(methodDecl, methodDecl.getModifiersProperty()).insertFirst(annot, null);
699         }
700         Javadoc javadoc= methodDecl.getJavadoc();
701         if (javadoc != null || !is50OrHigher) {
702             if (!is50OrHigher) {
703                 javadoc= ast.newJavadoc();
704                 rewrite.set(methodDecl, MethodDeclaration.JAVADOC_PROPERTY, javadoc, null);
705             }
706             TagElement newTag= ast.newTagElement();
707             newTag.setTagName(TagElement.TAG_DEPRECATED);
708             JavadocTagsSubProcessor.insertTag(rewrite.getListRewrite(javadoc, Javadoc.TAGS_PROPERTY), newTag, null);
709         }
710         
711         String JavaDoc label= CorrectionMessages.ModifierCorrectionSubProcessor_overrides_deprecated_description;
712         Image image= JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_CHANGE);
713         ASTRewriteCorrectionProposal proposal= new ASTRewriteCorrectionProposal(label, cu, rewrite, 15, image);
714         proposals.add(proposal);
715     }
716         
717     public static void removeOverrideAnnotationProposal(IInvocationContext context, IProblemLocation problem, Collection JavaDoc proposals) throws CoreException {
718         ICompilationUnit cu= context.getCompilationUnit();
719
720         ASTNode selectedNode= problem.getCoveringNode(context.getASTRoot());
721         if (!(selectedNode instanceof MethodDeclaration)) {
722             return;
723         }
724         MethodDeclaration methodDecl= (MethodDeclaration) selectedNode;
725         Annotation annot= findAnnotation("java.lang.Override", methodDecl.modifiers()); //$NON-NLS-1$
726
if (annot != null) {
727             ASTRewrite rewrite= ASTRewrite.create(annot.getAST());
728             rewrite.remove(annot, null);
729             String JavaDoc label= CorrectionMessages.ModifierCorrectionSubProcessor_remove_override;
730             Image image= JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_CHANGE);
731             ASTRewriteCorrectionProposal proposal= new ASTRewriteCorrectionProposal(label, cu, rewrite, 6, image);
732             proposals.add(proposal);
733             
734             QuickAssistProcessor.getCreateInSuperClassProposals(context, methodDecl.getName(), proposals);
735         }
736     }
737
738     private static final String JavaDoc KEY_MODIFIER= "modifier"; //$NON-NLS-1$
739

740     private static class ModifierLinkedModeProposal extends LinkedProposalPositionGroup.Proposal {
741
742         private final int fModifier;
743
744         public ModifierLinkedModeProposal(int modifier, int relevance) {
745             super(null, null, relevance);
746             fModifier= modifier;
747         }
748
749         public String JavaDoc getAdditionalProposalInfo() {
750             return getDisplayString();
751         }
752
753         public String JavaDoc getDisplayString() {
754             if (fModifier == 0) {
755                 return CorrectionMessages.ModifierCorrectionSubProcessor_default_visibility_label;
756             } else {
757                 return ModifierKeyword.fromFlagValue(fModifier).toString();
758             }
759         }
760
761         /* (non-Javadoc)
762          * @see org.eclipse.jdt.internal.corext.fix.PositionGroup.Proposal#computeEdits(int, org.eclipse.jface.text.link.LinkedPosition, char, int, org.eclipse.jface.text.link.LinkedModeModel)
763          */

764         public TextEdit computeEdits(int offset, LinkedPosition currentPosition, char trigger, int stateMask, LinkedModeModel model) throws CoreException {
765             try {
766                 IDocument document= currentPosition.getDocument();
767                 MultiTextEdit edit= new MultiTextEdit();
768                 int documentLen= document.getLength();
769                 if (fModifier == 0) {
770                     int end= currentPosition.offset + currentPosition.length; // current end position
771
int k= end;
772                     while (k < documentLen && IndentManipulation.isIndentChar(document.getChar(k))) {
773                         k++;
774                     }
775                     // first remove space then replace range (remove space can destroy empty position)
776
edit.addChild(new ReplaceEdit(end, k - end, new String JavaDoc())); // remove extra spaces
777
edit.addChild(new ReplaceEdit(currentPosition.offset, currentPosition.length, new String JavaDoc()));
778                 } else {
779                     // first then replace range the insert space (insert space can destroy empty position)
780
edit.addChild(new ReplaceEdit(currentPosition.offset, currentPosition.length, ModifierKeyword.fromFlagValue(fModifier).toString()));
781                     int end= currentPosition.offset + currentPosition.length; // current end position
782
if (end < documentLen && !Character.isWhitespace(document.getChar(end))) {
783                         edit.addChild(new ReplaceEdit(end, 0, String.valueOf(' '))); // insert extra space
784
}
785                 }
786                 return edit;
787             } catch (BadLocationException e) {
788                 throw new CoreException(new Status(IStatus.ERROR, JavaUI.ID_PLUGIN, IStatus.ERROR, e.getMessage(), e));
789             }
790         }
791     }
792     
793     public static void installLinkedVisibilityProposals(LinkedProposalModel linkedProposalModel, ASTRewrite rewrite, List JavaDoc modifiers, boolean inInterface) {
794         ASTNode modifier= findVisibilityModifier(modifiers);
795         if (modifier != null) {
796             int selected= ((Modifier) modifier).getKeyword().toFlagValue();
797             
798             LinkedProposalPositionGroup positionGroup= linkedProposalModel.getPositionGroup(KEY_MODIFIER, true);
799             positionGroup.addPosition(rewrite.track(modifier), false);
800             positionGroup.addProposal(new ModifierLinkedModeProposal(selected, 10));
801             
802             // add all others
803
int[] flagValues= inInterface ? new int[] { Modifier.PUBLIC, 0 } : new int[] { Modifier.PUBLIC, 0, Modifier.PROTECTED, Modifier.PRIVATE };
804             for (int i= 0; i < flagValues.length; i++) {
805                 if (flagValues[i] != selected) {
806                     positionGroup.addProposal(new ModifierLinkedModeProposal(flagValues[i], 9 - i));
807                 }
808             }
809         }
810     }
811     
812     private static Modifier findVisibilityModifier(List JavaDoc modifiers) {
813         for (int i= 0; i < modifiers.size(); i++) {
814             Object JavaDoc curr= modifiers.get(i);
815             if (curr instanceof Modifier) {
816                 Modifier modifier= (Modifier) curr;
817                 ModifierKeyword keyword= modifier.getKeyword();
818                 if (keyword == ModifierKeyword.PUBLIC_KEYWORD || keyword == ModifierKeyword.PROTECTED_KEYWORD || keyword == ModifierKeyword.PRIVATE_KEYWORD) {
819                     return modifier;
820                 }
821             }
822         }
823         return null;
824     }
825     
826     private static Annotation findAnnotation(String JavaDoc qualifiedTypeName, List JavaDoc modifiers) {
827         for (int i= 0; i < modifiers.size(); i++) {
828             Object JavaDoc curr= modifiers.get(i);
829             if (curr instanceof Annotation) {
830                 Annotation annot= (Annotation) curr;
831                 ITypeBinding binding= annot.getTypeName().resolveTypeBinding();
832                 if (binding != null && qualifiedTypeName.equals(binding.getQualifiedName())) {
833                     return annot;
834                 }
835             }
836         }
837         return null;
838     }
839     
840     private static class ProposalParameter {
841         public final boolean useSuper;
842         public final ICompilationUnit compilationUnit;
843         public final ASTRewrite astRewrite;
844         public final Expression accessNode;
845         public final Expression qualifier;
846         public final IVariableBinding variableBinding;
847
848         public ProposalParameter(boolean useSuper, ICompilationUnit compilationUnit, ASTRewrite rewrite, Expression accessNode, Expression qualifier, IVariableBinding variableBinding) {
849             this.useSuper= useSuper;
850             this.compilationUnit= compilationUnit;
851             this.astRewrite= rewrite;
852             this.accessNode= accessNode;
853             this.qualifier= qualifier;
854             this.variableBinding= variableBinding;
855         }
856     }
857
858     public static class SelfEncapsulateFieldProposal extends ChangeCorrectionProposal {
859
860         private IField fField;
861         private boolean fNoDialog;
862
863         public SelfEncapsulateFieldProposal(int relevance, IField field, boolean isReadAccess) {
864             super(getDescription(isReadAccess), null, relevance, JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_CHANGE));
865             fField= field;
866             fNoDialog= false;
867         }
868         
869         public void setNoDialog(boolean noDialog) {
870             fNoDialog= noDialog;
871         }
872
873         private static String JavaDoc getDescription(boolean getter) {
874             if (getter)
875                 return CorrectionMessages.ModifierCorrectionSubProcessor_creategetterunsingencapsulatefield_description;
876             else
877                 return CorrectionMessages.ModifierCorrectionSubProcessor_createsetterusingencapsulatefield_description;
878         }
879
880         public void apply(IDocument document) {
881             try {
882                 final SelfEncapsulateFieldRefactoring refactoring= new SelfEncapsulateFieldRefactoring(fField);
883                 refactoring.setVisibility(Flags.AccPublic);
884                 refactoring.setConsiderVisibility(false);//private field references are just searched in local file
885
if (fNoDialog) {
886                     IWorkbenchWindow window= PlatformUI.getWorkbench().getActiveWorkbenchWindow();
887                     final RefactoringExecutionHelper helper= new RefactoringExecutionHelper(refactoring, RefactoringStatus.ERROR, RefactoringSaveHelper.SAVE_JAVA_ONLY_UPDATES, JavaPlugin.getActiveWorkbenchShell(), window);
888                     if (Display.getCurrent() != null) {
889                         try {
890                             helper.perform(false, false);
891                         } catch (InterruptedException JavaDoc e) {
892                             JavaPlugin.log(e);
893                         } catch (InvocationTargetException JavaDoc e) {
894                             JavaPlugin.log(e);
895                         }
896                     } else {
897                         Display.getDefault().syncExec(new Runnable JavaDoc() {
898                             public void run() {
899                                 try {
900                                     helper.perform(false, false);
901                                 } catch (InterruptedException JavaDoc e) {
902                                     JavaPlugin.log(e);
903                                 } catch (InvocationTargetException JavaDoc e) {
904                                     JavaPlugin.log(e);
905                                 }
906                             }
907                         });
908                     }
909                 } else {
910                     new RefactoringStarter().activate(refactoring, new SelfEncapsulateFieldWizard(refactoring), JavaPlugin.getActiveWorkbenchShell(), "", RefactoringSaveHelper.SAVE_JAVA_ONLY_UPDATES); //$NON-NLS-1$
911
}
912             } catch (JavaModelException e) {
913                 ExceptionHandler.handle(e, CorrectionMessages.ModifierCorrectionSubProcessor_encapsulate_field_error_title, CorrectionMessages.ModifierCorrectionSubProcessor_encapsulate_field_error_message);
914             }
915         }
916     }
917
918     public static void addGetterSetterProposal(IInvocationContext context, IProblemLocation problem, Collection JavaDoc proposals, int relevance) {
919         ASTNode coveringNode= problem.getCoveringNode(context.getASTRoot());
920         ICompilationUnit compilationUnit= context.getCompilationUnit();
921         if (coveringNode instanceof SimpleName) {
922             SimpleName sn= (SimpleName) coveringNode;
923             if (sn.isDeclaration())
924                 return;
925             IVariableBinding variableBinding= (IVariableBinding) sn.resolveBinding();
926             if (variableBinding == null || !variableBinding.isField())
927                 return;
928             ChangeCorrectionProposal proposal= getProposal(compilationUnit, sn, variableBinding, relevance);
929             if (proposal != null)
930                 proposals.add(proposal);
931         }
932     }
933
934     private static ChangeCorrectionProposal getProposal(ICompilationUnit cu, SimpleName sn, IVariableBinding variableBinding, int relevance) {
935         Expression accessNode= sn;
936         Expression qualifier= null;
937         AST ast= sn.getAST();
938         ASTRewrite rewrite= ASTRewrite.create(ast);
939         boolean useSuper= false;
940         boolean writeAccess= ASTResolving.isWriteAccess(sn);
941         ASTNode parent= sn.getParent();
942         switch (parent.getNodeType()) {
943         case ASTNode.QUALIFIED_NAME:
944             accessNode= (Expression) parent;
945             qualifier= ((QualifiedName) parent).getQualifier();
946             break;
947         case ASTNode.SUPER_FIELD_ACCESS:
948             accessNode= (Expression) parent;
949             qualifier= ((SuperFieldAccess) parent).getQualifier();
950             useSuper= true;
951             break;
952         }
953         ProposalParameter gspc= new ProposalParameter(useSuper, cu, rewrite, accessNode, qualifier, variableBinding);
954         if (writeAccess)
955             return addSetterProposal(gspc, relevance);
956         else
957             return addGetterProposal(gspc, relevance);
958     }
959
960     /**
961      * Proposes a getter for this field
962      * @param context
963      * @param relevance relevance of this proposal
964      * @return the proposal if available or null
965      */

966     private static ChangeCorrectionProposal addGetterProposal(ProposalParameter context, int relevance) {
967         IMethodBinding method= findGetter(context);
968         if (method != null) {
969             Expression mi= createMethodInvocation(context, method, null);
970             context.astRewrite.replace(context.accessNode, mi, null);
971
972             String JavaDoc label= Messages.format(CorrectionMessages.ModifierCorrectionSubProcessor_replacewithgetter_description, context.accessNode);
973             Image image= JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_CHANGE);
974             ASTRewriteCorrectionProposal proposal= new ASTRewriteCorrectionProposal(label, context.compilationUnit, context.astRewrite, relevance, image);
975             return proposal;
976         } else {
977             IJavaElement element= context.variableBinding.getJavaElement();
978             if (element instanceof IField) {
979                 IField field= (IField) element;
980                 try {
981                     if (RefactoringAvailabilityTester.isSelfEncapsulateAvailable(field))
982                         return new SelfEncapsulateFieldProposal(relevance, field, true);
983                 } catch (JavaModelException e) {
984                     JavaPlugin.log(e);
985                 }
986             }
987         }
988         return null;
989     }
990
991     private static IMethodBinding findGetter(ProposalParameter context) {
992         ITypeBinding returnType= context.variableBinding.getType();
993         String JavaDoc getterName= GetterSetterUtil.getGetterName(context.variableBinding, context.compilationUnit.getJavaProject(), null, isBoolean(context));
994         ITypeBinding declaringType= context.variableBinding.getDeclaringClass();
995         IMethodBinding getter= Bindings.findMethodInHierarchy(declaringType, getterName, new ITypeBinding[0]);
996         if (getter != null && getter.getReturnType().isAssignmentCompatible(returnType) && Modifier.isStatic(getter.getModifiers()) == Modifier.isStatic(context.variableBinding.getModifiers()))
997             return getter;
998         return null;
999     }
1000
1001    private static Expression createMethodInvocation(ProposalParameter context, IMethodBinding method, Expression argument) {
1002        AST ast= context.astRewrite.getAST();
1003        Expression qualifier= context.qualifier;
1004        if (context.useSuper) {
1005            SuperMethodInvocation invocation= ast.newSuperMethodInvocation();
1006            invocation.setName(ast.newSimpleName(method.getName()));
1007            if (qualifier != null)
1008                invocation.setQualifier((Name) context.astRewrite.createCopyTarget(qualifier));
1009            if (argument != null)
1010                invocation.arguments().add(argument);
1011            return invocation;
1012        } else {
1013            MethodInvocation invocation= ast.newMethodInvocation();
1014            invocation.setName(ast.newSimpleName(method.getName()));
1015            if (qualifier != null)
1016                invocation.setExpression((Expression) context.astRewrite.createCopyTarget(qualifier));
1017            if (argument != null)
1018                invocation.arguments().add(argument);
1019            return invocation;
1020        }
1021    }
1022
1023    /**
1024     * Proposes a setter for this field
1025     * @param context
1026     * @param relevance relevance of this proposal
1027     * @return the proposal if available or null
1028     */

1029    private static ChangeCorrectionProposal addSetterProposal(ProposalParameter context, int relevance) {
1030        boolean isBoolean= isBoolean(context);
1031        String JavaDoc setterName= GetterSetterUtil.getSetterName(context.variableBinding, context.compilationUnit.getJavaProject(), null, isBoolean);
1032        ITypeBinding declaringType= context.variableBinding.getDeclaringClass();
1033        IMethodBinding method= Bindings.findMethodInHierarchy(declaringType, setterName, new ITypeBinding[] { context.variableBinding.getType() });
1034        if (method != null && Bindings.isVoidType(method.getReturnType()) && (Modifier.isStatic(method.getModifiers()) == Modifier.isStatic(context.variableBinding.getModifiers()))) {
1035            Expression assignedValue= getAssignedValue(context);
1036            if (assignedValue == null)
1037                return null; //we don't know how to handle those cases.
1038
Expression mi= createMethodInvocation(context, method, assignedValue);
1039            context.astRewrite.replace(context.accessNode.getParent(), mi, null);
1040
1041            String JavaDoc label= Messages.format(CorrectionMessages.ModifierCorrectionSubProcessor_replacewithsetter_description, context.accessNode);
1042            Image image= JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_CHANGE);
1043            ASTRewriteCorrectionProposal proposal= new ASTRewriteCorrectionProposal(label, context.compilationUnit, context.astRewrite, relevance, image);
1044            return proposal;
1045        } else {
1046            IJavaElement element= context.variableBinding.getJavaElement();
1047            if (element instanceof IField) {
1048                IField field= (IField) element;
1049                try {
1050                    if (RefactoringAvailabilityTester.isSelfEncapsulateAvailable(field))
1051                        return new SelfEncapsulateFieldProposal(relevance, field, false);
1052                } catch (JavaModelException e) {
1053                    JavaPlugin.log(e);
1054                }
1055            }
1056        }
1057        return null;
1058    }
1059
1060    private static boolean isBoolean(ProposalParameter context) {
1061        AST ast= context.astRewrite.getAST();
1062        boolean isBoolean= ast.resolveWellKnownType("boolean") == context.variableBinding.getType(); //$NON-NLS-1$
1063
if (!isBoolean)
1064            isBoolean= ast.resolveWellKnownType("java.lang.Boolean") == context.variableBinding.getType(); //$NON-NLS-1$
1065
return isBoolean;
1066    }
1067
1068    private static Expression getAssignedValue(ProposalParameter context) {
1069        ASTNode parent= context.accessNode.getParent();
1070        AST ast= context.astRewrite.getAST();
1071        switch (parent.getNodeType()) {
1072        case ASTNode.ASSIGNMENT:
1073            Assignment assignment= ((Assignment) parent);
1074            Expression rightHandSide= assignment.getRightHandSide();
1075            Expression copiedRightOp= (Expression) context.astRewrite.createCopyTarget(rightHandSide);
1076            if (isNotInBlock(parent))
1077                break;
1078            if (assignment.getOperator() == Operator.ASSIGN) {
1079                ITypeBinding rightHandSideType= rightHandSide.resolveTypeBinding();
1080                copiedRightOp= checkForNarrowCast(context, copiedRightOp, true, rightHandSideType);
1081                return copiedRightOp;
1082            }
1083            IMethodBinding getter= findGetter(context);
1084            if (getter != null) {
1085                InfixExpression infix= ast.newInfixExpression();
1086                infix.setLeftOperand(createMethodInvocation(context, getter, null));
1087                infix.setOperator(ASTNodes.convertToInfixOperator(assignment.getOperator()));
1088                infix.setRightOperand(copiedRightOp);
1089                ITypeBinding infixType= infix.resolveTypeBinding();
1090                return checkForNarrowCast(context, infix, true, infixType);
1091            }
1092            break;
1093        case ASTNode.POSTFIX_EXPRESSION:
1094            PostfixExpression po= (PostfixExpression) parent;
1095            if (isNotInBlock(parent))
1096                break;
1097            InfixExpression.Operator postfixOp= null;
1098            if (po.getOperator() == PostfixExpression.Operator.INCREMENT)
1099                postfixOp= InfixExpression.Operator.PLUS;
1100            if (po.getOperator() == PostfixExpression.Operator.DECREMENT)
1101                postfixOp= InfixExpression.Operator.MINUS;
1102            if (postfixOp == null)
1103                break;
1104            return createInfixInvocationFromPostPrefixExpression(context, postfixOp);
1105        case ASTNode.PREFIX_EXPRESSION:
1106            PrefixExpression pe= (PrefixExpression) parent;
1107            if (isNotInBlock(parent))
1108                break;
1109            InfixExpression.Operator prefixOp= null;
1110            if (pe.getOperator() == PrefixExpression.Operator.INCREMENT)
1111                prefixOp= InfixExpression.Operator.PLUS;
1112            if (pe.getOperator() == PrefixExpression.Operator.DECREMENT)
1113                prefixOp= InfixExpression.Operator.MINUS;
1114            if (prefixOp == null)
1115                break;
1116            return createInfixInvocationFromPostPrefixExpression(context, prefixOp);
1117        }
1118
1119        return null;
1120    }
1121
1122    private static boolean isNotInBlock(ASTNode parent) {
1123        ASTNode grandParent= parent.getParent();
1124        return (grandParent.getNodeType() != ASTNode.EXPRESSION_STATEMENT) || (grandParent.getParent().getNodeType() != ASTNode.BLOCK);
1125    }
1126
1127    private static Expression createInfixInvocationFromPostPrefixExpression(ProposalParameter context, InfixExpression.Operator operator) {
1128        AST ast= context.astRewrite.getAST();
1129        IMethodBinding getter= findGetter(context);
1130        if (getter != null) {
1131            InfixExpression infix= ast.newInfixExpression();
1132            infix.setLeftOperand(createMethodInvocation(context, getter, null));
1133            infix.setOperator(operator);
1134            NumberLiteral number= ast.newNumberLiteral();
1135            number.setToken("1"); //$NON-NLS-1$
1136
infix.setRightOperand(number);
1137            ITypeBinding infixType= infix.resolveTypeBinding();
1138            return checkForNarrowCast(context, infix, true, infixType);
1139        }
1140        return null;
1141    }
1142
1143    /**
1144     *
1145     * @param context general context
1146     * @param expression the right handside
1147     * @param parenthesize if true places () around expression
1148     * @param expressionType the type of the right handside. Can be null
1149     * @return the casted expression if necessary
1150     */

1151    private static Expression checkForNarrowCast(ProposalParameter context, Expression expression, boolean parenthesize, ITypeBinding expressionType) {
1152        PrimitiveType castTo= null;
1153        ITypeBinding type= context.variableBinding.getType();
1154        if (type.isEqualTo(expressionType))
1155            return expression; //no cast for same type
1156
AST ast= context.astRewrite.getAST();
1157        if (JavaModelUtil.is50OrHigher(context.compilationUnit.getJavaProject())) {
1158            if (ast.resolveWellKnownType("java.lang.Character").isEqualTo(type)) //$NON-NLS-1$
1159
castTo= ast.newPrimitiveType(PrimitiveType.CHAR);
1160            if (ast.resolveWellKnownType("java.lang.Byte").isEqualTo(type)) //$NON-NLS-1$
1161
castTo= ast.newPrimitiveType(PrimitiveType.BYTE);
1162            if (ast.resolveWellKnownType("java.lang.Short").isEqualTo(type)) //$NON-NLS-1$
1163
castTo= ast.newPrimitiveType(PrimitiveType.SHORT);
1164        }
1165        if (ast.resolveWellKnownType("char").isEqualTo(type)) //$NON-NLS-1$
1166
castTo= ast.newPrimitiveType(PrimitiveType.CHAR);
1167        if (ast.resolveWellKnownType("byte").isEqualTo(type)) //$NON-NLS-1$
1168
castTo= ast.newPrimitiveType(PrimitiveType.BYTE);
1169        if (ast.resolveWellKnownType("short").isEqualTo(type)) //$NON-NLS-1$
1170
castTo= ast.newPrimitiveType(PrimitiveType.SHORT);
1171        if (castTo != null) {
1172            CastExpression cast= ast.newCastExpression();
1173            if (parenthesize) {
1174                ParenthesizedExpression parenthesized= ast.newParenthesizedExpression();
1175                parenthesized.setExpression(expression);
1176                cast.setExpression(parenthesized);
1177            } else
1178                cast.setExpression(expression);
1179            cast.setType(castTo);
1180            return cast;
1181        }
1182        return expression;
1183    }
1184
1185}
1186
Popular Tags