KickJava   Java API By Example, From Geeks To Geeks.

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


1 /*******************************************************************************
2  * Copyright (c) 2000, 2006 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  * Sebastian Davids <sdavids@gmx.de> - Bug 37432 getInvertEqualsProposal
11  *******************************************************************************/

12 package org.eclipse.jdt.internal.ui.text.correction;
13
14 import java.util.ArrayList JavaDoc;
15 import java.util.Collection JavaDoc;
16 import java.util.HashMap JavaDoc;
17 import java.util.Hashtable JavaDoc;
18 import java.util.List JavaDoc;
19 import java.util.Map JavaDoc;
20
21 import org.eclipse.core.runtime.CoreException;
22 import org.eclipse.core.runtime.NullProgressMonitor;
23
24 import org.eclipse.swt.graphics.Image;
25
26 import org.eclipse.ltk.core.refactoring.Refactoring;
27 import org.eclipse.ltk.core.refactoring.TextChange;
28
29 import org.eclipse.jdt.core.Flags;
30 import org.eclipse.jdt.core.ICompilationUnit;
31 import org.eclipse.jdt.core.compiler.IProblem;
32 import org.eclipse.jdt.core.dom.AST;
33 import org.eclipse.jdt.core.dom.ASTNode;
34 import org.eclipse.jdt.core.dom.AnonymousClassDeclaration;
35 import org.eclipse.jdt.core.dom.ArrayCreation;
36 import org.eclipse.jdt.core.dom.ArrayInitializer;
37 import org.eclipse.jdt.core.dom.ArrayType;
38 import org.eclipse.jdt.core.dom.Assignment;
39 import org.eclipse.jdt.core.dom.Block;
40 import org.eclipse.jdt.core.dom.BodyDeclaration;
41 import org.eclipse.jdt.core.dom.CastExpression;
42 import org.eclipse.jdt.core.dom.CatchClause;
43 import org.eclipse.jdt.core.dom.ChildListPropertyDescriptor;
44 import org.eclipse.jdt.core.dom.ClassInstanceCreation;
45 import org.eclipse.jdt.core.dom.CompilationUnit;
46 import org.eclipse.jdt.core.dom.ConditionalExpression;
47 import org.eclipse.jdt.core.dom.DoStatement;
48 import org.eclipse.jdt.core.dom.Expression;
49 import org.eclipse.jdt.core.dom.ExpressionStatement;
50 import org.eclipse.jdt.core.dom.ForStatement;
51 import org.eclipse.jdt.core.dom.IBinding;
52 import org.eclipse.jdt.core.dom.IMethodBinding;
53 import org.eclipse.jdt.core.dom.ITypeBinding;
54 import org.eclipse.jdt.core.dom.IVariableBinding;
55 import org.eclipse.jdt.core.dom.IfStatement;
56 import org.eclipse.jdt.core.dom.InfixExpression;
57 import org.eclipse.jdt.core.dom.Initializer;
58 import org.eclipse.jdt.core.dom.MethodDeclaration;
59 import org.eclipse.jdt.core.dom.MethodInvocation;
60 import org.eclipse.jdt.core.dom.Modifier;
61 import org.eclipse.jdt.core.dom.Name;
62 import org.eclipse.jdt.core.dom.ParenthesizedExpression;
63 import org.eclipse.jdt.core.dom.PrimitiveType;
64 import org.eclipse.jdt.core.dom.SimpleName;
65 import org.eclipse.jdt.core.dom.SimpleType;
66 import org.eclipse.jdt.core.dom.SingleVariableDeclaration;
67 import org.eclipse.jdt.core.dom.Statement;
68 import org.eclipse.jdt.core.dom.StructuralPropertyDescriptor;
69 import org.eclipse.jdt.core.dom.ThisExpression;
70 import org.eclipse.jdt.core.dom.TryStatement;
71 import org.eclipse.jdt.core.dom.Type;
72 import org.eclipse.jdt.core.dom.TypeDeclaration;
73 import org.eclipse.jdt.core.dom.VariableDeclaration;
74 import org.eclipse.jdt.core.dom.VariableDeclarationExpression;
75 import org.eclipse.jdt.core.dom.VariableDeclarationFragment;
76 import org.eclipse.jdt.core.dom.VariableDeclarationStatement;
77 import org.eclipse.jdt.core.dom.WhileStatement;
78 import org.eclipse.jdt.core.dom.rewrite.ASTRewrite;
79 import org.eclipse.jdt.core.dom.rewrite.ImportRewrite;
80 import org.eclipse.jdt.core.dom.rewrite.ListRewrite;
81
82 import org.eclipse.jdt.internal.corext.dom.ASTNodeFactory;
83 import org.eclipse.jdt.internal.corext.dom.ASTNodes;
84 import org.eclipse.jdt.internal.corext.dom.Bindings;
85 import org.eclipse.jdt.internal.corext.dom.LinkedNodeFinder;
86 import org.eclipse.jdt.internal.corext.dom.Selection;
87 import org.eclipse.jdt.internal.corext.dom.SelectionAnalyzer;
88 import org.eclipse.jdt.internal.corext.fix.CleanUpConstants;
89 import org.eclipse.jdt.internal.corext.fix.ControlStatementsFix;
90 import org.eclipse.jdt.internal.corext.fix.ConvertLoopFix;
91 import org.eclipse.jdt.internal.corext.fix.IFix;
92 import org.eclipse.jdt.internal.corext.fix.LinkedProposalModel;
93 import org.eclipse.jdt.internal.corext.fix.VariableDeclarationFix;
94 import org.eclipse.jdt.internal.corext.refactoring.code.ConvertAnonymousToNestedRefactoring;
95 import org.eclipse.jdt.internal.corext.refactoring.code.ExtractConstantRefactoring;
96 import org.eclipse.jdt.internal.corext.refactoring.code.ExtractTempRefactoring;
97 import org.eclipse.jdt.internal.corext.refactoring.code.InlineTempRefactoring;
98 import org.eclipse.jdt.internal.corext.refactoring.code.PromoteTempToFieldRefactoring;
99 import org.eclipse.jdt.internal.corext.util.Messages;
100
101 import org.eclipse.jdt.ui.text.java.IInvocationContext;
102 import org.eclipse.jdt.ui.text.java.IJavaCompletionProposal;
103 import org.eclipse.jdt.ui.text.java.IProblemLocation;
104 import org.eclipse.jdt.ui.text.java.IQuickAssistProcessor;
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.ControlStatementsCleanUp;
109 import org.eclipse.jdt.internal.ui.fix.ConvertLoopCleanUp;
110 import org.eclipse.jdt.internal.ui.fix.ICleanUp;
111 import org.eclipse.jdt.internal.ui.fix.VariableDeclarationCleanUp;
112 import org.eclipse.jdt.internal.ui.viewsupport.JavaElementImageProvider;
113
114 /**
115   */

