diff options
Diffstat (limited to 'plugins/IntentionPowerPak/src/com/siyeh/ipp')
22 files changed, 552 insertions, 645 deletions
diff --git a/plugins/IntentionPowerPak/src/com/siyeh/ipp/exceptions/ConvertCatchToThrowsPredicate.java b/plugins/IntentionPowerPak/src/com/siyeh/ipp/exceptions/ConvertCatchToThrowsPredicate.java index 9d4dfac96170..dd7e88a49121 100644 --- a/plugins/IntentionPowerPak/src/com/siyeh/ipp/exceptions/ConvertCatchToThrowsPredicate.java +++ b/plugins/IntentionPowerPak/src/com/siyeh/ipp/exceptions/ConvertCatchToThrowsPredicate.java @@ -1,5 +1,5 @@ /* - * Copyright 2007 Bas Leijdekkers + * Copyright 2007-2013 Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,27 +16,20 @@ package com.siyeh.ipp.exceptions; import com.intellij.psi.*; -import com.intellij.psi.tree.IElementType; import com.intellij.psi.util.PsiTreeUtil; import com.siyeh.ipp.base.PsiElementPredicate; class ConvertCatchToThrowsPredicate implements PsiElementPredicate { public boolean satisfiedBy(PsiElement element) { - if (!(element instanceof PsiKeyword)) { - return false; - } - final PsiJavaToken javaToken = (PsiJavaToken)element; - final IElementType tokenType = javaToken.getTokenType(); - if (!tokenType.equals(JavaTokenType.CATCH_KEYWORD)) { + final PsiElement parent = element.getParent(); + if (!(parent instanceof PsiCatchSection)) { return false; } - final PsiElement parent = javaToken.getParent(); - if (!(parent instanceof PsiCatchSection)) { + if (element instanceof PsiCodeBlock) { return false; } - final PsiMethod method = - PsiTreeUtil.getParentOfType(parent, PsiMethod.class); + final PsiMethod method = PsiTreeUtil.getParentOfType(parent, PsiMethod.class, true, PsiClass.class); return method != null; } } diff --git a/plugins/IntentionPowerPak/src/com/siyeh/ipp/exceptions/DetailExceptionsIntention.java b/plugins/IntentionPowerPak/src/com/siyeh/ipp/exceptions/DetailExceptionsIntention.java index e7645c9685a5..092ff01be0a5 100644 --- a/plugins/IntentionPowerPak/src/com/siyeh/ipp/exceptions/DetailExceptionsIntention.java +++ b/plugins/IntentionPowerPak/src/com/siyeh/ipp/exceptions/DetailExceptionsIntention.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2012 Dave Griffith, Bas Leijdekkers + * Copyright 2003-2013 Dave Griffith, Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -35,14 +35,15 @@ public class DetailExceptionsIntention extends Intention { @Override public void processIntention(@NotNull PsiElement element) throws IncorrectOperationException { final PsiJavaToken token = (PsiJavaToken)element; - final PsiTryStatement tryStatement = (PsiTryStatement)token.getParent(); - if (tryStatement == null) { + PsiElement parent = token.getParent(); + if (parent instanceof PsiCatchSection) { + parent = parent.getParent(); + } + if (!(parent instanceof PsiTryStatement)) { return; } - final String text = tryStatement.getText(); - final int length = text.length(); - @NonNls final StringBuilder newTryStatement = new StringBuilder(length); - newTryStatement.append("try"); + final PsiTryStatement tryStatement = (PsiTryStatement)parent; + @NonNls final StringBuilder newTryStatement = new StringBuilder("try"); final Set<PsiType> exceptionsThrown = new HashSet<PsiType>(); final PsiResourceList resourceList = tryStatement.getResourceList(); if (resourceList != null) { @@ -74,24 +75,15 @@ public class DetailExceptionsIntention extends Intention { exceptionsToExpand.removeAll(exceptionsAlreadyEmitted); Collections.sort(exceptionsToExpand, comparator); for (PsiType thrownType : exceptionsToExpand) { - newTryStatement.append("catch("); - final String exceptionType = thrownType.getCanonicalText(); - newTryStatement.append(exceptionType); - newTryStatement.append(' '); - final String parameterName = parameter.getName(); - newTryStatement.append(parameterName); - newTryStatement.append(')'); - final String blockText = block.getText(); - newTryStatement.append(blockText); + newTryStatement.append("catch(").append(thrownType.getCanonicalText()).append(' ').append(parameter.getName()).append(')'); + newTryStatement.append(block.getText()); exceptionsAlreadyEmitted.add(thrownType); } } } final PsiCodeBlock finallyBlock = tryStatement.getFinallyBlock(); if (finallyBlock != null) { - newTryStatement.append("finally"); - final String finallyBlockText = finallyBlock.getText(); - newTryStatement.append(finallyBlockText); + newTryStatement.append("finally").append(finallyBlock.getText()); } final String newStatement = newTryStatement.toString(); replaceStatementAndShorten(newStatement, tryStatement); diff --git a/plugins/IntentionPowerPak/src/com/siyeh/ipp/exceptions/DetailExceptionsPredicate.java b/plugins/IntentionPowerPak/src/com/siyeh/ipp/exceptions/DetailExceptionsPredicate.java index 6281ba230e73..9979821b5290 100644 --- a/plugins/IntentionPowerPak/src/com/siyeh/ipp/exceptions/DetailExceptionsPredicate.java +++ b/plugins/IntentionPowerPak/src/com/siyeh/ipp/exceptions/DetailExceptionsPredicate.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2012 Dave Griffith, Bas Leijdekkers + * Copyright 2003-2013 Dave Griffith, Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -31,10 +31,13 @@ class DetailExceptionsPredicate implements PsiElementPredicate { return false; } final IElementType tokenType = ((PsiJavaToken)element).getTokenType(); - if (!JavaTokenType.TRY_KEYWORD.equals(tokenType)) { + if (!JavaTokenType.TRY_KEYWORD.equals(tokenType) && !JavaTokenType.CATCH_KEYWORD.equals(tokenType)) { return false; } - final PsiElement parent = element.getParent(); + PsiElement parent = element.getParent(); + if (parent instanceof PsiCatchSection) { + parent = parent.getParent(); + } if (!(parent instanceof PsiTryStatement)) { return false; } diff --git a/plugins/IntentionPowerPak/src/com/siyeh/ipp/exceptions/ExceptionUtils.java b/plugins/IntentionPowerPak/src/com/siyeh/ipp/exceptions/ExceptionUtils.java index 2cf500c07020..fb8431b4fd05 100644 --- a/plugins/IntentionPowerPak/src/com/siyeh/ipp/exceptions/ExceptionUtils.java +++ b/plugins/IntentionPowerPak/src/com/siyeh/ipp/exceptions/ExceptionUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2012 Dave Griffith, Bas Leijdekkers + * Copyright 2003-2013 Dave Griffith, Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -339,9 +339,9 @@ class ExceptionUtils { final PsiPostfixExpression postfixExpression = (PsiPostfixExpression)expression; calculateExceptionsThrownForPostfixExpression(postfixExpression, exceptionTypes); } - else if (expression instanceof PsiBinaryExpression) { - final PsiBinaryExpression binaryExpression = (PsiBinaryExpression)expression; - calculateExceptionsThrownForBinaryExpression(binaryExpression, exceptionTypes); + else if (expression instanceof PsiPolyadicExpression) { + final PsiPolyadicExpression polyadicExpression = (PsiPolyadicExpression)expression; + calculateExceptionsThrownForPolyadicExpression(polyadicExpression, exceptionTypes); } else if (expression instanceof PsiAssignmentExpression) { final PsiAssignmentExpression assignmentExpression = (PsiAssignmentExpression)expression; @@ -351,6 +351,11 @@ class ExceptionUtils { final PsiConditionalExpression conditionalExpression = (PsiConditionalExpression)expression; calculateExceptionsThrownForConditionalExpression(conditionalExpression, exceptionTypes); } + else if (expression instanceof PsiParenthesizedExpression) { + final PsiParenthesizedExpression parenthesizedExpression = (PsiParenthesizedExpression)expression; + final PsiExpression innerExpression = parenthesizedExpression.getExpression(); + calculateExceptionsThrownForExpression(innerExpression, exceptionTypes); + } } private static void calculateExceptionsThrownForTypeCast(PsiTypeCastExpression typeCastExpression, Set<PsiType> exceptionTypes) { @@ -414,11 +419,11 @@ class ExceptionUtils { calculateExceptionsThrownForExpression(thenExpression, exceptionTypes); } - private static void calculateExceptionsThrownForBinaryExpression(PsiBinaryExpression binaryExpression, Set<PsiType> exceptionTypes) { - final PsiExpression lOperand = binaryExpression.getLOperand(); - calculateExceptionsThrownForExpression(lOperand, exceptionTypes); - final PsiExpression rhs = binaryExpression.getROperand(); - calculateExceptionsThrownForExpression(rhs, exceptionTypes); + private static void calculateExceptionsThrownForPolyadicExpression(PsiPolyadicExpression polyadicExpression, Set<PsiType> exceptionTypes) { + final PsiExpression[] operands = polyadicExpression.getOperands(); + for (PsiExpression operand : operands) { + calculateExceptionsThrownForExpression(operand, exceptionTypes); + } } private static void calculateExceptionsThrownForAssignmentExpression(PsiAssignmentExpression assignmentExpression, diff --git a/plugins/IntentionPowerPak/src/com/siyeh/ipp/exceptions/MulticatchPredicate.java b/plugins/IntentionPowerPak/src/com/siyeh/ipp/exceptions/MulticatchPredicate.java index 878df78fed76..5866835ccd43 100644 --- a/plugins/IntentionPowerPak/src/com/siyeh/ipp/exceptions/MulticatchPredicate.java +++ b/plugins/IntentionPowerPak/src/com/siyeh/ipp/exceptions/MulticatchPredicate.java @@ -1,5 +1,5 @@ /* - * Copyright 2011 Bas Leijdekkers + * Copyright 2011-2013 Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,21 +16,15 @@ package com.siyeh.ipp.exceptions; import com.intellij.psi.*; -import com.intellij.psi.tree.IElementType; import com.siyeh.ipp.base.PsiElementPredicate; class MulticatchPredicate implements PsiElementPredicate { public boolean satisfiedBy(PsiElement element) { - if (!(element instanceof PsiKeyword)) { + if (element instanceof PsiCodeBlock) { return false; } - final PsiJavaToken javaToken = (PsiJavaToken)element; - final IElementType tokenType = javaToken.getTokenType(); - if (!tokenType.equals(JavaTokenType.CATCH_KEYWORD)) { - return false; - } - final PsiElement parent = javaToken.getParent(); + final PsiElement parent = element.getParent(); if (!(parent instanceof PsiCatchSection)) { return false; } diff --git a/plugins/IntentionPowerPak/src/com/siyeh/ipp/exceptions/SplitMulticatchIntention.java b/plugins/IntentionPowerPak/src/com/siyeh/ipp/exceptions/SplitMultiCatchIntention.java index 1a0eab9992db..f0288078a691 100644 --- a/plugins/IntentionPowerPak/src/com/siyeh/ipp/exceptions/SplitMulticatchIntention.java +++ b/plugins/IntentionPowerPak/src/com/siyeh/ipp/exceptions/SplitMultiCatchIntention.java @@ -16,14 +16,15 @@ package com.siyeh.ipp.exceptions; import com.intellij.psi.*; +import com.intellij.psi.impl.PsiImplUtil; import com.intellij.util.IncorrectOperationException; import com.siyeh.ipp.base.Intention; import com.siyeh.ipp.base.PsiElementPredicate; import org.jetbrains.annotations.NotNull; -import java.util.List; +import static com.intellij.psi.PsiAnnotation.TargetType; -public class SplitMulticatchIntention extends Intention { +public class SplitMultiCatchIntention extends Intention { @NotNull @Override @@ -32,8 +33,7 @@ public class SplitMulticatchIntention extends Intention { } @Override - protected void processIntention(@NotNull PsiElement element) - throws IncorrectOperationException { + protected void processIntention(@NotNull PsiElement element) throws IncorrectOperationException { final PsiElement parent = element.getParent(); if (!(parent instanceof PsiCatchSection)) { return; @@ -51,22 +51,28 @@ public class SplitMulticatchIntention extends Intention { if (!(type instanceof PsiDisjunctionType)) { return; } - final PsiDisjunctionType disjunctionType = (PsiDisjunctionType)type; - final List<PsiType> disjunctions = disjunctionType.getDisjunctions(); - final PsiElementFactory factory = - JavaPsiFacade.getElementFactory(element.getProject()); - for (PsiType disjunction : disjunctions) { + + final PsiModifierList modifierList = parameter.getModifierList(); + if (modifierList != null) { + for (PsiAnnotation annotation : modifierList.getAnnotations()) { + if (PsiImplUtil.findApplicableTarget(annotation, TargetType.TYPE_USE) == TargetType.TYPE_USE) { + annotation.delete(); + } + } + } + + final PsiElementFactory factory = JavaPsiFacade.getElementFactory(element.getProject()); + for (PsiType disjunction : ((PsiDisjunctionType)type).getDisjunctions()) { final PsiCatchSection copy = (PsiCatchSection)catchSection.copy(); final PsiParameter copyParameter = copy.getParameter(); - if (copyParameter == null) { - continue; - } + assert copyParameter != null : copy.getText(); final PsiTypeElement typeElement = copyParameter.getTypeElement(); - final PsiTypeElement newTypeElement = - factory.createTypeElement(disjunction); + assert typeElement != null : copyParameter.getText(); + final PsiTypeElement newTypeElement = factory.createTypeElement(disjunction); typeElement.replace(newTypeElement); grandParent.addBefore(copy, catchSection); } + catchSection.delete(); } } diff --git a/plugins/IntentionPowerPak/src/com/siyeh/ipp/exceptions/SplitTryWithMultipleResourcesIntention.java b/plugins/IntentionPowerPak/src/com/siyeh/ipp/exceptions/SplitTryWithMultipleResourcesIntention.java index c836078fdd87..2683504a0646 100644 --- a/plugins/IntentionPowerPak/src/com/siyeh/ipp/exceptions/SplitTryWithMultipleResourcesIntention.java +++ b/plugins/IntentionPowerPak/src/com/siyeh/ipp/exceptions/SplitTryWithMultipleResourcesIntention.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2012 JetBrains s.r.o. + * Copyright 2000-2013 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,6 +19,7 @@ import com.intellij.psi.*; import com.intellij.util.IncorrectOperationException; import com.siyeh.ipp.base.Intention; import com.siyeh.ipp.base.PsiElementPredicate; +import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import java.util.List; @@ -41,7 +42,7 @@ public class SplitTryWithMultipleResourcesIntention extends Intention { if (resourceList == null) { return; } - final StringBuilder newTryStatementText = new StringBuilder(); + @NonNls final StringBuilder newTryStatementText = new StringBuilder(); final List<PsiResourceVariable> variables = resourceList.getResourceVariables(); boolean braces = false; for (PsiResourceVariable variable : variables) { @@ -60,6 +61,10 @@ public class SplitTryWithMultipleResourcesIntention extends Intention { for (int i = 1; i < variables.size(); i++) { newTryStatementText.append("\n}"); } + final PsiCatchSection[] catchSections = tryStatement.getCatchSections(); + for (PsiCatchSection catchSection : catchSections) { + newTryStatementText.append(catchSection.getText()); + } replaceStatement(newTryStatementText.toString(), tryStatement); } } diff --git a/plugins/IntentionPowerPak/src/com/siyeh/ipp/exceptions/TryWithMultipleResourcesPredicate.java b/plugins/IntentionPowerPak/src/com/siyeh/ipp/exceptions/TryWithMultipleResourcesPredicate.java index 1dfdf84476da..647b56b28a8f 100644 --- a/plugins/IntentionPowerPak/src/com/siyeh/ipp/exceptions/TryWithMultipleResourcesPredicate.java +++ b/plugins/IntentionPowerPak/src/com/siyeh/ipp/exceptions/TryWithMultipleResourcesPredicate.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2012 JetBrains s.r.o. + * Copyright 2000-2013 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -28,12 +28,15 @@ class TryWithMultipleResourcesPredicate implements PsiElementPredicate { @Override public boolean satisfiedBy(PsiElement element) { - if (!(element instanceof PsiJavaToken)) { - return false; + + if (element instanceof PsiJavaToken) { + final PsiJavaToken javaToken = (PsiJavaToken)element; + final IElementType tokenType = javaToken.getTokenType(); + if (!JavaTokenType.TRY_KEYWORD.equals(tokenType)) { + return false; + } } - final PsiJavaToken javaToken = (PsiJavaToken)element; - final IElementType tokenType = javaToken.getTokenType(); - if (!JavaTokenType.TRY_KEYWORD.equals(tokenType)) { + else if (!(element instanceof PsiResourceList)) { return false; } final PsiElement parent = element.getParent(); @@ -41,10 +44,6 @@ class TryWithMultipleResourcesPredicate implements PsiElementPredicate { return false; } final PsiTryStatement tryStatement = (PsiTryStatement)parent; - final PsiCodeBlock[] catchBlocks = tryStatement.getCatchBlocks(); - if (catchBlocks.length > 0) { - return false; - } final PsiCodeBlock finallyBlock = tryStatement.getFinallyBlock(); if (finallyBlock != null) { return false; @@ -57,7 +56,6 @@ class TryWithMultipleResourcesPredicate implements PsiElementPredicate { if (tryBlock == null) { return false; } - final List<PsiResourceVariable> variables = resourceList.getResourceVariables(); - return variables.size() > 1; + return resourceList.getResourceVariables().size() > 1; } } diff --git a/plugins/IntentionPowerPak/src/com/siyeh/ipp/expression/ExpressionPredicate.java b/plugins/IntentionPowerPak/src/com/siyeh/ipp/expression/ExpressionPredicate.java index b543fabb9e37..7055f691077e 100644 --- a/plugins/IntentionPowerPak/src/com/siyeh/ipp/expression/ExpressionPredicate.java +++ b/plugins/IntentionPowerPak/src/com/siyeh/ipp/expression/ExpressionPredicate.java @@ -1,5 +1,5 @@ /* - * Copyright 2007 Dave Griffith, Bas Leijdekkers + * Copyright 2007-2013 Dave Griffith, Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,24 +15,36 @@ */ package com.siyeh.ipp.expression; -import com.intellij.psi.PsiBinaryExpression; -import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiExpression; +import com.intellij.psi.*; import com.siyeh.ipp.base.PsiElementPredicate; import com.siyeh.ipp.psiutils.ComparisonUtils; -import com.siyeh.ipp.psiutils.ErrorUtil; class ExpressionPredicate implements PsiElementPredicate { public boolean satisfiedBy(PsiElement element) { - if (!(element instanceof PsiBinaryExpression)) { + if (!(element instanceof PsiJavaToken)) { return false; } - final PsiBinaryExpression expression = (PsiBinaryExpression)element; - final PsiExpression rhs = expression.getROperand(); - if (rhs == null) { + final PsiElement parent = element.getParent(); + if (!(parent instanceof PsiPolyadicExpression)) { return false; } - return !ComparisonUtils.isComparison((PsiExpression)element); + final PsiPolyadicExpression expression = (PsiPolyadicExpression)parent; + final PsiExpression[] operands = expression.getOperands(); + if (operands.length < 2) { + return false; + } + PsiExpression prevOperand = null; + for (PsiExpression operand : operands) { + final PsiJavaToken token = expression.getTokenBeforeOperand(operand); + if (element == token) { + if (prevOperand == null || operand.getText().equals(prevOperand.getText())) { + return false; + } + break; + } + prevOperand = operand; + } + return !ComparisonUtils.isComparison(expression); } }
\ No newline at end of file diff --git a/plugins/IntentionPowerPak/src/com/siyeh/ipp/expression/FlipExpressionIntention.java b/plugins/IntentionPowerPak/src/com/siyeh/ipp/expression/FlipExpressionIntention.java index e2dfc021dcba..5c992ad66f37 100644 --- a/plugins/IntentionPowerPak/src/com/siyeh/ipp/expression/FlipExpressionIntention.java +++ b/plugins/IntentionPowerPak/src/com/siyeh/ipp/expression/FlipExpressionIntention.java @@ -1,5 +1,5 @@ /* - * Copyright 2007-2010 Dave Griffith, Bas Leijdekkers + * Copyright 2007-2013 Dave Griffith, Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,15 +15,17 @@ */ package com.siyeh.ipp.expression; -import com.intellij.psi.PsiBinaryExpression; +import com.intellij.openapi.editor.CaretModel; +import com.intellij.openapi.editor.Editor; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiExpression; import com.intellij.psi.PsiJavaToken; +import com.intellij.psi.PsiPolyadicExpression; import com.intellij.psi.tree.IElementType; -import com.intellij.util.IncorrectOperationException; import com.siyeh.IntentionPowerPackBundle; import com.siyeh.ipp.base.MutablyNamedIntention; import com.siyeh.ipp.base.PsiElementPredicate; +import com.siyeh.ipp.psiutils.ConcatenationUtils; import com.siyeh.ipp.psiutils.ParenthesesUtils; import org.jetbrains.annotations.NotNull; @@ -31,19 +33,17 @@ public class FlipExpressionIntention extends MutablyNamedIntention { @Override public String getTextForElement(PsiElement element) { - final PsiBinaryExpression expression = (PsiBinaryExpression)element; - final PsiJavaToken sign = expression.getOperationSign(); - final String operatorText = sign.getText(); - final IElementType token = sign.getTokenType(); - final boolean commutative = - ParenthesesUtils.isCommutativeBinaryOperator(token); - if (commutative) { - return IntentionPowerPackBundle.message("flip.smth.intention.name", - operatorText); + final PsiPolyadicExpression expression = (PsiPolyadicExpression)element.getParent(); + final PsiExpression[] operands = expression.getOperands(); + final PsiJavaToken sign = expression.getTokenBeforeOperand(operands[1]); + final String operatorText = sign == null ? "" : sign.getText(); + final IElementType tokenType = expression.getOperationTokenType(); + final boolean commutative = ParenthesesUtils.isCommutativeOperator(tokenType); + if (commutative && !ConcatenationUtils.isConcatenation(expression)) { + return IntentionPowerPackBundle.message("flip.smth.intention.name", operatorText); } else { - return IntentionPowerPackBundle.message("flip.smth.intention.name1", - operatorText); + return IntentionPowerPackBundle.message("flip.smth.intention.name1", operatorText); } } @@ -54,24 +54,37 @@ public class FlipExpressionIntention extends MutablyNamedIntention { } @Override - public void processIntention(@NotNull PsiElement element) - throws IncorrectOperationException { - final PsiBinaryExpression expression = (PsiBinaryExpression)element; - final PsiExpression lhs = expression.getLOperand(); - final PsiExpression rhs = expression.getROperand(); - final PsiJavaToken sign = expression.getOperationSign(); - if (rhs == null) { + public void processIntention(@NotNull PsiElement element) { + final PsiJavaToken token = (PsiJavaToken)element; + final PsiElement parent = token.getParent(); + if (!(parent instanceof PsiPolyadicExpression)) { return; } - final String signText = sign.getText(); - final String lhsText = lhs.getText(); - final String rhsText = rhs.getText(); - final StringBuilder newExpression = new StringBuilder(rhsText); - newExpression.append(signText); - if (lhsText.startsWith(signText)) { - newExpression.append(' '); + final PsiPolyadicExpression polyadicExpression = (PsiPolyadicExpression)parent; + final PsiExpression[] operands = polyadicExpression.getOperands(); + final StringBuilder newExpression = new StringBuilder(); + String prevOperand = null; + final String tokenText = token.getText() + ' '; // 2- -1 without the space is not legal + for (PsiExpression operand : operands) { + final PsiJavaToken token1 = polyadicExpression.getTokenBeforeOperand(operand); + if (token == token1) { + newExpression.append(operand.getText()).append(tokenText); + continue; + } + if (prevOperand != null) { + newExpression.append(prevOperand).append(tokenText); + } + prevOperand = operand.getText(); } - newExpression.append(lhsText); - replaceExpression(newExpression.toString(), expression); + newExpression.append(prevOperand); + replaceExpression(newExpression.toString(), polyadicExpression); + } + + @Override + protected void processIntention(Editor editor, @NotNull PsiElement element) { + final CaretModel caretModel = editor.getCaretModel(); + final int offset = caretModel.getOffset(); + super.processIntention(editor, element); + caretModel.moveToOffset(offset); } }
\ No newline at end of file diff --git a/plugins/IntentionPowerPak/src/com/siyeh/ipp/forloop/IterableForEachLoopPredicate.java b/plugins/IntentionPowerPak/src/com/siyeh/ipp/forloop/IterableForEachLoopPredicate.java index c9780104203c..e925b5c0ba67 100644 --- a/plugins/IntentionPowerPak/src/com/siyeh/ipp/forloop/IterableForEachLoopPredicate.java +++ b/plugins/IntentionPowerPak/src/com/siyeh/ipp/forloop/IterableForEachLoopPredicate.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2006 Dave Griffith, Bas Leijdekkers + * Copyright 2003-2013 Dave Griffith, Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,6 +17,7 @@ package com.siyeh.ipp.forloop; import com.intellij.psi.*; import com.intellij.psi.tree.IElementType; +import com.intellij.psi.util.InheritanceUtil; import com.siyeh.ipp.base.PsiElementPredicate; import com.siyeh.ipp.psiutils.ErrorUtil; @@ -35,13 +36,15 @@ class IterableForEachLoopPredicate implements PsiElementPredicate { if (!(parent instanceof PsiForeachStatement)) { return false; } - final PsiForeachStatement foreachStatement = - (PsiForeachStatement)parent; + final PsiForeachStatement foreachStatement = (PsiForeachStatement)parent; final PsiExpression iteratedValue = foreachStatement.getIteratedValue(); if (iteratedValue == null) { return false; } final PsiType type = iteratedValue.getType(); - return type instanceof PsiClassType && !ErrorUtil.containsError(parent); + if (!InheritanceUtil.isInheritor(type, CommonClassNames.JAVA_LANG_ITERABLE)) { + return false; + } + return !ErrorUtil.containsError(foreachStatement); } }
\ No newline at end of file diff --git a/plugins/IntentionPowerPak/src/com/siyeh/ipp/opassign/ReplaceOperatorAssignmentWithAssignmentIntention.java b/plugins/IntentionPowerPak/src/com/siyeh/ipp/opassign/ReplaceOperatorAssignmentWithAssignmentIntention.java index d9af9bba12e7..ea69411b0db1 100644 --- a/plugins/IntentionPowerPak/src/com/siyeh/ipp/opassign/ReplaceOperatorAssignmentWithAssignmentIntention.java +++ b/plugins/IntentionPowerPak/src/com/siyeh/ipp/opassign/ReplaceOperatorAssignmentWithAssignmentIntention.java @@ -1,5 +1,5 @@ /* - * Copyright 2007-2012 Bas Leijdekkers + * Copyright 2007-2013 Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,7 +18,6 @@ package com.siyeh.ipp.opassign; import com.intellij.psi.*; import com.intellij.psi.tree.IElementType; import com.intellij.psi.util.TypeConversionUtil; -import com.intellij.util.IncorrectOperationException; import com.siyeh.IntentionPowerPackBundle; import com.siyeh.ipp.base.MutablyNamedIntention; import com.siyeh.ipp.base.PsiElementPredicate; @@ -28,22 +27,23 @@ import org.jetbrains.annotations.NotNull; import java.util.HashMap; import java.util.Map; -public class ReplaceOperatorAssignmentWithAssignmentIntention - extends MutablyNamedIntention { +public class ReplaceOperatorAssignmentWithAssignmentIntention extends MutablyNamedIntention { - private static final Map<IElementType, IElementType> tokenMap = new HashMap<IElementType, IElementType>() {{ - put(JavaTokenType.PLUSEQ, JavaTokenType.PLUS); - put(JavaTokenType.MINUSEQ, JavaTokenType.MINUS); - put(JavaTokenType.ASTERISKEQ, JavaTokenType.ASTERISK); - put(JavaTokenType.DIVEQ, JavaTokenType.DIV); - put(JavaTokenType.ANDEQ, JavaTokenType.AND); - put(JavaTokenType.OREQ, JavaTokenType.OR); - put(JavaTokenType.XOREQ, JavaTokenType.XOR); - put(JavaTokenType.PERCEQ, JavaTokenType.PERC); - put(JavaTokenType.LTLTEQ, JavaTokenType.LTLT); - put(JavaTokenType.GTGTEQ, JavaTokenType.GTGT); - put(JavaTokenType.GTGTGTEQ, JavaTokenType.GTGTGT); - }}; + private static final Map<IElementType, IElementType> tokenMap = new HashMap<IElementType, IElementType>(); + + static { + tokenMap.put(JavaTokenType.PLUSEQ, JavaTokenType.PLUS); + tokenMap.put(JavaTokenType.MINUSEQ, JavaTokenType.MINUS); + tokenMap.put(JavaTokenType.ASTERISKEQ, JavaTokenType.ASTERISK); + tokenMap.put(JavaTokenType.DIVEQ, JavaTokenType.DIV); + tokenMap.put(JavaTokenType.ANDEQ, JavaTokenType.AND); + tokenMap.put(JavaTokenType.OREQ, JavaTokenType.OR); + tokenMap.put(JavaTokenType.XOREQ, JavaTokenType.XOR); + tokenMap.put(JavaTokenType.PERCEQ, JavaTokenType.PERC); + tokenMap.put(JavaTokenType.LTLTEQ, JavaTokenType.LTLT); + tokenMap.put(JavaTokenType.GTGTEQ, JavaTokenType.GTGT); + tokenMap.put(JavaTokenType.GTGTGTEQ, JavaTokenType.GTGTGT); + } @Override @NotNull @@ -53,17 +53,14 @@ public class ReplaceOperatorAssignmentWithAssignmentIntention @Override protected String getTextForElement(PsiElement element) { - final PsiAssignmentExpression assignmentExpression = - (PsiAssignmentExpression)element; + final PsiAssignmentExpression assignmentExpression = (PsiAssignmentExpression)element; final PsiJavaToken sign = assignmentExpression.getOperationSign(); final String operator = sign.getText(); - return IntentionPowerPackBundle.message( - "replace.operator.assignment.with.assignment.intention.name", - operator); + return IntentionPowerPackBundle.message("replace.operator.assignment.with.assignment.intention.name", operator); } @Override - protected void processIntention(@NotNull PsiElement element) throws IncorrectOperationException { + protected void processIntention(@NotNull PsiElement element) { final PsiAssignmentExpression assignmentExpression = (PsiAssignmentExpression)element; final PsiJavaToken sign = assignmentExpression.getOperationSign(); final PsiExpression lhs = assignmentExpression.getLExpression(); @@ -73,13 +70,13 @@ public class ReplaceOperatorAssignmentWithAssignmentIntention final String lhsText = lhs.getText(); final String rhsText = (rhs == null) ? "" : rhs.getText(); final boolean parentheses; - if (rhs instanceof PsiBinaryExpression) { - final PsiBinaryExpression binaryExpression = (PsiBinaryExpression)rhs; + if (rhs instanceof PsiPolyadicExpression) { + final PsiPolyadicExpression binaryExpression = (PsiPolyadicExpression)rhs; final int precedence1 = ParenthesesUtils.getPrecedenceForOperator(binaryExpression.getOperationTokenType()); final IElementType signTokenType = sign.getTokenType(); final IElementType newOperatorToken = tokenMap.get(signTokenType); final int precedence2 = ParenthesesUtils.getPrecedenceForOperator(newOperatorToken); - parentheses = precedence1 >= precedence2 || !ParenthesesUtils.isCommutativeBinaryOperator(newOperatorToken); + parentheses = precedence1 >= precedence2 || !ParenthesesUtils.isCommutativeOperator(newOperatorToken); } else { parentheses = false; diff --git a/plugins/IntentionPowerPak/src/com/siyeh/ipp/opassign/ReplaceWithOperatorAssignmentIntention.java b/plugins/IntentionPowerPak/src/com/siyeh/ipp/opassign/ReplaceWithOperatorAssignmentIntention.java index 6e61e4dfe77a..f4d0397fcc93 100644 --- a/plugins/IntentionPowerPak/src/com/siyeh/ipp/opassign/ReplaceWithOperatorAssignmentIntention.java +++ b/plugins/IntentionPowerPak/src/com/siyeh/ipp/opassign/ReplaceWithOperatorAssignmentIntention.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2007 Dave Griffith, Bas Leijdekkers + * Copyright 2003-2013 Dave Griffith, Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,50 +17,53 @@ package com.siyeh.ipp.opassign; import com.intellij.psi.*; import com.intellij.psi.util.PsiUtil; -import com.intellij.util.IncorrectOperationException; import com.siyeh.IntentionPowerPackBundle; import com.siyeh.ipp.base.MutablyNamedIntention; import com.siyeh.ipp.base.PsiElementPredicate; import org.jetbrains.annotations.NotNull; -public class ReplaceWithOperatorAssignmentIntention - extends MutablyNamedIntention { +public class ReplaceWithOperatorAssignmentIntention extends MutablyNamedIntention { public String getTextForElement(PsiElement element) { - final PsiAssignmentExpression assignmentExpression = - (PsiAssignmentExpression)element; + final PsiAssignmentExpression assignmentExpression = (PsiAssignmentExpression)element; final PsiExpression rhs = assignmentExpression.getRExpression(); - final PsiBinaryExpression expression = - (PsiBinaryExpression)PsiUtil.deparenthesizeExpression(rhs); + final PsiPolyadicExpression expression = (PsiPolyadicExpression)PsiUtil.deparenthesizeExpression(rhs); assert expression != null; - final PsiJavaToken sign = expression.getOperationSign(); + final PsiJavaToken sign = expression.getTokenBeforeOperand(expression.getOperands()[1]); + assert sign != null; final String operator = sign.getText(); - return IntentionPowerPackBundle.message( - "replace.assignment.with.operator.assignment.intention.name", - operator); + return IntentionPowerPackBundle.message("replace.assignment.with.operator.assignment.intention.name", operator); } @NotNull public PsiElementPredicate getElementPredicate() { - return new AssignmentExpressionReplaceableWithOperatorAssigment(); + return new ReplaceableWithOperatorAssignmentPredicate(); } - public void processIntention(@NotNull PsiElement element) - throws IncorrectOperationException { - final PsiAssignmentExpression expression = - (PsiAssignmentExpression)element; - final PsiExpression rhs = - expression.getRExpression(); - final PsiBinaryExpression binaryExpression = - (PsiBinaryExpression)PsiUtil.deparenthesizeExpression(rhs); + public void processIntention(@NotNull PsiElement element){ + final PsiAssignmentExpression expression = (PsiAssignmentExpression)element; + final PsiExpression rhs = expression.getRExpression(); + final PsiPolyadicExpression polyadicExpression = (PsiPolyadicExpression)PsiUtil.deparenthesizeExpression(rhs); + assert polyadicExpression != null; final PsiExpression lhs = expression.getLExpression(); assert rhs != null; - final PsiJavaToken sign = binaryExpression.getOperationSign(); - final String operand = sign.getText(); - final PsiExpression binaryRhs = binaryExpression.getROperand(); - assert binaryRhs != null; - final String newExpression = - lhs.getText() + operand + '=' + binaryRhs.getText(); - replaceExpression(newExpression, expression); + final PsiExpression[] operands = polyadicExpression.getOperands(); + final PsiJavaToken sign = polyadicExpression.getTokenBeforeOperand(operands[1]); + assert sign != null; + final String signText = sign.getText(); + final StringBuilder newExpression = new StringBuilder(); + newExpression.append(lhs.getText()).append(signText).append('='); + boolean token = false; + for (int i = 1; i < operands.length; i++) { + final PsiExpression operand = operands[i]; + if (token) { + newExpression.append(signText); + } + else { + token = true; + } + newExpression.append(operand.getText()); + } + replaceExpression(newExpression.toString(), expression); } }
\ No newline at end of file diff --git a/plugins/IntentionPowerPak/src/com/siyeh/ipp/opassign/AssignmentExpressionReplaceableWithOperatorAssigment.java b/plugins/IntentionPowerPak/src/com/siyeh/ipp/opassign/ReplaceableWithOperatorAssignmentPredicate.java index ca0f09e7ef42..1f397a5a57bf 100644 --- a/plugins/IntentionPowerPak/src/com/siyeh/ipp/opassign/AssignmentExpressionReplaceableWithOperatorAssigment.java +++ b/plugins/IntentionPowerPak/src/com/siyeh/ipp/opassign/ReplaceableWithOperatorAssignmentPredicate.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2007 Dave Griffith, Bas Leijdekkers + * Copyright 2003-2013 Dave Griffith, Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,45 +23,37 @@ import com.siyeh.ipp.psiutils.EquivalenceChecker; import com.siyeh.ipp.psiutils.ErrorUtil; import com.siyeh.ipp.psiutils.SideEffectChecker; -class AssignmentExpressionReplaceableWithOperatorAssigment - implements PsiElementPredicate { +class ReplaceableWithOperatorAssignmentPredicate implements PsiElementPredicate { public boolean satisfiedBy(PsiElement element) { if (!(element instanceof PsiAssignmentExpression)) { return false; } - final PsiAssignmentExpression assignment = - (PsiAssignmentExpression)element; + final PsiAssignmentExpression assignment = (PsiAssignmentExpression)element; final IElementType tokenType = assignment.getOperationTokenType(); if (!JavaTokenType.EQ.equals(tokenType)) { return false; } final PsiExpression rhs = assignment.getRExpression(); final PsiExpression expression = PsiUtil.deparenthesizeExpression(rhs); - if (expression == null) { + if (!(expression instanceof PsiPolyadicExpression)) { return false; } - if (!(expression instanceof PsiBinaryExpression)) { + final PsiPolyadicExpression polyadicExpression = (PsiPolyadicExpression)expression; + final PsiExpression[] operands = polyadicExpression.getOperands(); + if (operands.length < 2) { return false; } - final PsiBinaryExpression binaryRhs = (PsiBinaryExpression)expression; - final PsiExpression rhsRhs = binaryRhs.getROperand(); - final PsiExpression rhsLhs = binaryRhs.getLOperand(); - if (rhsRhs == null) { - return false; - } - final IElementType rhsTokenType = binaryRhs.getOperationTokenType(); - if (JavaTokenType.OROR.equals(rhsTokenType) || - JavaTokenType.ANDAND.equals(rhsTokenType) || - JavaTokenType.EQEQ.equals(rhsTokenType) || - JavaTokenType.NE.equals(rhsTokenType)) { + final IElementType rhsTokenType = polyadicExpression.getOperationTokenType(); + if (JavaTokenType.OROR.equals(rhsTokenType) || JavaTokenType.ANDAND.equals(rhsTokenType) || + JavaTokenType.EQEQ.equals(rhsTokenType) || JavaTokenType.NE.equals(rhsTokenType)) { return false; } final PsiExpression lhs = assignment.getLExpression(); if (SideEffectChecker.mayHaveSideEffects(lhs)) { return false; } - if (!EquivalenceChecker.expressionsAreEquivalent(lhs, rhsLhs)) { + if (!EquivalenceChecker.expressionsAreEquivalent(lhs, operands[0])) { return false; } return !ErrorUtil.containsError(element); diff --git a/plugins/IntentionPowerPak/src/com/siyeh/ipp/psiutils/ConcatenationUtils.java b/plugins/IntentionPowerPak/src/com/siyeh/ipp/psiutils/ConcatenationUtils.java index c2766e595967..0a62b3181b88 100644 --- a/plugins/IntentionPowerPak/src/com/siyeh/ipp/psiutils/ConcatenationUtils.java +++ b/plugins/IntentionPowerPak/src/com/siyeh/ipp/psiutils/ConcatenationUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2010 Dave Griffith, Bas Leijdekkers + * Copyright 2003-2013 Dave Griffith, Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,9 +20,7 @@ import com.intellij.psi.tree.IElementType; public class ConcatenationUtils { - private ConcatenationUtils() { - super(); - } + private ConcatenationUtils() {} public static boolean isConcatenation(PsiElement element) { if (!(element instanceof PsiPolyadicExpression)) { @@ -33,20 +31,24 @@ public class ConcatenationUtils { if (!tokenType.equals(JavaTokenType.PLUS)) { return false; } - PsiExpression[] operands = expression.getOperands(); - if (operands.length <= 1) return false; + final PsiExpression[] operands = expression.getOperands(); + if (operands.length <= 1) { + return false; + } final PsiType type = expression.getType(); if (type == null) { for (PsiExpression operand : operands) { - if (hasStringType(operand)) return true; + if (hasStringType(operand)) { + return true; + } } return false; } - return type.equalsToText("java.lang.String"); + return type.equalsToText(CommonClassNames.JAVA_LANG_STRING); } private static boolean hasStringType(PsiExpression expression) { final PsiType type = expression.getType(); - return type != null && type.equalsToText("java.lang.String"); + return type != null && type.equalsToText(CommonClassNames.JAVA_LANG_STRING); } } diff --git a/plugins/IntentionPowerPak/src/com/siyeh/ipp/psiutils/ParenthesesUtils.java b/plugins/IntentionPowerPak/src/com/siyeh/ipp/psiutils/ParenthesesUtils.java index b4d97f52687d..ab2971af6b81 100644 --- a/plugins/IntentionPowerPak/src/com/siyeh/ipp/psiutils/ParenthesesUtils.java +++ b/plugins/IntentionPowerPak/src/com/siyeh/ipp/psiutils/ParenthesesUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2012 Dave Griffith, Bas Leijdekkers + * Copyright 2003-2013 Dave Griffith, Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -81,7 +81,7 @@ public class ParenthesesUtils { return expression; } - public static boolean isCommutativeBinaryOperator(@NotNull IElementType token) { + public static boolean isCommutativeOperator(@NotNull IElementType token) { return !(token.equals(JavaTokenType.MINUS) || token.equals(JavaTokenType.DIV) || token.equals(JavaTokenType.PERC) || @@ -185,8 +185,8 @@ public class ParenthesesUtils { removeParensFromPostfixExpression(postfixExpression, ignoreClarifyingParentheses); } if (expression instanceof PsiPolyadicExpression) { - final PsiPolyadicExpression binaryExpression = (PsiPolyadicExpression)expression; - removeParensFromPolyadicExpression(binaryExpression, ignoreClarifyingParentheses); + final PsiPolyadicExpression polyadicExpression = (PsiPolyadicExpression)expression; + removeParensFromPolyadicExpression(polyadicExpression, ignoreClarifyingParentheses); } if (expression instanceof PsiInstanceOfExpression) { final PsiInstanceOfExpression instanceofExpression = (PsiInstanceOfExpression)expression; @@ -225,12 +225,15 @@ public class ParenthesesUtils { return; } else if (parent instanceof PsiArrayAccessExpression) { - // use addAfter() + delete() instead of replace() to - // workaround automatic insertion of parentheses by psi - final PsiExpression newExpression = (PsiExpression)parent.addAfter(body, parenthesizedExpression); - parenthesizedExpression.delete(); - removeParentheses(newExpression, ignoreClarifyingParentheses); - return; + final PsiArrayAccessExpression arrayAccessExpression = (PsiArrayAccessExpression)parent; + if (parenthesizedExpression == arrayAccessExpression.getIndexExpression()) { + // use addAfter() + delete() instead of replace() to + // workaround automatic insertion of parentheses by psi + final PsiExpression newExpression = (PsiExpression)parent.addAfter(body, parenthesizedExpression); + parenthesizedExpression.delete(); + removeParentheses(newExpression, ignoreClarifyingParentheses); + return; + } } final PsiExpression parentExpression = (PsiExpression)parent; final int parentPrecedence = getPrecedence(parentExpression); @@ -245,15 +248,15 @@ public class ParenthesesUtils { } else if (parentPrecedence == childPrecedence) { if (parentExpression instanceof PsiPolyadicExpression && body instanceof PsiPolyadicExpression) { - final PsiPolyadicExpression parentBinaryExpression = (PsiPolyadicExpression)parentExpression; - final IElementType parentOperator = parentBinaryExpression.getOperationTokenType(); - final PsiPolyadicExpression bodyBinaryExpression = (PsiPolyadicExpression)body; - final IElementType bodyOperator = bodyBinaryExpression.getOperationTokenType(); - final PsiType parentType = parentBinaryExpression.getType(); + final PsiPolyadicExpression parentPolyadicExpression = (PsiPolyadicExpression)parentExpression; + final IElementType parentOperator = parentPolyadicExpression.getOperationTokenType(); + final PsiPolyadicExpression bodyPolyadicExpression = (PsiPolyadicExpression)body; + final IElementType bodyOperator = bodyPolyadicExpression.getOperationTokenType(); + final PsiType parentType = parentPolyadicExpression.getType(); final PsiType bodyType = body.getType(); if (parentType != null && parentType.equals(bodyType) && parentOperator.equals(bodyOperator)) { - final PsiExpression[] parentOperands = parentBinaryExpression.getOperands(); - if (PsiTreeUtil.isAncestor(parentOperands[0], body, true) || isCommutativeBinaryOperator(bodyOperator)) { + final PsiExpression[] parentOperands = parentPolyadicExpression.getOperands(); + if (PsiTreeUtil.isAncestor(parentOperands[0], body, true) || isCommutativeOperator(bodyOperator)) { // use addAfter() + delete() instead of replace() to // workaround automatic insertion of parentheses by psi final PsiExpression newExpression = (PsiExpression)parent.addAfter(body, parenthesizedExpression); @@ -407,12 +410,18 @@ public class ParenthesesUtils { if (child == null) { return true; } + if (parent instanceof PsiArrayAccessExpression) { + final PsiArrayAccessExpression arrayAccessExpression = (PsiArrayAccessExpression)parent; + final PsiExpression indexExpression = arrayAccessExpression.getIndexExpression(); + if (expression == indexExpression) { + return false; + } + } return areParenthesesNeeded(child, (PsiExpression)parent); } public static boolean areParenthesesNeeded(PsiExpression expression, PsiExpression parentExpression) { - if (parentExpression instanceof PsiParenthesizedExpression || parentExpression instanceof PsiArrayAccessExpression || - parentExpression instanceof PsiArrayInitializerExpression) { + if (parentExpression instanceof PsiParenthesizedExpression || parentExpression instanceof PsiArrayInitializerExpression) { return false; } final int parentPrecedence = getPrecedence(parentExpression); @@ -451,7 +460,7 @@ public class ParenthesesUtils { final PsiExpression[] parentOperands = parentPolyadicExpression.getOperands(); if (!PsiTreeUtil.isAncestor(parentOperands[0], expression, false)) { final IElementType parentOperator = parentPolyadicExpression.getOperationTokenType(); - if (!isCommutativeBinaryOperator(parentOperator)) { + if (!isCommutativeOperator(parentOperator)) { return true; } } diff --git a/plugins/IntentionPowerPak/src/com/siyeh/ipp/switchtoif/IfStatementBranch.java b/plugins/IntentionPowerPak/src/com/siyeh/ipp/switchtoif/IfStatementBranch.java index 218ddf50fb5e..598809d5e25a 100644 --- a/plugins/IntentionPowerPak/src/com/siyeh/ipp/switchtoif/IfStatementBranch.java +++ b/plugins/IntentionPowerPak/src/com/siyeh/ipp/switchtoif/IfStatementBranch.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2011 Dave Griffith, Bas Leijdekkers + * Copyright 2003-2013 Dave Griffith, Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,7 +24,7 @@ class IfStatementBranch { private final Set<String> topLevelVariables = new HashSet<String>(3); private final LinkedList<String> comments = new LinkedList<String>(); private final LinkedList<String> statementComments = new LinkedList<String>(); - private final List<String> conditions = new ArrayList<String>(3); + private final List<PsiExpression> caseExpressions = new ArrayList<PsiExpression>(3); private final PsiStatement statement; private final boolean elseBranch; @@ -42,30 +42,28 @@ class IfStatementBranch { statementComments.addFirst(comment); } - public void addCondition(String conditionString) { - conditions.add(conditionString); + public void addCaseExpression(PsiExpression expression) { + caseExpressions.add(expression); } public PsiStatement getStatement() { return statement; } - public List<String> getConditions() { - return Collections.unmodifiableList(conditions); + public List<PsiExpression> getCaseExpressions() { + return Collections.unmodifiableList(caseExpressions); } public boolean isElse() { return elseBranch; } - public boolean topLevelDeclarationsConflictWith( - IfStatementBranch testBranch) { + public boolean topLevelDeclarationsConflictWith(IfStatementBranch testBranch) { final Set<String> topLevel = testBranch.topLevelVariables; return intersects(topLevelVariables, topLevel); } - private static boolean intersects(Set<String> set1, - Set<String> set2) { + private static boolean intersects(Set<String> set1, Set<String> set2) { for (final String s : set1) { if (set2.contains(s)) { return true; @@ -87,10 +85,8 @@ class IfStatementBranch { return; } if (statement instanceof PsiDeclarationStatement) { - final PsiDeclarationStatement declarationStatement = - (PsiDeclarationStatement)statement; - final PsiElement[] elements = - declarationStatement.getDeclaredElements(); + final PsiDeclarationStatement declarationStatement = (PsiDeclarationStatement)statement; + final PsiElement[] elements = declarationStatement.getDeclaredElements(); for (PsiElement element : elements) { final PsiVariable variable = (PsiVariable)element; final String varName = variable.getName(); diff --git a/plugins/IntentionPowerPak/src/com/siyeh/ipp/switchtoif/LabelSearchVisitor.java b/plugins/IntentionPowerPak/src/com/siyeh/ipp/switchtoif/LabelSearchVisitor.java index ac7987373ded..5ab51566d190 100644 --- a/plugins/IntentionPowerPak/src/com/siyeh/ipp/switchtoif/LabelSearchVisitor.java +++ b/plugins/IntentionPowerPak/src/com/siyeh/ipp/switchtoif/LabelSearchVisitor.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2005 Dave Griffith + * Copyright 2003-2013 Dave Griffith, Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,10 +15,7 @@ */ package com.siyeh.ipp.switchtoif; -import com.intellij.psi.JavaRecursiveElementWalkingVisitor; -import com.intellij.psi.PsiIdentifier; -import com.intellij.psi.PsiLabeledStatement; -import com.intellij.psi.PsiReferenceExpression; +import com.intellij.psi.*; class LabelSearchVisitor extends JavaRecursiveElementWalkingVisitor { @@ -26,12 +23,15 @@ class LabelSearchVisitor extends JavaRecursiveElementWalkingVisitor { private boolean m_used = false; LabelSearchVisitor(String name) { - super(); m_labelName = name; } @Override - public void visitReferenceExpression(PsiReferenceExpression expression) { + public void visitElement(PsiElement element) { + if (m_used) { + return; + } + super.visitElement(element); } @Override diff --git a/plugins/IntentionPowerPak/src/com/siyeh/ipp/switchtoif/LocalVariableUsageVisitor.java b/plugins/IntentionPowerPak/src/com/siyeh/ipp/switchtoif/LocalVariableUsageVisitor.java deleted file mode 100644 index 4fc5a2c32c64..000000000000 --- a/plugins/IntentionPowerPak/src/com/siyeh/ipp/switchtoif/LocalVariableUsageVisitor.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 2003-2005 Dave Griffith - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.siyeh.ipp.switchtoif; - -import com.intellij.psi.JavaRecursiveElementWalkingVisitor; -import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiLocalVariable; -import com.intellij.psi.PsiReferenceExpression; - -class LocalVariableUsageVisitor extends JavaRecursiveElementWalkingVisitor { - - private final PsiLocalVariable m_var; - private boolean m_used = false; - - LocalVariableUsageVisitor(PsiLocalVariable name) { - super(); - m_var = name; - } - - @Override - public void visitReferenceExpression(PsiReferenceExpression expression) { - final PsiElement reference = expression.resolve(); - if (m_var.equals(reference)) { - m_used = true; - } - super.visitReferenceElement(expression); - } - - public boolean isUsed() { - return m_used; - } -}
\ No newline at end of file diff --git a/plugins/IntentionPowerPak/src/com/siyeh/ipp/switchtoif/ReplaceIfWithSwitchIntention.java b/plugins/IntentionPowerPak/src/com/siyeh/ipp/switchtoif/ReplaceIfWithSwitchIntention.java index 4d7e34bc3834..cfd5406bec1d 100644 --- a/plugins/IntentionPowerPak/src/com/siyeh/ipp/switchtoif/ReplaceIfWithSwitchIntention.java +++ b/plugins/IntentionPowerPak/src/com/siyeh/ipp/switchtoif/ReplaceIfWithSwitchIntention.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2011 Dave Griffith, Bas Leijdekkers + * Copyright 2003-2013 Dave Griffith, Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,7 +18,6 @@ package com.siyeh.ipp.switchtoif; import com.intellij.psi.*; import com.intellij.psi.tree.IElementType; import com.intellij.psi.util.PsiTreeUtil; -import com.intellij.util.IncorrectOperationException; import com.siyeh.ipp.base.Intention; import com.siyeh.ipp.base.PsiElementPredicate; import com.siyeh.ipp.psiutils.ControlFlowUtils; @@ -39,8 +38,7 @@ public class ReplaceIfWithSwitchIntention extends Intention { } @Override - public void processIntention(@NotNull PsiElement element) - throws IncorrectOperationException { + public void processIntention(@NotNull PsiElement element) { final PsiJavaToken switchToken = (PsiJavaToken)element; PsiIfStatement ifStatement = (PsiIfStatement)switchToken.getParent(); if (ifStatement == null) { @@ -50,67 +48,37 @@ public class ReplaceIfWithSwitchIntention extends Intention { PsiStatement breakTarget = null; String labelString = ""; if (ControlFlowUtils.statementContainsNakedBreak(ifStatement)) { - breakTarget = PsiTreeUtil.getParentOfType(ifStatement, - PsiLoopStatement.class, PsiSwitchStatement.class); + breakTarget = PsiTreeUtil.getParentOfType(ifStatement, PsiLoopStatement.class, PsiSwitchStatement.class); if (breakTarget != null) { final PsiElement parent = breakTarget.getParent(); if (parent instanceof PsiLabeledStatement) { - final PsiLabeledStatement labeledStatement = - (PsiLabeledStatement)parent; - labelString = - labeledStatement.getLabelIdentifier().getText(); + final PsiLabeledStatement labeledStatement = (PsiLabeledStatement)parent; + labelString = labeledStatement.getLabelIdentifier().getText(); breakTarget = labeledStatement; breaksNeedRelabeled = true; } else { - labelString = SwitchUtils.findUniqueLabelName(ifStatement, - "label"); + labelString = SwitchUtils.findUniqueLabelName(ifStatement, "label"); breaksNeedRelabeled = true; } } } final PsiIfStatement statementToReplace = ifStatement; - final PsiExpression switchExpression = - SwitchUtils.getSwitchExpression(ifStatement); - assert switchExpression != null; - - final List<IfStatementBranch> branches = - new ArrayList<IfStatementBranch>(20); + final PsiExpression switchExpression = SwitchUtils.getSwitchExpression(ifStatement); + if (switchExpression == null) { + return; + } + final List<IfStatementBranch> branches = new ArrayList<IfStatementBranch>(20); while (true) { final PsiExpression condition = ifStatement.getCondition(); - final List<PsiExpression> labels = - getValuesFromExpression(condition, switchExpression, - new ArrayList()); final PsiStatement thenBranch = ifStatement.getThenBranch(); - final IfStatementBranch ifBranch = - new IfStatementBranch(thenBranch, false); + final IfStatementBranch ifBranch = new IfStatementBranch(thenBranch, false); + extractCaseExpressions(condition, switchExpression, ifBranch); if (!branches.isEmpty()) { extractIfComments(ifStatement, ifBranch); } extractStatementComments(thenBranch, ifBranch); - for (final PsiExpression label : labels) { - if (label instanceof PsiReferenceExpression) { - final PsiReferenceExpression reference = - (PsiReferenceExpression)label; - final PsiElement referent = reference.resolve(); - if (referent instanceof PsiEnumConstant) { - final PsiEnumConstant constant = - (PsiEnumConstant)referent; - final String constantName = constant.getName(); - ifBranch.addCondition(constantName); - } - else { - final String labelText = label.getText(); - ifBranch.addCondition(labelText); - } - } - else { - final String labelText = label.getText(); - ifBranch.addCondition(labelText); - } - } branches.add(ifBranch); - final PsiStatement elseBranch = ifStatement.getElseBranch(); if (elseBranch instanceof PsiIfStatement) { ifStatement = (PsiIfStatement)elseBranch; @@ -119,8 +87,7 @@ public class ReplaceIfWithSwitchIntention extends Intention { break; } else { - final IfStatementBranch elseIfBranch = - new IfStatementBranch(elseBranch, true); + final IfStatementBranch elseIfBranch = new IfStatementBranch(elseBranch, true); final PsiKeyword elseKeyword = ifStatement.getElseElement(); extractIfComments(elseKeyword, elseIfBranch); extractStatementComments(elseBranch, elseIfBranch); @@ -129,11 +96,10 @@ public class ReplaceIfWithSwitchIntention extends Intention { } } - @NonNls final StringBuilder switchStatementText = - new StringBuilder(); - switchStatementText.append("switch("); - switchStatementText.append(switchExpression.getText()); - switchStatementText.append("){"); + @NonNls final StringBuilder switchStatementText = new StringBuilder(); + switchStatementText.append("switch(").append(switchExpression.getText()).append("){"); + final PsiType type = switchExpression.getType(); + final boolean castToInt = type != null && type.equalsToText(CommonClassNames.JAVA_LANG_INTEGER); for (IfStatementBranch branch : branches) { boolean hasConflicts = false; for (IfStatementBranch testBranch : branches) { @@ -144,39 +110,30 @@ public class ReplaceIfWithSwitchIntention extends Intention { hasConflicts = true; } } - dumpBranch(branch, hasConflicts, breaksNeedRelabeled, labelString, - switchStatementText); + dumpBranch(branch, castToInt, hasConflicts, breaksNeedRelabeled, labelString, switchStatementText); } switchStatementText.append('}'); - final JavaPsiFacade psiFacade = - JavaPsiFacade.getInstance(element.getProject()); + final JavaPsiFacade psiFacade = JavaPsiFacade.getInstance(element.getProject()); final PsiElementFactory factory = psiFacade.getElementFactory(); if (breaksNeedRelabeled) { final StringBuilder out = new StringBuilder(); if (!(breakTarget instanceof PsiLabeledStatement)) { - out.append(labelString); - out.append(':'); + out.append(labelString).append(':'); } - termReplace(breakTarget, statementToReplace, switchStatementText, - out); + termReplace(breakTarget, statementToReplace, switchStatementText, out); final String newStatementText = out.toString(); - final PsiStatement newStatement = - factory.createStatementFromText(newStatementText, element); + final PsiStatement newStatement = factory.createStatementFromText(newStatementText, element); breakTarget.replace(newStatement); } else { - final PsiStatement newStatement = - factory.createStatementFromText( - switchStatementText.toString(), element); + final PsiStatement newStatement = factory.createStatementFromText(switchStatementText.toString(), element); statementToReplace.replace(newStatement); } } @Nullable - public static <T extends PsiElement> T getPrevSiblingOfType( - @Nullable PsiElement element, - @NotNull Class<T> aClass, - @NotNull Class<? extends PsiElement>... stopAt) { + public static <T extends PsiElement> T getPrevSiblingOfType(@Nullable PsiElement element, @NotNull Class<T> aClass, + @NotNull Class<? extends PsiElement>... stopAt) { if (element == null) { return null; } @@ -192,18 +149,15 @@ public class ReplaceIfWithSwitchIntention extends Intention { return (T)sibling; } - private static void extractIfComments(PsiElement element, - IfStatementBranch out) { - PsiComment comment = getPrevSiblingOfType(element, - PsiComment.class, PsiStatement.class); + private static void extractIfComments(PsiElement element, IfStatementBranch out) { + PsiComment comment = getPrevSiblingOfType(element, PsiComment.class, PsiStatement.class); while (comment != null) { final PsiElement sibling = comment.getPrevSibling(); final String commentText; if (sibling instanceof PsiWhiteSpace) { final String whiteSpaceText = sibling.getText(); if (whiteSpaceText.startsWith("\n")) { - commentText = whiteSpaceText.substring(1) + - comment.getText(); + commentText = whiteSpaceText.substring(1) + comment.getText(); } else { commentText = comment.getText(); @@ -213,23 +167,19 @@ public class ReplaceIfWithSwitchIntention extends Intention { commentText = comment.getText(); } out.addComment(commentText); - comment = getPrevSiblingOfType(comment, PsiComment.class, - PsiStatement.class); + comment = getPrevSiblingOfType(comment, PsiComment.class, PsiStatement.class); } } - private static void extractStatementComments(PsiElement element, - IfStatementBranch out) { - PsiComment comment = getPrevSiblingOfType(element, - PsiComment.class, PsiStatement.class, PsiKeyword.class); + private static void extractStatementComments(PsiElement element, IfStatementBranch out) { + PsiComment comment = getPrevSiblingOfType(element, PsiComment.class, PsiStatement.class, PsiKeyword.class); while (comment != null) { final PsiElement sibling = comment.getPrevSibling(); final String commentText; if (sibling instanceof PsiWhiteSpace) { final String whiteSpaceText = sibling.getText(); if (whiteSpaceText.startsWith("\n")) { - commentText = whiteSpaceText.substring(1) + - comment.getText(); + commentText = whiteSpaceText.substring(1) + comment.getText(); } else { commentText = comment.getText(); @@ -239,14 +189,11 @@ public class ReplaceIfWithSwitchIntention extends Intention { commentText = comment.getText(); } out.addStatementComment(commentText); - comment = getPrevSiblingOfType(comment, PsiComment.class, - PsiStatement.class, PsiKeyword.class); + comment = getPrevSiblingOfType(comment, PsiComment.class, PsiStatement.class, PsiKeyword.class); } } - private static void termReplace( - PsiElement target, PsiElement replace, - StringBuilder stringToReplaceWith, StringBuilder out) { + private static void termReplace(PsiElement target, PsiElement replace, StringBuilder stringToReplaceWith, StringBuilder out) { if (target.equals(replace)) { out.append(stringToReplaceWith); } @@ -261,120 +208,118 @@ public class ReplaceIfWithSwitchIntention extends Intention { } } - private static List<PsiExpression> getValuesFromExpression( - PsiExpression expression, PsiExpression caseExpression, - List<PsiExpression> values) { + private static void extractCaseExpressions(PsiExpression expression, PsiExpression switchExpression, IfStatementBranch values) { if (expression instanceof PsiMethodCallExpression) { - final PsiMethodCallExpression methodCallExpression = - (PsiMethodCallExpression)expression; - final PsiExpressionList argumentList = - methodCallExpression.getArgumentList(); + final PsiMethodCallExpression methodCallExpression = (PsiMethodCallExpression)expression; + final PsiExpressionList argumentList = methodCallExpression.getArgumentList(); final PsiExpression[] arguments = argumentList.getExpressions(); final PsiExpression argument = arguments[0]; - final PsiReferenceExpression methodExpression = - methodCallExpression.getMethodExpression(); - final PsiExpression qualifierExpression = - methodExpression.getQualifierExpression(); - if (EquivalenceChecker.expressionsAreEquivalent(caseExpression, - argument)) { - values.add(qualifierExpression); + final PsiReferenceExpression methodExpression = methodCallExpression.getMethodExpression(); + final PsiExpression qualifierExpression = methodExpression.getQualifierExpression(); + if (EquivalenceChecker.expressionsAreEquivalent(switchExpression, argument)) { + values.addCaseExpression(qualifierExpression); } else { - values.add(argument); + values.addCaseExpression(argument); } } - else if (expression instanceof PsiBinaryExpression) { - final PsiBinaryExpression binaryExpression = - (PsiBinaryExpression)expression; - final PsiExpression lhs = binaryExpression.getLOperand(); - final PsiExpression rhs = binaryExpression.getROperand(); - final IElementType tokenType = binaryExpression.getOperationTokenType(); + else if (expression instanceof PsiPolyadicExpression) { + final PsiPolyadicExpression polyadicExpression = (PsiPolyadicExpression)expression; + final PsiExpression[] operands = polyadicExpression.getOperands(); + final IElementType tokenType = polyadicExpression.getOperationTokenType(); if (JavaTokenType.OROR.equals(tokenType)) { - getValuesFromExpression(lhs, caseExpression, - values); - getValuesFromExpression(rhs, caseExpression, - values); + for (PsiExpression operand : operands) { + extractCaseExpressions(operand, switchExpression, values); + } } - else { - if (EquivalenceChecker.expressionsAreEquivalent(caseExpression, - rhs)) { - values.add(lhs); + else if (JavaTokenType.EQEQ.equals(tokenType) && operands.length == 2) { + final PsiExpression lhs = operands[0]; + final PsiExpression rhs = operands[1]; + if (EquivalenceChecker.expressionsAreEquivalent(switchExpression, rhs)) { + values.addCaseExpression(lhs); } - else { - values.add(rhs); + else if (EquivalenceChecker.expressionsAreEquivalent(switchExpression, lhs)){ + values.addCaseExpression(rhs); } } } else if (expression instanceof PsiParenthesizedExpression) { - final PsiParenthesizedExpression parenthesizedExpression = - (PsiParenthesizedExpression)expression; - final PsiExpression contents = - parenthesizedExpression.getExpression(); - getValuesFromExpression(contents, caseExpression, values); + final PsiParenthesizedExpression parenthesizedExpression = (PsiParenthesizedExpression)expression; + final PsiExpression contents = parenthesizedExpression.getExpression(); + extractCaseExpressions(contents, switchExpression, values); } - return values; } - private static void dumpBranch(IfStatementBranch branch, - boolean wrap, - boolean renameBreaks, - String breakLabelName, - StringBuilder switchStatementText) { + private static void dumpBranch(IfStatementBranch branch, boolean castToInt, boolean wrap, boolean renameBreaks, String breakLabelName, + @NonNls StringBuilder switchStatementText) { dumpComments(branch.getComments(), switchStatementText); if (branch.isElse()) { switchStatementText.append("default: "); } else { - for (String label : branch.getConditions()) { - switchStatementText.append("case "); - switchStatementText.append(label); - switchStatementText.append(": "); + for (PsiExpression caseExpression : branch.getCaseExpressions()) { + switchStatementText.append("case ").append(getCaseLabelText(caseExpression, castToInt)).append(": "); } } dumpComments(branch.getStatementComments(), switchStatementText); - dumpBody(branch.getStatement(), wrap, renameBreaks, breakLabelName, - switchStatementText - ); + dumpBody(branch.getStatement(), wrap, renameBreaks, breakLabelName, switchStatementText); } - private static void dumpComments(List<String> comments, - StringBuilder switchStatementText) { - if (!comments.isEmpty()) { - switchStatementText.append('\n'); - for (String comment : comments) { - switchStatementText.append(comment); - switchStatementText.append('\n'); + @NonNls + private static String getCaseLabelText(PsiExpression expression, boolean castToInt) { + if (expression instanceof PsiReferenceExpression) { + final PsiReferenceExpression referenceExpression = (PsiReferenceExpression)expression; + final PsiElement target = referenceExpression.resolve(); + if (target instanceof PsiEnumConstant) { + final PsiEnumConstant enumConstant = (PsiEnumConstant)target; + return enumConstant.getName(); } } + if (castToInt) { + final PsiType type = expression.getType(); + if (!PsiType.INT.equals(type)) { + /* + because + Integer a = 1; + switch (a) { + case (byte)7: + } + does not compile with javac (but does with Eclipse) + */ + return "(int)" + expression.getText(); + } + } + return expression.getText(); + } + + private static void dumpComments(List<String> comments, StringBuilder switchStatementText) { + if (comments.isEmpty()) { + return; + } + switchStatementText.append('\n'); + for (String comment : comments) { + switchStatementText.append(comment).append('\n'); + } } - private static void dumpBody(PsiStatement bodyStatement, - boolean wrap, - boolean renameBreaks, - String breakLabelName, + private static void dumpBody(PsiStatement bodyStatement, boolean wrap, boolean renameBreaks, String breakLabelName, @NonNls StringBuilder switchStatementText) { if (wrap) { switchStatementText.append('{'); } if (bodyStatement instanceof PsiBlockStatement) { - final PsiCodeBlock codeBlock = - ((PsiBlockStatement)bodyStatement).getCodeBlock(); + final PsiCodeBlock codeBlock = ((PsiBlockStatement)bodyStatement).getCodeBlock(); final PsiElement[] children = codeBlock.getChildren(); //skip the first and last members, to unwrap the block for (int i = 1; i < children.length - 1; i++) { final PsiElement child = children[i]; - appendElement(child, renameBreaks, breakLabelName, - switchStatementText - ); + appendElement(child, renameBreaks, breakLabelName, switchStatementText); } } else { - appendElement(bodyStatement, renameBreaks, breakLabelName, - switchStatementText - ); + appendElement(bodyStatement, renameBreaks, breakLabelName, switchStatementText); } - if (ControlFlowUtils.statementMayCompleteNormally( - bodyStatement)) { + if (ControlFlowUtils.statementMayCompleteNormally(bodyStatement)) { switchStatementText.append("break;"); } if (wrap) { @@ -382,39 +327,43 @@ public class ReplaceIfWithSwitchIntention extends Intention { } } - private static void appendElement(PsiElement element, - boolean renameBreakElements, - String breakLabelString, + private static void appendElement(PsiElement element, boolean renameBreakElements, String breakLabelString, @NonNls StringBuilder switchStatementText) { final String text = element.getText(); if (!renameBreakElements) { switchStatementText.append(text); } else if (element instanceof PsiBreakStatement) { - final PsiBreakStatement breakStatement = - (PsiBreakStatement)element; - final PsiIdentifier identifier = - breakStatement.getLabelIdentifier(); + final PsiBreakStatement breakStatement = (PsiBreakStatement)element; + final PsiIdentifier identifier = breakStatement.getLabelIdentifier(); if (identifier == null) { - switchStatementText.append("break "); - switchStatementText.append(breakLabelString); - switchStatementText.append(';'); + switchStatementText.append("break ").append(breakLabelString).append(';'); } else { switchStatementText.append(text); } } - else if (element instanceof PsiBlockStatement || - element instanceof PsiCodeBlock || - element instanceof PsiIfStatement) { + else if (element instanceof PsiBlockStatement || element instanceof PsiCodeBlock || element instanceof PsiIfStatement) { final PsiElement[] children = element.getChildren(); for (final PsiElement child : children) { - appendElement(child, renameBreakElements, breakLabelString, - switchStatementText); + appendElement(child, renameBreakElements, breakLabelString, switchStatementText); } } else { switchStatementText.append(text); } + final PsiElement lastChild = element.getLastChild(); + if (isEndOfLineComment(lastChild)) { + switchStatementText.append('\n'); + } + } + + private static boolean isEndOfLineComment(PsiElement element) { + if (!(element instanceof PsiComment)) { + return false; + } + final PsiComment comment = (PsiComment)element; + final IElementType tokenType = comment.getTokenType(); + return JavaTokenType.END_OF_LINE_COMMENT.equals(tokenType); } -} +}
\ No newline at end of file diff --git a/plugins/IntentionPowerPak/src/com/siyeh/ipp/switchtoif/SwitchUtils.java b/plugins/IntentionPowerPak/src/com/siyeh/ipp/switchtoif/SwitchUtils.java index b48e8b8526ca..4ca574870472 100644 --- a/plugins/IntentionPowerPak/src/com/siyeh/ipp/switchtoif/SwitchUtils.java +++ b/plugins/IntentionPowerPak/src/com/siyeh/ipp/switchtoif/SwitchUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2011 Dave Griffith, Bas Leijdekkers + * Copyright 2003-2013 Dave Griffith, Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,136 +21,117 @@ import com.intellij.psi.tree.IElementType; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.util.PsiUtil; import com.siyeh.ipp.psiutils.EquivalenceChecker; +import com.siyeh.ipp.psiutils.ParenthesesUtils; import com.siyeh.ipp.psiutils.SideEffectChecker; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.Nullable; -import java.util.List; - class SwitchUtils { - private SwitchUtils() { - } + private SwitchUtils() {} - private static boolean canBeCaseLabel(PsiExpression expression, - LanguageLevel languageLevel) { - if (expression == null) { - return false; + @Nullable + public static PsiExpression getSwitchExpression(PsiIfStatement statement) { + final PsiExpression condition = statement.getCondition(); + final LanguageLevel languageLevel = PsiUtil.getLanguageLevel(statement); + final PsiExpression possibleSwitchExpression = determinePossibleSwitchExpressions(condition, languageLevel); + if (!canBeSwitchExpression(possibleSwitchExpression, languageLevel)) { + return null; } - if (languageLevel.compareTo(LanguageLevel.JDK_1_5) >= 0 - && expression instanceof PsiReferenceExpression) { - final PsiElement referent = ((PsiReference)expression).resolve(); - if (referent instanceof PsiEnumConstant) { - return true; + while (true) { + if (!canBeMadeIntoCase(statement.getCondition(), possibleSwitchExpression, languageLevel)) { + break; + } + final PsiStatement elseBranch = statement.getElseBranch(); + if (!(elseBranch instanceof PsiIfStatement)) { + return possibleSwitchExpression; } + statement = (PsiIfStatement)elseBranch; } - final PsiType type = expression.getType(); - return type != null && - (type.equals(PsiType.INT) || - type.equals(PsiType.CHAR) || - type.equals(PsiType.LONG) || - type.equals(PsiType.SHORT)) && - PsiUtil.isConstantExpression(expression); + return null; } - public static boolean isUsedByStatementList(PsiLocalVariable variable, - List<PsiElement> elements) { - for (PsiElement element : elements) { - if (isUsedByStatement(variable, element)) { + private static boolean canBeMadeIntoCase(PsiExpression expression, PsiExpression switchExpression, LanguageLevel languageLevel) { + expression = ParenthesesUtils.stripParentheses(expression); + if (languageLevel.isAtLeast(LanguageLevel.JDK_1_7)) { + final PsiExpression stringSwitchExpression = determinePossibleStringSwitchExpression(expression); + if (EquivalenceChecker.expressionsAreEquivalent(switchExpression, stringSwitchExpression)) { return true; } } - return false; - } - - private static boolean isUsedByStatement(PsiLocalVariable variable, - PsiElement statement) { - final LocalVariableUsageVisitor visitor = - new LocalVariableUsageVisitor(variable); - statement.accept(visitor); - return visitor.isUsed(); - } - - public static String findUniqueLabelName(PsiStatement statement, - @NonNls String baseName) { - final PsiElement ancestor = - PsiTreeUtil.getParentOfType(statement, PsiMember.class); - if (!checkForLabel(baseName, ancestor)) { - return baseName; + if (!(expression instanceof PsiPolyadicExpression)) { + return false; } - int val = 1; - while (true) { - final String name = baseName + val; - if (!checkForLabel(name, ancestor)) { - return name; + final PsiPolyadicExpression polyadicExpression = (PsiPolyadicExpression)expression; + final IElementType operation = polyadicExpression.getOperationTokenType(); + final PsiExpression[] operands = polyadicExpression.getOperands(); + if (operation.equals(JavaTokenType.OROR)) { + for (PsiExpression operand : operands) { + if (!canBeMadeIntoCase(operand, switchExpression, languageLevel)) { + return false; + } } - val++; + return true; + } + else if (operation.equals(JavaTokenType.EQEQ) && operands.length == 2) { + return (canBeCaseLabel(operands[0], languageLevel) && EquivalenceChecker.expressionsAreEquivalent(switchExpression, operands[1])) || + (canBeCaseLabel(operands[1], languageLevel) && EquivalenceChecker.expressionsAreEquivalent(switchExpression, operands[0])); + } + else { + return false; } } - private static boolean checkForLabel(String name, PsiElement ancestor) { - final LabelSearchVisitor visitor = new LabelSearchVisitor(name); - ancestor.accept(visitor); - return visitor.isUsed(); - } - - @Nullable - public static PsiExpression getSwitchExpression(PsiIfStatement statement) { - final PsiExpression condition = statement.getCondition(); - final LanguageLevel languageLevel = - PsiUtil.getLanguageLevel(statement); - final PsiExpression possibleSwitchExpression = - determinePossibleSwitchExpressions(condition, languageLevel); - if (possibleSwitchExpression == null) { - return null; + private static boolean canBeSwitchExpression(PsiExpression expression, LanguageLevel languageLevel) { + if (expression == null || SideEffectChecker.mayHaveSideEffects(expression)) { + return false; } - if (SideEffectChecker.mayHaveSideEffects(possibleSwitchExpression)) { - return null; + final PsiType type = expression.getType(); + if (PsiType.CHAR.equals(type) || PsiType.BYTE.equals(type) || PsiType.SHORT.equals(type) || PsiType.INT.equals(type)) { + return true; } - while (true) { - final PsiExpression caseCondition = statement.getCondition(); - if (!canBeMadeIntoCase(caseCondition, possibleSwitchExpression, - languageLevel)) { - break; + else if (type instanceof PsiClassType) { + if (type.equalsToText(CommonClassNames.JAVA_LANG_CHARACTER) || type.equalsToText(CommonClassNames.JAVA_LANG_BYTE) || + type.equalsToText(CommonClassNames.JAVA_LANG_SHORT) || type.equalsToText(CommonClassNames.JAVA_LANG_INTEGER)) { + return true; } - final PsiStatement elseBranch = statement.getElseBranch(); - if (!(elseBranch instanceof PsiIfStatement)) { - return possibleSwitchExpression; + if (languageLevel.isAtLeast(LanguageLevel.JDK_1_5)) { + final PsiClassType classType = (PsiClassType)type; + final PsiClass aClass = classType.resolve(); + if (aClass != null && aClass.isEnum()) { + return true; + } + } + if (languageLevel.isAtLeast(LanguageLevel.JDK_1_7) && type.equalsToText(CommonClassNames.JAVA_LANG_STRING)) { + return true; } - statement = (PsiIfStatement)elseBranch; } - return null; + return false; } - private static PsiExpression determinePossibleSwitchExpressions( - PsiExpression expression, LanguageLevel languageLevel) { - while (expression instanceof PsiParenthesizedExpression) { - final PsiParenthesizedExpression parenthesizedExpression = - (PsiParenthesizedExpression)expression; - expression = parenthesizedExpression.getExpression(); - } + private static PsiExpression determinePossibleSwitchExpressions(PsiExpression expression, LanguageLevel languageLevel) { + expression = ParenthesesUtils.stripParentheses(expression); if (expression == null) { return null; } - if (languageLevel.compareTo(LanguageLevel.JDK_1_7) >= 0) { - final PsiExpression jdk17Expression = - determinePossibleStringSwitchExpression(expression); + if (languageLevel.isAtLeast(LanguageLevel.JDK_1_7)) { + final PsiExpression jdk17Expression = determinePossibleStringSwitchExpression(expression); if (jdk17Expression != null) { return jdk17Expression; } } - if (!(expression instanceof PsiBinaryExpression)) { + if (!(expression instanceof PsiPolyadicExpression)) { return null; } - final PsiBinaryExpression binaryExpression = - (PsiBinaryExpression)expression; - final IElementType operation = binaryExpression.getOperationTokenType(); - final PsiExpression lhs = binaryExpression.getLOperand(); - final PsiExpression rhs = binaryExpression.getROperand(); - if (operation.equals(JavaTokenType.OROR)) { - return determinePossibleSwitchExpressions(lhs, languageLevel); + final PsiPolyadicExpression polyadicExpression = (PsiPolyadicExpression)expression; + final IElementType operation = polyadicExpression.getOperationTokenType(); + final PsiExpression[] operands = polyadicExpression.getOperands(); + if (operation.equals(JavaTokenType.OROR) && operands.length > 0) { + return determinePossibleSwitchExpressions(operands[0], languageLevel); } - else if (operation.equals(JavaTokenType.EQEQ)) { + else if (operation.equals(JavaTokenType.EQEQ) && operands.length == 2) { + final PsiExpression lhs = operands[0]; + final PsiExpression rhs = operands[1]; if (canBeCaseLabel(lhs, languageLevel)) { return rhs; } @@ -161,39 +142,32 @@ class SwitchUtils { return null; } - private static PsiExpression determinePossibleStringSwitchExpression( - PsiExpression expression) { + private static PsiExpression determinePossibleStringSwitchExpression(PsiExpression expression) { if (!(expression instanceof PsiMethodCallExpression)) { return null; } - final PsiMethodCallExpression methodCallExpression = - (PsiMethodCallExpression)expression; - final PsiReferenceExpression methodExpression = - methodCallExpression.getMethodExpression(); - @NonNls final String referenceName = - methodExpression.getReferenceName(); + final PsiMethodCallExpression methodCallExpression = (PsiMethodCallExpression)expression; + final PsiReferenceExpression methodExpression = methodCallExpression.getMethodExpression(); + @NonNls final String referenceName = methodExpression.getReferenceName(); if (!"equals".equals(referenceName)) { return null; } - final PsiExpression qualifierExpression = - methodExpression.getQualifierExpression(); + final PsiExpression qualifierExpression = methodExpression.getQualifierExpression(); if (qualifierExpression == null) { return null; } final PsiType type = qualifierExpression.getType(); - if (type == null || !type.equalsToText("java.lang.String")) { + if (type == null || !type.equalsToText(CommonClassNames.JAVA_LANG_STRING)) { return null; } - final PsiExpressionList argumentList = - methodCallExpression.getArgumentList(); + final PsiExpressionList argumentList = methodCallExpression.getArgumentList(); final PsiExpression[] arguments = argumentList.getExpressions(); if (arguments.length != 1) { return null; } final PsiExpression argument = arguments[0]; final PsiType argumentType = argument.getType(); - if (argumentType == null || - !argumentType.equalsToText("java.lang.String")) { + if (argumentType == null || !argumentType.equalsToText(CommonClassNames.JAVA_LANG_STRING)) { return null; } if (PsiUtil.isConstantExpression(qualifierExpression)) { @@ -205,45 +179,39 @@ class SwitchUtils { return null; } - private static boolean canBeMadeIntoCase( - PsiExpression expression, PsiExpression caseExpression, - LanguageLevel languageLevel) { - while (expression instanceof PsiParenthesizedExpression) { - final PsiParenthesizedExpression parenthesizedExpression = - (PsiParenthesizedExpression)expression; - expression = parenthesizedExpression.getExpression(); - } - if (languageLevel.compareTo(LanguageLevel.JDK_1_7) >= 0) { - final PsiExpression stringCaseExpression = - determinePossibleStringSwitchExpression(expression); - if (EquivalenceChecker.expressionsAreEquivalent(caseExpression, - stringCaseExpression)) { + private static boolean canBeCaseLabel(PsiExpression expression, LanguageLevel languageLevel) { + if (expression == null) { + return false; + } + if (languageLevel.isAtLeast(LanguageLevel.JDK_1_5) && expression instanceof PsiReferenceExpression) { + final PsiElement referent = ((PsiReference)expression).resolve(); + if (referent instanceof PsiEnumConstant) { return true; } } - if (!(expression instanceof PsiBinaryExpression)) { - return false; - } - final PsiBinaryExpression binaryExpression = - (PsiBinaryExpression)expression; - final IElementType operation = binaryExpression.getOperationTokenType(); - final PsiExpression lOperand = binaryExpression.getLOperand(); - final PsiExpression rhs = binaryExpression.getROperand(); - if (operation.equals(JavaTokenType.OROR)) { - return canBeMadeIntoCase(lOperand, caseExpression, languageLevel) && - canBeMadeIntoCase(rhs, caseExpression, languageLevel); - } - else if (operation.equals(JavaTokenType.EQEQ)) { - return (canBeCaseLabel(lOperand, languageLevel) && - EquivalenceChecker.expressionsAreEquivalent( - caseExpression, rhs)) - || - (canBeCaseLabel(rhs, languageLevel) && - EquivalenceChecker.expressionsAreEquivalent( - caseExpression, lOperand)); + final PsiType type = expression.getType(); + return (PsiType.INT.equals(type) || PsiType.SHORT.equals(type) || PsiType.BYTE.equals(type) || PsiType.CHAR.equals(type)) && + PsiUtil.isConstantExpression(expression); + } + + public static String findUniqueLabelName(PsiStatement statement, @NonNls String baseName) { + final PsiElement ancestor = PsiTreeUtil.getParentOfType(statement, PsiMember.class); + if (!checkForLabel(baseName, ancestor)) { + return baseName; } - else { - return false; + int val = 1; + while (true) { + final String name = baseName + val; + if (!checkForLabel(name, ancestor)) { + return name; + } + val++; } } + + private static boolean checkForLabel(String name, PsiElement ancestor) { + final LabelSearchVisitor visitor = new LabelSearchVisitor(name); + ancestor.accept(visitor); + return visitor.isUsed(); + } }
\ No newline at end of file diff --git a/plugins/IntentionPowerPak/src/com/siyeh/ipp/types/ReplaceMethodRefWithLambdaIntention.java b/plugins/IntentionPowerPak/src/com/siyeh/ipp/types/ReplaceMethodRefWithLambdaIntention.java index f0d54848106c..8ffc5eebfbe0 100644 --- a/plugins/IntentionPowerPak/src/com/siyeh/ipp/types/ReplaceMethodRefWithLambdaIntention.java +++ b/plugins/IntentionPowerPak/src/com/siyeh/ipp/types/ReplaceMethodRefWithLambdaIntention.java @@ -82,15 +82,18 @@ public class ReplaceMethodRefWithLambdaIntention extends Intention { buf.append("{"); } final PsiElement qualifier = referenceExpression.getQualifier(); - boolean isReceiver = false; + PsiClass containingClass = null; if (resolveElement instanceof PsiMethod) { - final PsiClass containingClass = ((PsiMember)resolveElement).getContainingClass(); + containingClass = ((PsiMember)resolveElement).getContainingClass(); LOG.assertTrue(containingClass != null); - isReceiver = PsiMethodReferenceUtil.isReceiverType(functionalInterfaceType, containingClass, (PsiMethod)resolveElement); } else if (resolveElement instanceof PsiClass) { - isReceiver = PsiMethodReferenceUtil.isReceiverType(functionalInterfaceType, (PsiClass)resolveElement, (PsiMethod)null); + containingClass = (PsiClass)resolveElement; } + final boolean onArrayRef = + JavaPsiFacade.getElementFactory(element.getProject()).getArrayClass(PsiUtil.getLanguageLevel(element)) == containingClass; + boolean isReceiver = PsiMethodReferenceUtil.isReceiverType(functionalInterfaceType, containingClass, resolveElement instanceof PsiMethod ? (PsiMethod)resolveElement : null); + final PsiElement referenceNameElement = referenceExpression.getReferenceNameElement(); if (isReceiver){ buf.append(parameters[0].getName()).append("."); @@ -113,43 +116,52 @@ public class ReplaceMethodRefWithLambdaIntention extends Intention { if (referenceNameElement instanceof PsiKeyword) { //class name buf.append(" "); - buf.append(((PsiMember)resolveElement).getName()); - - final PsiSubstitutor substitutor = resolveResult.getSubstitutor(); - - PsiClass containingClass; - if (resolveElement instanceof PsiClass) { - containingClass = (PsiClass)resolveElement; - } else { - containingClass = ((PsiMember)resolveElement).getContainingClass(); - } - - LOG.assertTrue(containingClass != null); - if (containingClass.hasTypeParameters() && !PsiUtil.isRawSubstitutor(containingClass, substitutor)) { - buf.append("<").append(StringUtil.join(containingClass.getTypeParameters(), new Function<PsiTypeParameter, String>() { - @Override - public String fun(PsiTypeParameter parameter) { - final PsiType psiType = substitutor.substitute(parameter); - LOG.assertTrue(psiType != null); - return psiType.getCanonicalText(); + if (onArrayRef) { + if (qualifier instanceof PsiTypeElement) { + final PsiType type = ((PsiTypeElement)qualifier).getType(); + int dim = type.getArrayDimensions(); + buf.append(type.getDeepComponentType().getCanonicalText()); + buf.append("["); + buf.append(map.get(parameters[0])); + buf.append("]"); + while (--dim > 0) { + buf.append("[]"); } - }, ", ")).append(">"); + } + } else { + buf.append(((PsiMember)resolveElement).getName()); + + final PsiSubstitutor substitutor = resolveResult.getSubstitutor(); + + LOG.assertTrue(containingClass != null); + if (containingClass.hasTypeParameters() && !PsiUtil.isRawSubstitutor(containingClass, substitutor)) { + buf.append("<").append(StringUtil.join(containingClass.getTypeParameters(), new Function<PsiTypeParameter, String>() { + @Override + public String fun(PsiTypeParameter parameter) { + final PsiType psiType = substitutor.substitute(parameter); + LOG.assertTrue(psiType != null); + return psiType.getCanonicalText(); + } + }, ", ")).append(">"); + } } } - //param list - buf.append("("); - boolean first = true; - for (int i = isReceiver ? 1 : 0; i < parameters.length; i++) { - PsiParameter parameter = parameters[i]; - if (!first) { - buf.append(", "); - } else { - first = false; + if (!onArrayRef || isReceiver) { + //param list + buf.append("("); + boolean first = true; + for (int i = isReceiver ? 1 : 0; i < parameters.length; i++) { + PsiParameter parameter = parameters[i]; + if (!first) { + buf.append(", "); + } else { + first = false; + } + buf.append(map.get(parameter)); } - buf.append(map.get(parameter)); + buf.append(")"); } - buf.append(")"); if (needBraces) { buf.append(";}"); |