1 12 package org.eclipse.jdt.internal.ui.text.correction; 13 14 import java.util.ArrayList ; 15 import java.util.Collection ; 16 import java.util.HashMap ; 17 import java.util.Hashtable ; 18 import java.util.List ; 19 import java.util.Map ; 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 116 public class QuickAssistProcessor implements IQuickAssistProcessor { 117 118 public static final String SPLIT_JOIN_VARIABLE_DECLARATION_ID= "org.eclipse.jdt.ui.correction.splitJoinVariableDeclaration.assist"; public static final String CONVERT_FOR_LOOP_ID= "org.eclipse.jdt.ui.correction.convertForLoop.assist"; public static final String ASSIGN_TO_LOCAL_ID= "org.eclipse.jdt.ui.correction.assignToLocal.assist"; public static final String ASSIGN_TO_FIELD_ID= "org.eclipse.jdt.ui.correction.assignToField.assist"; public static final String ASSIGN_PARAM_TO_FIELD_ID= "org.eclipse.jdt.ui.correction.assignParamToField.assist"; public static final String ADD_BLOCK_ID= "org.eclipse.jdt.ui.correction.addBlock.assist"; public static final String EXTRACT_LOCAL_ID= "org.eclipse.jdt.ui.correction.extractLocal.assist"; public static final String EXTRACT_CONSTANT_ID= "org.eclipse.jdt.ui.correction.extractConstant.assist"; public static final String INLINE_LOCAL_ID= "org.eclipse.jdt.ui.correction.inlineLocal.assist"; public static final String CONVERT_LOCAL_TO_FIELD_ID= "org.eclipse.jdt.ui.correction.convertLocalToField.assist"; public static final String CONVERT_ANONYMOUS_TO_LOCAL_ID= "org.eclipse.jdt.ui.correction.convertAnonymousToLocal.assist"; 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 resultingCollections= new ArrayList (); 166 boolean noErrorsAtLocation= noErrorsAtLocation(locations); 167 168 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 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 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()); 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 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()); 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 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 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 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 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 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 rewrite.replace(assignParent, rewrite.createMoveTarget(statement), null); 371 } else { 372 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 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 412 ASTNode statementParent= statement.getParent(); 413 StructuralPropertyDescriptor property= statement.getLocationInParent(); 414 if (!property.isChildListProperty()) { 415 return false; 416 } 417 418 List list= (List ) 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 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; } 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 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; } 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 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 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 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; } 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 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 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 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 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; } 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 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 { ASTRewrite rewrite= ASTRewrite.create(ast); 666 667 removeCatchBlock(rewrite, catchClause); 668 String 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 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 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)) { 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 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 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 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 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 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; } 833 } else if (outer instanceof Block) { 834 body= block; 836 outer= block; 837 label= CorrectionMessages.QuickAssistProcessor_unwrap_block; 838 } else if (outer instanceof ParenthesizedExpression) { 839 } 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 resultingCollections) { 888 IFix[] fixes= ControlStatementsFix.createRemoveBlockFix(context.getASTRoot(), coveringNode); 889 if (fixes != null) { 890 if (resultingCollections == null) { 891 return true; 892 } 893 Map options= new Hashtable (); 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 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) { return false; 926 } 927 } else { 928 if (offset > statementStart || offset + length < statementEnd) { 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 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 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 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())) { return false; 1072 } 1073 List arguments= method.arguments(); 1074 if (arguments.size() != 1) { return false; 1076 } 1077 Expression right= (Expression) arguments.get(0); 1078 ITypeBinding binding = right.resolveTypeBinding(); 1079 if (binding != null && !(binding.isClass() || binding.isInterface())) { 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) { 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) { 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 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 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 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 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 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 params= decl.parameters(); 1195 String [] paramNames= new String [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 label= Messages.format(CorrectionMessages.QuickAssistProcessor_createmethodinsuper_description, new String [] { 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 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 options= new HashMap (); 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 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 options= new HashMap (); 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 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 options= new Hashtable (); 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 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 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 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 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 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 |