mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
java [unused declaration] - switch on functional ref nodes
GitOrigin-RevId: b79fa6d91931bcc2c47f6f363f4a099736000d44
This commit is contained in:
committed by
intellij-monorepo-bot
parent
b2bbb963d6
commit
4572835609
+3
@@ -270,6 +270,9 @@ public final class RefJavaManagerImpl extends RefJavaManager {
|
||||
else if (uElement instanceof UField) {
|
||||
return new RefFieldImpl((UField)uElement, psi, myRefManager);
|
||||
}
|
||||
else if (uElement instanceof ULambdaExpression || uElement instanceof UCallableReferenceExpression) {
|
||||
return new RefFunctionalExpressionImpl((UExpression)uElement, psi, myRefManager);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
+34
-61
@@ -244,48 +244,45 @@ public class RefJavaUtilImpl extends RefJavaUtil {
|
||||
if (refResolved instanceof RefMethodImpl) {
|
||||
updateRefMethod(psiResolved, (RefMethodImpl)refResolved, node, decl);
|
||||
}
|
||||
else if (refResolved instanceof RefField) {
|
||||
if (node instanceof UResolvable) {
|
||||
UMethod uProperty = UastContextKt.toUElement(((UResolvable)node).resolve(), UMethod.class);
|
||||
if (uProperty != null) {
|
||||
// PsiMethod property = uProperty.getJavaPsi();
|
||||
// RefElement refProperty = refManager.getReference(uProperty);
|
||||
// if (refProperty != null) {
|
||||
// refProperty.waitForInitialized();
|
||||
// refFrom.addReference(refProperty, property, decl, false, true, node);
|
||||
// }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (psiResolved instanceof PsiMember) {
|
||||
//TODO support kotlin
|
||||
addClassReferenceForStaticImport(node, (PsiMember)psiResolved, refFrom, decl);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visitLambdaExpression(@NotNull ULambdaExpression lambda) {
|
||||
processFunctionalExpression(lambda, lambda.getFunctionalInterfaceType());
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visitCallableReferenceExpression(@NotNull UCallableReferenceExpression methodRef) {
|
||||
RefElement refMethod = refFrom.getRefManager().getReference(methodRef.getSourcePsi());
|
||||
if (refFrom == refMethod) {
|
||||
visitReferenceExpression(methodRef);
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
// todo currently if psiResolved is KtParameter, it doesn't convert to UParameter, that seems wrong
|
||||
UParameter uParam = UastContextKt.toUElement(psiResolved, UParameter.class);
|
||||
if (uParam != null) {
|
||||
addReferenceToLambdaParameter(uParam, psiResolved, decl, refFrom);
|
||||
}
|
||||
processFunctionalExpression(methodRef, getFunctionalInterfaceType(methodRef));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visitLambdaExpression(@NotNull ULambdaExpression node) {
|
||||
processFunctionalExpression(node, node.getFunctionalInterfaceType());
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visitCallableReferenceExpression(@NotNull UCallableReferenceExpression node) {
|
||||
visitReferenceExpression(node);
|
||||
// todo doesn't work for kotlin
|
||||
PsiType interfaceType = getFunctionalInterfaceType(node);
|
||||
processFunctionalExpression(node, interfaceType);
|
||||
markParametersReferenced(node, interfaceType);
|
||||
return false;
|
||||
}
|
||||
|
||||
private void markParametersReferenced(@NotNull UCallableReferenceExpression node, @Nullable PsiType type) {
|
||||
PsiMethod method = LambdaUtil.getFunctionalInterfaceMethod(type);
|
||||
if (method == null) return;
|
||||
for (PsiParameter param : method.getParameterList().getParameters()) {
|
||||
RefElement paramRef = refManager.getReference(param);
|
||||
if (paramRef != null) {
|
||||
paramRef.waitForInitialized();
|
||||
refFrom.addReference(paramRef, param, decl, false, true, node);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void processFunctionalExpression(@NotNull UExpression expression, @Nullable PsiType type) {
|
||||
PsiElement aClass = PsiUtil.resolveClassInType(type);
|
||||
if (aClass != null) {
|
||||
@@ -295,14 +292,11 @@ public class RefJavaUtilImpl extends RefJavaUtil {
|
||||
final RefElement refWhat = refManager.getReference(aClass);
|
||||
if (refWhat != null) refWhat.waitForInitialized();
|
||||
refFrom.addReference(refWhat, aClass, decl, false, true, null);
|
||||
final PsiMethod interfaceMethod = LambdaUtil.getFunctionalInterfaceMethod(type);
|
||||
if (interfaceMethod != null) {
|
||||
RefElement interfaceMethodRef = refManager.getReference(interfaceMethod);
|
||||
if (interfaceMethodRef != null) interfaceMethodRef.waitForInitialized();
|
||||
refFrom.addReference(interfaceMethodRef, interfaceMethod, decl, false, true, null);
|
||||
refManager.fireNodeMarkedReferenced(interfaceMethod, expression.getSourcePsi());
|
||||
}
|
||||
}
|
||||
PsiElement functionalExpr = expression.getSourcePsi();
|
||||
RefElement refFunctionalExpr = refFrom.getRefManager().getReference(functionalExpr);
|
||||
if (refFunctionalExpr != null) refFunctionalExpr.waitForInitialized();
|
||||
refFrom.addReference(refFunctionalExpr, functionalExpr, decl, false, true, expression);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -413,27 +407,6 @@ public class RefJavaUtilImpl extends RefJavaUtil {
|
||||
}
|
||||
}
|
||||
|
||||
private static void addReferenceToLambdaParameter(@NotNull UParameter uParam, @NotNull PsiElement param, @NotNull UElement decl,
|
||||
@NotNull RefJavaElementImpl refFrom) {
|
||||
ULambdaExpression lambda = UastUtils.getParentOfType(uParam, ULambdaExpression.class);
|
||||
if (lambda == null) return;
|
||||
int paramIndex = -1;
|
||||
List<UParameter> lambdaParams = lambda.getParameters();
|
||||
for (int i = 0; i < lambdaParams.size(); i++) {
|
||||
if (lambdaParams.get(i).equals(uParam)) {
|
||||
paramIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (paramIndex == -1) return;
|
||||
RefElement method = refFrom.getRefManager().getReference(LambdaUtil.getFunctionalInterfaceMethod(lambda.getFunctionalInterfaceType()));
|
||||
if (method instanceof RefMethod) {
|
||||
method.waitForInitialized();
|
||||
RefParameter[] methodParams = ((RefMethod)method).getParameters();
|
||||
refFrom.addReference(methodParams[paramIndex], param, decl, false, true, null);
|
||||
}
|
||||
}
|
||||
|
||||
private static void addClassReferenceForStaticImport(UExpression node,
|
||||
PsiMember psiResolved,
|
||||
RefJavaElementImpl refFrom, UElement decl) {
|
||||
|
||||
-24
@@ -59,30 +59,6 @@ public final class RedundantThrowsGraphAnnotator extends RefGraphAnnotatorEx {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMarkReferenced(PsiElement what, PsiElement from, boolean referencedFromClassInitializer) {
|
||||
if (from instanceof PsiFunctionalExpression) {
|
||||
RefElement refResolved = myRefManager.getReference(what);
|
||||
if (refResolved instanceof RefMethodImpl) {
|
||||
PsiFunctionalExpression expression = (PsiFunctionalExpression)from;
|
||||
final Collection<PsiClassType> exceptionTypes;
|
||||
if (expression instanceof PsiLambdaExpression) {
|
||||
PsiElement body = ((PsiLambdaExpression)expression).getBody();
|
||||
exceptionTypes = body != null ? ExceptionUtil.collectUnhandledExceptions(body, expression, false) : Collections.emptyList();
|
||||
}
|
||||
else {
|
||||
final PsiElement resolve = ((PsiMethodReferenceExpression)expression).resolve();
|
||||
exceptionTypes = resolve instanceof PsiMethod
|
||||
? Arrays.asList(((PsiMethod)resolve).getThrowsList().getReferencedTypes())
|
||||
: Collections.emptyList();
|
||||
}
|
||||
for (final PsiClassType exceptionType : exceptionTypes) {
|
||||
((RefMethodImpl)refResolved).updateThrowsList(exceptionType);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static Set<PsiClassType> getUnhandledExceptions(PsiCodeBlock body, PsiMethod method, PsiClass containingClass) {
|
||||
Collection<PsiClassType> types = ExceptionUtil.collectUnhandledExceptions(body, method, false);
|
||||
Set<PsiClassType> unhandled = new HashSet<>(types);
|
||||
|
||||
+12
-12
@@ -262,18 +262,18 @@ public final class UnusedDeclarationInspection extends UnusedDeclarationInspecti
|
||||
}
|
||||
}
|
||||
}
|
||||
//else if (refElement instanceof RefField) {
|
||||
// UField field = ((RefField)refElement).getUastElement();
|
||||
// if (field != null) {
|
||||
// UExpression initializer = field.getUastInitializer();
|
||||
// if (initializer != null) {
|
||||
// initializer = UastUtils.skipParenthesizedExprDown(initializer);
|
||||
// if (initializer instanceof ULambdaExpression) {
|
||||
// findUnusedLocalVariables(((ULambdaExpression)initializer).getBody(), refElement);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
else if (refElement instanceof RefField) {
|
||||
UField field = ((RefField)refElement).getUastElement();
|
||||
if (field != null) {
|
||||
UExpression initializer = field.getUastInitializer();
|
||||
if (initializer != null) {
|
||||
initializer = UastUtils.skipParenthesizedExprDown(initializer);
|
||||
if (initializer instanceof ULambdaExpression) {
|
||||
findUnusedLocalVariables(((ULambdaExpression)initializer).getBody(), refElement);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void findUnusedLocalVariables(UExpression body, RefElement refElement) {
|
||||
|
||||
@@ -1,5 +1,15 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<problems>
|
||||
<problem>
|
||||
<file>Lambda_UnusedMethod.java</file>
|
||||
<line>12</line>
|
||||
<description>Method is never used.</description>
|
||||
</problem>
|
||||
<problem>
|
||||
<file>MethodRef_UnusedMethod.java</file>
|
||||
<line>12</line>
|
||||
<description>Method is never used.</description>
|
||||
</problem>
|
||||
<problem>
|
||||
<file>Lambda_UnusedMethodInHierarchy.java</file>
|
||||
<line>12</line>
|
||||
|
||||
+6
-2
@@ -1,10 +1,14 @@
|
||||
public class Test {
|
||||
public static void main(String[] args) {
|
||||
final Memento m = () -> isPlaying;
|
||||
final Memento m = () -> isPlaying();
|
||||
System.out.println(m);
|
||||
}
|
||||
|
||||
private static boolean isPlaying() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public static interface Memento {
|
||||
boolean isPlaying();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,8 +2,105 @@
|
||||
<problems>
|
||||
<problem>
|
||||
<file>A.java</file>
|
||||
<line>3</line>
|
||||
<line>5</line>
|
||||
<description>Variable <code>i</code> is never used</description>
|
||||
</problem>
|
||||
<problem>
|
||||
<file>A.java</file>
|
||||
<line>7</line>
|
||||
<description>Variable <code>k</code> is never used</description>
|
||||
</problem>
|
||||
<problem>
|
||||
<file>A.java</file>
|
||||
<line>10</line>
|
||||
<description>Variable <code>unusedStr1</code> is never used</description>
|
||||
</problem>
|
||||
<problem>
|
||||
<file>A.java</file>
|
||||
<line>13</line>
|
||||
<description>Variable <code>unusedStr3</code> is never used</description>
|
||||
</problem>
|
||||
<problem>
|
||||
<file>A.java</file>
|
||||
<line>18</line>
|
||||
<description>Variable <code>unusedStr5</code> is never used</description>
|
||||
</problem>
|
||||
<problem>
|
||||
<file>A.java</file>
|
||||
<line>21</line>
|
||||
<description>Variable <code>unusedStr7</code> is never used</description>
|
||||
</problem>
|
||||
<problem>
|
||||
<file>A.java</file>
|
||||
<line>26</line>
|
||||
<description>Variable <code>unusedStr8</code> is never used</description>
|
||||
</problem>
|
||||
<problem>
|
||||
<file>A.java</file>
|
||||
<line>27</line>
|
||||
<description>Variable <code>unusedStr9</code> is never used</description>
|
||||
</problem>
|
||||
<problem>
|
||||
<file>A.java</file>
|
||||
<line>34</line>
|
||||
<description>Variable <code>unusedStr10</code> is never used</description>
|
||||
</problem>
|
||||
<problem>
|
||||
<file>A.java</file>
|
||||
<line>35</line>
|
||||
<description>Variable <code>unusedStr11</code> is never used</description>
|
||||
</problem>
|
||||
|
||||
<problem>
|
||||
<file>Lambda.java</file>
|
||||
<line>6</line>
|
||||
<description>Field has no usages.</description>
|
||||
</problem>
|
||||
<problem>
|
||||
<file>Lambda.java</file>
|
||||
<line>7</line>
|
||||
<description>Variable <code>i1</code> is never used</description>
|
||||
</problem>
|
||||
<problem>
|
||||
<file>Lambda.java</file>
|
||||
<line>12</line>
|
||||
<description>Variable <code>i3</code> is never used</description>
|
||||
</problem>
|
||||
<problem>
|
||||
<file>Lambda.java</file>
|
||||
<line>24</line>
|
||||
<description>Variable <code>i1</code> is never used</description>
|
||||
</problem>
|
||||
<problem>
|
||||
<file>Lambda.java</file>
|
||||
<line>29</line>
|
||||
<description>Variable <code>i3</code> is never used</description>
|
||||
</problem>
|
||||
|
||||
<problem>
|
||||
<file>AnonymousClass.java</file>
|
||||
<line>6</line>
|
||||
<description>Field has no usages.</description>
|
||||
</problem>
|
||||
<problem>
|
||||
<file>AnonymousClass.java</file>
|
||||
<line>10</line>
|
||||
<description>Variable <code>i1</code> is never used</description>
|
||||
</problem>
|
||||
<problem>
|
||||
<file>AnonymousClass.java</file>
|
||||
<line>21</line>
|
||||
<description>Variable <code>i3</code> is never used</description>
|
||||
</problem>
|
||||
<problem>
|
||||
<file>AnonymousClass.java</file>
|
||||
<line>39</line>
|
||||
<description>Variable <code>i1</code> is never used</description>
|
||||
</problem>
|
||||
<problem>
|
||||
<file>AnonymousClass.java</file>
|
||||
<line>50</line>
|
||||
<description>Variable <code>i3</code> is never used</description>
|
||||
</problem>
|
||||
</problems>
|
||||
|
||||
|
||||
@@ -1,7 +1,51 @@
|
||||
import java.util.*;
|
||||
|
||||
class A {
|
||||
public static void main(String[] args) {
|
||||
int i = 0;
|
||||
@SuppressWarnings("unused") int j = 0;
|
||||
int k;
|
||||
|
||||
initializeCons(value -> {
|
||||
String unusedStr1 = "s";
|
||||
@SuppressWarnings("unused") String unusedStr2 = "s";
|
||||
{
|
||||
String unusedStr3;
|
||||
}
|
||||
String unusedStr4 = "str";
|
||||
initializeCons(innerValue1 -> {
|
||||
{
|
||||
String unusedStr5 = unusedStr4;
|
||||
}
|
||||
String unusedStr6 = "s";
|
||||
String unusedStr7;
|
||||
initializeSup(() -> unusedStr6);
|
||||
|
||||
class Local {
|
||||
void test() {
|
||||
String unusedStr8;
|
||||
String unusedStr9 = "Str";
|
||||
}
|
||||
}
|
||||
new Local().test();
|
||||
|
||||
Local o = new Local() {
|
||||
void test() {
|
||||
String unusedStr10;
|
||||
String unusedStr11 = "Str";
|
||||
}
|
||||
}
|
||||
System.out.println(o);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
private static void initializeCons(Consumer<String> consumer) {
|
||||
consumer.accept("String to test");
|
||||
}
|
||||
|
||||
private static void initializeSup(Supplier<String> supplier) {
|
||||
supplier.get();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
interface Unused {
|
||||
boolean test();
|
||||
}
|
||||
|
||||
class Test {
|
||||
Unused lambda1 = new Unused() {
|
||||
|
||||
@java.lang.Override
|
||||
public boolean test() {
|
||||
int i1 = 1;
|
||||
Unused lambda2 = new Unused() {
|
||||
|
||||
@java.lang.Override
|
||||
public boolean test() {
|
||||
int i2 = 1;
|
||||
Unused lambda3 = new Unused() {
|
||||
|
||||
@java.lang.Override
|
||||
public boolean test() {
|
||||
System.out.println(i2);
|
||||
int i3 = 1;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
System.out.println(lambda3);
|
||||
return false;
|
||||
}
|
||||
};
|
||||
System.out.println(lambda2);
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
public static void main(String[] args) {
|
||||
bar(new Unused() {
|
||||
|
||||
@java.lang.Override
|
||||
public boolean test() {
|
||||
int i1 = 1;
|
||||
Unused lambda2 = new Unused() {
|
||||
|
||||
@java.lang.Override
|
||||
public boolean test() {
|
||||
int i2 = 1;
|
||||
Unused lambda3 = new Unused() {
|
||||
|
||||
@java.lang.Override
|
||||
public boolean test() {
|
||||
System.out.println(i2);
|
||||
int i3 = 1;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
System.out.println(lambda3);
|
||||
return false;
|
||||
}
|
||||
};
|
||||
System.out.println(lambda2);
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
static void bar(Unused unused) {
|
||||
unused.test();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
interface Unused {
|
||||
boolean test();
|
||||
}
|
||||
|
||||
class Test {
|
||||
Unused lambda1 = () -> {
|
||||
int i1 = 1;
|
||||
Unused lambda2 = () -> {
|
||||
int i2 = 1;
|
||||
Unused lambda3 = () -> {
|
||||
System.out.println(i2);
|
||||
int i3 = 1;
|
||||
return true;
|
||||
}
|
||||
System.out.println(lambda3);
|
||||
return false;
|
||||
};
|
||||
System.out.println(lambda2);
|
||||
return false;
|
||||
};
|
||||
|
||||
public static void main(String[] args) {
|
||||
bar(() -> {
|
||||
int i1 = 1;
|
||||
Unused lambda2 = () -> {
|
||||
int i2 = 1;
|
||||
Unused lambda3 = () -> {
|
||||
System.out.println(i2);
|
||||
int i3 = 1;
|
||||
return true;
|
||||
}
|
||||
System.out.println(lambda3);
|
||||
return false;
|
||||
};
|
||||
System.out.println(lambda2);
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
static void bar(Unused unused) {
|
||||
unused.test();
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,4 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<problems>
|
||||
<problem>
|
||||
<file>Test.java</file>
|
||||
<line>2</line>
|
||||
<description>All implementations of this method are empty</description>
|
||||
</problem>
|
||||
</problems>
|
||||
|
||||
|
||||
@@ -12,5 +12,11 @@
|
||||
<problem_class>Method returns the same value</problem_class>
|
||||
<description>Method always returns <code>0</code></description>
|
||||
</problem>
|
||||
<problem>
|
||||
<file>LambdaWithSameValue.java</file>
|
||||
<line>2</line>
|
||||
<problem_class>Method returns the same value</problem_class>
|
||||
<description>All implementations of this method always return <code>42</code></description>
|
||||
</problem>
|
||||
</problems>
|
||||
|
||||
|
||||
+2
-8
@@ -3,16 +3,10 @@ interface ILambdaTest {
|
||||
}
|
||||
|
||||
class LambdaTest implements ILambdaTest {
|
||||
ILambdaTest lambda = this::getResult;
|
||||
|
||||
@Override
|
||||
public int getResult() {
|
||||
return 42;
|
||||
}
|
||||
}
|
||||
|
||||
class LamdaTest2 implements ILambdaTest {
|
||||
|
||||
@Override
|
||||
public int getResult() {
|
||||
return 43;
|
||||
}
|
||||
}
|
||||
@@ -81,7 +81,7 @@ public class SafeDeleteTest extends MultiFileTestCase {
|
||||
public void testDeepDeleteParameterOtherTypeInBinaryExpression() throws Exception {
|
||||
doSingleFileTest();
|
||||
}
|
||||
|
||||
|
||||
public void testDeepDeleteFieldAndAssignedParameter() throws Exception {
|
||||
doSingleFileTest();
|
||||
}
|
||||
@@ -133,7 +133,7 @@ public class SafeDeleteTest extends MultiFileTestCase {
|
||||
public void testDeleteMethodWithPropertyUsage() {
|
||||
doTest("Foo");
|
||||
}
|
||||
|
||||
|
||||
public void testDeleteClassWithPropertyUsage() {
|
||||
doTest("Foo");
|
||||
}
|
||||
@@ -267,7 +267,7 @@ public class SafeDeleteTest extends MultiFileTestCase {
|
||||
}
|
||||
|
||||
public void testInterfaceAsTypeParameterBound() throws Exception {
|
||||
doSingleFileTest();
|
||||
doSingleFileTest();
|
||||
}
|
||||
|
||||
public void testNestedTypeParameterBounds() throws Exception {
|
||||
@@ -340,7 +340,7 @@ public class SafeDeleteTest extends MultiFileTestCase {
|
||||
public void testTypeParameterWithinMethodHierarchy() throws Exception {
|
||||
doSingleFileTest();
|
||||
}
|
||||
|
||||
|
||||
public void testTypeParameterNoMethodHierarchy() throws Exception {
|
||||
doSingleFileTest();
|
||||
}
|
||||
|
||||
+5
@@ -1,2 +1,7 @@
|
||||
<problems>
|
||||
<problem>
|
||||
<file>Lambda.java</file>
|
||||
<line>2</line>
|
||||
<description>Method <code>foo()</code> and all its derivables always return constants</description>
|
||||
</problem>
|
||||
</problems>
|
||||
|
||||
Reference in New Issue
Block a user