116 public class QuickAssistProcessor implements IQuickAssistProcessor {
117
118     public static final String JavaDoc SPLIT_JOIN_VARIABLE_DECLARATION_ID= "org.eclipse.jdt.ui.correction.splitJoinVariableDeclaration.assist"; //$NON-NLS-1$
119
public static final String JavaDoc CONVERT_FOR_LOOP_ID= "org.eclipse.jdt.ui.correction.convertForLoop.assist"; //$NON-NLS-1$
120
public static final String JavaDoc ASSIGN_TO_LOCAL_ID= "org.eclipse.jdt.ui.correction.assignToLocal.assist"; //$NON-NLS-1$
121
public static final String JavaDoc ASSIGN_TO_FIELD_ID= "org.eclipse.jdt.ui.correction.assignToField.assist"; //$NON-NLS-1$
122
public static final String JavaDoc ASSIGN_PARAM_TO_FIELD_ID= "org.eclipse.jdt.ui.correction.assignParamToField.assist"; //$NON-NLS-1$
123
public static final String JavaDoc ADD_BLOCK_ID= "org.eclipse.jdt.ui.correction.addBlock.assist"; //$NON-NLS-1$
124
public static final String JavaDoc EXTRACT_LOCAL_ID= "org.eclipse.jdt.ui.correction.extractLocal.assist"; //$NON-NLS-1$
125
public static final String JavaDoc EXTRACT_CONSTANT_ID= "org.eclipse.jdt.ui.correction.extractConstant.assist"; //$NON-NLS-1$
126
public static final String JavaDoc INLINE_LOCAL_ID= "org.eclipse.jdt.ui.correction.inlineLocal.assist"; //$NON-NLS-1$
127
public static final String JavaDoc CONVERT_LOCAL_TO_FIELD_ID= "org.eclipse.jdt.ui.correction.convertLocalToField.assist"; //$NON-NLS-1$
128
public static final String JavaDoc CONVERT_ANONYMOUS_TO_LOCAL_ID= "org.eclipse.jdt.ui.correction.convertAnonymousToLocal.assist"; //$NON-NLS-1$
129

130     public QuickAssistProcessor() {
131         super();
132     }
133
134     public boolean hasAssists(IInvocationContext context) throws CoreException {
135         ASTNode coveringNode= context.getCoveringNode();
136         if (coveringNode != null) {
137             return getCatchClauseToThrowsProposals(context, coveringNode, null)
138                 || getRenameLocalProposals(context, coveringNode, null, false, null)
139                 || getAssignToVariableProposals(context, coveringNode, null)
140                 || getUnWrapProposals(context, coveringNode, null)
141                 || getAssignParamToFieldProposals(context, coveringNode, null)
142                 || getJoinVariableProposals(context, coveringNode, null)
143                 || getAddFinallyProposals(context, coveringNode, null)
144                 || getAddElseProposals(context, coveringNode, null)
145                 || getSplitVariableProposals(context, coveringNode, null)
146                 || getAddBlockProposals(context, coveringNode, null)
147                 || getArrayInitializerToArrayCreation(context, coveringNode, null)
148                 || getCreateInSuperClassProposals(context, coveringNode, null)
149                 || getInvertEqualsProposal(context, coveringNode, null)
150                 || getConvertForLoopProposal(context, coveringNode, null)
151                 || getExtractLocalProposal(context, coveringNode, null)
152                 || getInlineLocalProposal(context, coveringNode, null)
153                 || getConvertLocalToFieldProposal(context, coveringNode, null)
154                 || getConvertAnonymousToNestedProposal(context, coveringNode, null)
155                 || getConvertIterableLoopProposal(context, coveringNode, null)
156                 || getRemoveBlockProposals(context, coveringNode, null)
157                 || getMakeVariableDeclarationFinalProposals(context, coveringNode, null);
158         }
159         return false;
160     }
161
162     public IJavaCompletionProposal[] getAssists(IInvocationContext context, IProblemLocation[] locations) throws CoreException {
163         ASTNode coveringNode= context.getCoveringNode();
164         if (coveringNode != null) {
165             ArrayList JavaDoc resultingCollections= new ArrayList JavaDoc();
166             boolean noErrorsAtLocation= noErrorsAtLocation(locations);
167             
168             // quick assists that show up also if there is an error/warning
169
getRenameLocalProposals(context, coveringNode, locations, noErrorsAtLocation, resultingCollections);
170             getAssignToVariableProposals(context, coveringNode, resultingCollections);
171             getAssignParamToFieldProposals(context, coveringNode, resultingCollections);
172             
173             if (noErrorsAtLocation) {
174                 getCatchClauseToThrowsProposals(context, coveringNode, resultingCollections);
175                 getUnWrapProposals(context, coveringNode, resultingCollections);
176                 getSplitVariableProposals(context, coveringNode, resultingCollections);
177                 getJoinVariableProposals(context, coveringNode, resultingCollections);
178                 getAddFinallyProposals(context, coveringNode, resultingCollections);
179                 getAddElseProposals(context, coveringNode, resultingCollections);
180                 getAddBlockProposals(context, coveringNode, resultingCollections);
181                 getInvertEqualsProposal(context, coveringNode, resultingCollections);
182                 getArrayInitializerToArrayCreation(context, coveringNode, resultingCollections);
183                 getCreateInSuperClassProposals(context, coveringNode, resultingCollections);
184                 getExtractLocalProposal(context, coveringNode, resultingCollections);
185                 getInlineLocalProposal(context, coveringNode, resultingCollections);
186                 getConvertLocalToFieldProposal(context, coveringNode, resultingCollections);
187                 getConvertAnonymousToNestedProposal(context, coveringNode, resultingCollections);
188                 if (!getConvertForLoopProposal(context, coveringNode, resultingCollections))
189                     getConvertIterableLoopProposal(context, coveringNode, resultingCollections);
190                 getRemoveBlockProposals(context, coveringNode, resultingCollections);
191                 getMakeVariableDeclarationFinalProposals(context, coveringNode, resultingCollections);
192             }
193             return (IJavaCompletionProposal[]) resultingCollections.toArray(new IJavaCompletionProposal[resultingCollections.size()]);
194         }
195         return null;
196     }
197
198     private boolean noErrorsAtLocation(IProblemLocation[] locations) {
199         if (locations != null) {
200             for (int i= 0; i < locations.length; i++) {
201                 if (locations[i].isError()) {
202                     return false;
203                 }
204             }
205         }
206         return true;
207     }
208     
209     private static boolean getExtractLocalProposal(IInvocationContext context, ASTNode covering, Collection JavaDoc proposals) throws CoreException {
210         ASTNode node= context.getCoveredNode();
211         
212         if (!(node instanceof Expression)) {
213             return false;
214         }
215         final Expression expression= (Expression) node;
216         
217         ITypeBinding binding= expression.resolveTypeBinding();
218         if (binding == null || Bindings.isVoidType(binding)) {
219             return false;
220         }
221         if (proposals == null) {
222             return true;
223         }
224         
225         final ICompilationUnit cu= context.getCompilationUnit();
226         final ExtractTempRefactoring extractTempRefactoring= new ExtractTempRefactoring(context.getASTRoot(), expression.getStartPosition(), expression.getLength());
227         if (extractTempRefactoring.checkInitialConditions(new NullProgressMonitor()).isOK()) {
228             String JavaDoc label= CorrectionMessages.QuickAssistProcessor_extract_to_local_description;
229             Image image= JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_LOCAL);
230             CUCorrectionProposal proposal= new CUCorrectionProposal(label, cu, 5, image) {
231                 protected TextChange createTextChange() throws CoreException {
232                     extractTempRefactoring.setTempName(extractTempRefactoring.guessTempName()); // expensive
233
extractTempRefactoring.setLinkedProposalModel(getLinkedProposalModel());
234                     return extractTempRefactoring.createTextChange(new NullProgressMonitor());
235                 }
236             };
237             proposal.setCommandId(EXTRACT_LOCAL_ID);
238             proposals.add(proposal);
239         }
240         final ExtractConstantRefactoring extractConstRefactoring= new ExtractConstantRefactoring(context.getASTRoot(), expression.getStartPosition(), expression.getLength());
241         if (extractConstRefactoring.checkInitialConditions(new NullProgressMonitor()).isOK()) {
242             String JavaDoc label= CorrectionMessages.QuickAssistProcessor_extract_to_constant_description;
243             Image image= JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_LOCAL);
244             CUCorrectionProposal proposal= new CUCorrectionProposal(label, cu, 4, image) {
245                 protected TextChange createTextChange() throws CoreException {
246                     extractConstRefactoring.setConstantName(extractConstRefactoring.guessConstantName()); // expensive
247
extractConstRefactoring.setLinkedProposalModel(getLinkedProposalModel());
248                     return extractConstRefactoring.createTextChange(new NullProgressMonitor());
249                 }
250             };
251             proposal.setCommandId(EXTRACT_CONSTANT_ID);
252             proposals.add(proposal);
253         }
254         return false;
255     }
256     
257
258     private static boolean getConvertAnonymousToNestedProposal(IInvocationContext context, final ASTNode node, Collection JavaDoc proposals) throws CoreException {
259         if (!(node instanceof Name))
260             return false;
261         
262         ASTNode normalized= ASTNodes.getNormalizedNode(node);
263         if (normalized.getLocationInParent() != ClassInstanceCreation.TYPE_PROPERTY)
264             return false;
265         
266         final AnonymousClassDeclaration anonymTypeDecl= ((ClassInstanceCreation) normalized.getParent()).getAnonymousClassDeclaration();
267         if (anonymTypeDecl == null || anonymTypeDecl.resolveBinding() == null) {
268             return false;
269         }
270         
271         if (proposals == null) {
272             return true;
273         }
274
275         final ICompilationUnit cu= context.getCompilationUnit();
276         final ConvertAnonymousToNestedRefactoring refactoring= new ConvertAnonymousToNestedRefactoring(anonymTypeDecl);
277         String JavaDoc extTypeName= ASTNodes.getSimpleNameIdentifier((Name) node);
278         if (anonymTypeDecl.resolveBinding().getInterfaces().length == 0) {
279             refactoring.setClassName(Messages.format(CorrectionMessages.QuickAssistProcessor_name_extension_from_interface, extTypeName));
280         } else {
281             refactoring.setClassName(Messages.format(CorrectionMessages.QuickAssistProcessor_name_extension_from_class, extTypeName));
282         }
283
284         if (refactoring.checkInitialConditions(new NullProgressMonitor()).isOK()) {
285             LinkedProposalModel linkedProposalModel= new LinkedProposalModel();
286             refactoring.setLinkedProposalModel(linkedProposalModel);
287             
288             String JavaDoc label= CorrectionMessages.QuickAssistProcessor_convert_anonym_to_nested;
289             Image image= JavaPlugin.getImageDescriptorRegistry().get(JavaElementImageProvider.getTypeImageDescriptor(true, false, Flags.AccPrivate, false));
290             RefactoringCorrectionProposal proposal= new RefactoringCorrectionProposal(label, cu, refactoring, 5, image);
291             proposal.setLinkedProposalModel(linkedProposalModel);
292             proposal.setCommandId(CONVERT_ANONYMOUS_TO_LOCAL_ID);
293             proposals.add(proposal);
294         }
295         return false;
296     }
297
298     private static boolean getJoinVariableProposals(IInvocationContext context, ASTNode node, Collection JavaDoc resultingCollections) {
299         ASTNode parent= node.getParent();
300         
301         VariableDeclarationFragment fragment= null;
302         boolean onFirstAccess= false;
303         if (node instanceof SimpleName && node.getLocationInParent() == Assignment.LEFT_HAND_SIDE_PROPERTY) {
304             onFirstAccess= true;
305             SimpleName name= (SimpleName) node;
306             IBinding binding= name.resolveBinding();
307             if (!(binding instanceof IVariableBinding)) {
308                 return false;
309             }
310             ASTNode declaring= context.getASTRoot().findDeclaringNode(binding);
311             if (declaring instanceof VariableDeclarationFragment) {
312                 fragment= (VariableDeclarationFragment) declaring;
313             } else {
314                 return false;
315             }
316         } else if (parent instanceof VariableDeclarationFragment) {
317             fragment= (VariableDeclarationFragment) parent;
318         } else {
319             return false;
320         }
321
322         IVariableBinding binding= fragment.resolveBinding();
323         if (fragment.getInitializer() != null || binding == null || binding.isField()) {
324             return false;
325         }
326
327         if (!(fragment.getParent() instanceof VariableDeclarationStatement)) {
328             return false;
329         }
330         VariableDeclarationStatement statement= (VariableDeclarationStatement) fragment.getParent();
331
332         SimpleName[] names= LinkedNodeFinder.findByBinding(statement.getParent(), binding);
333         if (names.length <= 1 || names[0] != fragment.getName()) {
334             return false;
335         }
336         SimpleName firstAccess= names[1];
337         if (onFirstAccess) {
338             if (firstAccess != node) {
339                 return false;
340             }
341         } else {
342             if (firstAccess.getLocationInParent() != Assignment.LEFT_HAND_SIDE_PROPERTY) {
343                 return false;
344             }
345         }
346         Assignment assignment= (Assignment) firstAccess.getParent();
347         if (assignment.getLocationInParent() != ExpressionStatement.EXPRESSION_PROPERTY) {
348             return false;
349         }
350         ExpressionStatement assignParent= (ExpressionStatement) assignment.getParent();
351
352         if (resultingCollections == null) {
353             return true;
354         }
355
356         AST ast= statement.getAST();
357         ASTRewrite rewrite= ASTRewrite.create(ast);
358
359         String JavaDoc label= CorrectionMessages.QuickAssistProcessor_joindeclaration_description;
360         Image image= JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_LOCAL);
361         LinkedCorrectionProposal proposal= new LinkedCorrectionProposal(label, context.getCompilationUnit(), rewrite, 1, image);
362         proposal.setCommandId(SPLIT_JOIN_VARIABLE_DECLARATION_ID);
363         
364         Expression placeholder= (Expression) rewrite.createMoveTarget(assignment.getRightHandSide());
365         rewrite.set(fragment, VariableDeclarationFragment.INITIALIZER_PROPERTY, placeholder, null);
366
367         
368         if (onFirstAccess) {
369             // replace assignment with variable declaration
370
rewrite.replace(assignParent, rewrite.createMoveTarget(statement), null);
371         } else {
372             // different scopes -> remove assignments, set variable initializer
373
if (ASTNodes.isControlStatementBody(assignParent.getLocationInParent())) {
374                 Block block= ast.newBlock();
375                 rewrite.replace(assignParent, block, null);
376             } else {
377                 rewrite.remove(assignParent, null);
378             }
379         }
380
381         proposal.setEndPosition(rewrite.track(fragment.getName()));
382         resultingCollections.add(proposal);
383         return true;
384
385     }
386
387     private static boolean getSplitVariableProposals(IInvocationContext context, ASTNode node, Collection JavaDoc resultingCollections) {
388         VariableDeclarationFragment fragment;
389         if (node instanceof VariableDeclarationFragment) {
390             fragment= (VariableDeclarationFragment) node;
391         } else if (node.getLocationInParent() == VariableDeclarationFragment.NAME_PROPERTY) {
392             fragment= (VariableDeclarationFragment) node.getParent();
393         } else {
394             return false;
395         }
396
397         if (fragment.getInitializer() == null) {
398             return false;
399         }
400
401         Statement statement;
402         ASTNode fragParent= fragment.getParent();
403         if (fragParent instanceof VariableDeclarationStatement) {
404             statement= (VariableDeclarationStatement) fragParent;
405         } else if (fragParent instanceof VariableDeclarationExpression) {
406             statement= (Statement) fragParent.getParent();
407         } else {
408             return false;
409         }
410         // statement is ForStatement or VariableDeclarationStatement
411

412         ASTNode statementParent= statement.getParent();
413         StructuralPropertyDescriptor property= statement.getLocationInParent();
414         if (!property.isChildListProperty()) {
415             return false;
416         }
417
418         List JavaDoc list= (List JavaDoc) statementParent.getStructuralProperty(property);
419
420         if (resultingCollections == null) {
421             return true;
422         }
423
424         AST ast= statement.getAST();
425         ASTRewrite rewrite= ASTRewrite.create(ast);
426
427         String JavaDoc label= CorrectionMessages.QuickAssistProcessor_splitdeclaration_description;
428         Image image= JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_LOCAL);
429         ASTRewriteCorrectionProposal proposal= new ASTRewriteCorrectionProposal(label, context.getCompilationUnit(), rewrite, 1, image);
430         proposal.setCommandId(SPLIT_JOIN_VARIABLE_DECLARATION_ID);
431         
432         Statement newStatement;
433         int insertIndex= list.indexOf(statement);
434
435         Expression placeholder= (Expression) rewrite.createMoveTarget(fragment.getInitializer());
436         ITypeBinding binding= fragment.getInitializer().resolveTypeBinding();
437         if (placeholder instanceof ArrayInitializer && binding != null && binding.isArray()) {
438             ArrayCreation creation= ast.newArrayCreation();
439             creation.setInitializer((ArrayInitializer) placeholder);
440             final ITypeBinding componentType= binding.getElementType();
441             Type type= null;
442             if (componentType.isPrimitive())
443                 type= ast.newPrimitiveType(PrimitiveType.toCode(componentType.getName()));
444             else
445                 type= ast.newSimpleType(ast.newSimpleName(componentType.getName()));
446             creation.setType(ast.newArrayType(type, binding.getDimensions()));
447             placeholder= creation;
448         }
449         Assignment assignment= ast.newAssignment();
450         assignment.setRightHandSide(placeholder);
451         assignment.setLeftHandSide(ast.newSimpleName(fragment.getName().getIdentifier()));
452
453         if (statement instanceof VariableDeclarationStatement) {
454             newStatement= ast.newExpressionStatement(assignment);
455             insertIndex+= 1; // add after declaration
456
} else {
457             rewrite.replace(fragment.getParent(), assignment, null);
458             VariableDeclarationFragment newFrag= ast.newVariableDeclarationFragment();
459             newFrag.setName(ast.newSimpleName(fragment.getName().getIdentifier()));
460             newFrag.setExtraDimensions(fragment.getExtraDimensions());
461
462             VariableDeclarationExpression oldVarDecl= (VariableDeclarationExpression) fragParent;
463
464             VariableDeclarationStatement newVarDec= ast.newVariableDeclarationStatement(newFrag);
465             newVarDec.setType((Type) ASTNode.copySubtree(ast, oldVarDecl.getType()));
466             newVarDec.modifiers().addAll(ASTNodeFactory.newModifiers(ast, oldVarDecl.getModifiers()));
467             newStatement= newVarDec;
468         }
469
470         ListRewrite listRewriter= rewrite.getListRewrite(statementParent, (ChildListPropertyDescriptor) property);
471         listRewriter.insertAt(newStatement, insertIndex, null);
472
473         resultingCollections.add(proposal);
474         return true;
475     }
476
477     private static boolean getAssignToVariableProposals(IInvocationContext context, ASTNode node, Collection JavaDoc resultingCollections) {
478         Statement statement= ASTResolving.findParentStatement(node);
479         if (!(statement instanceof ExpressionStatement)) {
480             return false;
481         }
482         ExpressionStatement expressionStatement= (ExpressionStatement) statement;
483
484         Expression expression= expressionStatement.getExpression();
485         if (expression.getNodeType() == ASTNode.ASSIGNMENT) {
486             return false; // too confusing and not helpful
487
}
488
489         ITypeBinding typeBinding= expression.resolveTypeBinding();
490         typeBinding= Bindings.normalizeTypeBinding(typeBinding);
491         if (typeBinding == null) {
492             return false;
493         }
494         if (resultingCollections == null) {
495             return true;
496         }
497
498         ICompilationUnit cu= context.getCompilationUnit();
499
500         AssignToVariableAssistProposal localProposal= new AssignToVariableAssistProposal(cu, AssignToVariableAssistProposal.LOCAL, expressionStatement, typeBinding, 2);
501         localProposal.setCommandId(ASSIGN_TO_LOCAL_ID);
502         resultingCollections.add(localProposal);
503
504         ASTNode type= ASTResolving.findParentType(expression);
505         if (type != null) {
506             AssignToVariableAssistProposal fieldProposal= new AssignToVariableAssistProposal(cu, AssignToVariableAssistProposal.FIELD, expressionStatement, typeBinding, 1);
507             fieldProposal.setCommandId(ASSIGN_TO_FIELD_ID);
508             resultingCollections.add(fieldProposal);
509         }
510         return false;
511
512     }
513
514     private static boolean getAssignParamToFieldProposals(IInvocationContext context, ASTNode node, Collection JavaDoc resultingCollections) {
515         node= ASTNodes.getNormalizedNode(node);
516         ASTNode parent= node.getParent();
517         if (!(parent instanceof SingleVariableDeclaration) || !(parent.getParent() instanceof MethodDeclaration)) {
518             return false;
519         }
520         SingleVariableDeclaration paramDecl= (SingleVariableDeclaration) parent;
521         IVariableBinding binding= paramDecl.resolveBinding();
522
523         MethodDeclaration methodDecl= (MethodDeclaration) parent.getParent();
524         if (binding == null || methodDecl.getBody() == null) {
525             return false;
526         }
527         ITypeBinding typeBinding= binding.getType();
528         if (typeBinding == null) {
529             return false;
530         }
531         
532         if (resultingCollections == null) {
533             return true;
534         }
535         
536         ITypeBinding parentType= Bindings.getBindingOfParentType(node);
537         if (parentType != null) {
538             // assign to existing fields
539
CompilationUnit root= context.getASTRoot();
540             IVariableBinding[] declaredFields= parentType.getDeclaredFields();
541             boolean isStaticContext= ASTResolving.isInStaticContext(node);
542             for (int i= 0; i < declaredFields.length; i++) {
543                 IVariableBinding curr= declaredFields[i];
544                 if (isStaticContext == Modifier.isStatic(curr.getModifiers()) && typeBinding.isAssignmentCompatible(curr.getType())) {
545                     ASTNode fieldDeclFrag= root.findDeclaringNode(curr);
546                     if (fieldDeclFrag instanceof VariableDeclarationFragment) {
547                         VariableDeclarationFragment fragment= (VariableDeclarationFragment) fieldDeclFrag;
548                         if (fragment.getInitializer() == null) {
549                             resultingCollections.add(new AssignToVariableAssistProposal(context.getCompilationUnit(), paramDecl, fragment, typeBinding, 1));
550                         }
551                     }
552                 }
553             }
554         }
555
556         AssignToVariableAssistProposal fieldProposal= new AssignToVariableAssistProposal(context.getCompilationUnit(), paramDecl, null, typeBinding, 3);
557         fieldProposal.setCommandId(ASSIGN_PARAM_TO_FIELD_ID);
558         resultingCollections.add(fieldProposal);
559         return true;
560     }
561
562     private static boolean getAddFinallyProposals(IInvocationContext context, ASTNode node, Collection JavaDoc resultingCollections) {
563         TryStatement tryStatement= ASTResolving.findParentTryStatement(node);
564         if (tryStatement == null || tryStatement.getFinally() != null) {
565             return false;
566         }
567         Statement statement= ASTResolving.findParentStatement(node);
568         if (tryStatement != statement && tryStatement.getBody() != statement) {
569             return false; // an node inside a catch or finally block
570
}
571
572         if (resultingCollections == null) {
573             return true;
574         }
575
576         AST ast= tryStatement.getAST();
577         ASTRewrite rewrite= ASTRewrite.create(ast);
578         Block finallyBody= ast.newBlock();
579
580         rewrite.set(tryStatement, TryStatement.FINALLY_PROPERTY, finallyBody, null);
581
582         String JavaDoc label= CorrectionMessages.QuickAssistProcessor_addfinallyblock_description;
583         Image image= JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_ADD);
584         ASTRewriteCorrectionProposal proposal= new ASTRewriteCorrectionProposal(label, context.getCompilationUnit(), rewrite, 1, image);
585         resultingCollections.add(proposal);
586         return true;
587     }
588
589     private static boolean getAddElseProposals(IInvocationContext context, ASTNode node, Collection JavaDoc resultingCollections) {
590         Statement statement= ASTResolving.findParentStatement(node);
591         if (!(statement instanceof IfStatement)) {
592             return false;
593         }
594         IfStatement ifStatement= (IfStatement) statement;
595         if (ifStatement.getElseStatement() != null) {
596             return false;
597         }
598
599         if (resultingCollections == null) {
600             return true;
601         }
602
603         AST ast= statement.getAST();
604         ASTRewrite rewrite= ASTRewrite.create(ast);
605         Block body= ast.newBlock();
606
607         rewrite.set(ifStatement, IfStatement.ELSE_STATEMENT_PROPERTY, body, null);
608
609         String JavaDoc label= CorrectionMessages.QuickAssistProcessor_addelseblock_description;
610         Image image= JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_ADD);
611         ASTRewriteCorrectionProposal proposal= new ASTRewriteCorrectionProposal(label, context.getCompilationUnit(), rewrite, 1, image);
612         resultingCollections.add(proposal);
613         return true;
614     }
615
616     public static boolean getCatchClauseToThrowsProposals(IInvocationContext context, ASTNode node, Collection JavaDoc resultingCollections) {
617         CatchClause catchClause= (CatchClause) ASTResolving.findAncestor(node, ASTNode.CATCH_CLAUSE);
618         if (catchClause == null) {
619             return false;
620         }
621
622         Statement statement= ASTResolving.findParentStatement(node);
623         if (statement != catchClause.getParent() && statement != catchClause.getBody()) {
624             return false; // selection is in a statement inside the body
625
}
626
627         Type type= catchClause.getException().getType();
628         if (!type.isSimpleType()) {
629             return false;
630         }
631
632         BodyDeclaration bodyDeclaration= ASTResolving.findParentBodyDeclaration(catchClause);
633         if (!(bodyDeclaration instanceof MethodDeclaration) && !(bodyDeclaration instanceof Initializer)) {
634             return false;
635         }
636
637         if (resultingCollections == null) {
638             return true;
639         }
640
641         AST ast= bodyDeclaration.getAST();
642
643         if (bodyDeclaration instanceof MethodDeclaration) {
644             MethodDeclaration methodDeclaration= (MethodDeclaration) bodyDeclaration;
645
646             ASTRewrite rewrite= ASTRewrite.create(ast);
647
648             removeCatchBlock(rewrite, catchClause);
649
650             ITypeBinding binding= type.resolveBinding();
651             if (binding == null || isNotYetThrown(binding, methodDeclaration.thrownExceptions())) {
652                 Name name= ((SimpleType) type).getName();
653                 Name newName= (Name) ASTNode.copySubtree(ast, name);
654
655                 ListRewrite listRewriter= rewrite.getListRewrite(methodDeclaration, MethodDeclaration.THROWN_EXCEPTIONS_PROPERTY);
656                 listRewriter.insertLast(newName, null);
657             }
658
659             String JavaDoc label= CorrectionMessages.QuickAssistProcessor_catchclausetothrows_description;
660             Image image= JavaPluginImages.get(JavaPluginImages.IMG_OBJS_EXCEPTION);
661             ASTRewriteCorrectionProposal proposal= new ASTRewriteCorrectionProposal(label, context.getCompilationUnit(), rewrite, 4, image);
662             resultingCollections.add(proposal);
663         }
664         { // for initializers or method declarations
665
ASTRewrite rewrite= ASTRewrite.create(ast);
666
667             removeCatchBlock(rewrite, catchClause);
668             String JavaDoc label= CorrectionMessages.QuickAssistProcessor_removecatchclause_description;
669             Image image= JavaPluginImages.get(JavaPluginImages.IMG_OBJS_EXCEPTION);
670             ASTRewriteCorrectionProposal proposal= new ASTRewriteCorrectionProposal(label, context.getCompilationUnit(), rewrite, 5, image);
671             resultingCollections.add(proposal);
672         }
673
674         return true;
675     }
676
677     private static void removeCatchBlock(ASTRewrite rewrite, CatchClause catchClause) {
678         TryStatement tryStatement= (TryStatement) catchClause.getParent();
679         if (tryStatement.catchClauses().size() > 1 || tryStatement.getFinally() != null) {
680             rewrite.remove(catchClause, null);
681         } else {
682             Block block= tryStatement.getBody();
683             List JavaDoc statements= block.statements();
684             int nStatements= statements.size();
685             if (nStatements == 1) {
686                 ASTNode first= (ASTNode) statements.get(0);
687                 rewrite.replace(tryStatement, rewrite.createCopyTarget(first), null);
688             } else if (nStatements > 1) {
689                 ListRewrite listRewrite= rewrite.getListRewrite(block, Block.STATEMENTS_PROPERTY);
690                 ASTNode first= (ASTNode) statements.get(0);
691                 ASTNode last= (ASTNode) statements.get(statements.size() - 1);
692                 ASTNode newStatement= listRewrite.createCopyTarget(first, last);
693                 if (ASTNodes.isControlStatementBody(tryStatement.getLocationInParent())) {
694                     Block newBlock= rewrite.getAST().newBlock();
695                     newBlock.statements().add(newStatement);
696                     newStatement= newBlock;
697                 }
698                 rewrite.replace(tryStatement, newStatement, null);
699             } else {
700                 rewrite.remove(tryStatement, null);
701             }
702         }
703     }
704
705     private static boolean isNotYetThrown(ITypeBinding binding, List JavaDoc thrownExcpetions) {
706         for (int i= 0; i < thrownExcpetions.size(); i++) {
707             Name name= (Name) thrownExcpetions.get(i);
708             ITypeBinding elem= (ITypeBinding) name.resolveBinding();
709             if (elem != null) {
710                 if (Bindings.isSuperType(elem, binding)) { // existing exception is base class of new
711
return false;
712                 }
713             }
714         }
715         return true;
716     }
717
718
719     private static boolean getRenameLocalProposals(IInvocationContext context, ASTNode node, IProblemLocation[] locations, boolean noErrorsAtLocation, Collection JavaDoc resultingCollections) {
720         if (!(node instanceof SimpleName)) {
721             return false;
722         }
723         SimpleName name= (SimpleName) node;
724         IBinding binding= name.resolveBinding();
725         if (binding != null && binding.getKind() == IBinding.PACKAGE) {
726             return false;
727         }
728
729         if (locations != null) {
730             for (int i= 0; i < locations.length; i++) {
731                 switch (locations[i].getProblemId()) {
732                     case IProblem.LocalVariableHidingLocalVariable:
733                     case IProblem.LocalVariableHidingField:
734                     case IProblem.FieldHidingLocalVariable:
735                     case IProblem.FieldHidingField:
736                     case IProblem.ArgumentHidingLocalVariable:
737                     case IProblem.ArgumentHidingField:
738                         return false;
739                 }
740             }
741         }
742
743         if (resultingCollections == null) {
744             return true;
745         }
746
747         LinkedNamesAssistProposal proposal= new LinkedNamesAssistProposal(context.getCompilationUnit(), name);
748         if (!noErrorsAtLocation) {
749             proposal.setRelevance(1);
750         }
751         
752         resultingCollections.add(proposal);
753         return true;
754     }
755
756     public static ASTNode getCopyOfInner(ASTRewrite rewrite, ASTNode statement, boolean toControlStatementBody) {
757         if (statement.getNodeType() == ASTNode.BLOCK) {
758             Block block= (Block) statement;
759             List JavaDoc innerStatements= block.statements();
760             int nStatements= innerStatements.size();
761             if (nStatements == 1) {
762                 return rewrite.createCopyTarget(((ASTNode) innerStatements.get(0)));
763             } else if (nStatements > 1) {
764                 if (toControlStatementBody) {
765                     return rewrite.createCopyTarget(block);
766                 }
767                 ListRewrite listRewrite= rewrite.getListRewrite(block, Block.STATEMENTS_PROPERTY);
768                 ASTNode first= (ASTNode) innerStatements.get(0);
769                 ASTNode last= (ASTNode) innerStatements.get(nStatements - 1);
770                 return listRewrite.createCopyTarget(first, last);
771             }
772             return null;
773         } else {
774             return rewrite.createCopyTarget(statement);
775         }
776     }
777
778
779     private static boolean getUnWrapProposals(IInvocationContext context, ASTNode node, Collection JavaDoc resultingCollections) {
780         ASTNode outer= node;
781
782         Block block= null;
783         if (outer.getNodeType() == ASTNode.BLOCK) {
784             block= (Block) outer;
785             outer= block.getParent();
786         }
787
788         ASTNode body= null;
789         String JavaDoc label= null;
790         if (outer instanceof IfStatement) {
791             IfStatement ifStatement= (IfStatement) outer;
792             Statement elseBlock= ifStatement.getElseStatement();
793             if (elseBlock == null || ((elseBlock instanceof Block) && ((Block) elseBlock).statements().isEmpty())) {
794                 body= ifStatement.getThenStatement();
795             }
796             label= CorrectionMessages.QuickAssistProcessor_unwrap_ifstatement;
797         } else if (outer instanceof WhileStatement) {
798             body=((WhileStatement) outer).getBody();
799             label= CorrectionMessages.QuickAssistProcessor_unwrap_whilestatement;
800         } else if (outer instanceof ForStatement) {
801             body=((ForStatement) outer).getBody();
802             label= CorrectionMessages.QuickAssistProcessor_unwrap_forstatement;
803         } else if (outer instanceof DoStatement) {
804             body=((DoStatement) outer).getBody();
805             label= CorrectionMessages.QuickAssistProcessor_unwrap_dostatement;
806         } else if (outer instanceof TryStatement) {
807             TryStatement tryStatement= (TryStatement) outer;
808             if (tryStatement.catchClauses().isEmpty()) {
809                 body= tryStatement.getBody();
810             }
811             label= CorrectionMessages.QuickAssistProcessor_unwrap_trystatement;
812         } else if (outer instanceof AnonymousClassDeclaration) {
813             List JavaDoc decls= ((AnonymousClassDeclaration) outer).bodyDeclarations();
814             for (int i= 0; i < decls.size(); i++) {
815                 ASTNode elem= (ASTNode) decls.get(i);
816                 if (elem instanceof MethodDeclaration) {
817                     Block curr= ((MethodDeclaration) elem).getBody();
818                     if (curr != null && !curr.statements().isEmpty()) {
819                         if (body != null) {
820                             return false;
821                         }
822                         body= curr;
823                     }
824                 } else if (elem instanceof TypeDeclaration) {
825                     return false;
826                 }
827             }
828             label= CorrectionMessages.QuickAssistProcessor_unwrap_anonymous;
829             outer= ASTResolving.findParentStatement(outer);
830             if (outer == null) {
831                 return false; // private Object o= new Object() { ... };
832
}
833         } else if (outer instanceof Block) {
834             // -> a block in a block
835
body= block;
836             outer= block;
837             label= CorrectionMessages.QuickAssistProcessor_unwrap_block;
838         } else if (outer instanceof ParenthesizedExpression) {
839             //ParenthesizedExpression expression= (ParenthesizedExpression) outer;
840
//body= expression.getExpression();
841
//label= CorrectionMessages.getString("QuickAssistProcessor.unwrap.parenthesis"); //$NON-NLS-1$
842
} else if (outer instanceof MethodInvocation) {
843             MethodInvocation invocation= (MethodInvocation) outer;
844             if (invocation.arguments().size() == 1) {
845                 body= (ASTNode) invocation.arguments().get(0);
846                 if (invocation.getParent().getNodeType() == ASTNode.EXPRESSION_STATEMENT) {
847                     int kind= body.getNodeType();
848                     if (kind != ASTNode.ASSIGNMENT && kind != ASTNode.PREFIX_EXPRESSION && kind != ASTNode.POSTFIX_EXPRESSION
849                             && kind != ASTNode.METHOD_INVOCATION && kind != ASTNode.SUPER_METHOD_INVOCATION) {
850                         body= null;
851                     }
852                 }
853                 label= CorrectionMessages.QuickAssistProcessor_unwrap_methodinvocation;
854             }
855         }
856         if (body == null) {
857             return false;
858         }
859         ASTRewrite rewrite= ASTRewrite.create(outer.getAST());
860         ASTNode inner= getCopyOfInner(rewrite, body, ASTNodes.isControlStatementBody(outer.getLocationInParent()));
861         if (inner == null) {
862             return false;
863         }
864         if (resultingCollections == null) {
865             return true;
866         }
867
868         rewrite.replace(outer, inner, null);
869         Image image= JavaPluginImages.get(JavaPluginImages.IMG_OBJS_EXCEPTION);
870         ASTRewriteCorrectionProposal proposal= new ASTRewriteCorrectionProposal(label, context.getCompilationUnit(), rewrite, 1, image);
871         resultingCollections.add(proposal);
872         return true;
873     }
874
875     private static boolean isControlStatementWithBlock(ASTNode node) {
876         switch (node.getNodeType()) {
877             case ASTNode.IF_STATEMENT:
878             case ASTNode.WHILE_STATEMENT:
879             case ASTNode.FOR_STATEMENT:
880             case ASTNode.DO_STATEMENT:
881                 return true;
882             default:
883                 return false;
884         }
885     }
886
887     private static boolean getRemoveBlockProposals(IInvocationContext context, ASTNode coveringNode, Collection JavaDoc resultingCollections) {
888         IFix[] fixes= ControlStatementsFix.createRemoveBlockFix(context.getASTRoot(), coveringNode);
889         if (fixes != null) {
890             if (resultingCollections == null) {
891                 return true;
892             }
893             Map JavaDoc options= new Hashtable JavaDoc();
894             options.put(CleanUpConstants.CONTROL_STATEMENTS_USE_BLOCKS, CleanUpConstants.TRUE);
895             options.put(CleanUpConstants.CONTROL_STATMENTS_USE_BLOCKS_NEVER, CleanUpConstants.TRUE);
896             ICleanUp cleanUp= new ControlStatementsCleanUp(options);
897             for (int i= 0; i < fixes.length; i++) {
898                 IFix fix= fixes[i];
899                 Image image= JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_CHANGE);
900                 FixCorrectionProposal proposal= new FixCorrectionProposal(fix, cleanUp, 0, image, context);
901                 resultingCollections.add(proposal);
902             }
903             return true;
904         }
905         return false;
906     }
907
908     private static boolean getAddBlockProposals(IInvocationContext context, ASTNode node, Collection JavaDoc resultingCollections) {
909         Statement statement= ASTResolving.findParentStatement(node);
910         if (statement == null) {
911             return false;
912         }
913
914         if (!isControlStatementWithBlock(statement)) {
915             if (!isControlStatementWithBlock(statement.getParent())) {
916                 return false;
917             }
918             int statementStart= statement.getStartPosition();
919             int statementEnd= statementStart + statement.getLength();
920
921             int offset= context.getSelectionOffset();
922             int length= context.getSelectionLength();
923             if (length == 0) {
924                 if (offset != statementEnd) { // cursor at end
925
return false;
926                 }
927             } else {
928                 if (offset > statementStart || offset + length < statementEnd) { // statement selected
929
return false;
930                 }
931             }
932             statement= (Statement) statement.getParent();
933         }
934
935         StructuralPropertyDescriptor childProperty= null;
936         ASTNode child= null;
937         switch (statement.getNodeType()) {
938             case ASTNode.IF_STATEMENT:
939                 int selectionStart= context.getSelectionOffset();
940                 int selectionEnd= context.getSelectionOffset() + context.getSelectionLength();
941                 ASTNode then= ((IfStatement) statement).getThenStatement();
942                 if (selectionEnd <= then.getStartPosition() + then.getLength()) {
943                     if (!(then instanceof Block)) {
944                         childProperty= IfStatement.THEN_STATEMENT_PROPERTY;
945                         child= then;
946                     }
947                 } else if (selectionStart >= then.getStartPosition() + then.getLength()) {
948                     ASTNode elseStatement= ((IfStatement) statement).getElseStatement();
949                     if (!(elseStatement instanceof Block)) {
950                         childProperty= IfStatement.ELSE_STATEMENT_PROPERTY;
951                         child= elseStatement;
952                     }
953                 }
954                 break;
955             case ASTNode.WHILE_STATEMENT:
956                 ASTNode whileBody= ((WhileStatement) statement).getBody();
957                 if (!(whileBody instanceof Block)) {
958                     childProperty= WhileStatement.BODY_PROPERTY;
959                     child= whileBody;
960                 }
961                 break;
962             case ASTNode.FOR_STATEMENT:
963                 ASTNode forBody= ((ForStatement) statement).getBody();
964                 if (!(forBody instanceof Block)) {
965                     childProperty= ForStatement.BODY_PROPERTY;
966                     child= forBody;
967                 }
968                 break;
969             case ASTNode.DO_STATEMENT:
970                 ASTNode doBody= ((DoStatement) statement).getBody();
971                 if (!(doBody instanceof Block)) {
972                     childProperty= DoStatement.BODY_PROPERTY;
973                     child= doBody;
974                 }
975                 break;
976             default:
977         }
978         if (child == null) {
979             return false;
980         }
981
982         if (resultingCollections == null) {
983             return true;
984         }
985         AST ast= statement.getAST();
986         {
987             ASTRewrite rewrite= ASTRewrite.create(ast);
988
989             ASTNode childPlaceholder= rewrite.createMoveTarget(child);
990             Block replacingBody= ast.newBlock();
991             replacingBody.statements().add(childPlaceholder);
992             rewrite.set(statement, childProperty, replacingBody, null);
993
994             String JavaDoc label;
995             if (childProperty == IfStatement.THEN_STATEMENT_PROPERTY) {
996                 label = CorrectionMessages.QuickAssistProcessor_replacethenwithblock_description;
997             } else if (childProperty == IfStatement.ELSE_STATEMENT_PROPERTY) {
998                 label = CorrectionMessages.QuickAssistProcessor_replaceelsewithblock_description;
999             } else {
1000                label = CorrectionMessages.QuickAssistProcessor_replacebodywithblock_description;
1001            }
1002
1003            Image image= JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_CHANGE);
1004            LinkedCorrectionProposal proposal= new LinkedCorrectionProposal(label, context.getCompilationUnit(), rewrite, 10, image);
1005            proposal.setCommandId(ADD_BLOCK_ID);
1006            proposal.setEndPosition(rewrite.track(child));
1007            resultingCollections.add(proposal);
1008        }
1009
1010        if (statement.getNodeType() == ASTNode.IF_STATEMENT) {
1011            ASTRewrite rewrite= ASTRewrite.create(ast);
1012            
1013            while (statement.getLocationInParent() == IfStatement.ELSE_STATEMENT_PROPERTY) {
1014                statement= (Statement) statement.getParent();
1015            }
1016            
1017            boolean missingBlockFound= false;
1018            boolean foundElse= false;
1019            
1020            IfStatement ifStatement;
1021            Statement thenStatment;
1022            Statement elseStatment;
1023            do {
1024                ifStatement= (IfStatement) statement;
1025                thenStatment= ifStatement.getThenStatement();
1026                elseStatment= ifStatement.getElseStatement();
1027
1028                if (!(thenStatment instanceof Block)) {
1029                    ASTNode childPlaceholder1= rewrite.createMoveTarget(thenStatment);
1030                    Block replacingBody1= ast.newBlock();
1031                    replacingBody1.statements().add(childPlaceholder1);
1032                    rewrite.set(ifStatement, IfStatement.THEN_STATEMENT_PROPERTY, replacingBody1, null);
1033                    if (thenStatment != child) {
1034                        missingBlockFound= true;
1035                    }
1036                }
1037                if (elseStatment != null) {
1038                    foundElse= true;
1039                }
1040                statement= elseStatment;
1041            } while (elseStatment instanceof IfStatement);
1042            
1043            if (elseStatment != null && !(elseStatment instanceof Block)) {
1044                ASTNode childPlaceholder2= rewrite.createMoveTarget(elseStatment);
1045                
1046                Block replacingBody2= ast.newBlock();
1047                replacingBody2.statements().add(childPlaceholder2);
1048                rewrite.set(ifStatement, IfStatement.ELSE_STATEMENT_PROPERTY, replacingBody2, null);
1049                if (elseStatment != child) {
1050                    missingBlockFound= true;
1051                }
1052            }
1053
1054            if (missingBlockFound && foundElse) {
1055                String JavaDoc label = CorrectionMessages.QuickAssistProcessor_replacethenelsewithblock_description;
1056                Image image= JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_CHANGE);
1057                ASTRewriteCorrectionProposal proposal= new ASTRewriteCorrectionProposal(label, context.getCompilationUnit(), rewrite, 10, image);
1058                resultingCollections.add(proposal);
1059            }
1060        }
1061        return true;
1062    }
1063
1064    private static boolean getInvertEqualsProposal(IInvocationContext context, ASTNode node, Collection JavaDoc resultingCollections) {
1065        ASTNode parent= node.getParent();
1066        if (!(parent instanceof MethodInvocation)) {
1067            return false;
1068        }
1069        MethodInvocation method= (MethodInvocation) parent;
1070        if (!"equals".equals(method.getName().getIdentifier())) { //$NON-NLS-1$
1071
return false;
1072        }
1073        List JavaDoc arguments= method.arguments();
1074        if (arguments.size() != 1) { //overloaded equals w/ more than 1 argument
1075
return false;
1076        }
1077        Expression right= (Expression) arguments.get(0);
1078        ITypeBinding binding = right.resolveTypeBinding();
1079        if (binding != null && !(binding.isClass() || binding.isInterface())) { //overloaded equals w/ non-class/interface argument or null
1080
return false;
1081        }
1082        if (resultingCollections == null) {
1083            return true;
1084        }
1085
1086        Expression left= method.getExpression();
1087
1088        AST ast= method.getAST();
1089        ASTRewrite rewrite= ASTRewrite.create(ast);
1090        if (left == null) { // equals(x) -> x.equals(this)
1091
MethodInvocation replacement= ast.newMethodInvocation();
1092            replacement.setName((SimpleName) rewrite.createCopyTarget(method.getName()));
1093            replacement.arguments().add(ast.newThisExpression());
1094            replacement.setExpression((Expression) rewrite.createCopyTarget(right));
1095            rewrite.replace(method, replacement, null);
1096        } else if (right instanceof ThisExpression) { // x.equals(this) -> equals(x)
1097
MethodInvocation replacement= ast.newMethodInvocation();
1098            replacement.setName((SimpleName) rewrite.createCopyTarget(method.getName()));
1099            replacement.arguments().add(rewrite.createCopyTarget(left));
1100            rewrite.replace(method, replacement, null);
1101        } else {
1102            ASTNode leftExpression= left;
1103            while (leftExpression instanceof ParenthesizedExpression) {
1104                leftExpression= ((ParenthesizedExpression) left).getExpression();
1105            }
1106            rewrite.replace(right, rewrite.createCopyTarget(leftExpression), null);
1107
1108            if ((right instanceof CastExpression)
1109                || (right instanceof Assignment)
1110                || (right instanceof ConditionalExpression)
1111                || (right instanceof InfixExpression)) {
1112                ParenthesizedExpression paren= ast.newParenthesizedExpression();
1113                paren.setExpression((Expression) rewrite.createCopyTarget(right));
1114                rewrite.replace(left, paren, null);
1115            } else {
1116                rewrite.replace(left, rewrite.createCopyTarget(right), null);
1117            }
1118        }
1119
1120        String JavaDoc label= CorrectionMessages.QuickAssistProcessor_invertequals_description;
1121        Image image= JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_CHANGE);
1122
1123        LinkedCorrectionProposal proposal= new LinkedCorrectionProposal(label, context.getCompilationUnit(), rewrite, 1, image);
1124        resultingCollections.add(proposal);
1125        return true;
1126    }
1127
1128    private static boolean getArrayInitializerToArrayCreation(IInvocationContext context, ASTNode node, Collection JavaDoc resultingCollections) throws CoreException {
1129        if (!(node instanceof ArrayInitializer)) {
1130            return false;
1131        }
1132        ArrayInitializer initializer= (ArrayInitializer) node;
1133
1134        ASTNode parent= initializer.getParent();
1135        while (parent instanceof ArrayInitializer) {
1136            initializer= (ArrayInitializer) parent;
1137            parent= parent.getParent();
1138        }
1139        ITypeBinding typeBinding= initializer.resolveTypeBinding();
1140        if (!(parent instanceof VariableDeclaration) || typeBinding == null || !typeBinding.isArray()) {
1141            return false;
1142        }
1143        if (resultingCollections == null) {
1144            return true;
1145        }
1146
1147        AST ast= node.getAST();
1148        ASTRewrite rewrite= ASTRewrite.create(ast);
1149
1150        String JavaDoc label= CorrectionMessages.QuickAssistProcessor_typetoarrayInitializer_description;
1151        Image image= JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_CHANGE);
1152
1153        LinkedCorrectionProposal proposal= new LinkedCorrectionProposal(label, context.getCompilationUnit(), rewrite, 1, image);
1154        
1155        ImportRewrite imports= proposal.createImportRewrite(context.getASTRoot());
1156        String JavaDoc typeName= imports.addImport(typeBinding);
1157
1158        ArrayCreation creation= ast.newArrayCreation();
1159        creation.setInitializer((ArrayInitializer) rewrite.createMoveTarget(initializer));
1160        creation.setType((ArrayType) ASTNodeFactory.newType(ast, typeName));
1161
1162        rewrite.replace(initializer, creation, null);
1163        
1164        resultingCollections.add(proposal);
1165        return true;
1166    }
1167
1168
1169    public static boolean getCreateInSuperClassProposals(IInvocationContext context, ASTNode node, Collection JavaDoc resultingCollections) throws CoreException {
1170        if (!(node instanceof SimpleName) || !(node.getParent() instanceof MethodDeclaration)) {
1171            return false;
1172        }
1173        MethodDeclaration decl= (MethodDeclaration) node.getParent();
1174        if (decl.getName() != node || decl.resolveBinding() == null || Modifier.isPrivate(decl.getModifiers())) {
1175            return false;
1176        }
1177
1178        ICompilationUnit cu= context.getCompilationUnit();
1179        CompilationUnit astRoot= context.getASTRoot();
1180
1181        IMethodBinding binding= decl.resolveBinding();
1182        ITypeBinding[] paramTypes= binding.getParameterTypes();
1183
1184        ITypeBinding[] superTypes= Bindings.getAllSuperTypes(binding.getDeclaringClass());
1185        if (resultingCollections == null) {
1186            for (int i= 0; i < superTypes.length; i++) {
1187                ITypeBinding curr= superTypes[i];
1188                if (curr.isFromSource() && Bindings.findOverriddenMethodInType(curr, binding) == null) {
1189                    return true;
1190                }
1191            }
1192            return false;
1193        }
1194        List JavaDoc params= decl.parameters();
1195        String JavaDoc[] paramNames= new String JavaDoc[paramTypes.length];
1196        for (int i = 0; i < params.size(); i++) {
1197            SingleVariableDeclaration param= (SingleVariableDeclaration) params.get(i);
1198            paramNames[i]= param.getName().getIdentifier();
1199        }
1200
1201        for (int i= 0; i < superTypes.length; i++) {
1202            ITypeBinding curr= superTypes[i];
1203            if (curr.isFromSource()) {
1204                IMethodBinding method= Bindings.findOverriddenMethodInType(curr, binding);
1205                if (method == null) {
1206                    ITypeBinding typeDecl= curr.getTypeDeclaration();
1207                    ICompilationUnit targetCU= ASTResolving.findCompilationUnitForBinding(cu, astRoot, typeDecl);
1208                    if (targetCU != null) {
1209                        String JavaDoc label= Messages.format(CorrectionMessages.QuickAssistProcessor_createmethodinsuper_description, new String JavaDoc[] { curr.getName(), binding.getName() });
1210                        resultingCollections.add(new NewDefiningMethodProposal(label, targetCU, astRoot, typeDecl, binding, paramNames, 6));
1211                    }
1212                }
1213            }
1214        }
1215        return true;
1216    }
1217
1218    private static boolean getConvertForLoopProposal(IInvocationContext context, ASTNode node, Collection JavaDoc resultingCollections) throws CoreException {
1219        ForStatement forStatement= getEnclosingForStatementHeader(node);
1220        if (forStatement == null)
1221            return false;
1222
1223        if (resultingCollections == null)
1224            return true;
1225        
1226        IFix fix= ConvertLoopFix.createConvertForLoopToEnhancedFix(context.getASTRoot(), forStatement);
1227        if (fix == null)
1228            return false;
1229        
1230        Image image= JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_CHANGE);
1231        Map JavaDoc options= new HashMap JavaDoc();
1232        options.put(CleanUpConstants.CONTROL_STATMENTS_CONVERT_FOR_LOOP_TO_ENHANCED, CleanUpConstants.TRUE);
1233        ICleanUp cleanUp= new ConvertLoopCleanUp(options);
1234        FixCorrectionProposal proposal= new FixCorrectionProposal(fix, cleanUp, 1, image, context);
1235        proposal.setCommandId(CONVERT_FOR_LOOP_ID);
1236        
1237        resultingCollections.add(proposal);
1238        return true;
1239    }
1240
1241    private static boolean getConvertIterableLoopProposal(IInvocationContext context, ASTNode node, Collection JavaDoc resultingCollections) throws CoreException {
1242        ForStatement forStatement= getEnclosingForStatementHeader(node);
1243        if (forStatement == null)
1244            return false;
1245
1246        if (resultingCollections == null)
1247            return true;
1248        
1249        IFix fix= ConvertLoopFix.createConvertIterableLoopToEnhancedFix(context.getASTRoot(), forStatement);
1250        if (fix == null)
1251            return false;
1252        
1253        Image image= JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_CHANGE);
1254        Map JavaDoc options= new HashMap JavaDoc();
1255        options.put(CleanUpConstants.CONTROL_STATMENTS_CONVERT_FOR_LOOP_TO_ENHANCED, CleanUpConstants.TRUE);
1256        ICleanUp cleanUp= new ConvertLoopCleanUp(options);
1257        FixCorrectionProposal proposal= new FixCorrectionProposal(fix, cleanUp, 1, image, context);
1258        proposal.setCommandId(CONVERT_FOR_LOOP_ID);
1259        
1260        resultingCollections.add(proposal);
1261        return true;
1262    }
1263
1264    private static ForStatement getEnclosingForStatementHeader(ASTNode node) {
1265        if (node instanceof ForStatement)
1266            return (ForStatement) node;
1267
1268        while (node != null) {
1269            ASTNode parent= node.getParent();
1270            if (parent instanceof ForStatement) {
1271                StructuralPropertyDescriptor locationInParent= node.getLocationInParent();
1272                if (locationInParent == ForStatement.EXPRESSION_PROPERTY
1273                        || locationInParent == ForStatement.INITIALIZERS_PROPERTY
1274                        || locationInParent == ForStatement.UPDATERS_PROPERTY)
1275                    return (ForStatement) parent;
1276                else
1277                    return null;
1278            }
1279            node= parent;
1280        }
1281        return null;
1282    }
1283    
1284    private static boolean getMakeVariableDeclarationFinalProposals(IInvocationContext context, ASTNode node, Collection JavaDoc resultingCollections) {
1285        SelectionAnalyzer analyzer= new SelectionAnalyzer(Selection.createFromStartLength(context.getSelectionOffset(), context.getSelectionLength()), false);
1286        context.getASTRoot().accept(analyzer);
1287        ASTNode[] selectedNodes= analyzer.getSelectedNodes();
1288        if (selectedNodes.length == 0)
1289            return false;
1290        
1291        IFix fix= VariableDeclarationFix.createChangeModifierToFinalFix(context.getASTRoot(), selectedNodes);
1292        if (fix == null)
1293            return false;
1294        
1295        if (resultingCollections == null)
1296            return true;
1297
1298        Image image= JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_CHANGE);
1299        Map JavaDoc options= new Hashtable JavaDoc();
1300        options.put(CleanUpConstants.VARIABLE_DECLARATIONS_USE_FINAL, CleanUpConstants.TRUE);
1301        options.put(CleanUpConstants.VARIABLE_DECLARATIONS_USE_FINAL_LOCAL_VARIABLES, CleanUpConstants.TRUE);
1302        options.put(CleanUpConstants.VARIABLE_DECLARATIONS_USE_FINAL_PARAMETERS, CleanUpConstants.TRUE);
1303        options.put(CleanUpConstants.VARIABLE_DECLARATIONS_USE_FINAL_PRIVATE_FIELDS, CleanUpConstants.TRUE);
1304        VariableDeclarationCleanUp cleanUp= new VariableDeclarationCleanUp(options);
1305        FixCorrectionProposal proposal= new FixCorrectionProposal(fix, cleanUp, 5, image, context);
1306        resultingCollections.add(proposal);
1307        return true;
1308    }
1309        
1310    private static boolean getInlineLocalProposal(IInvocationContext context, final ASTNode node, Collection JavaDoc proposals) throws CoreException {
1311        if (!(node instanceof SimpleName))
1312            return false;
1313        
1314        SimpleName name= (SimpleName) node;
1315        IBinding binding= name.resolveBinding();
1316        if (!(binding instanceof IVariableBinding))
1317            return false;
1318        IVariableBinding varBinding= (IVariableBinding) binding;
1319        if (varBinding.isField() || varBinding.isParameter())
1320            return false;
1321        ASTNode decl= context.getASTRoot().findDeclaringNode(varBinding);
1322        if (!(decl instanceof VariableDeclarationFragment) || decl.getLocationInParent() != VariableDeclarationStatement.FRAGMENTS_PROPERTY)
1323            return false;
1324        
1325        if (proposals == null) {
1326            return true;
1327        }
1328            
1329        InlineTempRefactoring refactoring= new InlineTempRefactoring((VariableDeclaration) decl);
1330        if (refactoring.checkInitialConditions(new NullProgressMonitor()).isOK()) {
1331            String JavaDoc label= CorrectionMessages.QuickAssistProcessor_inline_local_description;
1332            Image image= JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_CHANGE);
1333            RefactoringCorrectionProposal proposal= new RefactoringCorrectionProposal(label, context.getCompilationUnit(), refactoring, 5, image);
1334            proposal.setCommandId(INLINE_LOCAL_ID);
1335            proposals.add(proposal);
1336            
1337        }
1338        return true;
1339    }
1340    
1341    private static boolean getConvertLocalToFieldProposal(IInvocationContext context, final ASTNode node, Collection JavaDoc proposals) throws CoreException {
1342        if (!(node instanceof SimpleName))
1343            return false;
1344        
1345        SimpleName name= (SimpleName) node;
1346        IBinding binding= name.resolveBinding();
1347        if (!(binding instanceof IVariableBinding) || name.getLocationInParent() != VariableDeclarationFragment.NAME_PROPERTY)
1348            return false;
1349        IVariableBinding varBinding= (IVariableBinding) binding;
1350        if (varBinding.isField() || varBinding.isParameter())
1351            return false;
1352        VariableDeclarationFragment decl= (VariableDeclarationFragment) name.getParent();
1353        if (decl.getLocationInParent() != VariableDeclarationStatement.FRAGMENTS_PROPERTY)
1354            return false;
1355        
1356        if (proposals == null) {
1357            return true;
1358        }
1359            
1360        PromoteTempToFieldRefactoring refactoring= new PromoteTempToFieldRefactoring(decl);
1361        if (refactoring.checkInitialConditions(new NullProgressMonitor()).isOK()) {
1362            String JavaDoc label= CorrectionMessages.QuickAssistProcessor_convert_local_to_field_description;
1363            Image image= JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_CHANGE);
1364            LinkedProposalModel linkedProposalModel= new LinkedProposalModel();
1365            refactoring.setLinkedProposalModel(linkedProposalModel);
1366            
1367            RefactoringCorrectionProposal proposal= new RefactoringCorrectionProposal(label, context.getCompilationUnit(), refactoring, 5, image);
1368            proposal.setLinkedProposalModel(linkedProposalModel);
1369            proposal.setCommandId(CONVERT_LOCAL_TO_FIELD_ID);
1370            proposals.add(proposal);
1371        }
1372        return true;
1373    }
1374    
1375    private static class RefactoringCorrectionProposal extends CUCorrectionProposal {
1376        private final Refactoring fRefactoring;
1377
1378        public RefactoringCorrectionProposal(String JavaDoc name, ICompilationUnit cu, Refactoring refactoring, int relevance, Image image) {
1379            super(name, cu, null, relevance, image);
1380            fRefactoring= refactoring;
1381        }
1382        
1383        protected TextChange createTextChange() throws CoreException {
1384            return (TextChange) fRefactoring.createChange(new NullProgressMonitor());
1385        }
1386    }
1387}
1388
Popular Tags