diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/performance/KeySetIterationMayUseEntrySetInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/performance/KeySetIterationMayUseEntrySetInspection.java index ef5988e6242b..75dfb5785615 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/performance/KeySetIterationMayUseEntrySetInspection.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/performance/KeySetIterationMayUseEntrySetInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2008-2014 Bas Leijdekkers + * Copyright 2008-2017 Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,12 +22,13 @@ import com.intellij.psi.codeStyle.JavaCodeStyleManager; import com.intellij.psi.codeStyle.SuggestedNameInfo; import com.intellij.psi.codeStyle.VariableKind; import com.intellij.psi.util.PsiTreeUtil; -import com.intellij.util.IncorrectOperationException; +import com.intellij.psi.util.RedundantCastUtil; import com.siyeh.InspectionGadgetsBundle; import com.siyeh.ig.BaseInspection; import com.siyeh.ig.BaseInspectionVisitor; import com.siyeh.ig.InspectionGadgetsFix; import com.siyeh.ig.PsiReplacementUtil; +import com.siyeh.ig.psiutils.ParenthesesUtils; import com.siyeh.ig.psiutils.TypeUtils; import com.siyeh.ig.psiutils.VariableAccessUtils; import org.jetbrains.annotations.Nls; @@ -70,9 +71,9 @@ public class KeySetIterationMayUseEntrySetInspection extends BaseInspection { } @Override - protected void doFix(Project project, ProblemDescriptor descriptor) throws IncorrectOperationException { + protected void doFix(Project project, ProblemDescriptor descriptor) { final PsiElement element = descriptor.getPsiElement(); - final PsiElement parent = element.getParent(); + final PsiElement parent = ParenthesesUtils.getParentSkipParentheses(element); if (!(parent instanceof PsiForeachStatement)) { return; } @@ -140,7 +141,7 @@ public class KeySetIterationMayUseEntrySetInspection extends BaseInspection { replaceParameterAccess(parameter, variableName, map, foreachStatement); } final PsiElementFactory factory = JavaPsiFacade.getInstance(project).getElementFactory(); - final PsiParameter newParameter = factory.createParameter( variableName, parameterType); + final PsiParameter newParameter = factory.createParameter(variableName, parameterType); if (parameter.hasModifierProperty(PsiModifier.FINAL)) { final PsiModifierList modifierList = newParameter.getModifierList(); if (modifierList != null) { @@ -157,12 +158,19 @@ public class KeySetIterationMayUseEntrySetInspection extends BaseInspection { final ParameterAccessCollector collector = new ParameterAccessCollector(parameter, map); context.accept(collector); final List accesses = collector.getParameterAccesses(); + final String keyAccess = '(' + parameter.getType().getCanonicalText() + ')' + variableName + ".getKey()"; for (PsiExpression access : accesses) { if (access instanceof PsiMethodCallExpression) { PsiReplacementUtil.replaceExpression(access, variableName + ".getValue()"); } else { - PsiReplacementUtil.replaceExpression(access, variableName + ".getKey()"); + final PsiTypeCastExpression typeCastExpression = (PsiTypeCastExpression) + PsiReplacementUtil.replaceExpressionAndShorten(access, keyAccess); + if (RedundantCastUtil.isCastRedundant(typeCastExpression)) { + final PsiExpression operand = typeCastExpression.getOperand(); + assert operand != null; + typeCastExpression.replace(operand); + } } } } @@ -192,7 +200,7 @@ public class KeySetIterationMayUseEntrySetInspection extends BaseInspection { private final List parameterAccesses = new ArrayList<>(); - private ParameterAccessCollector(PsiParameter parameter, PsiElement map) { + ParameterAccessCollector(PsiParameter parameter, PsiElement map) { this.parameter = parameter; parameterName = parameter.getName(); this.map = map; @@ -212,17 +220,12 @@ public class KeySetIterationMayUseEntrySetInspection extends BaseInspection { if (!parameter.equals(target)) { return; } - try { - if (!collectValueUsage(expression)) { - parameterAccesses.add(expression); - } - } - catch (IncorrectOperationException e) { - throw new RuntimeException(e); + if (!collectValueUsage(expression)) { + parameterAccesses.add(expression); } } - private boolean collectValueUsage(PsiReferenceExpression expression) throws IncorrectOperationException { + private boolean collectValueUsage(PsiReferenceExpression expression) { final PsiElement parent = expression.getParent(); if (!(parent instanceof PsiExpressionList)) { return false; @@ -255,7 +258,7 @@ public class KeySetIterationMayUseEntrySetInspection extends BaseInspection { return true; } - private List getParameterAccesses() { + List getParameterAccesses() { Collections.reverse(parameterAccesses); return parameterAccesses; } @@ -267,13 +270,12 @@ public class KeySetIterationMayUseEntrySetInspection extends BaseInspection { return new KeySetIterationMayUseEntrySetVisitor(); } - private static class KeySetIterationMayUseEntrySetVisitor - extends BaseInspectionVisitor { + private static class KeySetIterationMayUseEntrySetVisitor extends BaseInspectionVisitor { @Override public void visitForeachStatement(PsiForeachStatement statement) { super.visitForeachStatement(statement); - final PsiExpression iteratedValue = statement.getIteratedValue(); + final PsiExpression iteratedValue = ParenthesesUtils.stripParentheses(statement.getIteratedValue()); if (iteratedValue == null) { return; } diff --git a/plugins/InspectionGadgets/test/com/siyeh/igfixes/performance/key_set_with_entry_set/CastNeeded1.after.java b/plugins/InspectionGadgets/test/com/siyeh/igfixes/performance/key_set_with_entry_set/CastNeeded1.after.java new file mode 100644 index 000000000000..0a84108ad87f --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igfixes/performance/key_set_with_entry_set/CastNeeded1.after.java @@ -0,0 +1,12 @@ +import java.util.HashMap; +import java.util.Map; + +class CastNeeded1 { + + void m() { + HashMap map = new HashMap<>(); + for (Map.Entry longIntegerEntry : ((map.entrySet()))) { + pass((int) (long) longIntegerEntry.getKey(), longIntegerEntry.getValue()); + } + } +} \ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igfixes/performance/key_set_with_entry_set/CastNeeded1.java b/plugins/InspectionGadgets/test/com/siyeh/igfixes/performance/key_set_with_entry_set/CastNeeded1.java new file mode 100644 index 000000000000..496f4dc37ef7 --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igfixes/performance/key_set_with_entry_set/CastNeeded1.java @@ -0,0 +1,11 @@ +import java.util.HashMap; + +class CastNeeded1 { + + void m() { + HashMap map = new HashMap<>(); + for (long l : ((map.keySet()))) { + pass((int)l, map.get(l)); + } + } +} \ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igfixes/performance/key_set_with_entry_set/CastNeeded2.after.java b/plugins/InspectionGadgets/test/com/siyeh/igfixes/performance/key_set_with_entry_set/CastNeeded2.after.java new file mode 100644 index 000000000000..8ef3a5b34b00 --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igfixes/performance/key_set_with_entry_set/CastNeeded2.after.java @@ -0,0 +1,13 @@ +import java.util.HashMap; +import java.util.Map; + +class CastNeeded2 { + + void m() { + HashMap map2 = new HashMap<>(); + for (Map.Entry stringStringEntry : map2.entrySet()) { + System.out.println((Number) (Object) stringStringEntry.getKey()); + System.out.println(stringStringEntry.getValue()); + } + } +} \ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igfixes/performance/key_set_with_entry_set/CastNeeded2.java b/plugins/InspectionGadgets/test/com/siyeh/igfixes/performance/key_set_with_entry_set/CastNeeded2.java new file mode 100644 index 000000000000..74f3cf203069 --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igfixes/performance/key_set_with_entry_set/CastNeeded2.java @@ -0,0 +1,12 @@ +import java.util.HashMap; + +class CastNeeded2 { + + void m() { + HashMap map2 = new HashMap<>(); + for (Object o : map2.keySet()) { + System.out.println((Number) o); + System.out.println(map2.get(o)); + } + } +} \ No newline at end of file diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/fixes/performance/KeySetIterationMayUseEntrySetFixTest.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/fixes/performance/KeySetIterationMayUseEntrySetFixTest.java index cc77256d21db..1979d96da21e 100644 --- a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/fixes/performance/KeySetIterationMayUseEntrySetFixTest.java +++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/fixes/performance/KeySetIterationMayUseEntrySetFixTest.java @@ -15,6 +15,7 @@ */ package com.siyeh.ig.fixes.performance; +import com.siyeh.InspectionGadgetsBundle; import com.siyeh.ig.IGQuickFixesTestCase; import com.siyeh.ig.performance.KeySetIterationMayUseEntrySetInspection; @@ -25,8 +26,11 @@ public class KeySetIterationMayUseEntrySetFixTest extends IGQuickFixesTestCase { super.setUp(); myFixture.enableInspections(new KeySetIterationMayUseEntrySetInspection()); myRelativePath = "performance/key_set_with_entry_set"; + myDefaultHint = InspectionGadgetsBundle.message("key.set.iteration.may.use.entry.set.quickfix"); } - public void testSimple() { doTest("Replace with 'entrySet()' iteration"); } + public void testSimple() { doTest(); } + public void testCastNeeded1() { doTest(); } + public void testCastNeeded2() { doTest(); } } \ No newline at end of file