diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/java18api/Java8CollectionsApiInspection.java b/java/java-analysis-impl/src/com/intellij/codeInspection/java18api/Java8CollectionsApiInspection.java new file mode 100644 index 000000000000..23e631cdaf78 --- /dev/null +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/java18api/Java8CollectionsApiInspection.java @@ -0,0 +1,238 @@ +/* + * Copyright 2000-2016 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. + * 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.intellij.codeInspection.java18api; + +import com.intellij.codeInsight.daemon.QuickFixBundle; +import com.intellij.codeInspection.BaseJavaBatchLocalInspectionTool; +import com.intellij.codeInspection.ProblemsHolder; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.*; +import com.intellij.psi.util.PsiUtil; +import com.siyeh.ig.psiutils.EquivalenceChecker; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +/** + * @author Dmitry Batkovich + */ +public class Java8CollectionsApiInspection extends BaseJavaBatchLocalInspectionTool { + private final static Logger LOG = Logger.getInstance(Java8CollectionsApiInspection.class); + + @NotNull + @Override + public PsiElementVisitor buildVisitor(@NotNull final ProblemsHolder holder, boolean isOnTheFly) { + if (!PsiUtil.isLanguageLevel8OrHigher(holder.getFile())) { + return PsiElementVisitor.EMPTY_VISITOR; + } + return new JavaElementVisitor() { + @Override + public void visitConditionalExpression(PsiConditionalExpression expression) { + final ConditionInfo conditionInfo = extractConditionInfo(expression.getCondition()); + if (conditionInfo == null) return; + final PsiExpression thenExpression = expression.getThenExpression(); + final PsiExpression elseExpression = expression.getElseExpression(); + if (thenExpression == null || elseExpression == null) return; + analyzeCorrespondenceOfPutAndGet(conditionInfo.isInverted() ? thenExpression : elseExpression, + conditionInfo.isInverted() ? elseExpression : thenExpression, + conditionInfo.getQualifier(), conditionInfo.getContainsKey(), + holder, expression); + } + + @Override + public void visitIfStatement(PsiIfStatement statement) { + final PsiExpression condition = statement.getCondition(); + final ConditionInfo conditionInfo = extractConditionInfo(condition); + if (conditionInfo == null) return; + PsiStatement maybeGetBranch = conditionInfo.isInverted() ? statement.getElseBranch() : statement.getThenBranch(); + if (maybeGetBranch instanceof PsiBlockStatement) { + final PsiStatement[] getBranchStatements = ((PsiBlockStatement)maybeGetBranch).getCodeBlock().getStatements(); + if (getBranchStatements.length > 1) { + return; + } + maybeGetBranch = getBranchStatements.length == 0 ? null : getBranchStatements[0]; + } + final PsiStatement branch = conditionInfo.isInverted() ? statement.getThenBranch() : statement.getElseBranch(); + final PsiStatement maybePutStatement; + if (branch instanceof PsiBlockStatement) { + final PsiStatement[] statements = ((PsiBlockStatement)branch).getCodeBlock().getStatements(); + if (statements.length == 0) return; + if (statements.length != 1) { + return; + } + maybePutStatement = statements[statements.length - 1]; + } + else { + maybePutStatement = branch; + } + LOG.assertTrue(maybePutStatement != null); + analyzeCorrespondenceOfPutAndGet(maybePutStatement, maybeGetBranch, conditionInfo.getQualifier(), conditionInfo.getContainsKey(), + holder, statement); + } + }; + } + + @Nullable + private static ConditionInfo extractConditionInfo(PsiExpression condition) { + boolean inverted = false; + final PsiMethodCallExpression conditionMethodCall; + if (condition instanceof PsiPrefixExpression) { + final PsiPrefixExpression prefixExpression = (PsiPrefixExpression)condition; + if (JavaTokenType.EXCL.equals(prefixExpression.getOperationSign().getTokenType()) && + prefixExpression.getOperand() instanceof PsiMethodCallExpression) { + conditionMethodCall = (PsiMethodCallExpression)prefixExpression.getOperand(); + inverted = true; + } + else { + return null; + } + } + else if (condition instanceof PsiMethodCallExpression) { + conditionMethodCall = (PsiMethodCallExpression)condition; + } + else { + return null; + } + if (!isJavaUtilMapMethodWithName(conditionMethodCall, "containsKey")) { + return null; + } + final PsiExpression containsQualifier = conditionMethodCall.getMethodExpression().getQualifierExpression(); + if (containsQualifier == null) { + return null; + } + final PsiExpression[] expressions = conditionMethodCall.getArgumentList().getExpressions(); + if (expressions.length != 1) { + return null; + } + PsiExpression containsKey = expressions[0]; + return new ConditionInfo(containsQualifier, containsKey, inverted); + } + + private static void analyzeCorrespondenceOfPutAndGet(@NotNull PsiElement adjustedElseBranch, + @Nullable PsiElement adjustedThenBranch, + @NotNull PsiExpression containsQualifier, + @NotNull PsiExpression containsKey, + @NotNull ProblemsHolder holder, + @NotNull PsiElement context) { + final PsiElement maybePutMethodCall; + final PsiElement maybeGetMethodCall; + if (adjustedThenBranch == null) { + maybeGetMethodCall = null; + if (adjustedElseBranch instanceof PsiExpressionStatement) { + final PsiExpression expression = ((PsiExpressionStatement)adjustedElseBranch).getExpression(); + if (expression instanceof PsiMethodCallExpression && isJavaUtilMapMethodWithName((PsiMethodCallExpression)expression, "put")) { + maybePutMethodCall = expression; + } + else { + maybePutMethodCall = null; + } + } + else { + maybePutMethodCall = null; + } + } + else { + if (adjustedElseBranch instanceof PsiStatement && adjustedThenBranch instanceof PsiStatement) { + final EquivalenceChecker.Decision decision = EquivalenceChecker.statementsAreEquivalentDecision((PsiStatement)adjustedElseBranch, + (PsiStatement)adjustedThenBranch); + maybePutMethodCall = decision.getLeftDiff(); + maybeGetMethodCall = decision.getRightDiff(); + } + else { + maybePutMethodCall = adjustedElseBranch; + maybeGetMethodCall = adjustedThenBranch; + } + } + if (maybePutMethodCall instanceof PsiMethodCallExpression && + (maybeGetMethodCall == null || maybeGetMethodCall instanceof PsiMethodCallExpression)) { + final PsiMethodCallExpression putMethodCall = (PsiMethodCallExpression)maybePutMethodCall; + final PsiMethodCallExpression getMethodCall = (PsiMethodCallExpression)maybeGetMethodCall; + final PsiExpression putQualifier = putMethodCall.getMethodExpression().getQualifierExpression(); + final PsiExpression getQualifier = getMethodCall == null ? null : getMethodCall.getMethodExpression().getQualifierExpression(); + if ((getMethodCall == null || EquivalenceChecker.expressionsAreEquivalent(putQualifier, getQualifier)) && + EquivalenceChecker.expressionsAreEquivalent(putQualifier, containsQualifier) && + isJavaUtilMapMethodWithName(putMethodCall, "put") && + (getMethodCall == null || isJavaUtilMapMethodWithName(getMethodCall, "get"))) { + + PsiExpression getArgument; + if (getMethodCall != null) { + final PsiExpression[] arguments = getMethodCall.getArgumentList().getExpressions(); + if (arguments.length != 1) { + return; + } + getArgument = arguments[0]; + } + else { + getArgument = null; + } + + final PsiExpression[] putArguments = putMethodCall.getArgumentList().getExpressions(); + if (putArguments.length != 2) { + return; + } + PsiExpression putKeyArgument = putArguments[0]; + + if (EquivalenceChecker.expressionsAreEquivalent(containsKey, putKeyArgument) && + (getArgument == null || EquivalenceChecker.expressionsAreEquivalent(getArgument, putKeyArgument))) { + holder.registerProblem(context, QuickFixBundle.message("java.8.collections.api.inspection.description"), + new ReplaceWithMapPutIfAbsentFix(putMethodCall)); + } + } + } + } + + private static boolean isJavaUtilMapMethodWithName(@NotNull PsiMethodCallExpression methodCallExpression, @NotNull String expectedName) { + if (!expectedName.equals(methodCallExpression.getMethodExpression().getReferenceName())) { + return false; + } + final PsiMethod method = methodCallExpression.resolveMethod(); + if (method == null) return false; + PsiMethod[] superMethods = method.findDeepestSuperMethods(); + if (superMethods.length == 0) { + superMethods = new PsiMethod[]{method}; + } + for (PsiMethod psiMethod : superMethods) { + final PsiClass aClass = psiMethod.getContainingClass(); + if (aClass != null && CommonClassNames.JAVA_UTIL_MAP.equals(aClass.getQualifiedName())) { + return true; + } + } + return false; + } + + private static class ConditionInfo { + private final PsiExpression myQualifier; + private final PsiExpression myContainsKey; + private final boolean myInverted; + + private ConditionInfo(PsiExpression qualifier, PsiExpression containsKey, boolean inverted) { + myQualifier = qualifier; + myContainsKey = containsKey; + myInverted = inverted; + } + + public PsiExpression getQualifier() { + return myQualifier; + } + + public PsiExpression getContainsKey() { + return myContainsKey; + } + + public boolean isInverted() { + return myInverted; + } + } +} \ No newline at end of file diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/java18api/ReplaceWithMapPutIfAbsentFix.java b/java/java-analysis-impl/src/com/intellij/codeInspection/java18api/ReplaceWithMapPutIfAbsentFix.java new file mode 100644 index 000000000000..a95825919bc8 --- /dev/null +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/java18api/ReplaceWithMapPutIfAbsentFix.java @@ -0,0 +1,145 @@ +/* + * Copyright 2000-2016 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. + * 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.intellij.codeInspection.java18api; + +import com.intellij.codeInsight.daemon.QuickFixBundle; +import com.intellij.codeInspection.LocalQuickFix; +import com.intellij.codeInspection.ProblemDescriptor; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Couple; +import com.intellij.openapi.util.TextRange; +import com.intellij.psi.*; +import com.intellij.psi.util.PsiTreeUtil; +import org.jetbrains.annotations.Nls; +import org.jetbrains.annotations.NotNull; + + +/** + * @author Dmitry Batkovich + */ +public class ReplaceWithMapPutIfAbsentFix implements LocalQuickFix { + private final SmartPsiElementPointer myPutExpressionPointer; + + public ReplaceWithMapPutIfAbsentFix(PsiMethodCallExpression putExpression) { + final SmartPointerManager smartPointerManager = SmartPointerManager.getInstance(putExpression.getProject()); + myPutExpressionPointer = smartPointerManager.createSmartPsiElementPointer(putExpression); + } + + @Override + public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) { + final PsiElement conditionalOperator = descriptor.getPsiElement(); + if (conditionalOperator == null) return; + final ConditionalOperatorHelper operatorHelper = getHelper(conditionalOperator); + + final PsiMethodCallExpression putExpression = myPutExpressionPointer.getElement(); + if (putExpression == null) return; + + PsiElement putContainingBranch = null; + for (PsiElement branch : operatorHelper.getBranches(conditionalOperator)) { + if (branch != null && PsiTreeUtil.isAncestor(branch, putExpression, false)) { + putContainingBranch = branch; + break; + } + } + if (putContainingBranch == null) return; + + final PsiExpression[] arguments = putExpression.getArgumentList().getExpressions(); + final PsiElement qualifier = putExpression.getMethodExpression().getQualifier(); + if (qualifier == null) { + return; + } + + final PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(project); + + final PsiElement putContainingElement = operatorHelper.getPutContainingElement(putExpression); + final Couple boundText = getBoundText(putContainingElement, putExpression); + + final PsiStatement newStatement = elementFactory.createStatementFromText(boundText.getFirst() + qualifier.getText() + ".putIfAbsent" + + "(" + arguments[0].getText() + "," + + putExpression.getArgumentList().getExpressions()[1].getText() + + ")" + boundText.getSecond(), conditionalOperator); + conditionalOperator.replace(newStatement); + } + + private static Couple getBoundText(@NotNull PsiElement parent, @NotNull PsiElement child) { + final TextRange childRange = child.getTextRange(); + final int parentStartOffset = parent.getTextRange().getStartOffset(); + final String parentText = parent.getText(); + return Couple.of(parentText.substring(0, childRange.getStartOffset() - parentStartOffset), + parentText.substring(childRange.getEndOffset() - parentStartOffset)); + } + + @Nls + @NotNull + @Override + public String getFamilyName() { + return QuickFixBundle.message("java.8.collections.api.inspection.fix.family.name"); + } + + @Nls + @NotNull + @Override + public String getName() { + return QuickFixBundle.message("java.8.collections.api.inspection.fix.text", "putIfAbsent"); + } + + private static ConditionalOperatorHelper getHelper(PsiElement element) { + return element instanceof PsiConditionalExpression ? new ConditionalExpressionHelper() : new IfStatementHelper(); + } + + interface ConditionalOperatorHelper { + @NotNull + PsiElement[] getBranches(PsiElement element); + + @NotNull + PsiElement getPutContainingElement(PsiElement putElement); + } + + private static class ConditionalExpressionHelper implements ConditionalOperatorHelper { + @NotNull + @Override + public PsiElement[] getBranches(PsiElement element) { + final PsiConditionalExpression conditionalExpression = (PsiConditionalExpression)element; + return new PsiElement[]{conditionalExpression.getThenExpression(), conditionalExpression.getElseExpression()}; + } + + @NotNull + @Override + public PsiElement getPutContainingElement(PsiElement putElement) { + for (PsiElement element : getBranches(PsiTreeUtil.getParentOfType(putElement, PsiConditionalExpression.class))) { + if (PsiTreeUtil.isAncestor(element, putElement, false)) { + return element; + } + } + throw new AssertionError(); + } + } + + private static class IfStatementHelper implements ConditionalOperatorHelper { + @NotNull + @Override + public PsiElement[] getBranches(PsiElement element) { + final PsiIfStatement ifStatement = (PsiIfStatement)element; + return new PsiElement[]{ifStatement.getThenBranch(), ifStatement.getElseBranch()}; + } + + @NotNull + @Override + public PsiElement getPutContainingElement(PsiElement putElement) { + return PsiTreeUtil.getParentOfType(putElement, PsiStatement.class); + } + } +} diff --git a/java/java-tests/testData/inspection/java8CollectionsApi/afterConditional.java b/java/java-tests/testData/inspection/java8CollectionsApi/afterConditional.java new file mode 100644 index 000000000000..fe4ab1775cd7 --- /dev/null +++ b/java/java-tests/testData/inspection/java8CollectionsApi/afterConditional.java @@ -0,0 +1,7 @@ +// "Replace with 'putIfAbsent' method call" "true" +import java.util.Map; +class Test { + void m1111(Map map) { + int i = map.putIfAbsent("asd", 123); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/inspection/java8CollectionsApi/afterConditional2.java b/java/java-tests/testData/inspection/java8CollectionsApi/afterConditional2.java new file mode 100644 index 000000000000..fe4ab1775cd7 --- /dev/null +++ b/java/java-tests/testData/inspection/java8CollectionsApi/afterConditional2.java @@ -0,0 +1,7 @@ +// "Replace with 'putIfAbsent' method call" "true" +import java.util.Map; +class Test { + void m1111(Map map) { + int i = map.putIfAbsent("asd", 123); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/inspection/java8CollectionsApi/afterSimpleIf.java b/java/java-tests/testData/inspection/java8CollectionsApi/afterSimpleIf.java new file mode 100644 index 000000000000..3d9c8fbacda2 --- /dev/null +++ b/java/java-tests/testData/inspection/java8CollectionsApi/afterSimpleIf.java @@ -0,0 +1,10 @@ +// "Replace with 'putIfAbsent' method call" "true" +import java.util.Map; + +class Test{ + + Integer m2(Map map) { + return map.putIfAbsent("asd", 123); + } + +} \ No newline at end of file diff --git a/java/java-tests/testData/inspection/java8CollectionsApi/beforeConditional.java b/java/java-tests/testData/inspection/java8CollectionsApi/beforeConditional.java new file mode 100644 index 000000000000..c0ccf8ec1dd9 --- /dev/null +++ b/java/java-tests/testData/inspection/java8CollectionsApi/beforeConditional.java @@ -0,0 +1,7 @@ +// "Replace with 'putIfAbsent' method call" "true" +import java.util.Map; +class Test { + void m1111(Map map) { + int i = !map.containsKey("asd") ? map.put("asd", 123) : map.get("asd"); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/inspection/java8CollectionsApi/beforeConditional2.java b/java/java-tests/testData/inspection/java8CollectionsApi/beforeConditional2.java new file mode 100644 index 000000000000..84cca2330e79 --- /dev/null +++ b/java/java-tests/testData/inspection/java8CollectionsApi/beforeConditional2.java @@ -0,0 +1,7 @@ +// "Replace with 'putIfAbsent' method call" "true" +import java.util.Map; +class Test { + void m1111(Map map) { + int i = map.containsKey("asd") ? map.get("asd") : map.put("asd", 123); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/inspection/java8CollectionsApi/beforePutBranchContainsOtherCode.java b/java/java-tests/testData/inspection/java8CollectionsApi/beforePutBranchContainsOtherCode.java new file mode 100644 index 000000000000..dfd1da2f0e60 --- /dev/null +++ b/java/java-tests/testData/inspection/java8CollectionsApi/beforePutBranchContainsOtherCode.java @@ -0,0 +1,10 @@ +// "Replace with 'putIfAbsent' method call" "false" +import java.util.Map; +class Test { + void m1(Map map) { + if (!map.containsKey("ads")) { + int i = 10; + map.put("ads", i); + } + } +} \ No newline at end of file diff --git a/java/java-tests/testData/inspection/java8CollectionsApi/beforeSimpleIf.java b/java/java-tests/testData/inspection/java8CollectionsApi/beforeSimpleIf.java new file mode 100644 index 000000000000..81098734cd4f --- /dev/null +++ b/java/java-tests/testData/inspection/java8CollectionsApi/beforeSimpleIf.java @@ -0,0 +1,14 @@ +// "Replace with 'putIfAbsent' method call" "true" +import java.util.Map; + +class Test{ + + Integer m2(Map map) { + if (!map.containsKey("asd")) { + return map.put("asd", 123); + } else { + return map.get("asd"); + } + } + +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/codeInspection/Java8CollectionsApiInspectionTest.java b/java/java-tests/testSrc/com/intellij/codeInspection/Java8CollectionsApiInspectionTest.java new file mode 100644 index 000000000000..726fb3fe8176 --- /dev/null +++ b/java/java-tests/testSrc/com/intellij/codeInspection/Java8CollectionsApiInspectionTest.java @@ -0,0 +1,43 @@ +/* + * Copyright 2000-2016 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. + * 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.intellij.codeInspection; + +import com.intellij.codeInsight.daemon.quickFix.LightQuickFixParameterizedTestCase; +import com.intellij.codeInspection.java18api.Java8CollectionsApiInspection; +import org.jetbrains.annotations.NotNull; + +/** + * @author Dmitry Batkovich + */ +public class Java8CollectionsApiInspectionTest extends LightQuickFixParameterizedTestCase { + + @NotNull + @Override + protected LocalInspectionTool[] configureLocalInspectionTools() { + return new LocalInspectionTool[]{ + new Java8CollectionsApiInspection(), + }; + } + + public void test() throws Exception { + doAllTests(); + } + + @Override + protected String getBasePath() { + return "/inspection/java8CollectionsApi"; + } +} diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/EquivalenceChecker.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/EquivalenceChecker.java index 1d4147c831b8..e58cccc6c334 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/EquivalenceChecker.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/EquivalenceChecker.java @@ -30,7 +30,7 @@ public class EquivalenceChecker { private EquivalenceChecker() {} private static final Decision EXACTLY_MATCHES = new Decision(true); - private static final Decision EXACTLY_UN_MATCHES = new Decision(false); + public static final Decision EXACTLY_UN_MATCHES = new Decision(false); public static class Decision { private final PsiElement myLeftDiff; @@ -540,7 +540,11 @@ public class EquivalenceChecker { @NotNull PsiReturnStatement statement2) { final PsiExpression returnValue1 = statement1.getReturnValue(); final PsiExpression returnValue2 = statement2.getReturnValue(); - return expressionsAreEquivalentDecision(returnValue1, returnValue2); + final Decision decision = expressionsAreEquivalentDecision(returnValue1, returnValue2); + if (decision.isExactUnMatches()) { + return new Decision(returnValue1, returnValue2); + } + return decision; } private static Decision throwstatementsAreEquivalentDecision( diff --git a/resources-en/src/inspectionDescriptions/Java8CollectionsApi.html b/resources-en/src/inspectionDescriptions/Java8CollectionsApi.html new file mode 100644 index 000000000000..ee30be059d44 --- /dev/null +++ b/resources-en/src/inspectionDescriptions/Java8CollectionsApi.html @@ -0,0 +1,11 @@ + + +Inspection detects usages of java's Map when they can be replaced with methods putIfAbsent. For example: +
+  if (!map.containsKey(aKey)) {
+    map.put(aKey, aValue);
+  }
+
+
+ + \ No newline at end of file diff --git a/resources-en/src/messages/QuickFixBundle.properties b/resources-en/src/messages/QuickFixBundle.properties index 0b853daccd46..0817009c165b 100644 --- a/resources-en/src/messages/QuickFixBundle.properties +++ b/resources-en/src/messages/QuickFixBundle.properties @@ -279,4 +279,7 @@ wrap.long.with.math.to.int.parameter.single.text=Wrap parameter using 'Math.toIn wrap.long.with.math.to.int.parameter.multiple.text=Wrap {0, choice, 1#1st|2#2nd|3#3rd|4#{0,number}th} parameter using ''Math.toIntExact()'' add.exception.from.field.initializer.to.constructor.throws.text=Add exception to class {0, choice, 0#default constructor|1#constructor|2#constructors} signature -add.exception.from.field.initializer.to.constructor.throws.family.text=Add exception to class constructors signature \ No newline at end of file +add.exception.from.field.initializer.to.constructor.throws.family.text=Add exception to class constructors signature +java.8.collections.api.inspection.description=If statement could be replaced with single method +java.8.collections.api.inspection.fix.family.name=Replace with single method call +java.8.collections.api.inspection.fix.text=Replace with ''{0}'' method call \ No newline at end of file diff --git a/resources/src/META-INF/IdeaPlugin.xml b/resources/src/META-INF/IdeaPlugin.xml index 92b1bd2dec0f..e047005baf85 100644 --- a/resources/src/META-INF/IdeaPlugin.xml +++ b/resources/src/META-INF/IdeaPlugin.xml @@ -770,6 +770,11 @@ groupKey="group.names.performance.issues" enabledByDefault="false" level="WARNING" implementationClass="com.intellij.codeInspection.CollectionAddAllCanBeReplacedWithConstructorInspection" displayName="Collection.addAll() can be replaced with parametrized constructor"/> + com.intellij.codeInsight.daemon.quickFix.RedundantLambdaParameterTypeIntention