mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-18 09:34:34 +07:00
ensure non-initialized fields used inside lambdas are rejected if lambda is inside class initializer only (IDEA-154305)
This commit is contained in:
+21
-2
@@ -403,13 +403,32 @@ public class HighlightControlFlowUtil {
|
||||
private static boolean inInnerClass(@NotNull PsiElement psiElement, @Nullable PsiClass containingClass, @NotNull PsiFile containingFile) {
|
||||
PsiElement element = psiElement;
|
||||
while (element != null) {
|
||||
if (element instanceof PsiLambdaExpression) return false;
|
||||
if (element instanceof PsiClass) return !containingFile.getManager().areElementsEquivalent(element, containingClass);
|
||||
if (element instanceof PsiClass) {
|
||||
final boolean innerClass = !containingFile.getManager().areElementsEquivalent(element, containingClass);
|
||||
if (innerClass) {
|
||||
final PsiLambdaExpression lambdaExpression = PsiTreeUtil.getParentOfType(psiElement, PsiLambdaExpression.class);
|
||||
return lambdaExpression == null || !inLambdaInsideClassInitialization(containingClass, (PsiClass)element);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
element = element.getParent();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static boolean inLambdaInsideClassInitialization(@Nullable PsiClass containingClass, PsiClass aClass) {
|
||||
PsiMember member = aClass;
|
||||
while (member != null) {
|
||||
if (member.getContainingClass() == containingClass) {
|
||||
return member instanceof PsiField ||
|
||||
member instanceof PsiMethod && ((PsiMethod)member).isConstructor() ||
|
||||
member instanceof PsiClassInitializer;
|
||||
}
|
||||
member = PsiTreeUtil.getParentOfType(member, PsiMember.class, true);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean isReassigned(@NotNull PsiVariable variable,
|
||||
@NotNull Map<PsiElement, Collection<ControlFlowUtil.VariableInfo>> finalVarProblems) {
|
||||
if (variable instanceof PsiLocalVariable) {
|
||||
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
class Test {
|
||||
|
||||
protected final String init;
|
||||
protected final Runnable foo = new Runnable() {
|
||||
{
|
||||
Runnable r = () -> {
|
||||
new Runnable() {
|
||||
{
|
||||
System.out.println(<error descr="Variable 'init' might not have been initialized">init</error>);
|
||||
}
|
||||
@Override
|
||||
public void run() {
|
||||
|
||||
}
|
||||
};
|
||||
};
|
||||
}
|
||||
@Override
|
||||
public void run() {
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
public Test(String init) {
|
||||
this.init = init;
|
||||
}
|
||||
|
||||
private void createClass() {
|
||||
new Thread() {
|
||||
{
|
||||
Runnable runnable1 = () -> System.out.println(init);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
+4
@@ -300,6 +300,10 @@ public class NewLambdaHighlightingTest extends LightDaemonAnalyzerTestCase {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testFieldReferencedFromLambdaInitializations() throws Exception {
|
||||
doTest();
|
||||
}
|
||||
|
||||
private void doTest() {
|
||||
doTest(false);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user