mirror of
https://gitflic.ru/project/openide/openide.git
synced 2025-12-13 15:52:01 +07:00
Java: inner class accessing local variable or parameter can't be static (IDEA-375602)
(cherry picked from commit 1b16d1388c09d51009b288ede89e73d156364619) IJ-CR-168593 GitOrigin-RevId: 7ff7cfa95cdc674c5b1d32a572eec0b95bbfb58d
This commit is contained in:
committed by
intellij-monorepo-bot
parent
5df57ad536
commit
9a906a8753
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2003-2017 Dave Griffith, Bas Leijdekkers
|
||||
* Copyright 2003-2025 Dave Griffith, Bas Leijdekkers
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -24,11 +24,11 @@ import org.jetbrains.annotations.NotNull;
|
||||
public class InnerClassReferenceVisitor extends JavaRecursiveElementWalkingVisitor {
|
||||
|
||||
private final PsiClass innerClass;
|
||||
private final boolean allowReferencesToLocalVariables;
|
||||
private boolean referencesStaticallyAccessible = true;
|
||||
private boolean allowReferencesToLocalVariables = true;
|
||||
|
||||
public InnerClassReferenceVisitor(@NotNull PsiClass innerClass) {
|
||||
this.innerClass = innerClass;
|
||||
this(innerClass, false);
|
||||
}
|
||||
|
||||
public InnerClassReferenceVisitor(@NotNull PsiClass innerClass, boolean allowReferencesToLocalVariables) {
|
||||
@@ -51,8 +51,8 @@ public class InnerClassReferenceVisitor extends JavaRecursiveElementWalkingVisit
|
||||
if (PsiTreeUtil.isAncestor(innerClass, aClass, false) || aClass.hasModifierProperty(PsiModifier.STATIC)) {
|
||||
return true;
|
||||
}
|
||||
if (aClass instanceof PsiTypeParameter) {
|
||||
PsiTypeParameterListOwner owner = ((PsiTypeParameter)aClass).getOwner();
|
||||
if (aClass instanceof PsiTypeParameter parameter) {
|
||||
PsiTypeParameterListOwner owner = parameter.getOwner();
|
||||
return owner != null && PsiTreeUtil.isAncestor(innerClass, owner, false);
|
||||
}
|
||||
final PsiClass containingClass = aClass.getContainingClass();
|
||||
@@ -98,7 +98,7 @@ public class InnerClassReferenceVisitor extends JavaRecursiveElementWalkingVisit
|
||||
}
|
||||
final PsiElement target = expression.resolve();
|
||||
if (target == null) {
|
||||
referencesStaticallyAccessible = false; // TODO(bartekpacia): We probably should introduce the 3rd "unknown" state to signal this
|
||||
referencesStaticallyAccessible = false;
|
||||
return;
|
||||
}
|
||||
if (target instanceof PsiLocalVariable || target instanceof PsiParameter) {
|
||||
@@ -128,7 +128,7 @@ public class InnerClassReferenceVisitor extends JavaRecursiveElementWalkingVisit
|
||||
}
|
||||
referencesStaticallyAccessible = false;
|
||||
}
|
||||
else if (target instanceof PsiClass && !isClassStaticallyAccessible((PsiClass)target)) {
|
||||
else if (target instanceof PsiClass aClass && !isClassStaticallyAccessible(aClass)) {
|
||||
referencesStaticallyAccessible = false;
|
||||
}
|
||||
}
|
||||
@@ -144,10 +144,7 @@ public class InnerClassReferenceVisitor extends JavaRecursiveElementWalkingVisit
|
||||
return;
|
||||
}
|
||||
final PsiElement target = classReference.resolve();
|
||||
if (!(target instanceof PsiClass)) {
|
||||
return;
|
||||
}
|
||||
if (!isClassStaticallyAccessible((PsiClass)target)) {
|
||||
if (target instanceof PsiClass aClass && !isClassStaticallyAccessible(aClass)) {
|
||||
referencesStaticallyAccessible = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -128,7 +128,7 @@ public final class ConvertToRecordFix implements LocalQuickFix {
|
||||
* @see com.siyeh.ig.memory.InnerClassMayBeStaticInspection
|
||||
*/
|
||||
private static boolean containsOuterNonStaticReferences(PsiClass psiClass) {
|
||||
InnerClassReferenceVisitor visitor = new InnerClassReferenceVisitor(psiClass, false);
|
||||
InnerClassReferenceVisitor visitor = new InnerClassReferenceVisitor(psiClass);
|
||||
psiClass.accept(visitor);
|
||||
return !visitor.canInnerClassBeStatic();
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2003-2023 Dave Griffith, Bas Leijdekkers
|
||||
* Copyright 2003-2025 Dave Griffith, Bas Leijdekkers
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -78,7 +78,7 @@ public final class AnonymousInnerClassMayBeStaticInspection extends BaseInspecti
|
||||
// strictly speaking can be named static inner class but not when part of the current containing class
|
||||
return;
|
||||
}
|
||||
final InnerClassReferenceVisitor visitor = new InnerClassReferenceVisitor(anonymousClass);
|
||||
final InnerClassReferenceVisitor visitor = new InnerClassReferenceVisitor(anonymousClass, true);
|
||||
anonymousClass.accept(visitor);
|
||||
if (!visitor.canInnerClassBeStatic()) {
|
||||
return;
|
||||
@@ -106,7 +106,7 @@ public final class AnonymousInnerClassMayBeStaticInspection extends BaseInspecti
|
||||
return;
|
||||
}
|
||||
final PsiElement target = reference.resolve();
|
||||
if (!(target instanceof PsiClass) || !PsiUtil.isLocalClass((PsiClass)target)) {
|
||||
if (!(target instanceof PsiClass aClass) || !PsiUtil.isLocalClass(aClass)) {
|
||||
return;
|
||||
}
|
||||
referenceToLocalClass = true;
|
||||
|
||||
@@ -26,4 +26,15 @@ class One<A> {
|
||||
public static void main(String[] args) {
|
||||
One.Two.Three<Void> x;
|
||||
}
|
||||
}
|
||||
class C {
|
||||
void x(int i) {
|
||||
new Object() {
|
||||
class Local { // can't be static
|
||||
int get() {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -26,4 +26,15 @@ class One<A> {
|
||||
public static void main(String[] args) {
|
||||
One<Void>.Two<Void>.Three<Void> x;
|
||||
}
|
||||
}
|
||||
class C {
|
||||
void x(int i) {
|
||||
new Object() {
|
||||
class Local { // can't be static
|
||||
int get() {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -1,18 +1,4 @@
|
||||
/*
|
||||
* Copyright 2000-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.siyeh.ig.classlayout;
|
||||
|
||||
import com.intellij.codeInspection.InspectionProfileEntry;
|
||||
@@ -69,6 +55,30 @@ public class ClassMayBeInterfaceInspectionTest extends LightJavaInspectionTestCa
|
||||
}""");
|
||||
}
|
||||
|
||||
public void testLocalClassAccessingParameter() {
|
||||
doTest("""
|
||||
class Outer {
|
||||
void x(int parameter) {
|
||||
abstract class Example {
|
||||
public static final int MY_CONST = 42;
|
||||
public abstract void foo();
|
||||
|
||||
public void g() {
|
||||
System.out.println(parameter);
|
||||
}
|
||||
}
|
||||
|
||||
class Inheritor extends Example {
|
||||
@Override
|
||||
public void foo() {
|
||||
System.out.println(MY_CONST);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
""");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected InspectionProfileEntry getInspection() {
|
||||
final ClassMayBeInterfaceInspection inspection = new ClassMayBeInterfaceInspection();
|
||||
|
||||
Reference in New Issue
Block a user