mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-04-20 13:31:28 +07:00
[java-highlighting] variable errors migrated; some improvements in incompatible type fixes
Part of IDEA-365344 Create a new Java error highlighter with minimal dependencies (PSI only) GitOrigin-RevId: b8531f50c89b009e852e1fdcc9efce1c29dcf4e1
This commit is contained in:
committed by
intellij-monorepo-bot
parent
8d746a5a24
commit
be747e6461
@@ -186,6 +186,7 @@ type.incompatible.reason.inference=<br/>reason: {0}
|
||||
type.void.not.allowed='void' type is not allowed here
|
||||
type.void.illegal=Illegal type: 'void'
|
||||
type.inaccessible=''{0}'' is inaccessible here
|
||||
type.restricted.identifier=Illegal reference to restricted type ''{0}''
|
||||
type.unknown.class=Unknown class: ''{0}''
|
||||
type.argument.primitive=Type argument cannot be of a primitive type
|
||||
type.wildcard.cannot.be.instantiated=Wildcard type ''{0}'' cannot be instantiated directly
|
||||
@@ -198,6 +199,8 @@ lvti.method.reference=Cannot infer type: method reference requires an explicit t
|
||||
lvti.array='var' is not allowed as an element type of an array
|
||||
lvti.null=Cannot infer type: variable initializer is 'null'
|
||||
lvti.void=Cannot infer type: variable initializer is 'void'
|
||||
lvti.self.referenced=Cannot infer type for ''{0}'', it is used in its own variable initializer
|
||||
lvti.compound='var' is not allowed in a compound declaration
|
||||
|
||||
label.without.statement=Label without statement
|
||||
label.duplicate=Label ''{0}'' already in use
|
||||
|
||||
@@ -701,6 +701,12 @@ final class ExpressionChecker {
|
||||
myVisitor.report(JavaErrorKinds.EXCEPTION_UNHANDLED_CLOSE.create(resource, unhandled));
|
||||
}
|
||||
|
||||
void checkVarTypeSelfReferencing(@NotNull PsiLocalVariable variable, @NotNull PsiReferenceExpression ref) {
|
||||
if (PsiTreeUtil.isAncestor(variable.getInitializer(), ref, false) && variable.getTypeElement().isInferredType()) {
|
||||
myVisitor.report(JavaErrorKinds.LVTI_SELF_REFERENCED.create(ref, variable));
|
||||
}
|
||||
}
|
||||
|
||||
static boolean isArrayDeclaration(@NotNull PsiVariable variable) {
|
||||
// Java-style 'var' arrays are prohibited by the parser; for C-style ones, looking for a bracket is enough
|
||||
return ContainerUtil.or(variable.getChildren(), e -> PsiUtil.isJavaToken(e, JavaTokenType.LBRACKET));
|
||||
@@ -1124,4 +1130,11 @@ final class ExpressionChecker {
|
||||
myVisitor.report(JavaErrorKinds.CALL_UNRESOLVED.create(methodCall, resolveResults));
|
||||
}
|
||||
}
|
||||
|
||||
void checkRestrictedIdentifierReference(@NotNull PsiJavaCodeReferenceElement ref, @NotNull PsiClass resolved) {
|
||||
String name = resolved.getName();
|
||||
if (PsiTypesUtil.isRestrictedIdentifier(name, myVisitor.languageLevel())) {
|
||||
myVisitor.report(JavaErrorKinds.TYPE_RESTRICTED_IDENTIFIER.create(ref));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -552,6 +552,23 @@ final class JavaErrorVisitor extends JavaElementVisitor {
|
||||
if (!hasErrorResults()) myRecordChecker.checkRecordHeader(aClass);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitVariable(@NotNull PsiVariable variable) {
|
||||
super.visitVariable(variable);
|
||||
if (variable instanceof PsiPatternVariable patternVariable) {
|
||||
PsiElement context = PsiTreeUtil.getParentOfType(
|
||||
variable, PsiInstanceOfExpression.class, PsiCaseLabelElementList.class, PsiForeachPatternStatement.class);
|
||||
if (!(context instanceof PsiForeachPatternStatement)) {
|
||||
JavaFeature feature = context instanceof PsiInstanceOfExpression ?
|
||||
JavaFeature.PATTERNS :
|
||||
JavaFeature.PATTERNS_IN_SWITCH;
|
||||
checkFeature(patternVariable.getNameIdentifier(), feature);
|
||||
}
|
||||
}
|
||||
if (!hasErrorResults()) myTypeChecker.checkVarTypeApplicability(variable);
|
||||
if (!hasErrorResults()) myTypeChecker.checkVariableInitializerType(variable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitReferenceExpression(@NotNull PsiReferenceExpression expression) {
|
||||
JavaResolveResult resultForIncompleteCode = doVisitReferenceElement(expression);
|
||||
@@ -566,6 +583,11 @@ final class JavaErrorVisitor extends JavaElementVisitor {
|
||||
PsiElement resolved = result.getElement();
|
||||
PsiElement parent = expression.getParent();
|
||||
PsiExpression qualifierExpression = expression.getQualifierExpression();
|
||||
if (resolved instanceof PsiVariable && resolved.getContainingFile() == expression.getContainingFile()) {
|
||||
if (!hasErrorResults() && resolved instanceof PsiLocalVariable localVariable) {
|
||||
myExpressionChecker.checkVarTypeSelfReferencing(localVariable, expression);
|
||||
}
|
||||
}
|
||||
if (parent instanceof PsiMethodCallExpression methodCallExpression &&
|
||||
methodCallExpression.getMethodExpression() == expression &&
|
||||
(!result.isAccessible() || !result.isStaticsScopeCorrect())) {
|
||||
@@ -656,6 +678,7 @@ final class JavaErrorVisitor extends JavaElementVisitor {
|
||||
if (!hasErrorResults()) myClassChecker.checkClassExtendsForeignInnerClass(ref, resolved);
|
||||
if (!hasErrorResults() && parent instanceof PsiNewExpression newExpression) myGenericsChecker.checkDiamondTypeNotAllowed(newExpression);
|
||||
if (!hasErrorResults()) myGenericsChecker.checkSelectStaticClassFromParameterizedType(resolved, ref);
|
||||
if (!hasErrorResults() && resolved instanceof PsiClass psiClass) myExpressionChecker.checkRestrictedIdentifierReference(ref, psiClass);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@@ -80,6 +80,24 @@ final class TypeChecker {
|
||||
}
|
||||
}
|
||||
|
||||
void checkVariableInitializerType(@NotNull PsiVariable variable) {
|
||||
PsiExpression initializer = variable.getInitializer();
|
||||
// array initializer checked in checkArrayInitializerApplicable
|
||||
if (initializer == null || initializer instanceof PsiArrayInitializerExpression) return;
|
||||
PsiType lType = variable.getType();
|
||||
PsiType rType = initializer.getType();
|
||||
myVisitor.myExpressionChecker.checkAssignability(lType, rType, initializer, initializer);
|
||||
}
|
||||
|
||||
void checkVarTypeApplicability(@NotNull PsiVariable variable) {
|
||||
if (variable instanceof PsiLocalVariable local && variable.getTypeElement().isInferredType()) {
|
||||
PsiElement parent = variable.getParent();
|
||||
if (parent instanceof PsiDeclarationStatement statement && statement.getDeclaredElements().length > 1) {
|
||||
myVisitor.report(JavaErrorKinds.LVTI_COMPOUND.create(local));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean allChildrenAreNullLiterals(PsiExpression expression) {
|
||||
expression = PsiUtil.skipParenthesizedExprDown(expression);
|
||||
if (expression == null) return false;
|
||||
|
||||
@@ -622,12 +622,20 @@ public final class JavaErrorKinds {
|
||||
public static final Simple<PsiTypeElement> TYPE_WILDCARD_CANNOT_BE_INSTANTIATED =
|
||||
error(PsiTypeElement.class, "type.wildcard.cannot.be.instantiated")
|
||||
.withRawDescription(type -> message("type.wildcard.cannot.be.instantiated", formatType(type.getType())));
|
||||
public static final Simple<PsiJavaCodeReferenceElement> TYPE_RESTRICTED_IDENTIFIER =
|
||||
error(PsiJavaCodeReferenceElement.class, "type.restricted.identifier")
|
||||
.withAnchor(ref -> requireNonNullElse(ref.getReferenceNameElement(), ref))
|
||||
.withRawDescription(ref -> message("type.restricted.identifier", ref.getReferenceName()));
|
||||
|
||||
public static final Simple<PsiExpression> FOREACH_NOT_APPLICABLE = error(PsiExpression.class, "foreach.not.applicable")
|
||||
.withRawDescription(expression -> message("foreach.not.applicable", formatType(expression.getType())));
|
||||
|
||||
public static final Simple<PsiLocalVariable> LVTI_NO_INITIALIZER = error(PsiLocalVariable.class, "lvti.no.initializer")
|
||||
.withAnchor(var -> var.getTypeElement());
|
||||
public static final Parameterized<PsiReferenceExpression, PsiLocalVariable> LVTI_SELF_REFERENCED =
|
||||
parameterized(PsiReferenceExpression.class, PsiLocalVariable.class, "lvti.self.referenced")
|
||||
.withRawDescription((ref, var) -> message("lvti.self.referenced", var.getName()));
|
||||
public static final Simple<PsiLocalVariable> LVTI_COMPOUND = error(PsiLocalVariable.class, "lvti.compound");
|
||||
public static final Simple<PsiLocalVariable> LVTI_VOID = error(PsiLocalVariable.class, "lvti.void")
|
||||
.withAnchor(var -> var.getTypeElement());
|
||||
public static final Simple<PsiLocalVariable> LVTI_NULL = error(PsiLocalVariable.class, "lvti.null")
|
||||
@@ -872,7 +880,7 @@ public final class JavaErrorKinds {
|
||||
.withDescription((psi, ctx) -> ctx.createDescription());
|
||||
public static final Parameterized<PsiMethodCallExpression, JavaResolveResult[]> CALL_UNRESOLVED =
|
||||
parameterized(PsiMethodCallExpression.class, JavaResolveResult[].class, "call.unresolved")
|
||||
.withAnchor((call, results) -> requireNonNullElse(call.getMethodExpression().getReferenceNameElement(), call))
|
||||
.withAnchor((call, results) -> call.getArgumentList())
|
||||
.withRawDescription((call, results) -> message(
|
||||
"call.unresolved", call.getMethodExpression().getReferenceName() + formatArgumentTypes(call.getArgumentList(), true)));
|
||||
public static final Parameterized<PsiMethodCallExpression, JavaAmbiguousCallContext> CALL_AMBIGUOUS =
|
||||
|
||||
@@ -233,6 +233,10 @@ final class AdaptExpressionTypeFixUtil {
|
||||
@Nullable PsiType expectedType,
|
||||
@Nullable PsiType actualType) {
|
||||
if (actualType == null || expectedType == null) return;
|
||||
HighlightFixUtil.registerChangeVariableTypeFixes(expression, expectedType, info);
|
||||
if (!(expression.getParent() instanceof PsiConditionalExpression && PsiTypes.voidType().equals(expectedType))) {
|
||||
info.accept(HighlightFixUtil.createChangeReturnTypeFix(expression, expectedType));
|
||||
}
|
||||
boolean mentionsTypeArgument = mentionsTypeArgument(expression, actualType);
|
||||
expectedType = GenericsUtil.getVariableTypeByExpressionType(expectedType);
|
||||
String role = wholeRange ? null : getRole(expression);
|
||||
|
||||
@@ -137,22 +137,11 @@ public final class HighlightFixUtil {
|
||||
|
||||
static void registerChangeVariableTypeFixes(@NotNull PsiExpression expression,
|
||||
@NotNull PsiType type,
|
||||
@Nullable PsiExpression lExpr,
|
||||
@NotNull Consumer<? super CommonIntentionAction> info) {
|
||||
if (!(expression instanceof PsiReferenceExpression ref)) return;
|
||||
if (!(ref.resolve() instanceof PsiVariable variable)) return;
|
||||
|
||||
registerChangeVariableTypeFixes(variable, type, lExpr, info);
|
||||
|
||||
PsiExpression stripped = PsiUtil.skipParenthesizedExprDown(lExpr);
|
||||
if (stripped instanceof PsiMethodCallExpression call && lExpr.getParent() instanceof PsiAssignmentExpression assignment) {
|
||||
if (assignment.getParent() instanceof PsiStatement) {
|
||||
PsiMethod method = call.resolveMethod();
|
||||
if (method != null && PsiTypes.voidType().equals(method.getReturnType())) {
|
||||
info.accept(new ReplaceAssignmentFromVoidWithStatementIntentionAction(assignment, stripped));
|
||||
}
|
||||
}
|
||||
}
|
||||
registerChangeVariableTypeFixes(variable, type, info);
|
||||
}
|
||||
|
||||
static void registerUnhandledExceptionFixes(@NotNull PsiElement element, @NotNull Consumer<? super CommonIntentionAction> info) {
|
||||
@@ -197,27 +186,21 @@ public final class HighlightFixUtil {
|
||||
|
||||
static void registerChangeVariableTypeFixes(@NotNull PsiVariable parameter,
|
||||
@Nullable PsiType itemType,
|
||||
@Nullable PsiExpression expr,
|
||||
@Nullable HighlightInfo.Builder highlightInfo) {
|
||||
registerChangeVariableTypeFixes(parameter, itemType, expr, HighlightUtil.asConsumer(highlightInfo));
|
||||
registerChangeVariableTypeFixes(parameter, itemType, HighlightUtil.asConsumer(highlightInfo));
|
||||
}
|
||||
|
||||
static void registerChangeVariableTypeFixes(@NotNull PsiVariable parameter,
|
||||
@Nullable PsiType itemType,
|
||||
@Nullable PsiExpression expr,
|
||||
@NotNull Consumer<? super CommonIntentionAction> info) {
|
||||
for (IntentionAction action : getChangeVariableTypeFixes(parameter, itemType)) {
|
||||
info.accept(action);
|
||||
}
|
||||
IntentionAction fix = createChangeReturnTypeFix(expr, parameter.getType());
|
||||
if (fix != null) {
|
||||
info.accept(fix);
|
||||
}
|
||||
}
|
||||
|
||||
static @Nullable IntentionAction createChangeReturnTypeFix(@Nullable PsiExpression expr, @NotNull PsiType toType) {
|
||||
if (expr instanceof PsiMethodCallExpression) {
|
||||
PsiMethod method = ((PsiMethodCallExpression)expr).resolveMethod();
|
||||
if (expr instanceof PsiMethodCallExpression call) {
|
||||
PsiMethod method = call.resolveMethod();
|
||||
if (method != null) {
|
||||
return PriorityIntentionActionWrapper
|
||||
.lowPriority(QuickFixFactory.getInstance().createMethodReturnFix(method, toType, true));
|
||||
@@ -680,7 +663,7 @@ public final class HighlightFixUtil {
|
||||
PsiType expectedTypeByApplicabilityConstraints = resolveResult.getSubstitutor(false).substitute(resolved.getReturnType());
|
||||
if (expectedTypeByApplicabilityConstraints != null && !variable.getType().isAssignableFrom(expectedTypeByApplicabilityConstraints) &&
|
||||
PsiTypesUtil.allTypeParametersResolved(variable, expectedTypeByApplicabilityConstraints)) {
|
||||
registerChangeVariableTypeFixes(variable, expectedTypeByApplicabilityConstraints, methodCall, info);
|
||||
registerChangeVariableTypeFixes(variable, expectedTypeByApplicabilityConstraints, info);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -755,7 +738,7 @@ public final class HighlightFixUtil {
|
||||
}
|
||||
PsiSubstitutor substitutor = factory.createSubstitutor(map);
|
||||
PsiType suggestedType = factory.createType(aClass, substitutor);
|
||||
registerChangeVariableTypeFixes(variable, suggestedType, variable.getInitializer(), info);
|
||||
registerChangeVariableTypeFixes(variable, suggestedType, info);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -200,7 +200,7 @@ public final class HighlightMethodUtil {
|
||||
HighlightUtil.registerReturnTypeFixes(builder, containingMethod, actualType);
|
||||
}
|
||||
} else if (parent instanceof PsiLocalVariable var) {
|
||||
HighlightFixUtil.registerChangeVariableTypeFixes(var, actualType, var.getInitializer(), builder);
|
||||
HighlightFixUtil.registerChangeVariableTypeFixes(var, actualType, builder);
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -247,55 +247,6 @@ public final class HighlightUtil {
|
||||
return null;
|
||||
}
|
||||
|
||||
static HighlightInfo.Builder checkVariableInitializerType(@NotNull PsiVariable variable) {
|
||||
PsiExpression initializer = variable.getInitializer();
|
||||
// array initializer checked in checkArrayInitializerApplicable
|
||||
if (initializer == null || initializer instanceof PsiArrayInitializerExpression) return null;
|
||||
PsiType lType = variable.getType();
|
||||
PsiType rType = initializer.getType();
|
||||
PsiTypeElement typeElement = variable.getTypeElement();
|
||||
int start = typeElement != null ? typeElement.getTextRange().getStartOffset() : variable.getTextRange().getStartOffset();
|
||||
int end = variable.getTextRange().getEndOffset();
|
||||
HighlightInfo.Builder highlightInfo = checkAssignability(lType, rType, initializer, new TextRange(start, end), 0);
|
||||
if (highlightInfo != null) {
|
||||
HighlightFixUtil.registerChangeVariableTypeFixes(variable, rType, variable.getInitializer(), highlightInfo);
|
||||
HighlightFixUtil.registerChangeVariableTypeFixes(initializer, lType, null, asConsumer(highlightInfo));
|
||||
}
|
||||
return highlightInfo;
|
||||
}
|
||||
|
||||
static HighlightInfo.Builder checkRestrictedIdentifierReference(@NotNull PsiJavaCodeReferenceElement ref,
|
||||
@NotNull PsiClass resolved,
|
||||
@NotNull LanguageLevel languageLevel) {
|
||||
String name = resolved.getName();
|
||||
if (PsiTypesUtil.isRestrictedIdentifier(name, languageLevel)) {
|
||||
String message = JavaErrorBundle.message("restricted.identifier.reference", name);
|
||||
PsiElement range = ObjectUtils.notNull(ref.getReferenceNameElement(), ref);
|
||||
return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).descriptionAndTooltip(message).range(range);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
static HighlightInfo.Builder checkVarTypeSelfReferencing(@NotNull PsiLocalVariable resolved, @NotNull PsiReferenceExpression ref) {
|
||||
if (PsiTreeUtil.isAncestor(resolved.getInitializer(), ref, false) && resolved.getTypeElement().isInferredType()) {
|
||||
return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR)
|
||||
.descriptionAndTooltip(JavaErrorBundle.message("lvti.selfReferenced", resolved.getName()))
|
||||
.range(ref);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
static HighlightInfo.Builder checkVarTypeApplicability(@NotNull PsiVariable variable) {
|
||||
if (variable instanceof PsiLocalVariable && variable.getTypeElement().isInferredType()) {
|
||||
PsiElement parent = variable.getParent();
|
||||
if (parent instanceof PsiDeclarationStatement statement && statement.getDeclaredElements().length > 1) {
|
||||
String message = JavaErrorBundle.message("lvti.compound");
|
||||
return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).descriptionAndTooltip(message).range(variable);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
static HighlightInfo.Builder checkAssignability(@Nullable PsiType lType,
|
||||
@Nullable PsiType rType,
|
||||
@Nullable PsiExpression expression,
|
||||
@@ -571,10 +522,10 @@ public final class HighlightUtil {
|
||||
}
|
||||
}
|
||||
else if (parent instanceof PsiLocalVariable localVariable) {
|
||||
HighlightFixUtil.registerChangeVariableTypeFixes(localVariable, expectedType, null, info);
|
||||
HighlightFixUtil.registerChangeVariableTypeFixes(localVariable, expectedType, info);
|
||||
}
|
||||
else if (parent instanceof PsiAssignmentExpression assignmentExpression) {
|
||||
HighlightFixUtil.registerChangeVariableTypeFixes(assignmentExpression.getLExpression(), expectedType, null, asConsumer(info));
|
||||
HighlightFixUtil.registerChangeVariableTypeFixes(assignmentExpression.getLExpression(), expectedType, asConsumer(info));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -744,9 +744,6 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
|
||||
if (!hasErrorResults()) {
|
||||
add(HighlightUtil.checkPackageAndClassConflict(ref, myFile));
|
||||
}
|
||||
if (!hasErrorResults() && resolved instanceof PsiClass) {
|
||||
add(HighlightUtil.checkRestrictedIdentifierReference(ref, (PsiClass)resolved, myLanguageLevel));
|
||||
}
|
||||
if (!hasErrorResults()) {
|
||||
add(HighlightUtil.checkMemberReferencedBeforeConstructorCalled(ref, resolved, mySurroundingConstructor));
|
||||
}
|
||||
@@ -811,9 +808,6 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
|
||||
catch (IndexNotReadyException ignored) {
|
||||
}
|
||||
}
|
||||
if (!hasErrorResults() && resolved instanceof PsiLocalVariable localVariable) {
|
||||
add(HighlightUtil.checkVarTypeSelfReferencing(localVariable, expression));
|
||||
}
|
||||
}
|
||||
|
||||
PsiElement parent = expression.getParent();
|
||||
@@ -1116,30 +1110,6 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitVariable(@NotNull PsiVariable variable) {
|
||||
super.visitVariable(variable);
|
||||
if (variable instanceof PsiPatternVariable patternVariable) {
|
||||
PsiElement context = PsiTreeUtil.getParentOfType(variable,
|
||||
PsiInstanceOfExpression.class,
|
||||
PsiCaseLabelElementList.class,
|
||||
PsiForeachPatternStatement.class);
|
||||
if (!(context instanceof PsiForeachPatternStatement)) {
|
||||
JavaFeature feature = context instanceof PsiInstanceOfExpression ?
|
||||
JavaFeature.PATTERNS :
|
||||
JavaFeature.PATTERNS_IN_SWITCH;
|
||||
PsiIdentifier varIdentifier = patternVariable.getNameIdentifier();
|
||||
add(checkFeature(varIdentifier, feature));
|
||||
}
|
||||
}
|
||||
try {
|
||||
if (!hasErrorResults()) add(HighlightUtil.checkVarTypeApplicability(variable));
|
||||
if (!hasErrorResults()) add(HighlightUtil.checkVariableInitializerType(variable));
|
||||
}
|
||||
catch (IndexNotReadyException ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitConditionalExpression(@NotNull PsiConditionalExpression expression) {
|
||||
super.visitConditionalExpression(expression);
|
||||
|
||||
@@ -482,9 +482,6 @@ final class JavaErrorFixProvider {
|
||||
if (anchor instanceof PsiExpression expression) {
|
||||
AddTypeArgumentsConditionalFix.register(sink, expression, lType);
|
||||
AdaptExpressionTypeFixUtil.registerExpectedTypeFixes(sink, expression, lType, rType);
|
||||
if (!(expression.getParent() instanceof PsiConditionalExpression && PsiTypes.voidType().equals(lType))) {
|
||||
sink.accept(HighlightFixUtil.createChangeReturnTypeFix(expression, lType));
|
||||
}
|
||||
sink.accept(ChangeNewOperatorTypeFix.createFix(expression, lType));
|
||||
if (PsiTypes.booleanType().equals(lType) && expression instanceof PsiAssignmentExpression assignment &&
|
||||
assignment.getOperationTokenType() == JavaTokenType.EQ) {
|
||||
@@ -506,21 +503,33 @@ final class JavaErrorFixProvider {
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (parent instanceof PsiLocalVariable var && rType != null) {
|
||||
HighlightFixUtil.registerChangeVariableTypeFixes(var, rType, var.getInitializer(), sink);
|
||||
else if (parent instanceof PsiVariable var &&
|
||||
PsiUtil.skipParenthesizedExprDown(var.getInitializer()) == expression && rType != null) {
|
||||
HighlightFixUtil.registerChangeVariableTypeFixes(var, rType, sink);
|
||||
}
|
||||
else if (parent instanceof PsiAssignmentExpression assignment && assignment.getRExpression() == expression) {
|
||||
else if (parent instanceof PsiAssignmentExpression assignment &&
|
||||
PsiUtil.skipParenthesizedExprDown(assignment.getRExpression()) == expression) {
|
||||
PsiExpression lExpr = assignment.getLExpression();
|
||||
|
||||
sink.accept(myFactory.createChangeToAppendFix(assignment.getOperationTokenType(), lType, assignment));
|
||||
if (rType != null) {
|
||||
HighlightFixUtil.registerChangeVariableTypeFixes(lExpr, rType, expression, sink);
|
||||
HighlightFixUtil.registerChangeVariableTypeFixes(expression, lType, lExpr, sink);
|
||||
HighlightFixUtil.registerChangeVariableTypeFixes(lExpr, rType, sink);
|
||||
if (expression instanceof PsiMethodCallExpression call && assignment.getParent() instanceof PsiStatement &&
|
||||
PsiTypes.voidType().equals(rType)) {
|
||||
sink.accept(new ReplaceAssignmentFromVoidWithStatementIntentionAction(assignment, call));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (anchor instanceof PsiParameter parameter && parent instanceof PsiForeachStatement forEach) {
|
||||
HighlightFixUtil.registerChangeVariableTypeFixes(parameter, rType, forEach.getIteratedValue(), sink);
|
||||
HighlightFixUtil.registerChangeVariableTypeFixes(parameter, lType, sink);
|
||||
PsiExpression iteratedValue = forEach.getIteratedValue();
|
||||
if (iteratedValue != null && rType != null) {
|
||||
PsiType type = iteratedValue.getType();
|
||||
if (type instanceof PsiArrayType) {
|
||||
AdaptExpressionTypeFixUtil.registerExpectedTypeFixes(sink, iteratedValue, rType.createArrayType(), type);
|
||||
}
|
||||
}
|
||||
}
|
||||
HighlightFixUtil.registerChangeParameterClassFix(lType, rType, sink);
|
||||
});
|
||||
|
||||
@@ -372,11 +372,8 @@ restricted.identifier.reference=Illegal reference to restricted type ''{0}''
|
||||
|
||||
lvti.lambda=Cannot infer type: lambda expression requires an explicit target type
|
||||
lvti.method.ref=Cannot infer type: method reference requires an explicit target type
|
||||
lvti.compound='var' is not allowed in a compound declaration
|
||||
lvti.null=Cannot infer type: variable initializer is 'null'
|
||||
lvti.void=Cannot infer type: variable initializer is 'void'
|
||||
lvti.selfReferenced=Cannot infer type for ''{0}'', it is used in its own variable initializer
|
||||
|
||||
record.accessor.wrong.return.type=Incorrect component accessor return type. Expected: ''{0}'', found: ''{1}''
|
||||
record.canonical.constructor.wrong.parameter.type=Incorrect parameter type for record component ''{0}''. Expected: ''{1}'', found: ''{2}''
|
||||
record.canonical.constructor.wrong.parameter.name=Canonical constructor parameter names must match record component names. Expected: ''{0}'', found: ''{1}''
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
// "Make 'getData()' return 'int[]'" "true-preview"
|
||||
class Test {
|
||||
public static void main(String[] args) {
|
||||
for (int <caret>arg : getData()) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private static int[] getData() {
|
||||
return new String[]{};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
// "Make 'getData()' return 'int[]'" "true-preview"
|
||||
class Test {
|
||||
public static void main(String[] args) {
|
||||
for (int <caret>arg : getData()) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private static String[] getData() {
|
||||
return new String[]{};
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user