mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[java-highlighting] Fixes in unnamed variables highlighting (IDEA-323960)
1. Highlight C-style arrays 2. Do not highlight variables inside for initializer 3. Highlight variables without initializer 4. Better message for underscore references when unnamed variables are allowed GitOrigin-RevId: 5bca18969cf8fb0ea6e052b0aef71323bbfa69b5
This commit is contained in:
committed by
intellij-monorepo-bot
parent
75f3bf6de4
commit
a828a34968
@@ -650,7 +650,8 @@ notification.file.system.issue=File Operation Issue
|
||||
notification.content.cannot.move.file=Cannot move ''{0}'' into ''{1}'': {2}
|
||||
intention.family.name.replace.with.unnamed.pattern=Replace with unnamed pattern
|
||||
intention.name.ignore.exception=Ignore exception ''{0}''
|
||||
error.unnamed.variable.not.allowed=Unnamed variable is not allowed
|
||||
error.unnamed.field.not.allowed=Unnamed field is not allowed
|
||||
error.unnamed.method.parameter.not.allowed=Unnamed method parameter is not allowed
|
||||
error.unnamed.local.variable.not.allowed.in.this.context=Unnamed local variable is not allowed in this context
|
||||
error.unnamed.variable.not.allowed.in.this.context=Unnamed variable declaration is not allowed in this context
|
||||
error.unnamed.variable.brackets=Brackets are not allowed after unnamed variable declaration
|
||||
error.unnamed.variable.without.initializer=Unnamed variable declaration must have an initializer
|
||||
|
||||
+29
-7
@@ -68,6 +68,7 @@ import com.siyeh.ig.psiutils.ControlFlowUtils;
|
||||
import com.siyeh.ig.psiutils.InstanceOfUtils;
|
||||
import com.siyeh.ig.psiutils.VariableAccessUtils;
|
||||
import com.siyeh.ig.psiutils.VariableNameGenerator;
|
||||
import one.util.streamex.StreamEx;
|
||||
import org.jetbrains.annotations.*;
|
||||
|
||||
import java.awt.*;
|
||||
@@ -840,7 +841,9 @@ public final class HighlightUtil {
|
||||
PsiElement parent = identifier.getParent();
|
||||
if (languageLevel.isAtLeast(LanguageLevel.JDK_1_9) && !(parent instanceof PsiUnnamedPattern) &&
|
||||
!(parent instanceof PsiVariable var && var.isUnnamed())) {
|
||||
String text = JavaErrorBundle.message("underscore.identifier.error");
|
||||
String text = HighlightingFeature.UNNAMED_PATTERNS_AND_VARIABLES.isSufficient(languageLevel) ?
|
||||
JavaErrorBundle.message("underscore.identifier.error.unnamed")
|
||||
: JavaErrorBundle.message("underscore.identifier.error");
|
||||
return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(identifier).descriptionAndTooltip(text);
|
||||
}
|
||||
else if (languageLevel.isAtLeast(LanguageLevel.JDK_1_8)) {
|
||||
@@ -855,13 +858,27 @@ public final class HighlightUtil {
|
||||
return null;
|
||||
}
|
||||
|
||||
static HighlightInfo.Builder checkAllowedUnnamedLocation(@NotNull PsiVariable variable) {
|
||||
static HighlightInfo.Builder checkUnnamedVariableDeclaration(@NotNull PsiVariable variable) {
|
||||
if (isArrayDeclaration(variable)) {
|
||||
IntentionAction fix = new NormalizeBracketsFix(variable).asIntention();
|
||||
TokenSet brackets = TokenSet.create(JavaTokenType.LBRACKET, JavaTokenType.RBRACKET);
|
||||
TextRange range = StreamEx.of(variable.getChildren())
|
||||
.filter(t -> PsiUtil.isJavaToken(t, brackets))
|
||||
.map(PsiElement::getTextRangeInParent)
|
||||
.reduce(TextRange::union)
|
||||
.orElseThrow()
|
||||
.shiftRight(variable.getTextRange().getStartOffset());// Must have at least one
|
||||
return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(range).descriptionAndTooltip(
|
||||
JavaAnalysisBundle.message("error.unnamed.variable.brackets")).registerFix(fix, null, null, null, null);
|
||||
}
|
||||
if (variable instanceof PsiPatternVariable) return null;
|
||||
if (variable instanceof PsiResourceVariable) return null;
|
||||
String message;
|
||||
IntentionAction fix = null;
|
||||
if (variable instanceof PsiLocalVariable local) {
|
||||
if (local.getParent() instanceof PsiDeclarationStatement decl && decl.getParent() instanceof PsiCodeBlock) return null;
|
||||
message = JavaAnalysisBundle.message("error.unnamed.local.variable.not.allowed.in.this.context");
|
||||
if (local.getInitializer() != null) return null;
|
||||
message = JavaAnalysisBundle.message("error.unnamed.variable.without.initializer");
|
||||
fix = getFixFactory().createAddVariableInitializerFix(local);
|
||||
}
|
||||
else if (variable instanceof PsiParameter parameter) {
|
||||
PsiElement scope = parameter.getDeclarationScope();
|
||||
@@ -872,10 +889,15 @@ public final class HighlightUtil {
|
||||
message = JavaAnalysisBundle.message("error.unnamed.field.not.allowed");
|
||||
}
|
||||
else {
|
||||
message = JavaAnalysisBundle.message("error.unnamed.variable.not.allowed");
|
||||
message = JavaAnalysisBundle.message("error.unnamed.variable.not.allowed.in.this.context");
|
||||
}
|
||||
return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(Objects.requireNonNull(variable.getNameIdentifier()))
|
||||
.descriptionAndTooltip(message);
|
||||
TextRange range = TextRange.create(variable.getTextRange().getStartOffset(),
|
||||
Objects.requireNonNull(variable.getNameIdentifier()).getTextRange().getEndOffset());
|
||||
HighlightInfo.Builder builder = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(range).descriptionAndTooltip(message);
|
||||
if (fix != null) {
|
||||
builder.registerFix(fix, null, null, null, null);
|
||||
}
|
||||
return builder;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
+1
-1
@@ -780,7 +780,7 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
|
||||
if (notAvailable != null) {
|
||||
add(notAvailable);
|
||||
} else {
|
||||
add(HighlightUtil.checkAllowedUnnamedLocation(variable));
|
||||
add(HighlightUtil.checkUnnamedVariableDeclaration(variable));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -416,6 +416,7 @@ override.not.allowed.in.interfaces=@Override is not allowed when implementing in
|
||||
declaration.not.allowed=Declaration not allowed here
|
||||
|
||||
underscore.identifier.error=Since Java 9, '_' is a keyword, and may not be used as an identifier
|
||||
underscore.identifier.error.unnamed=Using '_' as a reference is not allowed
|
||||
underscore.lambda.identifier=Use of '_' as a lambda parameter name is not allowed
|
||||
|
||||
assert.identifier.warn=Use of 'assert' as an identifier is not supported in releases since Java 1.4
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@ public class UnnamedPatterns {
|
||||
record R(int a, int b) {}
|
||||
|
||||
void test(Object obj) {
|
||||
if (obj instanceof <error descr="Since Java 9, '_' is a keyword, and may not be used as an identifier">_</error>) {}
|
||||
if (obj instanceof <error descr="Using '_' as a reference is not allowed">_</error>) {}
|
||||
|
||||
if (obj instanceof R(_, _)) {}
|
||||
if (obj instanceof R(int a, _)) {
|
||||
|
||||
+24
-9
@@ -1,28 +1,43 @@
|
||||
import java.util.function.*;
|
||||
|
||||
public class UnnamedVariables {
|
||||
void testParameter(int <error descr="Unnamed method parameter is not allowed">_</error>, String <error descr="Unnamed method parameter is not allowed">_</error>) {
|
||||
System.out.println(<error descr="Since Java 9, '_' is a keyword, and may not be used as an identifier">_</error>);
|
||||
void testParameter(<error descr="Unnamed method parameter is not allowed">int _</error>, <error descr="Unnamed method parameter is not allowed">String _</error>) {
|
||||
System.out.println(<error descr="Using '_' as a reference is not allowed">_</error>);
|
||||
}
|
||||
|
||||
int <error descr="Unnamed field is not allowed">_</error> = 123;
|
||||
String s = <error descr="Since Java 9, '_' is a keyword, and may not be used as an identifier">_</error>;
|
||||
<error descr="Unnamed field is not allowed">int _</error> = 123;
|
||||
String s = <error descr="Using '_' as a reference is not allowed">_</error>;
|
||||
|
||||
void testLambda() {
|
||||
Consumer<String> consumer = _ -> System.out.println("Hello");
|
||||
Consumer<String> consumer2 = _ -> System.out.println(<error descr="Since Java 9, '_' is a keyword, and may not be used as an identifier">_</error>);
|
||||
Consumer<String> consumer3 = _ -> System.out.println(<error descr="Since Java 9, '_' is a keyword, and may not be used as an identifier">_</error>.trim());
|
||||
Consumer<String> consumer2 = _ -> System.out.println(<error descr="Using '_' as a reference is not allowed">_</error>);
|
||||
Consumer<String> consumer3 = _ -> System.out.println(<error descr="Using '_' as a reference is not allowed">_</error>.trim());
|
||||
Consumer<String> consumer4 = _ -> {
|
||||
var v = <error descr="Since Java 9, '_' is a keyword, and may not be used as an identifier">_</error>;
|
||||
System.out.println(v.<error descr="Cannot resolve method 'trim()'">trim</error>());
|
||||
var v = <error descr="Using '_' as a reference is not allowed">_</error>;
|
||||
System.out.println(v.<error descr="Cannot resolve method 'trim()'" textAttributesKey="WRONG_REFERENCES_ATTRIBUTES">trim</error>());
|
||||
};
|
||||
BiConsumer<String, String> consumer5 = (_,_) -> {};
|
||||
}
|
||||
|
||||
void testWhen(Object obj) {
|
||||
switch (obj) {
|
||||
case String _ when <error descr="Using '_' as a reference is not allowed">_</error>.isEmpty() -> {}
|
||||
}
|
||||
}
|
||||
|
||||
void testLocal() {
|
||||
int _ = 10;
|
||||
int _ = 20;
|
||||
for (int <error descr="Unnamed local variable is not allowed in this context">_</error> = 1;;) {}
|
||||
int _<error descr="Brackets are not allowed after unnamed variable declaration ">[]</error> = {30};
|
||||
int[] _ = {40};
|
||||
var _ = "string";
|
||||
for (int _ = 1;;) {}
|
||||
}
|
||||
|
||||
void testNoInitializer() {
|
||||
<error descr="Unnamed variable declaration must have an initializer">int _</error>;
|
||||
|
||||
for(<error descr="Unnamed variable declaration must have an initializer">int _</error>;;) {}
|
||||
}
|
||||
|
||||
void testCatch() {
|
||||
|
||||
Reference in New Issue
Block a user