CharsetObjectCanBeUsedInspection: take into consideration current language level when suggesting replacement (IDEA-223282)

GitOrigin-RevId: efca3927ee8d81bba9334461b133a10c2ac95216
This commit is contained in:
Artemiy Sartakov
2019-10-10 09:05:03 +00:00
committed by intellij-monorepo-bot
parent 77f77314da
commit 042878d12f
2 changed files with 33 additions and 7 deletions
@@ -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);
}
}
@@ -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<caret>-8");
}
}
class URLEncoder {
static String encode(String text, String encoding) {
return text;
}
static String encode(String text, Charset charset) {
return text;
}
}