[java][guarded pattern] IDEA-273957 - Good code red: 'cannot resolve symbol' introduced in instanceof pattern

IDEA didn't use to consider that there might be instanceof patterns in the guard expression, so it ignored this part during resolution. Now IDEA tries to resolve a reference against both the pattern variable and guarding expression.

GitOrigin-RevId: 249ce6ec8ec6db84f9a5fc4622b4433550b38bf4
This commit is contained in:
Nikita Eshkeev
2021-07-28 12:11:57 +00:00
committed by intellij-monorepo-bot
parent 903d772e5a
commit 827f379576
6 changed files with 72 additions and 9 deletions
@@ -47,6 +47,10 @@ public class PsiGuardedPatternImpl extends CompositePsiElement implements PsiGua
PsiElement lastParent,
@NotNull PsiElement place) {
final PsiPrimaryPattern patternVariable = getPrimaryPattern();
return patternVariable.processDeclarations(processor, state, null, place);
if (!patternVariable.processDeclarations(processor, state, null, place)) return false;
final PsiExpression expression = getGuardingExpression();
if (expression == null) return true;
return expression.processDeclarations(processor, state, lastParent, place);
}
}
@@ -0,0 +1,16 @@
class Main {
void f(Object o) {
if (o instanceof (CharSequence cs && cs instanceof String s)) {
System.out.println(s);
}
}
void g(Object o) {
switch (o) {
case Integer i && o instanceof String s:
System.out.println(s);
default:
};
}
}
@@ -0,0 +1,10 @@
class Main {
private String s = "";
void f(Object o) {
if (o instanceof (CharSequence cs && cs instanceof String s)) {
System.out.println(<caret>s);
}
}
}
@@ -0,0 +1,11 @@
class Main {
private String s = "";
void g(Object o) {
switch (o) {
case Integer i && o instanceof String s:
System.out.println(<caret>s);
};
}
}
@@ -72,6 +72,10 @@ public class LightPatternsForSwitchHighlightingTest extends LightJavaCodeInsight
assertSize(2, IdentifierHighlighterPass.getUsages(element, file, true));
}
public void testGuardWithInstanceOfPatternMatching() {
doTest();
}
private void doTest() {
myFixture.configureByFile(getTestName(false) + ".java");
myFixture.checkHighlighting();
@@ -13,6 +13,7 @@ import org.jetbrains.annotations.NotNull;
import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
import static com.intellij.testFramework.assertions.Assertions.assertThat;
@@ -46,15 +47,13 @@ public class GotoDeclarationTest extends LightJavaCodeInsightTestCase {
}
public void testGotoDirectory() {
String name = getTestName(false);
configureByFile("/codeInsight/gotoDeclaration/" + name + ".java");
configure();
PsiDirectory element = (PsiDirectory)GotoDeclarationAction.findTargetElement(getProject(), getEditor(), getEditor().getCaretModel().getOffset());
assertEquals("java.lang", JavaDirectoryService.getInstance().getPackage(element).getQualifiedName());
}
private void doTestMultipleConstructors() {
String name = getTestName(false);
configureByFile("/codeInsight/gotoDeclaration/" + name + ".java");
configure();
final int offset = getEditor().getCaretModel().getOffset();
final PsiElement[] elements =
GotoDeclarationAction.findAllTargetElements(getProject(), getEditor(), offset);
@@ -76,8 +75,7 @@ public class GotoDeclarationTest extends LightJavaCodeInsightTestCase {
}
public void testMultipleConstructorsButArrayCreation() {
String name = getTestName(false);
configureByFile("/codeInsight/gotoDeclaration/" + name + ".java");
configure();
final int offset = getEditor().getCaretModel().getOffset();
final PsiReference reference = getFile().findReferenceAt(offset);
assertNotNull(reference);
@@ -134,12 +132,32 @@ public class GotoDeclarationTest extends LightJavaCodeInsightTestCase {
doTestPatternMatchingGuard();
}
public void testGuardWithInstanceOfPatternMatchingInIf() {
doTestGoToPatternVariable();
}
public void testGuardWithInstanceOfPatternMatchingInSwitch() {
doTestGoToPatternVariable();
}
private void doTestPatternMatchingGuard() {
String name = getTestName(false);
configureByFile("/codeInsight/gotoDeclaration/" + name + ".java");
configure();
final PsiJavaFile file = (PsiJavaFile)getFile();
final PsiField field = PsiTreeUtil.findChildOfType(file, PsiField.class);
final PsiElement element = GotoDeclarationAction.findTargetElement(getProject(), getEditor(), getEditor().getCaretModel().getOffset());
assertThat(element).isEqualTo(field);
}
private void doTestGoToPatternVariable() {
configure();
final Iterator<PsiPatternVariable> iterator = PsiTreeUtil.findChildrenOfType(getFile(), PsiPatternVariable.class).iterator();
iterator.next();
final PsiElement element = GotoDeclarationAction.findTargetElement(getProject(), getEditor(), getEditor().getCaretModel().getOffset());
assertThat(element).isEqualTo(iterator.next());
}
private void configure() {
String name = getTestName(false);
configureByFile("/codeInsight/gotoDeclaration/" + name + ".java");
}
}