From db1222cc6148f77f689cc2aae41215ebda084cc9 Mon Sep 17 00:00:00 2001 From: Tagir Valeev Date: Tue, 3 Jan 2017 21:16:12 +0600 Subject: [PATCH] Java8MapApiInspection: getOrDefault: precise type check for none expression --- .../java18api/Java8MapApiInspection.java | 19 ++++++++++++------- .../afterGetOrDefaultAssignment.java | 2 +- .../afterGetOrDefaultExtendsNull.java | 9 +++++++++ .../beforeGetOrDefaultAssignment.java | 2 +- .../beforeGetOrDefaultExtendsNull.java | 9 +++++++++ .../beforeGetOrDefaultTypeMismatch.java | 9 +++++++++ 6 files changed, 41 insertions(+), 9 deletions(-) create mode 100644 java/java-tests/testData/inspection/java8MapApi/afterGetOrDefaultExtendsNull.java create mode 100644 java/java-tests/testData/inspection/java8MapApi/beforeGetOrDefaultExtendsNull.java create mode 100644 java/java-tests/testData/inspection/java8MapApi/beforeGetOrDefaultTypeMismatch.java diff --git a/java/java-impl/src/com/intellij/codeInspection/java18api/Java8MapApiInspection.java b/java/java-impl/src/com/intellij/codeInspection/java18api/Java8MapApiInspection.java index 342c739a43be..863907b25ba9 100644 --- a/java/java-impl/src/com/intellij/codeInspection/java18api/Java8MapApiInspection.java +++ b/java/java-impl/src/com/intellij/codeInspection/java18api/Java8MapApiInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2016 JetBrains s.r.o. + * Copyright 2000-2017 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. @@ -143,7 +143,7 @@ public class Java8MapApiInspection extends BaseJavaBatchLocalInspectionTool { condition.register(holder, new ReplaceWithSingleMapOperation("putIfAbsent", getCall, putArgs[1], result)); } if (mySuggestMapGetOrDefault && condition.isContainsKey() && ExpressionUtils.isSimpleExpression(noneExpression) && - !(getCall.getType() instanceof PsiCapturedWildcardType)) { + condition.isMapValueType(noneExpression.getType())) { condition.register(holder, new ReplaceWithSingleMapOperation("getOrDefault", getCall, noneExpression, result)); } } @@ -157,11 +157,10 @@ public class Java8MapApiInspection extends BaseJavaBatchLocalInspectionTool { value = ... } */ - if (ExpressionUtils.isSimpleExpression(assignment.getRExpression()) && - condition.isValueReference(assignment.getLExpression()) && - !condition.isValueReference(assignment.getRExpression())) { - condition - .register(holder, ReplaceWithSingleMapOperation.fromIf("getOrDefault", condition, assignment.getRExpression())); + PsiExpression rValue = assignment.getRExpression(); + if (ExpressionUtils.isSimpleExpression(rValue) && condition.isValueReference(assignment.getLExpression()) && + !condition.isValueReference(rValue) && condition.isMapValueType(rValue.getType())) { + condition.register(holder, ReplaceWithSingleMapOperation.fromIf("getOrDefault", condition, rValue)); } } else if (condition.isGetNull()) { /* @@ -560,5 +559,11 @@ public class Java8MapApiInspection extends BaseJavaBatchLocalInspectionTool { //noinspection DialogTitleCapitalization holder.registerProblem(getFullCondition(), QuickFixBundle.message("java.8.map.api.inspection.description", fix.myMethodName), fix); } + + public boolean isMapValueType(PsiType type) { + PsiType mapExpressionType = myMapExpression.getType(); + PsiType valueTypeParameter = PsiUtil.substituteTypeParameter(mapExpressionType, CommonClassNames.JAVA_UTIL_MAP, 1, false); + return valueTypeParameter != null && valueTypeParameter.isAssignableFrom(type); + } } } \ No newline at end of file diff --git a/java/java-tests/testData/inspection/java8MapApi/afterGetOrDefaultAssignment.java b/java/java-tests/testData/inspection/java8MapApi/afterGetOrDefaultAssignment.java index 0f3e1006718c..e63029b9fe33 100644 --- a/java/java-tests/testData/inspection/java8MapApi/afterGetOrDefaultAssignment.java +++ b/java/java-tests/testData/inspection/java8MapApi/afterGetOrDefaultAssignment.java @@ -3,7 +3,7 @@ import java.util.Map; public class Main { - public void testGetOrDefault(Map map, String key) { + public void testGetOrDefault(Map map, String key) { Integer num = 123; System.out.println(num); num = map.getOrDefault(key, 0); diff --git a/java/java-tests/testData/inspection/java8MapApi/afterGetOrDefaultExtendsNull.java b/java/java-tests/testData/inspection/java8MapApi/afterGetOrDefaultExtendsNull.java new file mode 100644 index 000000000000..c734eb846334 --- /dev/null +++ b/java/java-tests/testData/inspection/java8MapApi/afterGetOrDefaultExtendsNull.java @@ -0,0 +1,9 @@ +// "Replace with 'getOrDefault' method call" "true" +import java.util.Map; + +public class Main { + + public void testGetOrDefault(Map map, String key) { + System.out.println(map.getOrDefault(key, null)); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/inspection/java8MapApi/beforeGetOrDefaultAssignment.java b/java/java-tests/testData/inspection/java8MapApi/beforeGetOrDefaultAssignment.java index d49cac72f4cc..ec2b533ea15a 100644 --- a/java/java-tests/testData/inspection/java8MapApi/beforeGetOrDefaultAssignment.java +++ b/java/java-tests/testData/inspection/java8MapApi/beforeGetOrDefaultAssignment.java @@ -3,7 +3,7 @@ import java.util.Map; public class Main { - public void testGetOrDefault(Map map, String key) { + public void testGetOrDefault(Map map, String key) { Integer num = 123; System.out.println(num); num = map.get(key); diff --git a/java/java-tests/testData/inspection/java8MapApi/beforeGetOrDefaultExtendsNull.java b/java/java-tests/testData/inspection/java8MapApi/beforeGetOrDefaultExtendsNull.java new file mode 100644 index 000000000000..8518dfd435f6 --- /dev/null +++ b/java/java-tests/testData/inspection/java8MapApi/beforeGetOrDefaultExtendsNull.java @@ -0,0 +1,9 @@ +// "Replace with 'getOrDefault' method call" "true" +import java.util.Map; + +public class Main { + + public void testGetOrDefault(Map map, String key) { + System.out.println(map.containsKey(key) ? map.get(key) : null); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/inspection/java8MapApi/beforeGetOrDefaultTypeMismatch.java b/java/java-tests/testData/inspection/java8MapApi/beforeGetOrDefaultTypeMismatch.java new file mode 100644 index 000000000000..25621a60eade --- /dev/null +++ b/java/java-tests/testData/inspection/java8MapApi/beforeGetOrDefaultTypeMismatch.java @@ -0,0 +1,9 @@ +// "Replace with 'getOrDefault' method call" "false" +import java.util.Map; + +public class Main { + + public void testGetOrDefault(Map map, String key) { + System.out.println(map.containsKey(key) ? map.get(key) : 0.0); + } +} \ No newline at end of file