mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Fixes IDEA-198701 The Default Charset inspection doesn't offer quick fix for PrintWriter in Java 10 or later
This commit is contained in:
+55
-15
@@ -30,7 +30,12 @@ import com.siyeh.ig.BaseInspection;
|
||||
import com.siyeh.ig.BaseInspectionVisitor;
|
||||
import com.siyeh.ig.InspectionGadgetsFix;
|
||||
import com.siyeh.ig.psiutils.TypeUtils;
|
||||
import org.jetbrains.annotations.*;
|
||||
import org.jetbrains.annotations.Nls;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
* @author Bas Leijdekkers
|
||||
@@ -55,29 +60,58 @@ public class ImplicitDefaultCharsetUsageInspection extends BaseInspection {
|
||||
}
|
||||
}
|
||||
|
||||
private static final Key<Boolean> HAS_CHARSET_OVERLOAD = Key.create("Method has Charset overload");
|
||||
enum CharsetOverload {
|
||||
EXIST, EXIST_WITH_FALSE, NONE;
|
||||
|
||||
@Contract("null -> false")
|
||||
private static boolean hasCharsetOverload(PsiMethod method) {
|
||||
if (method == null) return false;
|
||||
Boolean hasCharsetOverload = method.getUserData(HAS_CHARSET_OVERLOAD);
|
||||
if (hasCharsetOverload == null) {
|
||||
InspectionGadgetsFix createFix() {
|
||||
return this == NONE ? null : new AddUtf8CharsetFix(this);
|
||||
}
|
||||
|
||||
Stream<String> additionalArguments() {
|
||||
switch (this) {
|
||||
case EXIST:
|
||||
return Stream.of("java.nio.charset.StandardCharsets.UTF_8");
|
||||
case EXIST_WITH_FALSE:
|
||||
return Stream.of("false", "java.nio.charset.StandardCharsets.UTF_8");
|
||||
default:
|
||||
throw new IllegalStateException(this.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static final Key<CharsetOverload> HAS_CHARSET_OVERLOAD = Key.create("Method has Charset overload");
|
||||
|
||||
@NotNull
|
||||
private static CharsetOverload getCharsetOverload(PsiMethod method) {
|
||||
if (method == null) return CharsetOverload.NONE;
|
||||
|
||||
CharsetOverload charsetOverload = method.getUserData(HAS_CHARSET_OVERLOAD);
|
||||
if (charsetOverload == null) {
|
||||
PsiMethod methodWithCharsetArgument = null;
|
||||
PsiClass aClass = method.getContainingClass();
|
||||
charsetOverload = CharsetOverload.EXIST;
|
||||
if (aClass != null) {
|
||||
MethodSignature signature = method.getSignature(PsiSubstitutor.EMPTY);
|
||||
PsiType charsetType =
|
||||
JavaPsiFacade.getElementFactory(method.getProject()).createTypeByFQClassName("java.nio.charset.Charset", method.getResolveScope());
|
||||
PsiType[] parameterTypes = signature.getParameterTypes();
|
||||
if (method.isConstructor() && "java.io.PrintWriter".equals(aClass.getQualifiedName()) && parameterTypes.length == 1 &&
|
||||
parameterTypes[0].equalsToText("java.io.OutputStream")) {
|
||||
parameterTypes = ArrayUtil.append(parameterTypes, PsiType.BOOLEAN);
|
||||
charsetOverload = CharsetOverload.EXIST_WITH_FALSE;
|
||||
}
|
||||
MethodSignature newSignature = MethodSignatureUtil
|
||||
.createMethodSignature(signature.getName(), ArrayUtil.append(signature.getParameterTypes(), charsetType),
|
||||
.createMethodSignature(signature.getName(), ArrayUtil.append(parameterTypes, charsetType),
|
||||
signature.getTypeParameters(), signature.getSubstitutor(), signature.isConstructor()
|
||||
);
|
||||
methodWithCharsetArgument = MethodSignatureUtil.findMethodBySignature(aClass, newSignature, false);
|
||||
}
|
||||
hasCharsetOverload = methodWithCharsetArgument != null;
|
||||
method.putUserData(HAS_CHARSET_OVERLOAD, hasCharsetOverload);
|
||||
if (methodWithCharsetArgument == null) {
|
||||
charsetOverload = CharsetOverload.NONE;
|
||||
}
|
||||
method.putUserData(HAS_CHARSET_OVERLOAD, charsetOverload);
|
||||
}
|
||||
return hasCharsetOverload;
|
||||
return charsetOverload;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -86,7 +120,7 @@ public class ImplicitDefaultCharsetUsageInspection extends BaseInspection {
|
||||
PsiCallExpression call = (PsiCallExpression)infos[0];
|
||||
if (!PsiUtil.isLanguageLevel7OrHigher(call)) return null;
|
||||
PsiMethod method = call.resolveMethod();
|
||||
return hasCharsetOverload(method) ? new AddUtf8CharsetFix() : null;
|
||||
return getCharsetOverload(method).createFix();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -194,15 +228,21 @@ public class ImplicitDefaultCharsetUsageInspection extends BaseInspection {
|
||||
}
|
||||
|
||||
private static class AddUtf8CharsetFix extends InspectionGadgetsFix {
|
||||
private final CharsetOverload myCharsetOverload;
|
||||
|
||||
private AddUtf8CharsetFix(CharsetOverload charsetOverload) {
|
||||
myCharsetOverload = charsetOverload;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doFix(Project project, ProblemDescriptor descriptor) {
|
||||
PsiCallExpression call = PsiTreeUtil.getParentOfType(descriptor.getStartElement(), PsiCallExpression.class);
|
||||
if (call == null) return;
|
||||
PsiExpressionList arguments = call.getArgumentList();
|
||||
if (arguments == null) return;
|
||||
PsiExpression charsetArg =
|
||||
JavaPsiFacade.getElementFactory(project).createExpressionFromText("java.nio.charset.StandardCharsets.UTF_8", call);
|
||||
JavaCodeStyleManager.getInstance(project).shortenClassReferences(arguments.add(charsetArg));
|
||||
PsiElementFactory factory = JavaPsiFacade.getElementFactory(project);
|
||||
myCharsetOverload.additionalArguments().map(arg -> factory.createExpressionFromText(arg, call)).forEach(arguments::add);
|
||||
JavaCodeStyleManager.getInstance(project).shortenClassReferences(arguments);
|
||||
}
|
||||
|
||||
@Nls(capitalization = Nls.Capitalization.Sentence)
|
||||
|
||||
Reference in New Issue
Block a user