From 042878d12fbcd54f3ffa65033849610e03917bef Mon Sep 17 00:00:00 2001 From: Artemiy Sartakov Date: Thu, 10 Oct 2019 15:42:08 +0700 Subject: [PATCH] CharsetObjectCanBeUsedInspection: take into consideration current language level when suggesting replacement (IDEA-223282) GitOrigin-RevId: efca3927ee8d81bba9334461b133a10c2ac95216 --- .../CharsetObjectCanBeUsedInspection.java | 18 +++++++++------ .../beforeUrlEncoderEncode8.java | 22 +++++++++++++++++++ 2 files changed, 33 insertions(+), 7 deletions(-) create mode 100644 java/java-tests/testData/inspection/charsetObjectCanBeUsed/beforeUrlEncoderEncode8.java diff --git a/java/java-impl/src/com/intellij/codeInspection/CharsetObjectCanBeUsedInspection.java b/java/java-impl/src/com/intellij/codeInspection/CharsetObjectCanBeUsedInspection.java index 856a681d532b..9f89c63c1fed 100644 --- a/java/java-impl/src/com/intellij/codeInspection/CharsetObjectCanBeUsedInspection.java +++ b/java/java-impl/src/com/intellij/codeInspection/CharsetObjectCanBeUsedInspection.java @@ -4,8 +4,10 @@ package com.intellij.codeInspection; import com.intellij.codeInsight.ExceptionUtil; import com.intellij.codeInsight.daemon.impl.quickfix.DeleteCatchFix; import com.intellij.codeInsight.daemon.impl.quickfix.DeleteMultiCatchFix; +import com.intellij.codeInspection.java15api.Java15APIUsageInspection; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.text.StringUtil; +import com.intellij.pom.java.LanguageLevel; import com.intellij.psi.*; import com.intellij.psi.codeStyle.JavaCodeStyleManager; import com.intellij.psi.util.PsiTreeUtil; @@ -84,11 +86,12 @@ public class CharsetObjectCanBeUsedInspection extends AbstractBaseJavaLocalInspe @Override public PsiElementVisitor buildVisitor(@NotNull ProblemsHolder holder, boolean isOnTheFly) { if (!PsiUtil.isLanguageLevel7OrHigher(holder.getFile())) return PsiElementVisitor.EMPTY_VISITOR; + LanguageLevel languageLevel = PsiUtil.getLanguageLevel(holder.getFile()); return new JavaElementVisitor() { @Override public void visitCallExpression(PsiCallExpression call) { CharsetMatch match = StreamEx.of(MATCHERS) - .map(matcher -> matcher.extractCharsetMatch(call)) + .map(matcher -> matcher.extractCharsetMatch(languageLevel, call)) .nonNull() .findFirst().orElse(null); if (match == null) return; @@ -176,7 +179,7 @@ public class CharsetObjectCanBeUsedInspection extends AbstractBaseJavaLocalInspe } @Nullable - final CharsetMatch createMatch(PsiMethod method, PsiExpressionList arguments) { + final CharsetMatch createMatch(LanguageLevel languageLevel, PsiMethod method, PsiExpressionList arguments) { PsiExpression argument = arguments.getExpressions()[myCharsetParameterIndex]; PsiClass aClass = method.getContainingClass(); if (aClass == null) return null; @@ -184,13 +187,14 @@ public class CharsetObjectCanBeUsedInspection extends AbstractBaseJavaLocalInspe PsiMethod[] candidates = method.isConstructor() ? aClass.getConstructors() : aClass.findMethodsByName(method.getName(), false); PsiMethod charsetMethod = Arrays.stream(candidates) .filter(psiMethod -> checkMethod(psiMethod, "java.nio.charset.Charset")) + .filter(psiMethod -> Java15APIUsageInspection.getLastIncompatibleLanguageLevel(psiMethod, languageLevel) == null) .findFirst().orElse(null); if (charsetMethod == null) return null; return new CharsetMatch(argument, method, charsetMethod); } @Nullable - abstract CharsetMatch extractCharsetMatch(PsiCallExpression call); + abstract CharsetMatch extractCharsetMatch(LanguageLevel languageLevel, PsiCallExpression call); } static class CharsetConstructorMatcher extends CharsetCallMatcher { @@ -199,14 +203,14 @@ public class CharsetObjectCanBeUsedInspection extends AbstractBaseJavaLocalInspe } @Override - CharsetMatch extractCharsetMatch(PsiCallExpression call) { + CharsetMatch extractCharsetMatch(LanguageLevel languageLevel, PsiCallExpression call) { if (!(call instanceof PsiNewExpression)) return null; PsiNewExpression newExpression = (PsiNewExpression)call; PsiExpressionList argumentList = newExpression.getArgumentList(); if (argumentList == null || argumentList.getExpressionCount() != myParameters.length) return null; PsiMethod method = call.resolveMethod(); if (!checkMethod(method, JAVA_LANG_STRING) || !method.isConstructor()) return null; - return createMatch(method, argumentList); + return createMatch(languageLevel, method, argumentList); } } @@ -219,7 +223,7 @@ public class CharsetObjectCanBeUsedInspection extends AbstractBaseJavaLocalInspe } @Override - CharsetMatch extractCharsetMatch(PsiCallExpression call) { + CharsetMatch extractCharsetMatch(LanguageLevel languageLevel, PsiCallExpression call) { if (!(call instanceof PsiMethodCallExpression)) return null; PsiMethodCallExpression methodCallExpression = (PsiMethodCallExpression)call; if (!myMethodName.equals(methodCallExpression.getMethodExpression().getReferenceName())) return null; @@ -227,7 +231,7 @@ public class CharsetObjectCanBeUsedInspection extends AbstractBaseJavaLocalInspe if (argumentList.getExpressionCount() != myParameters.length) return null; PsiMethod method = call.resolveMethod(); if (!checkMethod(method, JAVA_LANG_STRING)) return null; - return createMatch(method, argumentList); + return createMatch(languageLevel, method, argumentList); } } diff --git a/java/java-tests/testData/inspection/charsetObjectCanBeUsed/beforeUrlEncoderEncode8.java b/java/java-tests/testData/inspection/charsetObjectCanBeUsed/beforeUrlEncoderEncode8.java new file mode 100644 index 000000000000..f06b7de30a3e --- /dev/null +++ b/java/java-tests/testData/inspection/charsetObjectCanBeUsed/beforeUrlEncoderEncode8.java @@ -0,0 +1,22 @@ +// "Replace with 'StandardCharsets.UTF-8'" "false" +package java.net; +import java.io.UnsupportedEncodingException; +import java.nio.charset.*; + +class Test { + String test(String uri, String text) throws UnsupportedEncodingException { + return uri + "&test=" + URLEncoder.encode(text, "UTF-8"); + } +} + +class URLEncoder { + + static String encode(String text, String encoding) { + return text; + } + + static String encode(String text, Charset charset) { + return text; + } + +} \ No newline at end of file