mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[java-highlighting] checkEnumSuperConstructorCall, checkSuperQualifierType converted
Part of IDEA-365344 Create a new Java error highlighter with minimal dependencies (PSI only) GitOrigin-RevId: 7b48c7780fb6990f01272e733ac54db93c43f5d4
This commit is contained in:
committed by
intellij-monorepo-bot
parent
df02b97035
commit
da92bfa562
@@ -166,3 +166,6 @@ literal.text.block.no.new.line=Illegal text block start: missing new line after
|
||||
exception.unhandled=Unhandled {1, choice, 0#exception|2#exceptions}: {0}
|
||||
#{0} - exceptions list (comma separated), {1} - exceptions count in the list, {2} - exception source
|
||||
exception.unhandled.close=Unhandled {1, choice, 0#exception|2#exceptions} from {2}: {0}
|
||||
|
||||
call.super.enum.constructor=Call to super is not allowed in enum constructor
|
||||
call.super.qualifier.not.inner.class=Qualifier is not allowed because superclass ''{0}'' is not a non-static inner class
|
||||
|
||||
+45
@@ -727,6 +727,51 @@ final class ClassChecker {
|
||||
checkBaseClassDefaultConstructorProblem(aClass, constructor, handledExceptions);
|
||||
}
|
||||
|
||||
void checkEnumSuperConstructorCall(@NotNull PsiMethodCallExpression expr) {
|
||||
PsiReferenceExpression methodExpression = expr.getMethodExpression();
|
||||
PsiElement refNameElement = methodExpression.getReferenceNameElement();
|
||||
if (refNameElement != null && PsiKeyword.SUPER.equals(refNameElement.getText())) {
|
||||
PsiMember constructor = PsiUtil.findEnclosingConstructorOrInitializer(expr);
|
||||
if (constructor instanceof PsiMethod) {
|
||||
PsiClass aClass = constructor.getContainingClass();
|
||||
if (aClass != null && aClass.isEnum()) {
|
||||
myVisitor.report(JavaErrorKinds.CALL_SUPER_ENUM_CONSTRUCTOR.create(expr));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void checkSuperQualifierType(@NotNull PsiMethodCallExpression superCall) {
|
||||
if (!JavaPsiConstructorUtil.isSuperConstructorCall(superCall)) return;
|
||||
PsiMethod ctr = PsiTreeUtil.getParentOfType(superCall, PsiMethod.class, true, PsiMember.class);
|
||||
if (ctr == null) return;
|
||||
PsiClass aClass = ctr.getContainingClass();
|
||||
if (aClass == null) return;
|
||||
PsiClass targetClass = aClass.getSuperClass();
|
||||
if (targetClass == null) return;
|
||||
PsiExpression qualifier = superCall.getMethodExpression().getQualifierExpression();
|
||||
if (qualifier != null) {
|
||||
if (isRealInnerClass(targetClass)) {
|
||||
PsiClass outerClass = targetClass.getContainingClass();
|
||||
if (outerClass != null) {
|
||||
PsiClassType outerType = JavaPsiFacade.getElementFactory(myVisitor.project()).createType(outerClass);
|
||||
myVisitor.myExpressionChecker.checkAssignability(outerType, null, qualifier, qualifier);
|
||||
}
|
||||
} else {
|
||||
myVisitor.report(JavaErrorKinds.CALL_SUPER_QUALIFIER_NOT_INNER_CLASS.create(qualifier, targetClass));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** JLS 8.1.3. Inner Classes and Enclosing Instances */
|
||||
private static boolean isRealInnerClass(PsiClass aClass) {
|
||||
if (PsiUtil.isInnerClass(aClass)) return true;
|
||||
if (!PsiUtil.isLocalOrAnonymousClass(aClass)) return false;
|
||||
if (aClass.hasModifierProperty(PsiModifier.STATIC)) return false; // check for implicit staticness
|
||||
PsiMember member = PsiTreeUtil.getParentOfType(aClass, PsiMember.class, true);
|
||||
return member != null && !member.hasModifierProperty(PsiModifier.STATIC);
|
||||
}
|
||||
|
||||
private static @Unmodifiable @NotNull Map<PsiJavaCodeReferenceElement, PsiClass> getPermittedClassesRefs(@NotNull PsiClass psiClass) {
|
||||
PsiReferenceList permitsList = psiClass.getPermitsList();
|
||||
if (permitsList == null) return Collections.emptyMap();
|
||||
|
||||
+27
@@ -2,10 +2,13 @@
|
||||
package com.intellij.java.codeserver.highlighting;
|
||||
|
||||
import com.intellij.java.codeserver.highlighting.errors.JavaErrorKinds;
|
||||
import com.intellij.java.codeserver.highlighting.errors.JavaIncompatibleTypeError;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.IncompleteModelUtil;
|
||||
import com.intellij.psi.util.InheritanceUtil;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.psi.util.TypeConversionUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -88,4 +91,28 @@ final class ExpressionChecker {
|
||||
myVisitor.report(JavaErrorKinds.CLASS_CANNOT_BE_REFERENCED_FROM_STATIC_CONTEXT.create(elementToHighlight, context));
|
||||
}
|
||||
}
|
||||
|
||||
void checkAssignability(@Nullable PsiType lType,
|
||||
@Nullable PsiType rType,
|
||||
@Nullable PsiExpression expression,
|
||||
@NotNull PsiElement elementToHighlight) {
|
||||
if (lType == rType) return;
|
||||
if (expression == null) {
|
||||
if (rType == null || lType == null || TypeConversionUtil.isAssignable(lType, rType)) return;
|
||||
}
|
||||
else if (TypeConversionUtil.areTypesAssignmentCompatible(lType, expression) || PsiTreeUtil.hasErrorElements(expression)) {
|
||||
return;
|
||||
}
|
||||
if (rType == null) {
|
||||
rType = expression.getType();
|
||||
}
|
||||
if (lType == null || lType == PsiTypes.nullType()) {
|
||||
return;
|
||||
}
|
||||
if (expression != null && IncompleteModelUtil.isIncompleteModel(expression) &&
|
||||
IncompleteModelUtil.isPotentiallyConvertible(lType, expression)) {
|
||||
return;
|
||||
}
|
||||
myVisitor.report(JavaErrorKinds.TYPE_INCOMPATIBLE.create(elementToHighlight, new JavaIncompatibleTypeError(lType, rType)));
|
||||
}
|
||||
}
|
||||
|
||||
+12
-1
@@ -37,7 +37,7 @@ final class JavaErrorVisitor extends JavaElementVisitor {
|
||||
private final @NotNull GenericsChecker myGenericsChecker = new GenericsChecker(this);
|
||||
private final @NotNull MethodChecker myMethodChecker = new MethodChecker(this);
|
||||
private final @NotNull ReceiverChecker myReceiverChecker = new ReceiverChecker(this);
|
||||
private final @NotNull ExpressionChecker myExpressionChecker = new ExpressionChecker(this);
|
||||
final @NotNull ExpressionChecker myExpressionChecker = new ExpressionChecker(this);
|
||||
private final @NotNull LiteralChecker myLiteralChecker = new LiteralChecker(this);
|
||||
private boolean myHasError; // true if myHolder.add() was called with HighlightInfo of >=ERROR severity. On each .visit(PsiElement) call this flag is reset. Useful to determine whether the error was already reported while visiting this PsiElement.
|
||||
|
||||
@@ -62,6 +62,10 @@ final class JavaErrorVisitor extends JavaElementVisitor {
|
||||
return myFile;
|
||||
}
|
||||
|
||||
@NotNull Project project() {
|
||||
return myProject;
|
||||
}
|
||||
|
||||
@NotNull LanguageLevel languageLevel() {
|
||||
return myLanguageLevel;
|
||||
}
|
||||
@@ -249,6 +253,13 @@ final class JavaErrorVisitor extends JavaElementVisitor {
|
||||
if (!hasErrorResults()) myClassChecker.checkIllegalInstanceMemberInRecord(field);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitMethodCallExpression(@NotNull PsiMethodCallExpression expression) {
|
||||
if (!hasErrorResults()) myClassChecker.checkEnumSuperConstructorCall(expression);
|
||||
if (!hasErrorResults()) myClassChecker.checkSuperQualifierType(expression);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitIdentifier(@NotNull PsiIdentifier identifier) {
|
||||
PsiElement parent = identifier.getParent();
|
||||
|
||||
+3
-4
@@ -5,10 +5,7 @@ import com.intellij.java.codeserver.highlighting.JavaCompilationErrorBundle;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.openapi.util.text.HtmlChunk;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import org.jetbrains.annotations.Nls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.annotations.PropertyKey;
|
||||
import org.jetbrains.annotations.*;
|
||||
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.BiFunction;
|
||||
@@ -229,6 +226,7 @@ public sealed interface JavaErrorKind<Psi extends PsiElement, Context> {
|
||||
* @param psi psi element to bind an error instance to
|
||||
* @return an instance of this error
|
||||
*/
|
||||
@Contract(pure = true)
|
||||
public @NotNull JavaCompilationError<Psi, Void> create(@NotNull Psi psi) {
|
||||
return new JavaCompilationError<>(this, psi, null);
|
||||
}
|
||||
@@ -319,6 +317,7 @@ public sealed interface JavaErrorKind<Psi extends PsiElement, Context> {
|
||||
* @param context context to bind an error instance to
|
||||
* @return an instance of this error
|
||||
*/
|
||||
@Contract(pure = true)
|
||||
public @NotNull JavaCompilationError<Psi, Context> create(@NotNull Psi psi, Context context) {
|
||||
return new JavaCompilationError<>(this, psi, context);
|
||||
}
|
||||
|
||||
+5
@@ -408,6 +408,11 @@ public final class JavaErrorKinds {
|
||||
error(PsiLiteralExpression.class, "literal.text.block.unclosed").withRange(e -> TextRange.from(e.getTextLength(), 0));
|
||||
public static final Simple<PsiLiteralExpression> LITERAL_TEXT_BLOCK_NO_NEW_LINE =
|
||||
error(PsiLiteralExpression.class, "literal.text.block.no.new.line").withRange(e -> TextRange.create(0, 3));
|
||||
|
||||
public static final Simple<PsiMethodCallExpression> CALL_SUPER_ENUM_CONSTRUCTOR = error("call.super.enum.constructor");
|
||||
public static final Parameterized<PsiExpression, PsiClass> CALL_SUPER_QUALIFIER_NOT_INNER_CLASS =
|
||||
parameterized(PsiExpression.class, PsiClass.class, "call.super.qualifier.not.inner.class")
|
||||
.withRawDescription((psi, cls) -> message("call.super.qualifier.not.inner.class", formatClass(cls)));
|
||||
|
||||
|
||||
private static @NotNull <Psi extends PsiElement> Simple<Psi> error(@NotNull String key) {
|
||||
|
||||
+40
-36
@@ -2,12 +2,9 @@
|
||||
package com.intellij.codeInsight.daemon.impl.analysis;
|
||||
|
||||
import com.intellij.codeInsight.daemon.QuickFixBundle;
|
||||
import com.intellij.codeInsight.daemon.impl.HighlightInfo;
|
||||
import com.intellij.codeInsight.daemon.impl.quickfix.*;
|
||||
import com.intellij.codeInsight.intention.IntentionAction;
|
||||
import com.intellij.codeInsight.intention.CommonIntentionAction;
|
||||
import com.intellij.codeInsight.intention.QuickFixFactory;
|
||||
import com.intellij.modcommand.ModCommandAction;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.source.resolve.graphInference.PsiPolyExpressionUtil;
|
||||
import com.intellij.psi.infos.MethodCandidateInfo;
|
||||
@@ -29,6 +26,7 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import static com.intellij.util.ObjectUtils.tryCast;
|
||||
|
||||
@@ -39,8 +37,7 @@ final class AdaptExpressionTypeFixUtil {
|
||||
|
||||
private AdaptExpressionTypeFixUtil() { }
|
||||
|
||||
private static void registerPatchParametersFixes(@NotNull HighlightInfo.Builder info,
|
||||
@NotNull TextRange textRange,
|
||||
private static void registerPatchParametersFixes(@NotNull Consumer<? super CommonIntentionAction> info,
|
||||
@NotNull PsiMethodCallExpression call,
|
||||
@NotNull PsiMethod method,
|
||||
@NotNull PsiType expectedTypeByParent,
|
||||
@@ -57,7 +54,7 @@ final class AdaptExpressionTypeFixUtil {
|
||||
Set<PsiTypeParameter> set = Set.of(typeParameter);
|
||||
|
||||
if (!PsiTreeUtil.isAncestor(method, typeParameter, true)) {
|
||||
registerPatchQualifierFixes(info, textRange, call, method, typeParameter, expectedTypeValue, parameters, set);
|
||||
registerPatchQualifierFixes(info, call, method, typeParameter, expectedTypeValue, parameters, set);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -81,21 +78,20 @@ final class AdaptExpressionTypeFixUtil {
|
||||
psiClassType.rawType().equalsToText(CommonClassNames.JAVA_LANG_CLASS) &&
|
||||
typeParameter == getSoleTypeParameter(parameterType)) {
|
||||
if (expectedTypeValue instanceof PsiClassType classType && JavaGenericsUtil.isReifiableType(expectedTypeValue)) {
|
||||
ReplaceExpressionAction fix = new ReplaceExpressionAction(
|
||||
info.accept(new ReplaceExpressionAction(
|
||||
arg, classType.rawType().getCanonicalText() + ".class",
|
||||
classType.rawType().getPresentableText() + ".class");
|
||||
info.registerFix(fix, null, null, null, null);
|
||||
classType.rawType().getPresentableText() + ".class"));
|
||||
}
|
||||
}
|
||||
PsiType expectedArgType = desiredSubstitutor.substitute(parameterType);
|
||||
if (arg instanceof PsiLambdaExpression && parameterType instanceof PsiClassType) {
|
||||
registerLambdaReturnFixes(info, textRange, (PsiLambdaExpression)arg, (PsiClassType)parameterType, expectedArgType, typeParameter);
|
||||
registerLambdaReturnFixes(info, (PsiLambdaExpression)arg, (PsiClassType)parameterType, expectedArgType, typeParameter);
|
||||
return;
|
||||
}
|
||||
PsiType actualArgType = PsiPolyExpressionUtil.isPolyExpression(arg) ?
|
||||
substitutor.put(typeParameter, substitution.myActualType).substitute(parameterType) :
|
||||
arg.getType();
|
||||
registerExpectedTypeFixes(info, textRange, arg, expectedArgType, actualArgType);
|
||||
registerExpectedTypeFixes(info, false, arg, expectedArgType, actualArgType);
|
||||
}
|
||||
|
||||
private static @Nullable PsiParameter findWrongParameter(@NotNull PsiMethodCallExpression call,
|
||||
@@ -131,8 +127,7 @@ final class AdaptExpressionTypeFixUtil {
|
||||
return ContainerUtil.getOnlyItem(candidates);
|
||||
}
|
||||
|
||||
private static void registerPatchQualifierFixes(@NotNull HighlightInfo.Builder info,
|
||||
@NotNull TextRange textRange,
|
||||
private static void registerPatchQualifierFixes(@NotNull Consumer<? super CommonIntentionAction> info,
|
||||
@NotNull PsiMethodCallExpression call,
|
||||
@NotNull PsiMethod method,
|
||||
@NotNull PsiTypeParameter typeParameter,
|
||||
@@ -154,12 +149,11 @@ final class AdaptExpressionTypeFixUtil {
|
||||
.createType(qualifierClass, classResolveResult.getSubstitutor().put(typeParameter, expectedTypeValue));
|
||||
PsiType actualType = qualifierCall.getType();
|
||||
if (actualType != null && !expectedQualifierType.equals(actualType)) {
|
||||
registerPatchParametersFixes(info, textRange, qualifierCall, qualifierMethod, expectedQualifierType, actualType);
|
||||
registerPatchParametersFixes(info, qualifierCall, qualifierMethod, expectedQualifierType, actualType);
|
||||
}
|
||||
}
|
||||
|
||||
private static void registerLambdaReturnFixes(@NotNull HighlightInfo.Builder info,
|
||||
@NotNull TextRange textRange,
|
||||
private static void registerLambdaReturnFixes(@NotNull Consumer<? super CommonIntentionAction> info,
|
||||
@NotNull PsiLambdaExpression arg,
|
||||
@NotNull PsiClassType parameterType,
|
||||
@Nullable PsiType expectedArgType,
|
||||
@@ -188,7 +182,7 @@ final class AdaptExpressionTypeFixUtil {
|
||||
}
|
||||
PsiType expectedFnReturnType = LambdaUtil.getFunctionalInterfaceReturnType(expectedArgType);
|
||||
if (expectedFnReturnType == null) return;
|
||||
registerExpectedTypeFixes(info, textRange, lambdaBody, expectedFnReturnType);
|
||||
registerExpectedTypeFixes(info, false, lambdaBody, expectedFnReturnType);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -198,7 +192,16 @@ final class AdaptExpressionTypeFixUtil {
|
||||
* @param expression expression whose type is incorrect
|
||||
* @param expectedType desired expression type.
|
||||
*/
|
||||
static void registerExpectedTypeFixes(@NotNull HighlightInfo.Builder info, @NotNull TextRange textRange,@NotNull PsiExpression expression, @Nullable PsiType expectedType) {
|
||||
static void registerExpectedTypeFixes(@NotNull Consumer<? super CommonIntentionAction> info,
|
||||
@NotNull PsiExpression expression,
|
||||
@Nullable PsiType expectedType) {
|
||||
registerExpectedTypeFixes(info, true, expression, expectedType);
|
||||
}
|
||||
|
||||
private static void registerExpectedTypeFixes(@NotNull Consumer<? super CommonIntentionAction> info,
|
||||
boolean wholeRange,
|
||||
@NotNull PsiExpression expression,
|
||||
@Nullable PsiType expectedType) {
|
||||
PsiType actualType;
|
||||
if (PsiPolyExpressionUtil.isPolyExpression(expression)) {
|
||||
actualType = ((PsiExpression)expression.copy()).getType();
|
||||
@@ -206,7 +209,7 @@ final class AdaptExpressionTypeFixUtil {
|
||||
else {
|
||||
actualType = expression.getType();
|
||||
}
|
||||
registerExpectedTypeFixes(info, textRange, expression, expectedType, actualType);
|
||||
registerExpectedTypeFixes(info, wholeRange, expression, expectedType, actualType);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -217,35 +220,36 @@ final class AdaptExpressionTypeFixUtil {
|
||||
* @param expectedType desired expression type
|
||||
* @param actualType actual expression type
|
||||
*/
|
||||
static void registerExpectedTypeFixes(@NotNull HighlightInfo.Builder info,
|
||||
@NotNull TextRange textRange,
|
||||
static void registerExpectedTypeFixes(@NotNull Consumer<? super CommonIntentionAction> info,
|
||||
@NotNull PsiExpression expression,
|
||||
@Nullable PsiType expectedType,
|
||||
@Nullable PsiType actualType) {
|
||||
registerExpectedTypeFixes(info, true, expression, expectedType, actualType);
|
||||
}
|
||||
|
||||
private static void registerExpectedTypeFixes(@NotNull Consumer<? super CommonIntentionAction> info,
|
||||
boolean wholeRange,
|
||||
@NotNull PsiExpression expression,
|
||||
@Nullable PsiType expectedType,
|
||||
@Nullable PsiType actualType) {
|
||||
if (actualType == null || expectedType == null) return;
|
||||
boolean mentionsTypeArgument = mentionsTypeArgument(expression, actualType);
|
||||
expectedType = GenericsUtil.getVariableTypeByExpressionType(expectedType);
|
||||
TextRange range = expression.getTextRange();
|
||||
String role = textRange.equals(range) ? null : getRole(expression);
|
||||
String role = wholeRange ? null : getRole(expression);
|
||||
if (!mentionsTypeArgument) {
|
||||
IntentionAction action3 = new WrapWithAdapterMethodCallFix(expectedType, expression, role);
|
||||
info.registerFix(action3, null, null, null, null);
|
||||
IntentionAction action2 = QuickFixFactory.getInstance().createWrapWithOptionalFix(expectedType, expression);
|
||||
info.registerFix(action2, null, null, null, null);
|
||||
var action1 = new WrapExpressionFix(expectedType, expression, role);
|
||||
info.registerFix(action1, null, null, null, null);
|
||||
info.accept(new WrapWithAdapterMethodCallFix(expectedType, expression, role));
|
||||
info.accept(QuickFixFactory.getInstance().createWrapWithOptionalFix(expectedType, expression));
|
||||
info.accept(new WrapExpressionFix(expectedType, expression, role));
|
||||
PsiType castToType = suggestCastTo(expression, expectedType, actualType);
|
||||
if (castToType != null) {
|
||||
ModCommandAction action = new AddTypeCastFix(castToType, expression, role);
|
||||
info.registerFix(action, null, null, null, null);
|
||||
info.accept(new AddTypeCastFix(castToType, expression, role));
|
||||
}
|
||||
}
|
||||
if (expectedType instanceof PsiArrayType arrayType) {
|
||||
PsiType erasedValueType = TypeConversionUtil.erasure(actualType);
|
||||
if (erasedValueType != null &&
|
||||
TypeConversionUtil.isAssignable(arrayType.getComponentType(), erasedValueType)) {
|
||||
IntentionAction action = QuickFixFactory.getInstance().createSurroundWithArrayFix(null, expression);
|
||||
info.registerFix(action, null, null, null, null);
|
||||
info.accept(QuickFixFactory.getInstance().createSurroundWithArrayFix(null, expression));
|
||||
}
|
||||
}
|
||||
HighlightFixUtil.registerCollectionToArrayFixAction(info, actualType, expectedType, expression);
|
||||
@@ -254,12 +258,12 @@ final class AdaptExpressionTypeFixUtil {
|
||||
if (qualifier != null) {
|
||||
PsiType type = qualifier.getType();
|
||||
if (type != null && expectedType.isAssignableFrom(type)) {
|
||||
info.registerFix(new ReplaceWithQualifierFix(call, role), null, null, null, null);
|
||||
info.accept(new ReplaceWithQualifierFix(call, role));
|
||||
}
|
||||
}
|
||||
PsiMethod argMethod = call.resolveMethod();
|
||||
if (argMethod != null) {
|
||||
registerPatchParametersFixes(info, textRange, call, argMethod, expectedType, actualType);
|
||||
registerPatchParametersFixes(info, call, argMethod, expectedType, actualType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
-16
@@ -1043,22 +1043,6 @@ public final class GenericsHighlightUtil {
|
||||
return null;
|
||||
}
|
||||
|
||||
static HighlightInfo.Builder checkEnumSuperConstructorCall(@NotNull PsiMethodCallExpression expr) {
|
||||
PsiReferenceExpression methodExpression = expr.getMethodExpression();
|
||||
PsiElement refNameElement = methodExpression.getReferenceNameElement();
|
||||
if (refNameElement != null && PsiKeyword.SUPER.equals(refNameElement.getText())) {
|
||||
PsiMember constructor = PsiUtil.findEnclosingConstructorOrInitializer(expr);
|
||||
if (constructor instanceof PsiMethod) {
|
||||
PsiClass aClass = constructor.getContainingClass();
|
||||
if (aClass != null && aClass.isEnum()) {
|
||||
String message = JavaErrorBundle.message("call.to.super.is.not.allowed.in.enum.constructor");
|
||||
return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(expr).descriptionAndTooltip(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
static HighlightInfo.Builder checkVarArgParameterIsLast(@NotNull PsiParameter parameter) {
|
||||
PsiElement declarationScope = parameter.getDeclarationScope();
|
||||
if (declarationScope instanceof PsiMethod psiMethod) {
|
||||
|
||||
-35
@@ -7,13 +7,11 @@ import com.intellij.codeInsight.daemon.impl.HighlightInfoType;
|
||||
import com.intellij.codeInsight.daemon.impl.quickfix.QuickFixAction;
|
||||
import com.intellij.codeInsight.intention.IntentionAction;
|
||||
import com.intellij.codeInsight.intention.QuickFixFactory;
|
||||
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.search.searches.DirectClassInheritorsSearch;
|
||||
import com.intellij.psi.util.*;
|
||||
import com.intellij.util.JavaPsiConstructorUtil;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -76,39 +74,6 @@ public final class HighlightClassUtil {
|
||||
return checkIllegalEnclosingUsage(placeToSearchEnclosingFrom, aClass, outerClass, element);
|
||||
}
|
||||
|
||||
static HighlightInfo.Builder checkSuperQualifierType(@NotNull Project project, @NotNull PsiMethodCallExpression superCall) {
|
||||
if (!JavaPsiConstructorUtil.isSuperConstructorCall(superCall)) return null;
|
||||
PsiMethod ctr = PsiTreeUtil.getParentOfType(superCall, PsiMethod.class, true, PsiMember.class);
|
||||
if (ctr == null) return null;
|
||||
PsiClass aClass = ctr.getContainingClass();
|
||||
if (aClass == null) return null;
|
||||
PsiClass targetClass = aClass.getSuperClass();
|
||||
if (targetClass == null) return null;
|
||||
PsiExpression qualifier = superCall.getMethodExpression().getQualifierExpression();
|
||||
if (qualifier != null) {
|
||||
if (isRealInnerClass(targetClass)) {
|
||||
PsiClass outerClass = targetClass.getContainingClass();
|
||||
if (outerClass != null) {
|
||||
PsiClassType outerType = JavaPsiFacade.getElementFactory(project).createType(outerClass);
|
||||
return HighlightUtil.checkAssignability(outerType, null, qualifier, qualifier);
|
||||
}
|
||||
} else {
|
||||
String description = JavaErrorBundle.message("not.inner.class", HighlightUtil.formatClass(targetClass));
|
||||
return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(qualifier).descriptionAndTooltip(description);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/** JLS 8.1.3. Inner Classes and Enclosing Instances */
|
||||
private static boolean isRealInnerClass(PsiClass aClass) {
|
||||
if (PsiUtil.isInnerClass(aClass)) return true;
|
||||
if (!PsiUtil.isLocalOrAnonymousClass(aClass)) return false;
|
||||
if (aClass.hasModifierProperty(PsiModifier.STATIC)) return false; // check for implicit staticness
|
||||
PsiMember member = PsiTreeUtil.getParentOfType(aClass, PsiMember.class, true);
|
||||
return member != null && !member.hasModifierProperty(PsiModifier.STATIC);
|
||||
}
|
||||
|
||||
static HighlightInfo.Builder checkIllegalEnclosingUsage(@NotNull PsiElement place,
|
||||
@Nullable PsiClass aClass,
|
||||
@NotNull PsiClass outerClass,
|
||||
|
||||
+15
-15
@@ -7,6 +7,7 @@ import com.intellij.codeInsight.daemon.impl.quickfix.QualifyMethodCallFix;
|
||||
import com.intellij.codeInsight.daemon.impl.quickfix.QuickFixAction;
|
||||
import com.intellij.codeInsight.daemon.impl.quickfix.ReplaceAssignmentFromVoidWithStatementIntentionAction;
|
||||
import com.intellij.codeInsight.daemon.impl.quickfix.ReplaceGetClassWithClassLiteralFix;
|
||||
import com.intellij.codeInsight.intention.CommonIntentionAction;
|
||||
import com.intellij.codeInsight.intention.IntentionAction;
|
||||
import com.intellij.codeInsight.intention.QuickFixFactory;
|
||||
import com.intellij.codeInsight.intention.impl.PriorityIntentionActionWrapper;
|
||||
@@ -35,13 +36,14 @@ import org.jetbrains.annotations.Nullable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public final class HighlightFixUtil {
|
||||
private static final Logger LOG = Logger.getInstance(HighlightFixUtil.class);
|
||||
private static final CallMatcher COLLECTION_TO_ARRAY =
|
||||
CallMatcher.instanceCall(CommonClassNames.JAVA_UTIL_COLLECTION, "toArray").parameterCount(0);
|
||||
|
||||
static void registerCollectionToArrayFixAction(@NotNull HighlightInfo.Builder info,
|
||||
static void registerCollectionToArrayFixAction(@NotNull Consumer<? super CommonIntentionAction> info,
|
||||
@Nullable PsiType fromType,
|
||||
@Nullable PsiType toType,
|
||||
@NotNull PsiExpression expression) {
|
||||
@@ -60,8 +62,7 @@ public final class HighlightFixUtil {
|
||||
InheritanceUtil.isInheritor(fromType, CommonClassNames.JAVA_UTIL_COLLECTION)) {
|
||||
PsiType collectionItemType = JavaGenericsUtil.getCollectionItemType(fromType, expression.getResolveScope());
|
||||
if (collectionItemType != null && arrayComponentType.isConvertibleFrom(collectionItemType)) {
|
||||
IntentionAction action = QuickFixFactory.getInstance().createCollectionToArrayFix(collection, expression, (PsiArrayType)toType);
|
||||
info.registerFix(action, null, null, null, null);
|
||||
info.accept(QuickFixFactory.getInstance().createCollectionToArrayFix(collection, expression, (PsiArrayType)toType));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -234,25 +235,25 @@ public final class HighlightFixUtil {
|
||||
@Nullable PsiType itemType,
|
||||
@Nullable PsiExpression expr,
|
||||
@Nullable HighlightInfo.Builder highlightInfo) {
|
||||
if (highlightInfo == null) return;
|
||||
for (IntentionAction action : getChangeVariableTypeFixes(parameter, itemType)) {
|
||||
if (highlightInfo != null) {
|
||||
highlightInfo.registerFix(action, null, null, null, null);
|
||||
}
|
||||
highlightInfo.registerFix(action, null, null, null, null);
|
||||
}
|
||||
IntentionAction fix = createChangeReturnTypeFix(expr, parameter.getType());
|
||||
if (fix != null) {
|
||||
highlightInfo.registerFix(fix, null, null, null, null);
|
||||
}
|
||||
registerChangeReturnTypeFix(highlightInfo, expr, parameter.getType());
|
||||
}
|
||||
|
||||
static void registerChangeReturnTypeFix(@Nullable HighlightInfo.Builder highlightInfo, @Nullable PsiExpression expr, @NotNull PsiType toType) {
|
||||
static @Nullable IntentionAction createChangeReturnTypeFix(@Nullable PsiExpression expr, @NotNull PsiType toType) {
|
||||
if (expr instanceof PsiMethodCallExpression) {
|
||||
PsiMethod method = ((PsiMethodCallExpression)expr).resolveMethod();
|
||||
if (method != null) {
|
||||
IntentionAction action = PriorityIntentionActionWrapper
|
||||
return PriorityIntentionActionWrapper
|
||||
.lowPriority(QuickFixFactory.getInstance().createMethodReturnFix(method, toType, true));
|
||||
if (highlightInfo != null) {
|
||||
highlightInfo.registerFix(action, null, null, null, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -331,11 +332,10 @@ public final class HighlightFixUtil {
|
||||
}
|
||||
}
|
||||
|
||||
static void registerLambdaReturnTypeFixes(@Nullable HighlightInfo.Builder info, @NotNull TextRange range, PsiLambdaExpression lambda, PsiExpression expression) {
|
||||
if (info == null) return;
|
||||
static void registerLambdaReturnTypeFixes(@NotNull Consumer<? super CommonIntentionAction> info, PsiLambdaExpression lambda, PsiExpression expression) {
|
||||
PsiType type = LambdaUtil.getFunctionalInterfaceReturnType(lambda);
|
||||
if (type != null) {
|
||||
AdaptExpressionTypeFixUtil.registerExpectedTypeFixes(info, range, expression, type);
|
||||
AdaptExpressionTypeFixUtil.registerExpectedTypeFixes(info, expression, type);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+4
-2
@@ -455,7 +455,8 @@ public final class HighlightMethodUtil {
|
||||
PsiType actualType = ((PsiExpression)methodCall.copy()).getType();
|
||||
TextRange fixRange = getFixRange(list);
|
||||
if (expectedTypeByParent != null && actualType != null && !expectedTypeByParent.isAssignableFrom(actualType)) {
|
||||
AdaptExpressionTypeFixUtil.registerExpectedTypeFixes(builder, fixRange, methodCall, expectedTypeByParent, actualType);
|
||||
AdaptExpressionTypeFixUtil.registerExpectedTypeFixes(
|
||||
HighlightUtil.asConsumer(builder), methodCall, expectedTypeByParent, actualType);
|
||||
}
|
||||
HighlightFixUtil.registerQualifyMethodCallFix(resolveHelper.getReferencedMethodCandidates(methodCall, false), methodCall,
|
||||
list, builder);
|
||||
@@ -647,7 +648,8 @@ public final class HighlightMethodUtil {
|
||||
builder = HighlightUtil.createIncompatibleTypeHighlightInfo(
|
||||
expectedTypeByParent, actualType, fixRange, 0, XmlStringUtil.escapeString(errorMessage));
|
||||
if (methodCall instanceof PsiExpression) {
|
||||
AdaptExpressionTypeFixUtil.registerExpectedTypeFixes(builder, fixRange, (PsiExpression)methodCall, expectedTypeByParent, actualType);
|
||||
AdaptExpressionTypeFixUtil.registerExpectedTypeFixes(HighlightUtil.asConsumer(builder),
|
||||
(PsiExpression)methodCall, expectedTypeByParent, actualType);
|
||||
}
|
||||
PsiElement parent = PsiUtil.skipParenthesizedExprUp(methodCall.getParent());
|
||||
if (parent instanceof PsiReturnStatement) {
|
||||
|
||||
+19
-5
@@ -19,6 +19,7 @@ import com.intellij.core.JavaPsiBundle;
|
||||
import com.intellij.ide.IdeBundle;
|
||||
import com.intellij.java.analysis.JavaAnalysisBundle;
|
||||
import com.intellij.lang.injection.InjectedLanguageManager;
|
||||
import com.intellij.modcommand.ModCommandAction;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.module.LanguageLevelUtil;
|
||||
import com.intellij.openapi.module.Module;
|
||||
@@ -457,7 +458,7 @@ public final class HighlightUtil {
|
||||
return highlightInfo;
|
||||
}
|
||||
|
||||
private static boolean isCastIntentionApplicable(@NotNull PsiExpression expression, @Nullable PsiType toType) {
|
||||
static boolean isCastIntentionApplicable(@NotNull PsiExpression expression, @Nullable PsiType toType) {
|
||||
while (expression instanceof PsiTypeCastExpression || expression instanceof PsiParenthesizedExpression) {
|
||||
if (expression instanceof PsiTypeCastExpression castExpression) {
|
||||
expression = castExpression.getOperand();
|
||||
@@ -610,21 +611,34 @@ public final class HighlightUtil {
|
||||
return null;
|
||||
}
|
||||
HighlightInfo.Builder highlightInfo = createIncompatibleTypeHighlightInfo(lType, rType, textRange, navigationShift);
|
||||
AddTypeArgumentsConditionalFix.register(highlightInfo, expression, lType);
|
||||
AddTypeArgumentsConditionalFix.register(asConsumer(highlightInfo), expression, lType);
|
||||
if (rType != null && expression != null && isCastIntentionApplicable(expression, lType)) {
|
||||
IntentionAction action = getFixFactory().createAddTypeCastFix(lType, expression);
|
||||
highlightInfo.registerFix(action, null, null, null, null);
|
||||
}
|
||||
if (expression != null) {
|
||||
AdaptExpressionTypeFixUtil.registerExpectedTypeFixes(highlightInfo, textRange, expression, lType, rType);
|
||||
AdaptExpressionTypeFixUtil.registerExpectedTypeFixes(asConsumer(highlightInfo), expression, lType, rType);
|
||||
if (!(expression.getParent() instanceof PsiConditionalExpression && PsiTypes.voidType().equals(lType))) {
|
||||
HighlightFixUtil.registerChangeReturnTypeFix(highlightInfo, expression, lType);
|
||||
IntentionAction fix = HighlightFixUtil.createChangeReturnTypeFix(expression, lType);
|
||||
if (fix != null) {
|
||||
highlightInfo.registerFix(fix, null, null, null, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
ChangeNewOperatorTypeFix.register(highlightInfo, expression, lType);
|
||||
ModCommandAction fix = ChangeNewOperatorTypeFix.createFix(expression, lType);
|
||||
if (fix != null) {
|
||||
highlightInfo.registerFix(fix, null, null, null, null);
|
||||
}
|
||||
return highlightInfo;
|
||||
}
|
||||
|
||||
static @NotNull Consumer<CommonIntentionAction> asConsumer(HighlightInfo.Builder highlightInfo) {
|
||||
if (highlightInfo == null) {
|
||||
return fix -> {};
|
||||
}
|
||||
return fix -> highlightInfo.registerFix(fix.asIntention(), null, null, null, null);
|
||||
}
|
||||
|
||||
static HighlightInfo.Builder checkReturnFromSwitchExpr(@NotNull PsiReturnStatement statement) {
|
||||
if (PsiImplUtil.findEnclosingSwitchExpression(statement) != null) {
|
||||
String message = JavaErrorBundle.message("return.outside.switch.expr");
|
||||
|
||||
+2
-3
@@ -400,7 +400,7 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
|
||||
info.registerFix(action, null, null, null, null);
|
||||
}
|
||||
if (element instanceof PsiExpression expr) {
|
||||
HighlightFixUtil.registerLambdaReturnTypeFixes(info, element.getTextRange(), expression, expr);
|
||||
HighlightFixUtil.registerLambdaReturnTypeFixes(HighlightUtil.asConsumer(info), expression, expr);
|
||||
}
|
||||
add(info);
|
||||
}
|
||||
@@ -845,8 +845,7 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
|
||||
|
||||
@Override
|
||||
public void visitMethodCallExpression(@NotNull PsiMethodCallExpression expression) {
|
||||
if (!hasErrorResults()) add(GenericsHighlightUtil.checkEnumSuperConstructorCall(expression));
|
||||
if (!hasErrorResults()) add(HighlightClassUtil.checkSuperQualifierType(myFile.getProject(), expression));
|
||||
visitElement(expression);
|
||||
if (!hasErrorResults()) {
|
||||
try {
|
||||
HighlightMethodUtil.checkMethodCall(expression, getResolveHelper(), myLanguageLevel, myJavaSdkVersion, myFile,
|
||||
|
||||
+15
-4
@@ -3,10 +3,7 @@ package com.intellij.codeInsight.daemon.impl.analysis;
|
||||
|
||||
import com.intellij.codeInsight.ClassUtil;
|
||||
import com.intellij.codeInsight.daemon.QuickFixBundle;
|
||||
import com.intellij.codeInsight.daemon.impl.quickfix.MoveAnnotationOnStaticMemberQualifyingTypeFix;
|
||||
import com.intellij.codeInsight.daemon.impl.quickfix.MoveAnnotationToPackageInfoFileFix;
|
||||
import com.intellij.codeInsight.daemon.impl.quickfix.MoveMembersIntoClassFix;
|
||||
import com.intellij.codeInsight.daemon.impl.quickfix.ReplaceVarWithExplicitTypeFix;
|
||||
import com.intellij.codeInsight.daemon.impl.quickfix.*;
|
||||
import com.intellij.codeInsight.intention.CommonIntentionAction;
|
||||
import com.intellij.codeInsight.intention.QuickFixFactory;
|
||||
import com.intellij.codeInsight.intention.impl.BaseIntentionAction;
|
||||
@@ -36,6 +33,7 @@ import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static com.intellij.codeInsight.daemon.impl.analysis.HighlightUtil.isCastIntentionApplicable;
|
||||
import static com.intellij.java.codeserver.highlighting.errors.JavaErrorKinds.*;
|
||||
import static java.util.Objects.requireNonNull;
|
||||
import static java.util.Objects.requireNonNullElse;
|
||||
@@ -146,6 +144,19 @@ final class JavaErrorFixProvider {
|
||||
return List.of(myFactory.createExtendsListFix(usedClass, throwableType, true));
|
||||
}
|
||||
}
|
||||
if (anchor instanceof PsiExpression expression) {
|
||||
List<CommonIntentionAction> registrar = new ArrayList<>();
|
||||
AddTypeArgumentsConditionalFix.register(registrar::add, expression, context.lType());
|
||||
if (context.rType() != null && isCastIntentionApplicable(expression, context.lType())) {
|
||||
ContainerUtil.addIfNotNull(registrar, myFactory.createAddTypeCastFix(context.lType(), expression));
|
||||
}
|
||||
AdaptExpressionTypeFixUtil.registerExpectedTypeFixes(registrar::add, expression, context.lType(), context.rType());
|
||||
if (!(expression.getParent() instanceof PsiConditionalExpression && PsiTypes.voidType().equals(context.lType()))) {
|
||||
ContainerUtil.addIfNotNull(registrar, HighlightFixUtil.createChangeReturnTypeFix(expression, context.lType()));
|
||||
}
|
||||
ContainerUtil.addIfNotNull(registrar, ChangeNewOperatorTypeFix.createFix(expression, context.lType()));
|
||||
return registrar;
|
||||
}
|
||||
return List.of();
|
||||
});
|
||||
|
||||
|
||||
+10
-12
@@ -1,13 +1,10 @@
|
||||
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.codeInsight.daemon.impl.quickfix;
|
||||
|
||||
import com.intellij.codeInsight.daemon.impl.HighlightInfo;
|
||||
import com.intellij.codeInsight.intention.CommonIntentionAction;
|
||||
import com.intellij.codeInsight.intention.PriorityAction;
|
||||
import com.intellij.java.analysis.JavaAnalysisBundle;
|
||||
import com.intellij.modcommand.ActionContext;
|
||||
import com.intellij.modcommand.ModPsiUpdater;
|
||||
import com.intellij.modcommand.Presentation;
|
||||
import com.intellij.modcommand.PsiUpdateModCommandAction;
|
||||
import com.intellij.modcommand.*;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.*;
|
||||
@@ -17,6 +14,8 @@ import com.intellij.psi.util.TypeConversionUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class AddTypeArgumentsConditionalFix extends PsiUpdateModCommandAction<PsiMethodCallExpression> {
|
||||
private static final Logger LOG = Logger.getInstance(AddTypeArgumentsConditionalFix.class);
|
||||
|
||||
@@ -73,7 +72,7 @@ public class AddTypeArgumentsConditionalFix extends PsiUpdateModCommandAction<Ps
|
||||
return PsiUtil.getEnclosingStaticElement(element, aClass) != null;
|
||||
}
|
||||
|
||||
public static void register(@NotNull HighlightInfo.Builder highlightInfo, @Nullable PsiExpression expression, @NotNull PsiType lType) {
|
||||
public static void register(@NotNull Consumer<? super CommonIntentionAction> highlightInfo, @Nullable PsiExpression expression, @NotNull PsiType lType) {
|
||||
if (lType != PsiTypes.nullType() && expression instanceof PsiConditionalExpression) {
|
||||
final PsiExpression thenExpression = ((PsiConditionalExpression)expression).getThenExpression();
|
||||
final PsiExpression elseExpression = ((PsiConditionalExpression)expression).getElseExpression();
|
||||
@@ -94,8 +93,8 @@ public class AddTypeArgumentsConditionalFix extends PsiUpdateModCommandAction<Ps
|
||||
}
|
||||
}
|
||||
|
||||
private static void inferTypeArgs(@NotNull HighlightInfo.Builder highlightInfo, PsiType lType, PsiExpression thenExpression) {
|
||||
final JavaResolveResult result = ((PsiMethodCallExpression)thenExpression).resolveMethodGenerics();
|
||||
private static void inferTypeArgs(Consumer<? super ModCommandAction> fixConsumer, PsiType lType, PsiExpression expression) {
|
||||
final JavaResolveResult result = ((PsiMethodCallExpression)expression).resolveMethodGenerics();
|
||||
final PsiMethod method = (PsiMethod)result.getElement();
|
||||
if (method != null) {
|
||||
final PsiType returnType = method.getReturnType();
|
||||
@@ -103,19 +102,18 @@ public class AddTypeArgumentsConditionalFix extends PsiUpdateModCommandAction<Ps
|
||||
if (returnType != null && aClass != null && aClass.getQualifiedName() != null) {
|
||||
final JavaPsiFacade javaPsiFacade = JavaPsiFacade.getInstance(method.getProject());
|
||||
final PsiDeclarationStatement variableDeclarationStatement =
|
||||
javaPsiFacade.getElementFactory().createVariableDeclarationStatement("xxx", lType, thenExpression, thenExpression);
|
||||
javaPsiFacade.getElementFactory().createVariableDeclarationStatement("xxx", lType, expression, expression);
|
||||
final PsiExpression initializer =
|
||||
((PsiLocalVariable)variableDeclarationStatement.getDeclaredElements()[0]).getInitializer();
|
||||
LOG.assertTrue(initializer != null);
|
||||
|
||||
final PsiSubstitutor substitutor = javaPsiFacade.getResolveHelper()
|
||||
.inferTypeArguments(method.getTypeParameters(), method.getParameterList().getParameters(),
|
||||
((PsiMethodCallExpression)thenExpression).getArgumentList().getExpressions(), PsiSubstitutor.EMPTY,
|
||||
((PsiMethodCallExpression)expression).getArgumentList().getExpressions(), PsiSubstitutor.EMPTY,
|
||||
initializer, DefaultParameterTypeInferencePolicy.INSTANCE);
|
||||
PsiType substitutedType = substitutor.substitute(returnType);
|
||||
if (substitutedType != null && TypeConversionUtil.isAssignable(lType, substitutedType)) {
|
||||
highlightInfo.registerFix(new AddTypeArgumentsConditionalFix(substitutor, (PsiMethodCallExpression)thenExpression, method), null,
|
||||
null, thenExpression.getTextRange(), null);
|
||||
fixConsumer.accept(new AddTypeArgumentsConditionalFix(substitutor, (PsiMethodCallExpression)expression, method));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+7
-11
@@ -2,12 +2,8 @@
|
||||
package com.intellij.codeInsight.daemon.impl.quickfix;
|
||||
|
||||
import com.intellij.codeInsight.daemon.QuickFixBundle;
|
||||
import com.intellij.codeInsight.daemon.impl.HighlightInfo;
|
||||
import com.intellij.codeInspection.RemoveRedundantTypeArgumentsUtil;
|
||||
import com.intellij.modcommand.ActionContext;
|
||||
import com.intellij.modcommand.ModPsiUpdater;
|
||||
import com.intellij.modcommand.Presentation;
|
||||
import com.intellij.modcommand.PsiUpdateModCommandAction;
|
||||
import com.intellij.modcommand.*;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.openapi.util.UnfairTextRange;
|
||||
@@ -121,10 +117,10 @@ public final class ChangeNewOperatorTypeFix extends PsiUpdateModCommandAction<Ps
|
||||
updater.moveCaretTo(newExpression.getTextRange().getEndOffset() + caretOffset);
|
||||
}
|
||||
|
||||
public static void register(@NotNull HighlightInfo.Builder highlightInfo, PsiExpression expression, PsiType lType) {
|
||||
if (PsiUtil.resolveClassInClassTypeOnly(lType) instanceof PsiAnonymousClass) return;
|
||||
public static ModCommandAction createFix(PsiExpression expression, PsiType lType) {
|
||||
if (PsiUtil.resolveClassInClassTypeOnly(lType) instanceof PsiAnonymousClass) return null;
|
||||
expression = PsiUtil.deparenthesizeExpression(expression);
|
||||
if (!(expression instanceof PsiNewExpression newExpression)) return;
|
||||
if (!(expression instanceof PsiNewExpression newExpression)) return null;
|
||||
final PsiType rType = expression.getType();
|
||||
PsiType newType = lType;
|
||||
if (rType instanceof PsiClassType rClassType && newType instanceof PsiClassType newClassType) {
|
||||
@@ -144,10 +140,10 @@ public final class ChangeNewOperatorTypeFix extends PsiUpdateModCommandAction<Ps
|
||||
}
|
||||
}
|
||||
}
|
||||
if (rType == null || newType.getCanonicalText().equals(rType.getCanonicalText())) return;
|
||||
if (rType == null || newType.getCanonicalText().equals(rType.getCanonicalText())) return null;
|
||||
final PsiClass aClass = PsiTypesUtil.getPsiClass(newType);
|
||||
if (aClass != null && (aClass.isEnum() || aClass.isAnnotationType())) return;
|
||||
highlightInfo.registerFix(new ChangeNewOperatorTypeFix(newType, newExpression), null, null, null, null);
|
||||
if (aClass != null && (aClass.isEnum() || aClass.isAnnotationType())) return null;
|
||||
return new ChangeNewOperatorTypeFix(newType, newExpression);
|
||||
}
|
||||
|
||||
/* Guesswork
|
||||
|
||||
+2
-2
@@ -4,9 +4,9 @@ class A {
|
||||
A(Integer... i) {}
|
||||
}
|
||||
class B extends A {
|
||||
<error descr="Ambiguous method call: both 'A.A(String...)' and 'A.A(Integer...)' match">public B()</error> {}
|
||||
<error descr="Ambiguous implicit constructor call: both 'A.A(String...)' and 'A.A(Integer...)' match">public B()</error> {}
|
||||
}
|
||||
<error descr="Ambiguous method call: both 'A.A(String...)' and 'A.A(Integer...)' match">class C extends A</error> {}
|
||||
<error descr="Ambiguous implicit constructor call: both 'A.A(String...)' and 'A.A(Integer...)' match">class C extends A</error> {}
|
||||
|
||||
class A1 {
|
||||
A1(String... i){}
|
||||
|
||||
Reference in New Issue
Block a user