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.HashSet ; 17 import java.util.Hashtable ; 18 import java.util.Iterator ; 19 import java.util.List ; 20 import java.util.Map ; 21 22 import org.eclipse.core.runtime.CoreException; 23 24 import org.eclipse.swt.graphics.Image; 25 26 import org.eclipse.jdt.core.ICompilationUnit; 27 import org.eclipse.jdt.core.dom.AST; 28 import org.eclipse.jdt.core.dom.ASTNode; 29 import org.eclipse.jdt.core.dom.Assignment; 30 import org.eclipse.jdt.core.dom.Block; 31 import org.eclipse.jdt.core.dom.BooleanLiteral; 32 import org.eclipse.jdt.core.dom.BreakStatement; 33 import org.eclipse.jdt.core.dom.CastExpression; 34 import org.eclipse.jdt.core.dom.ChildListPropertyDescriptor; 35 import org.eclipse.jdt.core.dom.ClassInstanceCreation; 36 import org.eclipse.jdt.core.dom.ConditionalExpression; 37 import org.eclipse.jdt.core.dom.ConstructorInvocation; 38 import org.eclipse.jdt.core.dom.ContinueStatement; 39 import org.eclipse.jdt.core.dom.DoStatement; 40 import org.eclipse.jdt.core.dom.EnumConstantDeclaration; 41 import org.eclipse.jdt.core.dom.Expression; 42 import org.eclipse.jdt.core.dom.ExpressionStatement; 43 import org.eclipse.jdt.core.dom.ForStatement; 44 import org.eclipse.jdt.core.dom.IBinding; 45 import org.eclipse.jdt.core.dom.ITypeBinding; 46 import org.eclipse.jdt.core.dom.IVariableBinding; 47 import org.eclipse.jdt.core.dom.IfStatement; 48 import org.eclipse.jdt.core.dom.InfixExpression; 49 import org.eclipse.jdt.core.dom.InstanceofExpression; 50 import org.eclipse.jdt.core.dom.MethodDeclaration; 51 import org.eclipse.jdt.core.dom.MethodInvocation; 52 import org.eclipse.jdt.core.dom.Name; 53 import org.eclipse.jdt.core.dom.ParenthesizedExpression; 54 import org.eclipse.jdt.core.dom.PostfixExpression; 55 import org.eclipse.jdt.core.dom.PrefixExpression; 56 import org.eclipse.jdt.core.dom.PrimitiveType; 57 import org.eclipse.jdt.core.dom.QualifiedName; 58 import org.eclipse.jdt.core.dom.ReturnStatement; 59 import org.eclipse.jdt.core.dom.SimpleName; 60 import org.eclipse.jdt.core.dom.SingleVariableDeclaration; 61 import org.eclipse.jdt.core.dom.Statement; 62 import org.eclipse.jdt.core.dom.StringLiteral; 63 import org.eclipse.jdt.core.dom.StructuralPropertyDescriptor; 64 import org.eclipse.jdt.core.dom.SuperConstructorInvocation; 65 import org.eclipse.jdt.core.dom.SuperMethodInvocation; 66 import org.eclipse.jdt.core.dom.SwitchCase; 67 import org.eclipse.jdt.core.dom.SwitchStatement; 68 import org.eclipse.jdt.core.dom.Type; 69 import org.eclipse.jdt.core.dom.VariableDeclarationFragment; 70 import org.eclipse.jdt.core.dom.VariableDeclarationStatement; 71 import org.eclipse.jdt.core.dom.WhileStatement; 72 import org.eclipse.jdt.core.dom.InfixExpression.Operator; 73 import org.eclipse.jdt.core.dom.rewrite.ASTRewrite; 74 import org.eclipse.jdt.core.dom.rewrite.ImportRewrite; 75 import org.eclipse.jdt.core.dom.rewrite.ListRewrite; 76 77 import org.eclipse.jdt.internal.corext.codemanipulation.StubUtility; 78 import org.eclipse.jdt.internal.corext.dom.ASTNodes; 79 import org.eclipse.jdt.internal.corext.dom.GenericVisitor; 80 import org.eclipse.jdt.internal.corext.dom.LinkedNodeFinder; 81 import org.eclipse.jdt.internal.corext.fix.CleanUpConstants; 82 import org.eclipse.jdt.internal.corext.fix.ExpressionsFix; 83 import org.eclipse.jdt.internal.corext.fix.IFix; 84 import org.eclipse.jdt.internal.corext.util.JavaModelUtil; 85 import org.eclipse.jdt.internal.corext.util.Messages; 86 87 import org.eclipse.jdt.ui.CodeStyleConfiguration; 88 import org.eclipse.jdt.ui.text.java.IInvocationContext; 89 import org.eclipse.jdt.ui.text.java.IJavaCompletionProposal; 90 import org.eclipse.jdt.ui.text.java.IProblemLocation; 91 import org.eclipse.jdt.ui.text.java.IQuickAssistProcessor; 92 93 import org.eclipse.jdt.internal.ui.JavaPluginImages; 94 import org.eclipse.jdt.internal.ui.fix.ExpressionsCleanUp; 95 96 98 public class AdvancedQuickAssistProcessor implements IQuickAssistProcessor { 99 public AdvancedQuickAssistProcessor() { 100 super(); 101 } 102 105 public boolean hasAssists(IInvocationContext context) throws CoreException { 106 ASTNode coveringNode = context.getCoveringNode(); 107 if (coveringNode != null) { 108 ArrayList coveredNodes= getFullyCoveredNodes(context, coveringNode); 109 return getInverseIfProposals(context, coveringNode, null) 110 || getIfReturnIntoIfElseAtEndOfVoidMethodProposals(context, coveringNode, null) 111 || getInverseIfContinueIntoIfThenInLoopsProposals(context, coveringNode, null) 112 || getInverseIfIntoContinueInLoopsProposals(context, coveringNode, null) 113 || getInverseConditionProposals(context, coveringNode, coveredNodes, null) 114 || getRemoveExtraParenthesisProposals(context, coveringNode, coveredNodes, null) 115 || getAddParanoidalParenthesisProposals(context, coveringNode, coveredNodes, null) 116 || getJoinAndIfStatementsProposals(context, coveringNode, null) 117 || getSplitAndConditionProposals(context, coveringNode, null) 118 || getJoinOrIfStatementsProposals(context, coveringNode, coveredNodes, null) 119 || getSplitOrConditionProposals(context, coveringNode, null) 120 || getInverseConditionalExpressionProposals(context, coveringNode, null) 121 || getExchangeInnerAndOuterIfConditionsProposals(context, coveringNode, null) 122 || getExchangeOperandsProposals(context, coveringNode, null) 123 || getCastAndAssignIfStatementProposals(context, coveringNode, null) 124 || getPickOutStringProposals(context, coveringNode, null) 125 || getReplaceIfElseWithConditionalProposals(context, coveringNode, null) 126 || getReplaceConditionalWithIfElseProposals(context, coveringNode, null) 127 || getInverseLocalVariableProposals(context, coveringNode, null) 128 || getPushNegationDownProposals(context, coveringNode, null) 129 || getPullNegationUpProposals(context, coveringNode, coveredNodes, null) 130 || getJoinIfListInIfElseIfProposals(context, coveringNode, coveredNodes, null) 131 || getConvertSwitchToIfProposals(context, coveringNode, null); 132 } 133 return false; 134 } 135 138 public IJavaCompletionProposal[] getAssists(IInvocationContext context, IProblemLocation[] locations) 139 throws CoreException { 140 ASTNode coveringNode = context.getCoveringNode(); 141 if (coveringNode != null) { 142 ArrayList coveredNodes = getFullyCoveredNodes(context, coveringNode); 143 ArrayList resultingCollections = new ArrayList (); 144 if (noErrorsAtLocation(locations)) { 145 getInverseIfProposals(context, coveringNode, resultingCollections); 146 getIfReturnIntoIfElseAtEndOfVoidMethodProposals(context, coveringNode, resultingCollections); 147 getInverseIfContinueIntoIfThenInLoopsProposals(context, coveringNode, resultingCollections); 148 getInverseIfIntoContinueInLoopsProposals(context, coveringNode, resultingCollections); 149 getInverseConditionProposals(context, coveringNode, coveredNodes, resultingCollections); 150 getRemoveExtraParenthesisProposals(context, coveringNode, coveredNodes, resultingCollections); 151 getAddParanoidalParenthesisProposals(context, coveringNode, coveredNodes, resultingCollections); 152 getJoinAndIfStatementsProposals(context, coveringNode, resultingCollections); 153 getSplitAndConditionProposals(context, coveringNode, resultingCollections); 154 getJoinOrIfStatementsProposals(context, coveringNode, coveredNodes, resultingCollections); 155 getSplitOrConditionProposals(context, coveringNode, resultingCollections); 156 getInverseConditionalExpressionProposals(context, coveringNode, resultingCollections); 157 getExchangeInnerAndOuterIfConditionsProposals(context, coveringNode, resultingCollections); 158 getExchangeOperandsProposals(context, coveringNode, resultingCollections); 159 getCastAndAssignIfStatementProposals(context, coveringNode, resultingCollections); 160 getPickOutStringProposals(context, coveringNode, resultingCollections); 161 getReplaceIfElseWithConditionalProposals(context, coveringNode, resultingCollections); 162 getReplaceConditionalWithIfElseProposals(context, coveringNode, resultingCollections); 163 getInverseLocalVariableProposals(context, coveringNode, resultingCollections); 164 getPushNegationDownProposals(context, coveringNode, resultingCollections); 165 getPullNegationUpProposals(context, coveringNode, coveredNodes, resultingCollections); 166 getJoinIfListInIfElseIfProposals(context, coveringNode, coveredNodes, resultingCollections); 167 getConvertSwitchToIfProposals(context, coveringNode, resultingCollections); 168 } 169 return (IJavaCompletionProposal[]) resultingCollections.toArray(new IJavaCompletionProposal[resultingCollections.size()]); 170 } 171 return null; 172 } 173 private static boolean noErrorsAtLocation(IProblemLocation[] locations) { 174 if (locations != null) { 175 for (int i = 0; i < locations.length; i++) { 176 if (locations[i].isError()) { 177 return false; 178 } 179 } 180 } 181 return true; 182 } 183 private static boolean getIfReturnIntoIfElseAtEndOfVoidMethodProposals(IInvocationContext context, ASTNode covering, 184 Collection resultingCollections) { 185 Statement coveringStatement = ASTResolving.findParentStatement(covering); 186 if (!(coveringStatement instanceof IfStatement)) { 187 return false; 188 } 189 IfStatement ifStatement = (IfStatement) coveringStatement; 190 if (ifStatement.getElseStatement() != null) { 191 return false; 192 } 193 Statement thenStatement = ifStatement.getThenStatement(); 195 if (!(thenStatement instanceof Block)) { 196 return false; 197 } 198 Block thenBlock = (Block) thenStatement; 199 List thenStatements = thenBlock.statements(); 200 if (thenStatements.isEmpty() || !(thenStatements.get(thenStatements.size() - 1) instanceof ReturnStatement)) { 201 return false; 202 } 203 MethodDeclaration coveringMetod = ASTResolving.findParentMethodDeclaration(covering); 205 if (coveringMetod == null) { 206 return false; 207 } 208 Type returnType = coveringMetod.getReturnType2(); 209 if (!(returnType instanceof PrimitiveType) 210 || ((PrimitiveType) returnType).getPrimitiveTypeCode() != PrimitiveType.VOID) 211 return false; 212 List statements = coveringMetod.getBody().statements(); 214 int ifIndex = statements.indexOf(ifStatement); 215 if (ifIndex == -1) { 216 return false; 217 } 218 if (resultingCollections == null) { 220 return true; 221 } 222 AST ast = coveringStatement.getAST(); 224 ASTRewrite rewrite = ASTRewrite.create(ast); 225 ListRewrite listRewriter = rewrite.getListRewrite(thenBlock, 227 (ChildListPropertyDescriptor) ifStatement.getLocationInParent()); 228 listRewriter.remove((ASTNode) thenStatements.get(thenStatements.size() - 1), null); 229 Expression conditionPlaceholder = (Expression) rewrite.createMoveTarget(ifStatement.getExpression()); 231 Statement thenPlaceholder = (Statement) rewrite.createMoveTarget(ifStatement.getThenStatement()); 232 Block elseBlock = ast.newBlock(); 234 for (int i = ifIndex + 1; i < statements.size(); i++) { 235 Statement statement = (Statement) statements.get(i); 236 elseBlock.statements().add(rewrite.createMoveTarget(statement)); 237 } 238 IfStatement newIf = ast.newIfStatement(); 240 newIf.setExpression(conditionPlaceholder); 241 newIf.setThenStatement(thenPlaceholder); 242 newIf.setElseStatement(elseBlock); 243 rewrite.replace(ifStatement, newIf, null); 244 String label = CorrectionMessages.AdvancedQuickAssistProcessor_convertToIfElse_description; 246 Image image = JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_CHANGE); 247 ASTRewriteCorrectionProposal proposal = new ASTRewriteCorrectionProposal(label, context.getCompilationUnit(), 248 rewrite, 1, image); 249 resultingCollections.add(proposal); 250 return true; 251 } 252 private static boolean getInverseIfProposals(IInvocationContext context, ASTNode covering, Collection resultingCollections) { 253 Statement coveringStatement = ASTResolving.findParentStatement(covering); 254 if (!(coveringStatement instanceof IfStatement)) { 255 return false; 256 } 257 IfStatement ifStatement = (IfStatement) coveringStatement; 258 if (ifStatement.getElseStatement() == null) { 259 return false; 260 } 261 if (resultingCollections == null) { 263 return true; 264 } 265 AST ast = coveringStatement.getAST(); 267 ASTRewrite rewrite = ASTRewrite.create(ast); 268 Statement thenStatement= ifStatement.getThenStatement(); 269 Statement elseStatement= ifStatement.getElseStatement(); 270 271 Expression inversedExpression = getInversedBooleanExpression(rewrite, ifStatement.getExpression()); 273 274 Statement newElseStatement = (Statement) rewrite.createMoveTarget(thenStatement); 275 Statement newThenStatement = (Statement) rewrite.createMoveTarget(elseStatement); 276 rewrite.set(ifStatement, IfStatement.EXPRESSION_PROPERTY, inversedExpression, null); 278 279 if (elseStatement instanceof IfStatement) { Block elseBlock = ast.newBlock(); 281 elseBlock.statements().add(newThenStatement); 282 newThenStatement= elseBlock; 283 } 284 rewrite.set(ifStatement, IfStatement.THEN_STATEMENT_PROPERTY, newThenStatement, null); 285 rewrite.set(ifStatement, IfStatement.ELSE_STATEMENT_PROPERTY, newElseStatement, null); 286 String label = CorrectionMessages.AdvancedQuickAssistProcessor_inverseIf_description; 288 Image image = JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_CHANGE); 289 ASTRewriteCorrectionProposal proposal = new ASTRewriteCorrectionProposal(label, context.getCompilationUnit(), 290 rewrite, 1, image); 291 resultingCollections.add(proposal); 292 return true; 293 } 294 private static boolean getInverseIfContinueIntoIfThenInLoopsProposals(IInvocationContext context, ASTNode covering, 295 Collection resultingCollections) { 296 Statement coveringStatement = ASTResolving.findParentStatement(covering); 297 if (!(coveringStatement instanceof IfStatement)) { 298 return false; 299 } 300 IfStatement ifStatement = (IfStatement) coveringStatement; 301 if (ifStatement.getElseStatement() != null) { 302 return false; 303 } 304 if (!(ifStatement.getThenStatement() instanceof ContinueStatement)) { 306 return false; 307 } 308 Block loopBlock = null; 310 if ((ifStatement.getParent() instanceof Block) && (ifStatement.getParent().getParent() instanceof ForStatement)) { 311 loopBlock = (Block) ifStatement.getParent(); 312 } else if ((ifStatement.getParent() instanceof Block) 313 && (ifStatement.getParent().getParent() instanceof WhileStatement)) { 314 loopBlock = (Block) ifStatement.getParent(); 315 } else { 316 return false; 317 } 318 if (resultingCollections == null) { 319 return true; 320 } 321 AST ast = coveringStatement.getAST(); 323 ASTRewrite rewrite = ASTRewrite.create(ast); 324 Expression inversedExpression = getInversedBooleanExpression(rewrite, ifStatement.getExpression()); 326 IfStatement newIf = ast.newIfStatement(); 327 newIf.setExpression(inversedExpression); 328 Block thenBlock = ast.newBlock(); 330 int ifIndex = loopBlock.statements().indexOf(ifStatement); 331 for (int i = ifIndex + 1; i < loopBlock.statements().size(); i++) { 332 Statement statement = (Statement) loopBlock.statements().get(i); 333 thenBlock.statements().add(rewrite.createMoveTarget(statement)); 334 } 335 newIf.setThenStatement(thenBlock); 336 rewrite.replace(ifStatement, newIf, null); 338 String label = CorrectionMessages.AdvancedQuickAssistProcessor_inverseIfContinue_description; 340 Image image = JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_CHANGE); 341 ASTRewriteCorrectionProposal proposal = new ASTRewriteCorrectionProposal(label, context.getCompilationUnit(), 342 rewrite, 1, image); 343 resultingCollections.add(proposal); 344 return true; 345 } 346 private static boolean getInverseIfIntoContinueInLoopsProposals(IInvocationContext context, ASTNode covering, Collection resultingCollections) { 347 Statement coveringStatement = ASTResolving.findParentStatement(covering); 348 if (!(coveringStatement instanceof IfStatement)) { 349 return false; 350 } 351 IfStatement ifStatement = (IfStatement) coveringStatement; 352 if (ifStatement.getElseStatement() != null) { 353 return false; 354 } 355 ASTNode ifParent = ifStatement.getParent(); 357 Block ifParentBlock = null; 358 ASTNode ifParentStructure = ifParent; 359 if (ifParentStructure instanceof Block) { 360 ifParentBlock = (Block) ifParent; 361 ifParentStructure = ifParentStructure.getParent(); 362 } 363 if (!(ifParentStructure instanceof ForStatement) && !(ifParentStructure instanceof WhileStatement)) { 365 return false; 366 } 367 if ((ifParentBlock != null) && (ifParentBlock.statements().indexOf(ifStatement) != ifParentBlock.statements().size() - 1)) { 368 return false; 369 } 370 if (resultingCollections == null) { 372 return true; 373 } 374 AST ast = coveringStatement.getAST(); 376 ASTRewrite rewrite = ASTRewrite.create(ast); 377 Expression inversedExpression = getInversedBooleanExpression(rewrite, ifStatement.getExpression()); 379 IfStatement newIf = ast.newIfStatement(); 380 newIf.setExpression(inversedExpression); 381 newIf.setThenStatement(ast.newContinueStatement()); 382 if (ifParentBlock == null) { 384 ifParentBlock = ast.newBlock(); 386 ifParentBlock.statements().add(newIf); 387 for (Iterator iter = getUnwrappedStatements(ifStatement.getThenStatement()).iterator(); iter.hasNext();) { 388 Statement statement = (Statement) iter.next(); 389 ifParentBlock.statements().add(rewrite.createMoveTarget(statement)); 390 } 391 if (ifParentStructure instanceof ForStatement) { 393 rewrite.set(ifParentStructure, ForStatement.BODY_PROPERTY, ifParentBlock, null); 394 } else if (ifParentStructure instanceof WhileStatement) { 395 rewrite.set(ifParentStructure, WhileStatement.BODY_PROPERTY, ifParentBlock, null); 396 } 397 } else { 398 ListRewrite listRewriter = rewrite.getListRewrite(ifParentBlock, 400 (ChildListPropertyDescriptor) ifStatement.getLocationInParent()); 401 listRewriter.replace(ifStatement, newIf, null); 402 for (Iterator iter = getUnwrappedStatements(ifStatement.getThenStatement()).iterator(); iter.hasNext();) { 404 Statement statement = (Statement) iter.next(); 405 listRewriter.insertLast(rewrite.createMoveTarget(statement), null); 406 } 407 } 408 String label = CorrectionMessages.AdvancedQuickAssistProcessor_inverseIfToContinue_description; 410 Image image = JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_CHANGE); 411 ASTRewriteCorrectionProposal proposal = new ASTRewriteCorrectionProposal(label, context.getCompilationUnit(), 412 rewrite, 1, image); 413 resultingCollections.add(proposal); 414 return true; 415 } 416 private static ArrayList getUnwrappedStatements(Statement body) { 417 ArrayList statements = new ArrayList (); 418 if (body instanceof Block) { 419 for (Iterator iter = ((Block) body).statements().iterator(); iter.hasNext();) { 420 Statement statement = (Statement) iter.next(); 421 statements.add(statement); 422 } 423 } else { 424 statements.add(body); 425 } 426 return statements; 427 } 428 private static boolean getInverseConditionProposals(IInvocationContext context, ASTNode covering, ArrayList coveredNodes, Collection resultingCollections) { 429 if (coveredNodes.isEmpty()) { 430 return false; 431 } 432 final AST ast = covering.getAST(); 434 final ASTRewrite rewrite = ASTRewrite.create(ast); 435 boolean hasChanges = false; 437 for (Iterator iter = coveredNodes.iterator(); iter.hasNext();) { 438 ASTNode covered = (ASTNode) iter.next(); 439 Expression coveredExpression= getBooleanExpression(covered); 440 if (coveredExpression != null) { 441 Expression inversedExpression = getInversedBooleanExpression(rewrite, coveredExpression); 442 rewrite.replace(coveredExpression, inversedExpression, null); 443 hasChanges = true; 444 } 445 } 446 if (!hasChanges) { 448 return false; 449 } 450 if (resultingCollections == null) { 451 return true; 452 } 453 String label = CorrectionMessages.AdvancedQuickAssistProcessor_inverseConditions_description; 455 Image image = JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_CHANGE); 456 ASTRewriteCorrectionProposal proposal = new ASTRewriteCorrectionProposal(label, context.getCompilationUnit(), 457 rewrite, 1, image); 458 resultingCollections.add(proposal); 459 return true; 460 } 461 private static Expression getInversedBooleanExpression(ASTRewrite rewrite, Expression expression) { 462 return getInversedBooleanExpression(rewrite, expression, null); 463 } 464 private interface SimpleNameRenameProvider { 465 SimpleName getRenamed(SimpleName name); 466 } 467 private static Expression getRenamedNameCopy(SimpleNameRenameProvider provider, 468 ASTRewrite rewrite, 469 Expression expression) { 470 if (provider != null) { 471 if (expression instanceof SimpleName) { 472 SimpleName name= (SimpleName) expression; 473 SimpleName newName= provider.getRenamed(name); 474 if (newName != null) { 475 return newName; 476 } 477 } 478 } 479 return (Expression) rewrite.createCopyTarget(expression); 480 } 481 private static Expression getInversedBooleanExpression(ASTRewrite rewrite, Expression expression, SimpleNameRenameProvider provider) { 482 if (!isBoolean(expression)) { 483 return (Expression) rewrite.createCopyTarget(expression); 484 } 485 AST ast= rewrite.getAST(); 486 if (expression instanceof BooleanLiteral) { 488 return ast.newBooleanLiteral(!((BooleanLiteral) expression).booleanValue()); 489 } 490 if (expression instanceof InfixExpression) { 491 InfixExpression infixExpression= (InfixExpression) expression; 492 InfixExpression.Operator operator= infixExpression.getOperator(); 493 if (operator == InfixExpression.Operator.LESS) { 494 return getInversedInfixBooleanExpression(rewrite, infixExpression, InfixExpression.Operator.GREATER_EQUALS, provider); 495 } 496 if (operator == InfixExpression.Operator.GREATER) { 497 return getInversedInfixBooleanExpression(rewrite, infixExpression, InfixExpression.Operator.LESS_EQUALS, provider); 498 } 499 if (operator == InfixExpression.Operator.LESS_EQUALS) { 500 return getInversedInfixBooleanExpression(rewrite, infixExpression, InfixExpression.Operator.GREATER, provider); 501 } 502 if (operator == InfixExpression.Operator.GREATER_EQUALS) { 503 return getInversedInfixBooleanExpression(rewrite, infixExpression, InfixExpression.Operator.LESS, provider); 504 } 505 if (operator == InfixExpression.Operator.EQUALS) { 506 return getInversedInfixBooleanExpression(rewrite, infixExpression, InfixExpression.Operator.NOT_EQUALS, provider); 507 } 508 if (operator == InfixExpression.Operator.NOT_EQUALS) { 509 return getInversedInfixBooleanExpression(rewrite, infixExpression, InfixExpression.Operator.EQUALS, provider); 510 } 511 if (operator == InfixExpression.Operator.CONDITIONAL_AND) { 512 return getInversedAndOrExpression(rewrite, infixExpression, InfixExpression.Operator.CONDITIONAL_OR, provider); 513 } 514 if (operator == InfixExpression.Operator.CONDITIONAL_OR) { 515 return getInversedAndOrExpression(rewrite, infixExpression, InfixExpression.Operator.CONDITIONAL_AND, provider); 516 } 517 if (operator == InfixExpression.Operator.AND) { 518 return getInversedAndOrExpression(rewrite, infixExpression, InfixExpression.Operator.OR, provider); 519 } 520 if (operator == InfixExpression.Operator.OR) { 521 return getInversedAndOrExpression(rewrite, infixExpression, InfixExpression.Operator.AND, provider); 522 } 523 } 524 if (expression instanceof PrefixExpression) { 525 PrefixExpression prefixExpression= (PrefixExpression) expression; 526 if (prefixExpression.getOperator() == PrefixExpression.Operator.NOT) { 527 return getRenamedNameCopy(provider, rewrite, prefixExpression.getOperand()); 528 } 529 } 530 if (expression instanceof InstanceofExpression) { 531 PrefixExpression prefixExpression= ast.newPrefixExpression(); 532 prefixExpression.setOperator(PrefixExpression.Operator.NOT); 533 ParenthesizedExpression parenthesizedExpression= ast.newParenthesizedExpression(); 534 parenthesizedExpression.setExpression((Expression) rewrite.createCopyTarget(expression)); 535 prefixExpression.setOperand(parenthesizedExpression); 536 return prefixExpression; 537 } 538 if (expression instanceof ParenthesizedExpression) { 539 ParenthesizedExpression parenthesizedExpression= (ParenthesizedExpression) expression; 540 Expression innerExpression= parenthesizedExpression.getExpression(); 541 while (innerExpression instanceof ParenthesizedExpression) { 542 innerExpression= ((ParenthesizedExpression) innerExpression).getExpression(); 543 } 544 if (innerExpression instanceof InstanceofExpression) { 545 return getInversedBooleanExpression(rewrite, innerExpression, provider); 546 } 547 parenthesizedExpression= ast.newParenthesizedExpression(); 548 parenthesizedExpression.setExpression(getInversedBooleanExpression(rewrite, innerExpression, provider)); 549 return parenthesizedExpression; 550 } 551 PrefixExpression prefixExpression= ast.newPrefixExpression(); 553 prefixExpression.setOperator(PrefixExpression.Operator.NOT); 554 prefixExpression.setOperand(getRenamedNameCopy(provider, rewrite, expression)); 555 return prefixExpression; 556 } 557 private static boolean isBoolean(Expression expression) { 558 return expression.resolveTypeBinding() == expression.getAST().resolveWellKnownType("boolean"); } 560 private static Expression getInversedInfixBooleanExpression(ASTRewrite rewrite, InfixExpression expression, InfixExpression.Operator newOperator, SimpleNameRenameProvider provider) { 561 InfixExpression newExpression = rewrite.getAST().newInfixExpression(); 562 newExpression.setOperator(newOperator); 563 newExpression.setLeftOperand(getInversedBooleanExpression(rewrite, expression.getLeftOperand(), provider)); 564 newExpression.setRightOperand(getInversedBooleanExpression(rewrite, expression.getRightOperand(), provider)); 565 return newExpression; 566 } 567 568 private static Expression parenthesizeIfRequired(Expression operand, int newOperatorPrecedence) { 569 if (newOperatorPrecedence < getExpressionPrecedence(operand)) { 570 return getParenthesizedExpression(operand.getAST(), operand); 571 } 572 return operand; 573 } 574 575 private static Expression getInversedAndOrExpression(ASTRewrite rewrite, InfixExpression infixExpression, Operator newOperator, SimpleNameRenameProvider provider) { 576 InfixExpression newExpression = rewrite.getAST().newInfixExpression(); 577 newExpression.setOperator(newOperator); 578 579 int newOperatorPrecedence = getInfixOperatorPrecedence(newOperator); 580 Expression leftOperand = getInversedBooleanExpression(rewrite, infixExpression.getLeftOperand(), provider); 582 newExpression.setLeftOperand(parenthesizeIfRequired(leftOperand, newOperatorPrecedence)); 583 584 Expression rightOperand = getInversedBooleanExpression(rewrite, infixExpression.getRightOperand(), provider); 585 newExpression.setRightOperand(parenthesizeIfRequired(rightOperand, newOperatorPrecedence)); 586 587 List extraOperands= infixExpression.extendedOperands(); 588 List newExtraOperands= newExpression.extendedOperands(); 589 for (int i= 0; i < extraOperands.size(); i++) { 590 Expression extraOperand = getInversedBooleanExpression(rewrite, (Expression) extraOperands.get(i), provider); 591 newExtraOperands.add(parenthesizeIfRequired(extraOperand, newOperatorPrecedence)); 592 } 593 return newExpression; 594 } 595 private static boolean getRemoveExtraParenthesisProposals(IInvocationContext context, ASTNode covering, ArrayList coveredNodes, 596 Collection resultingCollections) { 597 ArrayList nodes; 598 if ((context.getSelectionLength() == 0) && (covering instanceof ParenthesizedExpression)) { 599 nodes = new ArrayList (); 600 nodes.add(covering); 601 } else { 602 nodes= coveredNodes; 603 } 604 if (nodes.isEmpty()) 605 return false; 606 607 IFix fix= ExpressionsFix.createRemoveUnnecessaryParenthesisFix(context.getASTRoot(), (ASTNode[])nodes.toArray(new ASTNode[nodes.size()])); 608 if (fix == null) 609 return false; 610 611 if (resultingCollections == null) 612 return true; 613 614 Image image= JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_REMOVE); 615 Map options= new Hashtable (); 616 options.put(CleanUpConstants.EXPRESSIONS_USE_PARENTHESES, CleanUpConstants.TRUE); 617 options.put(CleanUpConstants.EXPRESSIONS_USE_PARENTHESES_NEVER, CleanUpConstants.TRUE); 618 FixCorrectionProposal proposal= new FixCorrectionProposal(fix, new ExpressionsCleanUp(options), 1, image, context); 619 resultingCollections.add(proposal); 620 return true; 621 } 622 private static int getExpressionPrecedence(Expression expression) { 623 if (expression instanceof PostfixExpression) { 624 return 0; 625 } 626 if (expression instanceof PrefixExpression) { 627 return 1; 628 } 629 if ((expression instanceof ClassInstanceCreation) || (expression instanceof CastExpression)) { 630 return 2; 631 } 632 if (expression instanceof InfixExpression) { 633 InfixExpression infixExpression = (InfixExpression) expression; 634 InfixExpression.Operator operator = infixExpression.getOperator(); 635 return getInfixOperatorPrecedence(operator); 636 } 637 if (expression instanceof InstanceofExpression) { 638 return 6; 639 } 640 if (expression instanceof ConditionalExpression) { 641 return 13; 642 } 643 if (expression instanceof Assignment) { 644 return 14; 645 } 646 if (expression instanceof MethodInvocation) { 647 return 2; 648 } 649 return -1; 650 } 651 private static int getInfixOperatorPrecedence(InfixExpression.Operator operator) { 652 if ((operator == InfixExpression.Operator.TIMES) || (operator == InfixExpression.Operator.DIVIDE) 653 || (operator == InfixExpression.Operator.REMAINDER)) { 654 return 3; 655 } 656 if ((operator == InfixExpression.Operator.PLUS) || (operator == InfixExpression.Operator.MINUS)) { 657 return 4; 658 } 659 if ((operator == InfixExpression.Operator.LEFT_SHIFT) 660 || (operator == InfixExpression.Operator.RIGHT_SHIFT_SIGNED) 661 || (operator == InfixExpression.Operator.RIGHT_SHIFT_UNSIGNED)) { 662 return 5; 663 } 664 if ((operator == InfixExpression.Operator.LESS) || (operator == InfixExpression.Operator.GREATER) 665 || (operator == InfixExpression.Operator.LESS_EQUALS) 666 || (operator == InfixExpression.Operator.GREATER_EQUALS)) { 667 return 6; 668 } 669 if ((operator == InfixExpression.Operator.EQUALS) || (operator == InfixExpression.Operator.NOT_EQUALS)) { 670 return 7; 671 } 672 if (operator == InfixExpression.Operator.AND) { 673 return 8; 674 } 675 if (operator == InfixExpression.Operator.XOR) { 676 return 9; 677 } 678 if (operator == InfixExpression.Operator.OR) { 679 return 10; 680 } 681 if (operator == InfixExpression.Operator.CONDITIONAL_AND) { 682 return 11; 683 } 684 if (operator == InfixExpression.Operator.CONDITIONAL_OR) { 685 return 12; 686 } 687 return -1; 688 } 689 690 private static boolean getAddParanoidalParenthesisProposals(IInvocationContext context, ASTNode covering, ArrayList coveredNodes, 691 Collection resultingCollections) throws CoreException { 692 693 IFix fix= ExpressionsFix.createAddParanoidalParenthesisFix(context.getASTRoot(), (ASTNode[])coveredNodes.toArray(new ASTNode[coveredNodes.size()])); 694 if (fix == null) 695 return false; 696 697 if (resultingCollections == null) 698 return true; 699 700 Image image = JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_CHANGE); 702 Map options= new Hashtable (); 703 options.put(CleanUpConstants.EXPRESSIONS_USE_PARENTHESES, CleanUpConstants.TRUE); 704 options.put(CleanUpConstants.EXPRESSIONS_USE_PARENTHESES_ALWAYS, CleanUpConstants.TRUE); 705 FixCorrectionProposal proposal= new FixCorrectionProposal(fix, new ExpressionsCleanUp(options), 1, image, context); 706 resultingCollections.add(proposal); 707 return true; 708 } 709 710 private static ArrayList getFullyCoveredNodes(IInvocationContext context, ASTNode coveringNode) { 711 final ArrayList coveredNodes = new ArrayList (); 712 final int selectionBegin = context.getSelectionOffset(); 713 final int selectionEnd = selectionBegin + context.getSelectionLength(); 714 coveringNode.accept(new GenericVisitor() { 715 protected boolean visitNode(ASTNode node) { 716 int nodeStart= node.getStartPosition(); 717 int nodeEnd= nodeStart + node.getLength(); 718 if (nodeEnd < selectionBegin || selectionEnd < nodeStart) { 720 return false; 721 } 722 if (isCovered(node)) { 724 ASTNode parent = node.getParent(); 725 if ((parent == null) || !isCovered(parent)) { 726 coveredNodes.add(node); 727 return false; 728 } 729 } 730 return true; 732 } 733 private boolean isCovered(ASTNode node) { 734 int begin = node.getStartPosition(); 735 int end = begin + node.getLength(); 736 return (begin >= selectionBegin) && (end <= selectionEnd); 737 } 738 }); 739 return coveredNodes; 740 } 741 private static boolean getJoinAndIfStatementsProposals(IInvocationContext context, ASTNode node, 742 Collection resultingCollections) { 743 Operator andOperator = InfixExpression.Operator.CONDITIONAL_AND; 744 boolean result = false; 745 Statement statement = ASTResolving.findParentStatement(node); 747 if (!(statement instanceof IfStatement)) { 748 return false; 749 } 750 IfStatement ifStatement = (IfStatement) statement; 751 if (ifStatement.getElseStatement() != null) { 752 return false; 753 } 754 { 756 IfStatement outerIf = null; 757 if (ifStatement.getParent() instanceof IfStatement) { 758 outerIf = (IfStatement) ifStatement.getParent(); 759 } else if (ifStatement.getParent() instanceof Block) { 760 Block block = (Block) ifStatement.getParent(); 761 if ((block.getParent() instanceof IfStatement) && (block.statements().size() == 1)) { 762 outerIf = (IfStatement) block.getParent(); 763 } 764 } 765 if ((outerIf != null) && (outerIf.getElseStatement() == null)) { 766 if (resultingCollections == null) { 767 return true; 768 } 769 AST ast = statement.getAST(); 771 ASTRewrite rewrite = ASTRewrite.create(ast); 772 Expression outerCondition = getParenthesizedForAndIfNeeded(ast, rewrite, outerIf.getExpression()); 774 Expression innerCondition = getParenthesizedForAndIfNeeded(ast, rewrite, ifStatement.getExpression()); 775 InfixExpression condition = ast.newInfixExpression(); 777 condition.setOperator(andOperator); 778 condition.setLeftOperand(outerCondition); 779 condition.setRightOperand(innerCondition); 780 IfStatement newIf = ast.newIfStatement(); 782 newIf.setExpression(condition); 783 Statement bodyPlaceholder = (Statement) rewrite.createCopyTarget(ifStatement.getThenStatement()); 784 newIf.setThenStatement(bodyPlaceholder); 785 rewrite.replace(outerIf, newIf, null); 786 String label = CorrectionMessages.AdvancedQuickAssistProcessor_joinWithOuter_description; 788 Image image = JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_CHANGE); 789 ASTRewriteCorrectionProposal proposal = new ASTRewriteCorrectionProposal(label, 790 context.getCompilationUnit(), rewrite, 1, image); 791 resultingCollections.add(proposal); 792 result = true; 793 } 794 } 795 { 797 IfStatement innerIf = null; 798 if (ifStatement.getThenStatement() instanceof IfStatement) { 799 innerIf = (IfStatement) ifStatement.getThenStatement(); 800 } else if (ifStatement.getThenStatement() instanceof Block) { 801 Block block = (Block) ifStatement.getThenStatement(); 802 if ((block.statements().size() == 1) && (block.statements().get(0) instanceof IfStatement)) { 803 innerIf = (IfStatement) block.statements().get(0); 804 } 805 } 806 if ((innerIf != null) && (innerIf.getElseStatement() == null)) { 807 if (resultingCollections == null) { 808 return true; 809 } 810 AST ast = statement.getAST(); 812 ASTRewrite rewrite = ASTRewrite.create(ast); 813 Expression outerCondition = getParenthesizedForAndIfNeeded(ast, rewrite, ifStatement.getExpression()); 815 Expression innerCondition = getParenthesizedForAndIfNeeded(ast, rewrite, innerIf.getExpression()); 816 InfixExpression condition = ast.newInfixExpression(); 818 condition.setOperator(andOperator); 819 condition.setLeftOperand(outerCondition); 820 condition.setRightOperand(innerCondition); 821 IfStatement newIf = ast.newIfStatement(); 823 newIf.setExpression(condition); 824 Statement bodyPlaceholder = (Statement) rewrite.createCopyTarget(innerIf.getThenStatement()); 825 newIf.setThenStatement(bodyPlaceholder); 826 rewrite.replace(ifStatement, newIf, null); 827 String label = CorrectionMessages.AdvancedQuickAssistProcessor_joinWithInner_description; 829 Image image = JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_CHANGE); 830 ASTRewriteCorrectionProposal proposal = new ASTRewriteCorrectionProposal(label, 831 context.getCompilationUnit(), rewrite, 1, image); 832 resultingCollections.add(proposal); 833 result = true; 834 } 835 } 836 return result; 837 } 838 private static Expression getParenthesizedForAndIfNeeded(AST ast, ASTRewrite rewrite, Expression expression) { 839 boolean addParentheses = false; 840 int nodeType = expression.getNodeType(); 841 if (nodeType == ASTNode.INFIX_EXPRESSION) { 842 InfixExpression infixExpression = (InfixExpression) expression; 843 addParentheses = infixExpression.getOperator() == InfixExpression.Operator.CONDITIONAL_OR; 844 } else { 845 addParentheses = nodeType == ASTNode.CONDITIONAL_EXPRESSION || nodeType == ASTNode.ASSIGNMENT 846 || nodeType == ASTNode.INSTANCEOF_EXPRESSION; 847 } 848 expression = (Expression) rewrite.createCopyTarget(expression); 849 if (addParentheses) { 850 return getParenthesizedExpression(ast, expression); 851 } 852 return expression; 853 } 854 private static Expression getParenthesizedExpression(AST ast, Expression expression) { 855 ParenthesizedExpression parenthesizedExpression = ast.newParenthesizedExpression(); 856 parenthesizedExpression.setExpression(expression); 857 return parenthesizedExpression; 858 } 859 private static boolean getSplitAndConditionProposals(IInvocationContext context, ASTNode node, 860 Collection resultingCollections) { 861 Operator andOperator = InfixExpression.Operator.CONDITIONAL_AND; 862 if (!(node instanceof InfixExpression)) { 864 return false; 865 } 866 InfixExpression infixExpression = (InfixExpression) node; 867 if (infixExpression.getOperator() != andOperator) { 868 return false; 869 } 870 int offset= isOperatorSelected(infixExpression, context.getSelectionOffset(), context.getSelectionLength()); 871 if (offset == -1) { 872 return false; 873 } 874 875 Statement statement = ASTResolving.findParentStatement(node); 877 if (!(statement instanceof IfStatement)) { 878 return false; 879 } 880 IfStatement ifStatement = (IfStatement) statement; 881 if (ifStatement.getElseStatement() != null) { 882 return false; 883 } 884 InfixExpression topInfixExpression = infixExpression; 886 while ((topInfixExpression.getParent() instanceof InfixExpression) 887 && ((InfixExpression) topInfixExpression.getParent()).getOperator() == andOperator) { 888 topInfixExpression = (InfixExpression) topInfixExpression.getParent(); 889 } 890 if (ifStatement.getExpression() != topInfixExpression) { 891 return false; 892 } 893 if (resultingCollections == null) { 895 return true; 896 } 897 AST ast = ifStatement.getAST(); 898 ASTRewrite rewrite = ASTRewrite.create(ast); 899 900 Expression[] newOperands= { null, null }; 902 breakInfixOperationAtOperation(rewrite, topInfixExpression, andOperator, offset, true, newOperands); 903 904 Expression leftCondition= newOperands[0]; 905 Expression rightCondition= newOperands[1]; 906 907 rewrite.set(ifStatement, IfStatement.EXPRESSION_PROPERTY, rightCondition, null); 909 IfStatement outerIfStatement = ast.newIfStatement(); 911 outerIfStatement.setExpression(leftCondition); 912 Block outerBlock = ast.newBlock(); 913 outerIfStatement.setThenStatement(outerBlock); 914 ASTNode ifPlaceholder = rewrite.createMoveTarget(ifStatement); 915 outerBlock.statements().add(ifPlaceholder); 916 rewrite.replace(ifStatement, outerIfStatement, null); 918 String label = CorrectionMessages.AdvancedQuickAssistProcessor_splitAndCondition_description; 920 Image image = JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_CHANGE); 921 ASTRewriteCorrectionProposal proposal = new ASTRewriteCorrectionProposal(label, context.getCompilationUnit(), 922 rewrite, 1, image); 923 resultingCollections.add(proposal); 924 return true; 925 } 926 private static boolean isSelectingOperator(ASTNode n1, ASTNode n2, int offset, int length) { 927 if (offset + length <= n2.getStartPosition() && offset >= ASTNodes.getExclusiveEnd(n1)) { 929 return true; 930 } 931 if (n1.getStartPosition() == offset && ASTNodes.getExclusiveEnd(n2) == offset + length) { 933 if (n1 instanceof InfixExpression || n2 instanceof InfixExpression) { 934 return false; 935 } 936 return true; 937 } 938 return false; 939 } 940 941 private static int isOperatorSelected(InfixExpression infixExpression, int offset, int length) { 942 ASTNode left= infixExpression.getLeftOperand(); 943 ASTNode right= infixExpression.getRightOperand(); 944 945 if (isSelectingOperator(left, right, offset, length)) { 946 return ASTNodes.getExclusiveEnd(left); 947 } 948 List extended= infixExpression.extendedOperands(); 949 for (int i= 0; i < extended.size(); i++) { 950 left= right; 951 right= (ASTNode) extended.get(i); 952 if (isSelectingOperator(left, right, offset, length)) { 953 return ASTNodes.getExclusiveEnd(left); 954 } 955 } 956 return -1; 957 } 958 959 private static boolean getJoinOrIfStatementsProposals(IInvocationContext context, ASTNode covering, ArrayList coveredNodes, 960 Collection resultingCollections) { 961 Operator orOperator = InfixExpression.Operator.CONDITIONAL_OR; 962 if (coveredNodes.size() < 2) 963 return false; 964 String commonThenSource = null; 966 for (Iterator iter = coveredNodes.iterator(); iter.hasNext();) { 967 ASTNode node = (ASTNode) iter.next(); 968 if (!(node instanceof IfStatement)) 969 return false; 970 IfStatement ifStatement = (IfStatement) node; 972 if (ifStatement.getElseStatement() != null) 973 return false; 974 Statement thenStatement = ifStatement.getThenStatement(); 976 try { 977 String thenSource = context.getCompilationUnit().getBuffer().getText(thenStatement.getStartPosition(), 978 thenStatement.getLength()); 979 if (commonThenSource == null) { 980 commonThenSource = thenSource; 981 } else { 982 if (!commonThenSource.equals(thenSource)) 983 return false; 984 } 985 } catch (Throwable e) { 986 return false; 987 } 988 } 989 if (resultingCollections == null) { 990 return true; 991 } 992 final AST ast = covering.getAST(); 994 final ASTRewrite rewrite = ASTRewrite.create(ast); 995 InfixExpression condition = null; 997 boolean hasRightOperand = false; 998 Statement thenStatement = null; 999 for (Iterator iter = coveredNodes.iterator(); iter.hasNext();) { 1000 IfStatement ifStatement = (IfStatement) iter.next(); 1001 if (thenStatement == null) 1002 thenStatement = (Statement) rewrite.createCopyTarget(ifStatement.getThenStatement()); 1003 Expression ifCondition = getParenthesizedForOrIfNeeded(ast, rewrite, ifStatement.getExpression()); 1004 if (condition == null) { 1005 condition = ast.newInfixExpression(); 1006 condition.setOperator(orOperator); 1007 condition.setLeftOperand(ifCondition); 1008 } else if (!hasRightOperand) { 1009 condition.setRightOperand(ifCondition); 1010 hasRightOperand = true; 1011 } else { 1012 InfixExpression newCondition = ast.newInfixExpression(); 1013 newCondition.setOperator(orOperator); 1014 newCondition.setLeftOperand(condition); 1015 newCondition.setRightOperand(ifCondition); 1016 condition = newCondition; 1017 } 1018 } 1019 IfStatement newIf = ast.newIfStatement(); 1021 newIf.setExpression(condition); 1022 newIf.setThenStatement(thenStatement); 1023 ListRewrite listRewriter = null; 1025 for (Iterator iter = coveredNodes.iterator(); iter.hasNext();) { 1026 IfStatement ifStatement = (IfStatement) iter.next(); 1027 if (listRewriter == null) { 1028 Block sourceBlock = (Block) ifStatement.getParent(); 1029 listRewriter = rewrite.getListRewrite(sourceBlock, 1031 (ChildListPropertyDescriptor) ifStatement.getLocationInParent()); 1032 } 1033 if (newIf != null) { 1034 listRewriter.replace(ifStatement, newIf, null); 1035 newIf = null; 1036 } else { 1037 listRewriter.remove(ifStatement, null); 1038 } 1039 } 1040 String label = CorrectionMessages.AdvancedQuickAssistProcessor_joinWithOr_description; 1042 Image image = JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_CHANGE); 1043 ASTRewriteCorrectionProposal proposal = new ASTRewriteCorrectionProposal(label, context.getCompilationUnit(), 1044 rewrite, 1, image); 1045 resultingCollections.add(proposal); 1046 return true; 1047 } 1048 private static Expression getParenthesizedForOrIfNeeded(AST ast, ASTRewrite rewrite, Expression expression) { 1049 boolean addParentheses = false; 1050 int nodeType = expression.getNodeType(); 1051 addParentheses = nodeType == ASTNode.CONDITIONAL_EXPRESSION || nodeType == ASTNode.ASSIGNMENT 1052 || nodeType == ASTNode.INSTANCEOF_EXPRESSION; 1053 expression = (Expression) rewrite.createCopyTarget(expression); 1054 if (addParentheses) { 1055 return getParenthesizedExpression(ast, expression); 1056 } 1057 return expression; 1058 } 1059 private static boolean getSplitOrConditionProposals(IInvocationContext context, ASTNode node, 1060 Collection resultingCollections) { 1061 Operator orOperator = InfixExpression.Operator.CONDITIONAL_OR; 1062 if (!(node instanceof InfixExpression)) { 1064 return false; 1065 } 1066 InfixExpression infixExpression = (InfixExpression) node; 1067 if (infixExpression.getOperator() != orOperator) { 1068 return false; 1069 } 1070 int offset= isOperatorSelected(infixExpression, context.getSelectionOffset(), context.getSelectionLength()); 1071 if (offset == -1) { 1072 return false; 1073 } 1074 Statement statement = ASTResolving.findParentStatement(node); 1076 if (!(statement instanceof IfStatement)) { 1077 return false; 1078 } 1079 IfStatement ifStatement = (IfStatement) statement; 1080 if (ifStatement.getElseStatement() != null) { 1081 return false; 1082 } 1083 InfixExpression topInfixExpression = infixExpression; 1085 while ((topInfixExpression.getParent() instanceof InfixExpression) 1086 && ((InfixExpression) topInfixExpression.getParent()).getOperator() == orOperator) { 1087 topInfixExpression = (InfixExpression) topInfixExpression.getParent(); 1088 } 1089 if (ifStatement.getExpression() != topInfixExpression) { 1090 return false; 1091 } 1092 if (resultingCollections == null) { 1094 return true; 1095 } 1096 AST ast = ifStatement.getAST(); 1097 ASTRewrite rewrite = ASTRewrite.create(ast); 1098 1099 Expression[] newOperands= { null, null }; 1101 breakInfixOperationAtOperation(rewrite, topInfixExpression, orOperator, offset, true, newOperands); 1102 1103 Expression leftCondition= newOperands[0]; 1104 Expression rightCondition= newOperands[1]; 1105 1106 IfStatement firstIf = ast.newIfStatement(); 1108 firstIf.setExpression(leftCondition); 1109 firstIf.setThenStatement((Statement) rewrite.createCopyTarget(ifStatement.getThenStatement())); 1110 IfStatement secondIf = ast.newIfStatement(); 1112 secondIf.setExpression(rightCondition); 1113 secondIf.setThenStatement((Statement) rewrite.createCopyTarget(ifStatement.getThenStatement())); 1114 Block sourceBlock = (Block) ifStatement.getParent(); 1116 int insertIndex = sourceBlock.statements().indexOf(ifStatement); 1117 ListRewrite listRewriter = rewrite.getListRewrite(sourceBlock, 1118 (ChildListPropertyDescriptor) statement.getLocationInParent()); 1119 listRewriter.replace(ifStatement, firstIf, null); 1120 listRewriter.insertAt(secondIf, insertIndex + 1, null); 1121 String label = CorrectionMessages.AdvancedQuickAssistProcessor_splitOrCondition_description; 1123 Image image = JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_CHANGE); 1124 ASTRewriteCorrectionProposal proposal = new ASTRewriteCorrectionProposal(label, context.getCompilationUnit(), 1125 rewrite, 1, image); 1126 resultingCollections.add(proposal); 1127 return true; 1128 } 1129 private static boolean getInverseConditionalExpressionProposals(IInvocationContext context, ASTNode covering, 1130 Collection resultingCollections) { 1131 while (covering instanceof Expression) { 1133 if (covering instanceof ConditionalExpression) 1134 break; 1135 covering = covering.getParent(); 1136 } 1137 if (!(covering instanceof ConditionalExpression)) { 1138 return false; 1139 } 1140 ConditionalExpression expression = (ConditionalExpression) covering; 1141 if (resultingCollections == null) { 1143 return true; 1144 } 1145 AST ast = covering.getAST(); 1147 ASTRewrite rewrite = ASTRewrite.create(ast); 1148 ConditionalExpression newExpression = ast.newConditionalExpression(); 1150 newExpression.setExpression(getInversedBooleanExpression(rewrite, expression.getExpression())); 1151 newExpression.setThenExpression((Expression) rewrite.createCopyTarget(expression.getElseExpression())); 1152 newExpression.setElseExpression((Expression) rewrite.createCopyTarget(expression.getThenExpression())); 1153 rewrite.replace(expression, newExpression, null); 1155 String label = CorrectionMessages.AdvancedQuickAssistProcessor_inverseConditionalExpression_description; 1157 Image image = JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_CHANGE); 1158 ASTRewriteCorrectionProposal proposal = new ASTRewriteCorrectionProposal(label, context.getCompilationUnit(), 1159 rewrite, 1, image); 1160 resultingCollections.add(proposal); 1161 return true; 1162 } 1163 private static boolean getExchangeInnerAndOuterIfConditionsProposals(IInvocationContext context, ASTNode node, 1164 Collection resultingCollections) { 1165 boolean result = false; 1166 Statement statement = ASTResolving.findParentStatement(node); 1168 if (!(statement instanceof IfStatement)) { 1169 return false; 1170 } 1171 IfStatement ifStatement = (IfStatement) statement; 1172 if (ifStatement.getElseStatement() != null) { 1173 return false; 1174 } 1175 { 1177 IfStatement outerIf = null; 1178 if (ifStatement.getParent() instanceof IfStatement) { 1179 outerIf = (IfStatement) ifStatement.getParent(); 1180 } else if (ifStatement.getParent() instanceof Block) { 1181 Block block = (Block) ifStatement.getParent(); 1182 if ((block.getParent() instanceof IfStatement) && (block.statements().size() == 1)) { 1183 outerIf = (IfStatement) block.getParent(); 1184 } 1185 } 1186 if ((outerIf != null) && (outerIf.getElseStatement() == null)) { 1187 if (resultingCollections == null) { 1188 return true; 1189 } 1190 AST ast = statement.getAST(); 1192 ASTRewrite rewrite = ASTRewrite.create(ast); 1193 Expression outerCondition = (Expression) rewrite.createCopyTarget(outerIf.getExpression()); 1195 Expression innerCondition = (Expression) rewrite.createCopyTarget(ifStatement.getExpression()); 1196 rewrite.replace(outerIf.getExpression(), innerCondition, null); 1198 rewrite.replace(ifStatement.getExpression(), outerCondition, null); 1199 String label = CorrectionMessages.AdvancedQuickAssistProcessor_exchangeInnerAndOuterIfConditions_description; 1201 Image image = JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_CHANGE); 1202 ASTRewriteCorrectionProposal proposal = new ASTRewriteCorrectionProposal(label, 1203 context.getCompilationUnit(), rewrite, 1, image); 1204 resultingCollections.add(proposal); 1205 result = true; 1206 } 1207 } 1208 { 1210 IfStatement innerIf = null; 1211 if (ifStatement.getThenStatement() instanceof IfStatement) { 1212 innerIf = (IfStatement) ifStatement.getThenStatement(); 1213 } else if (ifStatement.getThenStatement() instanceof Block) { 1214 Block block = (Block) ifStatement.getThenStatement(); 1215 if ((block.statements().size() == 1) && (block.statements().get(0) instanceof IfStatement)) { 1216 innerIf = (IfStatement) block.statements().get(0); 1217 } 1218 } 1219 if ((innerIf != null) && (innerIf.getElseStatement() == null)) { 1220 if (resultingCollections == null) { 1221 return true; 1222 } 1223 AST ast = statement.getAST(); 1225 ASTRewrite rewrite = ASTRewrite.create(ast); 1226 Expression innerCondition = (Expression) rewrite.createCopyTarget(innerIf.getExpression()); 1228 Expression outerCondition = (Expression) rewrite.createCopyTarget(ifStatement.getExpression()); 1229 rewrite.replace(innerIf.getExpression(), outerCondition, null); 1231 rewrite.replace(ifStatement.getExpression(), innerCondition, null); 1232 String label = CorrectionMessages.AdvancedQuickAssistProcessor_exchangeInnerAndOuterIfConditions_description; 1234 Image image = JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_CHANGE); 1235 ASTRewriteCorrectionProposal proposal = new ASTRewriteCorrectionProposal(label, 1236 context.getCompilationUnit(), rewrite, 1, image); 1237 resultingCollections.add(proposal); 1238 result = true; 1239 } 1240 } 1241 return result; 1242 } 1243 private static boolean getExchangeOperandsProposals(IInvocationContext context, ASTNode node, 1244 Collection resultingCollections) { 1245 if (!(node instanceof InfixExpression)) { 1247 return false; 1248 } 1249 InfixExpression infixExpression = (InfixExpression) node; 1250 Operator operator = infixExpression.getOperator(); 1251 if ((operator != InfixExpression.Operator.CONDITIONAL_AND) && (operator != InfixExpression.Operator.AND) 1252 && (operator != InfixExpression.Operator.CONDITIONAL_OR) && (operator != InfixExpression.Operator.OR) 1253 && (operator != InfixExpression.Operator.EQUALS) && (operator != InfixExpression.Operator.PLUS) 1254 && (operator != InfixExpression.Operator.TIMES) && (operator != InfixExpression.Operator.XOR)) { 1255 return false; 1256 } 1257 1258 int offset= isOperatorSelected(infixExpression, context.getSelectionOffset(), context.getSelectionLength()); 1259 if (offset == -1) { 1260 return false; 1261 } 1262 1263 if (resultingCollections == null) { 1265 return true; 1266 } 1267 AST ast = infixExpression.getAST(); 1268 ASTRewrite rewrite = ASTRewrite.create(ast); 1269 Expression leftExpression = null; 1271 Expression rightExpression = null; 1272 InfixExpression currentExpression = infixExpression; 1273 leftExpression= combineOperands(rewrite, leftExpression, infixExpression.getLeftOperand(), true, operator); 1274 if (infixExpression.getRightOperand().getStartPosition() <= context.getSelectionOffset()) { 1275 leftExpression= combineOperands(rewrite, leftExpression, infixExpression.getRightOperand(), true, operator); 1276 } else { 1277 rightExpression= combineOperands(rewrite, rightExpression, infixExpression.getRightOperand(), true, operator); 1278 } 1279 for (Iterator iter= currentExpression.extendedOperands().iterator(); iter.hasNext();) { 1280 Expression extendedOperand= (Expression) iter.next(); 1281 if (extendedOperand.getStartPosition() <= context.getSelectionOffset()) { 1282 leftExpression= combineOperands(rewrite, leftExpression, extendedOperand, true, operator); 1283 } else { 1284 rightExpression= combineOperands(rewrite, rightExpression, extendedOperand, true, operator); 1285 } 1286 } 1287 InfixExpression newInfix = ast.newInfixExpression(); 1289 newInfix.setOperator(operator); 1290 newInfix.setLeftOperand(rightExpression); 1291 newInfix.setRightOperand(leftExpression); 1292 rewrite.replace(infixExpression, newInfix, null); 1293 String label = CorrectionMessages.AdvancedQuickAssistProcessor_exchangeOperands_description; 1295 Image image = JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_CHANGE); 1296 ASTRewriteCorrectionProposal proposal = new ASTRewriteCorrectionProposal(label, context.getCompilationUnit(), rewrite, 1, image); 1297 resultingCollections.add(proposal); 1298 return true; 1299 } 1300 1301 1309 private static void breakInfixOperationAtOperation(ASTRewrite rewrite, Expression expression, Operator operator, int operatorOffset, boolean removeParenthesis, Expression[] res) { 1310 if (expression.getStartPosition() + expression.getLength() <= operatorOffset) { 1311 res[0]= combineOperands(rewrite, res[0], expression, removeParenthesis, operator); 1313 return; 1314 } 1315 if (operatorOffset <= expression.getStartPosition()) { 1316 res[1]= combineOperands(rewrite, res[1], expression, removeParenthesis, operator); 1318 return; 1319 } 1320 if (!(expression instanceof InfixExpression)) { 1321 throw new IllegalArgumentException ("Cannot break up non-infix expression"); } 1323 InfixExpression infixExpression= (InfixExpression) expression; 1324 if (infixExpression.getOperator() != operator) { 1325 throw new IllegalArgumentException ("Incompatible operator"); } 1327 breakInfixOperationAtOperation(rewrite, infixExpression.getLeftOperand(), operator, operatorOffset, removeParenthesis, res); 1328 breakInfixOperationAtOperation(rewrite, infixExpression.getRightOperand(), operator, operatorOffset, removeParenthesis, res); 1329 1330 List extended= infixExpression.extendedOperands(); 1331 for (int i= 0; i < extended.size(); i++) { 1332 breakInfixOperationAtOperation(rewrite, (Expression) extended.get(i), operator, operatorOffset, removeParenthesis, res); 1333 } 1334 } 1335 1336 private static Expression combineOperands(ASTRewrite rewrite, Expression existing, Expression nodeToAdd, boolean removeParenthesis, Operator operator) { 1337 if (existing == null && removeParenthesis) { 1338 while (nodeToAdd instanceof ParenthesizedExpression) { 1339 nodeToAdd= ((ParenthesizedExpression) nodeToAdd).getExpression(); 1340 } 1341 } 1342 Expression newRight= (Expression) rewrite.createMoveTarget(nodeToAdd); 1343 if (existing == null) { 1344 return newRight; 1345 } 1346 AST ast= rewrite.getAST(); 1347 InfixExpression infix= ast.newInfixExpression(); 1348 infix.setOperator(operator); 1349 infix.setLeftOperand(existing); 1350 infix.setRightOperand(newRight); 1351 return infix; 1352 } 1353 1354 private static boolean getCastAndAssignIfStatementProposals(IInvocationContext context, ASTNode node, Collection resultingCollections) { 1355 if (!(node instanceof InstanceofExpression)) { 1356 return false; 1357 } 1358 InstanceofExpression expression= (InstanceofExpression) node; 1359 while (node.getParent() instanceof Expression) { 1361 node= node.getParent(); 1362 } 1363 StructuralPropertyDescriptor locationInParent= node.getLocationInParent(); 1364 1365 boolean negated= isNegated(expression); 1366 1367 Statement body= null; 1368 ASTNode insertionPosition= null; 1369 if (negated) { 1370 insertionPosition= node.getParent(); 1371 if (locationInParent == IfStatement.EXPRESSION_PROPERTY) { 1372 body= ((IfStatement) node.getParent()).getElseStatement(); 1373 if (body != null) { 1374 negated= false; 1375 } 1376 } 1377 if (body == null && insertionPosition.getParent() instanceof Block) { 1378 body= (Statement)insertionPosition.getParent(); 1379 } 1380 } else { 1381 if (locationInParent == IfStatement.EXPRESSION_PROPERTY) { 1382 body= ((IfStatement) node.getParent()).getThenStatement(); 1383 } else if (locationInParent == WhileStatement.EXPRESSION_PROPERTY) { 1384 body= ((WhileStatement) node.getParent()).getBody(); 1385 } 1386 } 1387 if (body == null) { 1388 return false; 1389 } 1390 1391 Type originalType= expression.getRightOperand(); 1392 if (originalType.resolveBinding() == null) { 1393 return false; 1394 } 1395 1396 if (resultingCollections == null) { 1398 return true; 1399 } 1400 1401 final String KEY_NAME= "name"; final String KEY_TYPE= "type"; AST ast= expression.getAST(); 1405 ASTRewrite rewrite= ASTRewrite.create(ast); 1406 ICompilationUnit cu= context.getCompilationUnit(); 1407 String label= CorrectionMessages.AdvancedQuickAssistProcessor_castAndAssign; 1409 Image image= JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_LOCAL); 1410 LinkedCorrectionProposal proposal= new LinkedCorrectionProposal(label, cu, rewrite, 7, image); 1411 String [] varNames= suggestLocalVariableNames(cu, originalType.resolveBinding()); 1413 for (int i= 0; i < varNames.length; i++) { 1414 proposal.addLinkedPositionProposal(KEY_NAME, varNames[i], null); 1415 } 1416 CastExpression castExpression= ast.newCastExpression(); 1417 castExpression.setExpression((Expression) rewrite.createCopyTarget(expression.getLeftOperand())); 1418 castExpression.setType((Type) ASTNode.copySubtree(ast, originalType)); 1419 VariableDeclarationFragment vdf= ast.newVariableDeclarationFragment(); 1421 vdf.setName(ast.newSimpleName(varNames[0])); 1422 vdf.setInitializer(castExpression); 1423 VariableDeclarationStatement vds= ast.newVariableDeclarationStatement(vdf); 1425 vds.setType((Type) ASTNode.copySubtree(ast, originalType)); 1426 1427 if (negated) { 1429 ListRewrite listRewriter= rewrite.getListRewrite(body, Block.STATEMENTS_PROPERTY); 1430 listRewriter.insertAfter(vds, insertionPosition, null); 1431 } else { 1432 if (body instanceof Block) { 1433 ListRewrite listRewriter= rewrite.getListRewrite(body, Block.STATEMENTS_PROPERTY); 1434 listRewriter.insertAt(vds, 0, null); 1435 } else { 1436 Block newBlock= ast.newBlock(); 1437 List statements= newBlock.statements(); 1438 statements.add(vds); 1439 statements.add(rewrite.createMoveTarget(body)); 1440 rewrite.replace(body, newBlock, null); 1441 } 1442 } 1443 1444 proposal.addLinkedPosition(rewrite.track(vdf.getName()), true, KEY_NAME); 1446 proposal.addLinkedPosition(rewrite.track(vds.getType()), false, KEY_TYPE); 1447 proposal.addLinkedPosition(rewrite.track(castExpression.getType()), false, KEY_TYPE); 1448 proposal.setEndPosition(rewrite.track(vds)); resultingCollections.add(proposal); 1451 return true; 1452 } 1453 1454 private static boolean isNegated(Expression expression) { 1455 if (!(expression.getParent() instanceof ParenthesizedExpression)) 1456 return false; 1457 1458 ParenthesizedExpression parenthesis= (ParenthesizedExpression)expression.getParent(); 1459 if (!(parenthesis.getParent() instanceof PrefixExpression)) 1460 return false; 1461 1462 PrefixExpression prefix= (PrefixExpression)parenthesis.getParent(); 1463 if (!(prefix.getOperator() == PrefixExpression.Operator.NOT)) 1464 return false; 1465 1466 return true; 1467 } 1468 private static String [] suggestLocalVariableNames(ICompilationUnit cu, ITypeBinding binding) { 1469 return StubUtility.getVariableNameSuggestions(StubUtility.LOCAL, cu.getJavaProject(), binding, null, null); 1470 } 1471 1472 private static boolean getPickOutStringProposals(IInvocationContext context, ASTNode node, Collection resultingCollections) { 1473 if (!(node instanceof StringLiteral)) { 1475 return false; 1476 } 1477 int selectionPos= context.getSelectionOffset(); 1479 int selectionLen= context.getSelectionLength(); 1480 if (selectionLen == 0) { 1481 return false; 1482 } 1483 int valueStart= node.getStartPosition() + 1; 1484 int valueEnd= node.getStartPosition() + node.getLength() - 1; 1485 1486 if ((selectionPos < valueStart) || (selectionPos + selectionLen > valueEnd) || (valueEnd - valueStart == selectionLen)) { 1488 return false; 1489 } 1490 1491 StringLiteral stringLiteral= (StringLiteral) node; 1493 String stringValue= stringLiteral.getEscapedValue(); 1494 1495 int firstPos= selectionPos - node.getStartPosition(); 1496 int secondPos= firstPos + selectionLen; 1497 1498 1499 1501 AST ast= node.getAST(); 1502 StringLiteral leftLiteral= ast.newStringLiteral(); 1503 StringLiteral centerLiteral= ast.newStringLiteral(); 1504 StringLiteral rightLiteral= ast.newStringLiteral(); 1505 try { 1506 leftLiteral.setEscapedValue('"' + stringValue.substring(1, firstPos) + '"'); 1507 centerLiteral.setEscapedValue('"' + stringValue.substring(firstPos, secondPos) + '"'); 1508 rightLiteral.setEscapedValue('"' + stringValue.substring(secondPos, stringValue.length() - 1) + '"'); 1509 } catch (IllegalArgumentException e) { 1510 return false; 1511 } 1512 if (resultingCollections == null) { 1513 return true; 1514 } 1515 1516 ASTRewrite rewrite= ASTRewrite.create(ast); 1517 1518 InfixExpression expression= ast.newInfixExpression(); 1520 expression.setOperator(InfixExpression.Operator.PLUS); 1521 if (firstPos != 1 ) { 1522 expression.setLeftOperand(leftLiteral); 1523 } 1524 1525 1526 if (firstPos == 1) { 1527 expression.setLeftOperand(centerLiteral); 1528 } else { 1529 expression.setRightOperand(centerLiteral); 1530 } 1531 1532 if (secondPos < stringValue.length() - 1) { 1533 if (firstPos == 1) { 1534 expression.setRightOperand(rightLiteral); 1535 } else { 1536 expression.extendedOperands().add(rightLiteral); 1537 } 1538 } 1539 rewrite.replace(stringLiteral, expression, null); 1541 String label= CorrectionMessages.AdvancedQuickAssistProcessor_pickSelectedString; 1543 Image image= JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_CHANGE); 1544 LinkedCorrectionProposal proposal= new LinkedCorrectionProposal(label, context.getCompilationUnit(), rewrite, 1, image); 1545 proposal.addLinkedPosition(rewrite.track(centerLiteral), true, "CENTER_STRING"); resultingCollections.add(proposal); 1547 return true; 1548 } 1549 1550 private static Statement getSingleStatement(Statement statement) { 1551 if (statement instanceof Block) { 1552 List blockStatements= ((Block) statement).statements(); 1553 if (blockStatements.size() != 1) { 1554 return null; 1555 } 1556 return (Statement) blockStatements.get(0); 1557 } 1558 return statement; 1559 } 1560 1561 private static boolean getReplaceIfElseWithConditionalProposals(IInvocationContext context, ASTNode node, Collection resultingCollections) { 1562 if (!(node instanceof IfStatement)) { 1563 return false; 1564 } 1565 IfStatement ifStatement= (IfStatement) node; 1566 Statement thenStatement= getSingleStatement(ifStatement.getThenStatement()); 1567 Statement elseStatement= getSingleStatement(ifStatement.getElseStatement()); 1568 if (thenStatement == null || elseStatement == null) { 1569 return false; 1570 } 1571 Expression assigned= null; 1572 Expression thenExpression= null; 1573 Expression elseExpression= null; 1574 1575 ITypeBinding exprBinding= null; 1576 if (thenStatement instanceof ReturnStatement && elseStatement instanceof ReturnStatement) { 1577 thenExpression= ((ReturnStatement) thenStatement).getExpression(); 1578 elseExpression= ((ReturnStatement) elseStatement).getExpression(); 1579 MethodDeclaration declaration= ASTResolving.findParentMethodDeclaration(node); 1580 if (declaration == null || declaration.isConstructor()) { 1581 return false; 1582 } 1583 exprBinding= declaration.getReturnType2().resolveBinding(); 1584 } else if (thenStatement instanceof ExpressionStatement && elseStatement instanceof ExpressionStatement) { 1585 Expression inner1= ((ExpressionStatement) thenStatement).getExpression(); 1586 Expression inner2= ((ExpressionStatement) elseStatement).getExpression(); 1587 if (inner1 instanceof Assignment && inner2 instanceof Assignment) { 1588 Assignment assign1= (Assignment) inner1; 1589 Assignment assign2= (Assignment) inner2; 1590 Expression left1= assign1.getLeftHandSide(); 1591 Expression left2= assign2.getLeftHandSide(); 1592 if (left1 instanceof Name && left2 instanceof Name && assign1.getOperator() == assign2.getOperator()) { 1593 IBinding bind1= ((Name) left1).resolveBinding(); 1594 IBinding bind2= ((Name) left2).resolveBinding(); 1595 if (bind1 == bind2 && bind1 instanceof IVariableBinding) { 1596 assigned= left1; 1597 exprBinding= ((IVariableBinding) bind1).getType(); 1598 thenExpression= assign1.getRightHandSide(); 1599 elseExpression= assign2.getRightHandSide(); 1600 } 1601 } 1602 } 1603 } 1604 if (thenExpression == null || elseExpression == null) { 1605 return false; 1606 } 1607 1608 if (resultingCollections == null) { 1610 return true; 1611 } 1612 AST ast= node.getAST(); 1614 ASTRewrite rewrite= ASTRewrite.create(ast); 1615 1616 String label= CorrectionMessages.AdvancedQuickAssistProcessor_replaceIfWithConditional; 1617 Image image= JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_CHANGE); 1618 ASTRewriteCorrectionProposal proposal= new ASTRewriteCorrectionProposal(label, context.getCompilationUnit(), rewrite, 1, image); 1619 1620 1621 ConditionalExpression conditionalExpression = ast.newConditionalExpression(); 1623 Expression conditionCopy= (Expression) rewrite.createCopyTarget(ifStatement.getExpression()); 1624 conditionalExpression.setExpression(conditionCopy); 1625 Expression thenCopy= (Expression) rewrite.createCopyTarget(thenExpression); 1626 Expression elseCopy= (Expression) rewrite.createCopyTarget(elseExpression); 1627 1628 1629 if (!JavaModelUtil.is50OrHigher(context.getCompilationUnit().getJavaProject())) { 1630 ITypeBinding thenBinding= thenExpression.resolveTypeBinding(); 1631 ITypeBinding elseBinding= elseExpression.resolveTypeBinding(); 1632 if (thenBinding != null && elseBinding != null && exprBinding != null && !elseBinding.isAssignmentCompatible(thenBinding)) { 1633 CastExpression castException= ast.newCastExpression(); 1634 proposal.createImportRewrite(context.getASTRoot()); 1635 castException.setType(proposal.getImportRewrite().addImport(exprBinding, ast)); 1636 castException.setExpression(elseCopy); 1637 elseCopy= castException; 1638 } 1639 } 1640 conditionalExpression.setThenExpression(thenCopy); 1641 conditionalExpression.setElseExpression(elseCopy); 1642 1643 if (assigned == null) { 1645 ReturnStatement returnStatement = ast.newReturnStatement(); 1646 returnStatement.setExpression(conditionalExpression); 1647 rewrite.replace(ifStatement, returnStatement, null); 1648 } else { 1649 Assignment assignment= ast.newAssignment(); 1650 assignment.setLeftHandSide((Expression) rewrite.createCopyTarget(assigned)); 1651 assignment.setRightHandSide(conditionalExpression); 1652 assignment.setOperator(((Assignment) assigned.getParent()).getOperator()); 1653 1654 ExpressionStatement expressionStatement = ast.newExpressionStatement(assignment); 1655 rewrite.replace(ifStatement, expressionStatement, null); 1656 } 1657 1658 resultingCollections.add(proposal); 1660 return true; 1661 } 1662 1663 private static ReturnStatement createReturnExpression(ASTRewrite rewrite, Expression expression) { 1664 AST ast= rewrite.getAST(); 1665 ReturnStatement thenReturn = ast.newReturnStatement(); 1666 thenReturn.setExpression((Expression) rewrite.createCopyTarget(expression)); 1667 return thenReturn; 1668 } 1669 1670 private static Statement createAssignmentStatement(ASTRewrite rewrite, Assignment.Operator assignmentOperator, Expression origAssignee, Expression origAssigned) { 1671 AST ast= rewrite.getAST(); 1672 Assignment elseAssignment= ast.newAssignment(); 1673 elseAssignment.setOperator(assignmentOperator); 1674 elseAssignment.setLeftHandSide((Expression) rewrite.createCopyTarget(origAssignee)); 1675 elseAssignment.setRightHandSide((Expression) rewrite.createCopyTarget(origAssigned)); 1676 ExpressionStatement statement = ast.newExpressionStatement(elseAssignment); 1677 return statement; 1678 } 1679 1680 private static boolean getReplaceConditionalWithIfElseProposals(IInvocationContext context, ASTNode covering, Collection resultingCollections) { 1681 while (!(covering instanceof ConditionalExpression) && covering instanceof Expression) { 1683 covering= covering.getParent(); 1684 } 1685 if (!(covering instanceof ConditionalExpression)) { 1686 return false; 1687 } 1688 1689 StructuralPropertyDescriptor locationInParent= covering.getLocationInParent(); 1690 if (locationInParent == Assignment.RIGHT_HAND_SIDE_PROPERTY) { 1691 if (covering.getParent().getLocationInParent() != ExpressionStatement.EXPRESSION_PROPERTY) { 1692 return false; 1693 } 1694 } else if (locationInParent == VariableDeclarationFragment.INITIALIZER_PROPERTY) { 1695 ASTNode statement= covering.getParent().getParent(); 1696 if (!(statement instanceof VariableDeclarationStatement) || statement.getLocationInParent() != Block.STATEMENTS_PROPERTY) { 1697 return false; 1698 } 1699 } else if (locationInParent != ReturnStatement.EXPRESSION_PROPERTY) { 1700 return false; 1701 } 1702 1703 ConditionalExpression conditional= (ConditionalExpression) covering; 1704 if (resultingCollections == null) { 1706 return true; 1707 } 1708 AST ast= covering.getAST(); 1710 ASTRewrite rewrite= ASTRewrite.create(ast); 1711 Expression expression= conditional.getExpression(); 1713 while (expression instanceof ParenthesizedExpression) { 1714 expression= ((ParenthesizedExpression) expression).getExpression(); 1715 } 1716 IfStatement ifStatement= ast.newIfStatement(); 1717 ifStatement.setExpression((Expression) rewrite.createCopyTarget(expression)); 1718 if (locationInParent == Assignment.RIGHT_HAND_SIDE_PROPERTY) { 1719 Assignment assignment= (Assignment) covering.getParent(); 1720 Expression assignee= assignment.getLeftHandSide(); 1721 Assignment.Operator op= assignment.getOperator(); 1722 1723 ifStatement.setThenStatement(createAssignmentStatement(rewrite, op, assignee, conditional.getThenExpression())); 1724 ifStatement.setElseStatement(createAssignmentStatement(rewrite, op, assignee, conditional.getElseExpression())); 1725 1726 rewrite.replace(covering.getParent().getParent(), ifStatement, null); 1728 1729 } else if (locationInParent == ReturnStatement.EXPRESSION_PROPERTY) { 1730 ifStatement.setThenStatement(createReturnExpression(rewrite, conditional.getThenExpression())); 1731 ifStatement.setElseStatement(createReturnExpression(rewrite, conditional.getElseExpression())); 1732 rewrite.replace(conditional.getParent(), ifStatement, null); 1735 } else if (locationInParent == VariableDeclarationFragment.INITIALIZER_PROPERTY) { 1736 VariableDeclarationFragment frag= (VariableDeclarationFragment) covering.getParent(); 1737 Assignment.Operator op= Assignment.Operator.ASSIGN; 1738 1739 Expression assignee= frag.getName(); 1740 ifStatement.setThenStatement(createAssignmentStatement(rewrite, op, assignee, conditional.getThenExpression())); 1741 ifStatement.setElseStatement(createAssignmentStatement(rewrite, op, assignee, conditional.getElseExpression())); 1742 1743 rewrite.set(frag, VariableDeclarationFragment.INITIALIZER_PROPERTY, null, null); 1745 ASTNode statement= frag.getParent(); 1746 rewrite.getListRewrite(statement.getParent(), Block.STATEMENTS_PROPERTY).insertAfter(ifStatement, statement, null); 1747 } 1748 1749 String label= CorrectionMessages.AdvancedQuickAssistProcessor_replaceConditionalWithIf; 1751 Image image= JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_CHANGE); 1752 ASTRewriteCorrectionProposal proposal= new ASTRewriteCorrectionProposal(label, context.getCompilationUnit(), rewrite, 1, image); 1753 resultingCollections.add(proposal); 1754 return true; 1755 } 1756 private static boolean getInverseLocalVariableProposals(IInvocationContext context, 1757 ASTNode covering, 1758 Collection resultingCollections) { 1759 final AST ast= covering.getAST(); 1760 if (!(covering instanceof SimpleName)) { 1762 return false; 1763 } 1764 SimpleName coveringName= (SimpleName) covering; 1765 if (!coveringName.isDeclaration()) { 1766 return false; 1767 } 1768 final IBinding variableBinding= coveringName.resolveBinding(); 1770 if (!(variableBinding instanceof IVariableBinding)) { 1771 return false; 1772 } 1773 IVariableBinding binding= (IVariableBinding) variableBinding; 1774 if (binding.isField()) { 1775 return false; 1776 } 1777 if (!isBoolean(coveringName)) { 1779 return false; 1780 } 1781 if (resultingCollections == null) { 1783 return true; 1784 } 1785 final MethodDeclaration method= ASTResolving.findParentMethodDeclaration(covering); 1787 SimpleName[] linkedNodes= LinkedNodeFinder.findByBinding(method, variableBinding); 1788 final ASTRewrite rewrite= ASTRewrite.create(ast); 1790 String label= CorrectionMessages.AdvancedQuickAssistProcessor_inverseBooleanVariable; 1792 Image image= JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_CHANGE); 1793 final String KEY_NAME= "name"; final LinkedCorrectionProposal proposal= new LinkedCorrectionProposal(label, 1795 context.getCompilationUnit(), 1796 rewrite, 1797 1, 1798 image); 1799 final String oldIdentifier= coveringName.getIdentifier(); 1801 final String notString = Messages.format(CorrectionMessages.AdvancedQuickAssistProcessor_negatedVariableName, ""); final String newIdentifier; 1803 if (oldIdentifier.startsWith(notString)) { 1804 int notLength= notString.length(); 1805 if (oldIdentifier.length() > notLength) { 1806 newIdentifier= Character.toLowerCase(oldIdentifier.charAt(notLength)) + oldIdentifier.substring(notLength + 1); 1807 } else { 1808 newIdentifier= oldIdentifier; 1809 } 1810 } else { 1811 newIdentifier= Messages.format(CorrectionMessages.AdvancedQuickAssistProcessor_negatedVariableName, Character.toUpperCase(oldIdentifier.charAt(0)) + oldIdentifier.substring(1)); 1812 } 1813 proposal.addLinkedPositionProposal(KEY_NAME, newIdentifier, null); 1815 proposal.addLinkedPositionProposal(KEY_NAME, oldIdentifier, null); 1816 final HashSet renamedNames= new HashSet (); 1818 for (int i= 0; i < linkedNodes.length; i++) { 1819 SimpleName name= linkedNodes[i]; 1820 if (renamedNames.contains(name)) { 1821 continue; 1822 } 1823 SimpleName newName= ast.newSimpleName(newIdentifier); 1825 proposal.addLinkedPosition(rewrite.track(newName), name == coveringName, KEY_NAME); 1826 StructuralPropertyDescriptor location= name.getLocationInParent(); 1828 if (location == SingleVariableDeclaration.NAME_PROPERTY) { 1829 rewrite.replace(name, newName, null); 1831 } else if (location == Assignment.LEFT_HAND_SIDE_PROPERTY) { 1832 Assignment assignment= (Assignment) name.getParent(); 1833 Expression expression= assignment.getRightHandSide(); 1834 int exStart= expression.getStartPosition(); 1835 int exEnd= exStart + expression.getLength(); 1836 HashSet overlapNames= new HashSet (); 1838 for (int j= 0; j < linkedNodes.length; j++) { 1839 SimpleName name2= linkedNodes[j]; 1840 if (name2 == null) { 1841 continue; 1842 } 1843 int name2Start= name2.getStartPosition(); 1844 if (exStart <= name2Start && name2Start < exEnd) { 1845 overlapNames.add(name2); 1846 } 1847 } 1848 SimpleNameRenameProvider provider= new SimpleNameRenameProvider() { 1850 public SimpleName getRenamed(SimpleName simpleName) { 1851 if (simpleName.resolveBinding() == variableBinding) { 1852 renamedNames.add(simpleName); 1853 return ast.newSimpleName(newIdentifier); 1854 } 1855 return null; 1856 } 1857 }; 1858 Expression inversedExpression= getInversedBooleanExpression(rewrite, expression, provider); 1859 for (Iterator iter= overlapNames.iterator(); iter.hasNext();) { 1861 Object o= iter.next(); 1862 if (!renamedNames.contains(o)) { 1863 return false; 1864 } 1865 } 1866 Assignment.Operator operator= assignment.getOperator(); 1868 if (operator == Assignment.Operator.BIT_AND_ASSIGN) { 1869 Assignment newAssignment= ast.newAssignment(); 1870 newAssignment.setLeftHandSide(newName); 1871 newAssignment.setRightHandSide(inversedExpression); 1872 newAssignment.setOperator(Assignment.Operator.BIT_OR_ASSIGN); 1873 rewrite.replace(assignment, newAssignment, null); 1874 } else if (operator == Assignment.Operator.BIT_OR_ASSIGN) { 1875 Assignment newAssignment= ast.newAssignment(); 1876 newAssignment.setLeftHandSide(newName); 1877 newAssignment.setRightHandSide(inversedExpression); 1878 newAssignment.setOperator(Assignment.Operator.BIT_AND_ASSIGN); 1879 rewrite.replace(assignment, newAssignment, null); 1880 } else { 1881 rewrite.replace(expression, inversedExpression, null); 1882 rewrite.replace(name, newName, null); 1884 } 1885 } else if (location == VariableDeclarationFragment.NAME_PROPERTY) { 1886 VariableDeclarationFragment vdf= (VariableDeclarationFragment) name.getParent(); 1888 Expression expression= vdf.getInitializer(); 1889 if (expression != null) { 1890 rewrite.replace(expression, getInversedBooleanExpression(rewrite, expression), null); 1891 } 1892 rewrite.replace(name, newName, null); 1894 } else if ((name.getParent() instanceof PrefixExpression) 1895 && (((PrefixExpression) name.getParent()).getOperator() == PrefixExpression.Operator.NOT)) { 1896 rewrite.replace(name.getParent(), newName, null); 1897 } else { 1898 PrefixExpression expression= ast.newPrefixExpression(); 1899 expression.setOperator(PrefixExpression.Operator.NOT); 1900 expression.setOperand(newName); 1901 rewrite.replace(name, expression, null); 1902 } 1903 } 1904 resultingCollections.add(proposal); 1906 return true; 1907 } 1908 private static boolean getPushNegationDownProposals(IInvocationContext context, 1909 ASTNode covering, 1910 Collection resultingCollections) { 1911 PrefixExpression negationExpression= null; 1912 ParenthesizedExpression parenthesizedExpression= null; 1913 if (covering instanceof PrefixExpression) { 1915 PrefixExpression prefixExpression= (PrefixExpression) covering; 1916 if ((prefixExpression.getOperator() == PrefixExpression.Operator.NOT) 1917 && (prefixExpression.getOperand() instanceof ParenthesizedExpression)) { 1918 negationExpression= prefixExpression; 1919 parenthesizedExpression= (ParenthesizedExpression) prefixExpression.getOperand(); 1920 } 1921 } 1922 if ((covering instanceof ParenthesizedExpression) 1924 && (covering.getParent() instanceof PrefixExpression) 1925 && (((PrefixExpression) covering.getParent()).getOperator() == PrefixExpression.Operator.NOT)) { 1926 negationExpression= (PrefixExpression) covering.getParent(); 1927 parenthesizedExpression= (ParenthesizedExpression) covering; 1928 } 1929 if (negationExpression == null) { 1931 return false; 1932 } 1933 if (resultingCollections == null) { 1935 return true; 1936 } 1937 final AST ast= covering.getAST(); 1939 final ASTRewrite rewrite= ASTRewrite.create(ast); 1940 Expression inversedExpression= getInversedBooleanExpression(rewrite, parenthesizedExpression.getExpression()); 1942 boolean keepParentheses= false; 1944 if (negationExpression.getParent() instanceof Expression) { 1945 int parentPrecedence= getExpressionPrecedence((Expression) negationExpression.getParent()); 1946 int inversedExpressionPrecedence= getExpressionPrecedence(inversedExpression); 1947 keepParentheses= parentPrecedence < inversedExpressionPrecedence; 1948 } 1949 if (keepParentheses) { 1951 ParenthesizedExpression pe= ast.newParenthesizedExpression(); 1952 pe.setExpression(inversedExpression); 1953 rewrite.replace(negationExpression, pe, null); 1954 } else { 1955 rewrite.replace(negationExpression, inversedExpression, null); 1956 } 1957 String label= CorrectionMessages.AdvancedQuickAssistProcessor_pushNegationDown; 1959 Image image= JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_CHANGE); 1960 ASTRewriteCorrectionProposal proposal= new ASTRewriteCorrectionProposal(label, context.getCompilationUnit(), rewrite, 1, image); 1961 resultingCollections.add(proposal); 1962 return true; 1963 } 1964 1965 private static Expression getBooleanExpression(ASTNode node) { 1966 if (!(node instanceof Expression)) { 1967 return null; 1968 } 1969 1970 StructuralPropertyDescriptor locationInParent= node.getLocationInParent(); 1972 if (locationInParent == QualifiedName.NAME_PROPERTY) { 1973 node= node.getParent(); 1974 locationInParent= node.getLocationInParent(); 1975 } 1976 while (locationInParent == ParenthesizedExpression.EXPRESSION_PROPERTY) { 1977 node= node.getParent(); 1978 locationInParent= node.getLocationInParent(); 1979 } 1980 Expression expression= (Expression) node; 1981 if (!isBoolean(expression)) { 1982 return null; 1983 } 1984 if (expression.getParent() instanceof InfixExpression) { 1985 return expression; 1986 } 1987 if (locationInParent == Assignment.RIGHT_HAND_SIDE_PROPERTY 1988 || locationInParent == IfStatement.EXPRESSION_PROPERTY 1989 || locationInParent == WhileStatement.EXPRESSION_PROPERTY 1990 || locationInParent == DoStatement.EXPRESSION_PROPERTY 1991 || locationInParent == ReturnStatement.EXPRESSION_PROPERTY 1992 || locationInParent == ForStatement.EXPRESSION_PROPERTY 1993 || locationInParent == MethodInvocation.ARGUMENTS_PROPERTY 1994 || locationInParent == ConstructorInvocation.ARGUMENTS_PROPERTY 1995 || locationInParent == SuperMethodInvocation.ARGUMENTS_PROPERTY 1996 || locationInParent == EnumConstantDeclaration.ARGUMENTS_PROPERTY 1997 || locationInParent == SuperConstructorInvocation.ARGUMENTS_PROPERTY 1998 || locationInParent == ClassInstanceCreation.ARGUMENTS_PROPERTY 1999 || locationInParent == ConditionalExpression.EXPRESSION_PROPERTY 2000 || locationInParent == PrefixExpression.OPERAND_PROPERTY) { 2001 return expression; 2002 } 2003 return null; 2004 } 2005 2006 2007 2008 private static boolean getPullNegationUpProposals(IInvocationContext context, ASTNode covering, ArrayList coveredNodes, Collection resultingCollections) { 2009 if (coveredNodes.size() != 1) { 2010 return false; 2011 } 2012 ASTNode fullyCoveredNode= (ASTNode) coveredNodes.get(0); 2014 2015 Expression expression= getBooleanExpression(fullyCoveredNode); 2016 if (expression == null) { 2017 return false; 2018 } 2019 if (resultingCollections == null) { 2021 return true; 2022 } 2023 AST ast= expression.getAST(); 2025 final ASTRewrite rewrite= ASTRewrite.create(ast); 2026 Expression inversedExpression= getInversedBooleanExpression(rewrite, expression); 2028 ParenthesizedExpression parenthesizedExpression = ast.newParenthesizedExpression(); 2030 parenthesizedExpression.setExpression(inversedExpression); 2031 PrefixExpression prefixExpression = ast.newPrefixExpression(); 2033 prefixExpression.setOperator(PrefixExpression.Operator.NOT); 2034 prefixExpression.setOperand(parenthesizedExpression); 2035 rewrite.replace(expression, prefixExpression, null); 2037 String label= CorrectionMessages.AdvancedQuickAssistProcessor_pullNegationUp; 2039 Image image= JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_CHANGE); 2040 ASTRewriteCorrectionProposal proposal= new ASTRewriteCorrectionProposal(label, context.getCompilationUnit(), rewrite, 1, image); 2041 resultingCollections.add(proposal); 2042 return true; 2043 } 2044 private static boolean getJoinIfListInIfElseIfProposals(IInvocationContext context, 2045 ASTNode covering, 2046 ArrayList coveredNodes, 2047 Collection resultingCollections) { 2048 if (coveredNodes.isEmpty()) { 2049 return false; 2050 } 2051 if (coveredNodes.size() < 2) { 2053 return false; 2054 } 2055 for (Iterator iter= coveredNodes.iterator(); iter.hasNext();) { 2057 ASTNode node= (ASTNode) iter.next(); 2058 if (!(node instanceof IfStatement)) { 2059 return false; 2060 } 2061 IfStatement ifStatement= (IfStatement) node; 2062 if (ifStatement.getElseStatement() != null) { 2063 return false; 2064 } 2065 } 2066 if (resultingCollections == null) { 2068 return true; 2069 } 2070 final AST ast= covering.getAST(); 2072 final ASTRewrite rewrite= ASTRewrite.create(ast); 2073 IfStatement firstIfStatement= (IfStatement) coveredNodes.get(0); 2075 IfStatement firstNewIfStatement= null; 2076 IfStatement prevIfStatement= null; 2078 for (Iterator iter= coveredNodes.iterator(); iter.hasNext();) { 2079 IfStatement ifStatement= (IfStatement) iter.next(); 2080 IfStatement newIfStatement= ast.newIfStatement(); 2082 newIfStatement.setExpression((Expression) rewrite.createMoveTarget(ifStatement.getExpression())); 2083 Statement thenStatement= (Statement) rewrite.createMoveTarget(ifStatement.getThenStatement()); 2085 if (ifStatement.getThenStatement() instanceof IfStatement) { 2086 IfStatement ifBodyStatement= (IfStatement) ifStatement.getThenStatement(); 2087 if (ifBodyStatement.getElseStatement() == null) { 2088 Block thenBlock= ast.newBlock(); 2089 thenBlock.statements().add(thenStatement); 2090 thenStatement= thenBlock; 2091 } 2092 } 2093 newIfStatement.setThenStatement(thenStatement); 2094 if (prevIfStatement != null) { 2096 prevIfStatement.setElseStatement(newIfStatement); 2097 rewrite.remove(ifStatement, null); 2098 } else { 2099 firstNewIfStatement= newIfStatement; 2100 } 2101 prevIfStatement= newIfStatement; 2102 } 2103 rewrite.replace(firstIfStatement, firstNewIfStatement, null); 2104 String label= CorrectionMessages.AdvancedQuickAssistProcessor_joinIfSequence; 2106 Image image= JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_CHANGE); 2107 ASTRewriteCorrectionProposal proposal= new ASTRewriteCorrectionProposal(label, context.getCompilationUnit(), rewrite, 1, image); 2108 resultingCollections.add(proposal); 2109 return true; 2110 } 2111 private static boolean getConvertSwitchToIfProposals(IInvocationContext context, 2112 ASTNode covering, 2113 Collection resultingCollections) { 2114 if (!(covering instanceof SwitchStatement)) { 2115 return false; 2116 } 2117 if (resultingCollections == null) { 2119 return true; 2120 } 2121 final AST ast= covering.getAST(); 2123 final ASTRewrite rewrite= ASTRewrite.create(ast); 2124 final ImportRewrite importRewrite= CodeStyleConfiguration.createImportRewrite(context.getASTRoot(), true); 2125 SwitchStatement switchStatement= (SwitchStatement) covering; 2127 IfStatement firstIfStatement= null; 2128 IfStatement currentIfStatement= null; 2129 Block currentBlock= null; 2130 boolean hasStopAsLastExecutableStatement = false; 2131 Block defaultBlock= null; 2132 InfixExpression currentCondition= null; 2133 boolean defaultFound= false; 2134 int caseCount = 0; 2135 2136 ArrayList allBlocks= new ArrayList (); 2137 for (Iterator iter= switchStatement.statements().iterator(); iter.hasNext();) { 2139 Statement statement= (Statement) iter.next(); 2140 if (statement instanceof SwitchCase) { 2141 SwitchCase switchCase= (SwitchCase) statement; 2142 caseCount++; 2143 if (currentBlock != null) { 2145 if (!hasStopAsLastExecutableStatement) { 2146 return false; 2147 } 2148 currentBlock= null; 2149 } 2150 if (switchCase.isDefault()) { 2152 defaultFound= true; 2153 if (currentCondition != null) { 2154 return false; 2156 } 2157 continue; 2158 } 2159 if (defaultFound) { 2160 return false; 2161 } 2162 InfixExpression switchCaseCondition= createSwitchCaseCondition(ast, rewrite, importRewrite, switchStatement, switchCase); 2164 if (currentCondition == null) { 2165 currentCondition= switchCaseCondition; 2166 } else { 2167 InfixExpression condition= ast.newInfixExpression(); 2168 condition.setOperator(InfixExpression.Operator.CONDITIONAL_OR); 2169 condition.setLeftOperand(currentCondition); 2170 condition.setRightOperand(switchCaseCondition); 2171 currentCondition= condition; 2172 } 2173 } else if (statement instanceof BreakStatement) { 2174 currentBlock= null; 2175 } else { 2176 if (currentBlock == null) { 2178 defaultFound= false; 2179 if (currentCondition != null) { 2180 IfStatement ifStatement; 2181 if (firstIfStatement == null) { 2182 firstIfStatement= ast.newIfStatement(); 2183 ifStatement= firstIfStatement; 2184 } else { 2185 ifStatement= ast.newIfStatement(); 2186 currentIfStatement.setElseStatement(ifStatement); 2187 } 2188 currentIfStatement= ifStatement; 2189 ifStatement.setExpression(currentCondition); 2190 currentCondition= null; 2191 currentBlock= ast.newBlock(); 2192 ifStatement.setThenStatement(currentBlock); 2193 allBlocks.add(currentBlock); 2194 } else { 2195 defaultBlock= ast.newBlock(); 2197 currentBlock= defaultBlock; 2198 allBlocks.add(currentBlock); 2199 } 2201 } 2202 { 2204 hasStopAsLastExecutableStatement = hasStopAsLastExecutableStatement(statement); 2205 Statement copyStatement= copyStatementExceptBreak(ast, rewrite, statement); 2206 2207 2208 currentBlock.statements().add(copyStatement); 2209 } 2210 } 2211 } 2212 if (defaultBlock != null) { 2214 currentIfStatement.setElseStatement(defaultBlock); 2215 } 2216 for (int i= 0; i < allBlocks.size(); i++) { 2218 Block block= (Block) allBlocks.get(i); 2219 List statements= block.statements(); 2220 if (statements.size() == 1 && statements.get(0) instanceof Block) { 2221 Block innerBlock= (Block) statements.remove(0); 2222 block.getParent().setStructuralProperty(block.getLocationInParent(), innerBlock); 2223 } 2224 } 2225 rewrite.replace(switchStatement, firstIfStatement, null); 2227 String label= CorrectionMessages.AdvancedQuickAssistProcessor_convertSwitchToIf; 2229 2230 Image image= JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_CHANGE); 2232 ASTRewriteCorrectionProposal proposal= new ASTRewriteCorrectionProposal(label, 2233 context.getCompilationUnit(), 2234 rewrite, 2235 1, 2236 image); 2237 proposal.setImportRewrite(importRewrite); 2238 resultingCollections.add(proposal); 2239 return true; 2240 } 2241 private static InfixExpression createSwitchCaseCondition(AST ast, ASTRewrite rewrite, ImportRewrite importRewrite, 2242 SwitchStatement switchStatement, SwitchCase switchCase) { 2243 InfixExpression condition= ast.newInfixExpression(); 2244 condition.setOperator(InfixExpression.Operator.EQUALS); 2245 Expression leftExpression= (Expression) rewrite.createCopyTarget(switchStatement.getExpression()); 2247 condition.setLeftOperand(leftExpression); 2248 Expression rightExpression= null; 2250 Expression expression= switchCase.getExpression(); 2251 if (expression instanceof SimpleName && ((SimpleName) expression).resolveBinding() instanceof IVariableBinding) { 2252 IVariableBinding binding= (IVariableBinding) ((SimpleName) expression).resolveBinding(); 2253 if (binding.isEnumConstant()) { 2254 String qualifiedName= importRewrite.addImport(binding.getDeclaringClass()) + '.' + binding.getName(); 2255 rightExpression= ast.newName(qualifiedName); 2256 } 2257 } 2258 if (rightExpression == null) { 2259 rightExpression= (Expression) rewrite.createCopyTarget(expression); 2260 } 2261 condition.setRightOperand(rightExpression); 2262 return condition; 2264 } 2265 2266 2267 private static boolean hasStopAsLastExecutableStatement(Statement lastStatement) { 2268 if ((lastStatement instanceof ReturnStatement) || (lastStatement instanceof BreakStatement)) { 2269 return true; 2270 } 2271 if (lastStatement instanceof Block) { 2272 Block block= (Block)lastStatement; 2273 lastStatement = (Statement) block.statements().get(block.statements().size() - 1); 2274 return hasStopAsLastExecutableStatement(lastStatement); 2275 } 2276 return false; 2277 } 2278 private static Statement copyStatementExceptBreak(AST ast, ASTRewrite rewrite, Statement source) { 2279 if (source instanceof Block) { 2280 Block block= (Block) source; 2281 Block newBlock= ast.newBlock(); 2282 for (Iterator iter= block.statements().iterator(); iter.hasNext();) { 2283 Statement statement= (Statement) iter.next(); 2284 if (statement instanceof BreakStatement) { 2285 continue; 2286 } 2287 newBlock.statements().add(copyStatementExceptBreak(ast, rewrite, statement)); 2288 } 2289 return newBlock; 2290 } 2291 return (Statement) rewrite.createMoveTarget(source); 2292 } 2293} 2294 | Popular Tags |