mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
IG: check fields with initializers correctly in "Field may be final" inspection
This commit is contained in:
+5
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2009-2013 Bas Leijdekkers
|
||||
* Copyright 2009-2015 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,6 +24,10 @@ public class FinalUtils {
|
||||
private FinalUtils() {}
|
||||
|
||||
public static boolean canBeFinal(@NotNull PsiVariable variable) {
|
||||
if (variable.getInitializer() != null || variable instanceof PsiParameter) {
|
||||
// parameters hava implicit initializer
|
||||
return !VariableAccessUtils.variableIsAssigned(variable);
|
||||
}
|
||||
final FinalDefiniteAssignment definiteAssignment = new FinalDefiniteAssignment(variable);
|
||||
DefiniteAssignmentUtil.checkVariable(variable, definiteAssignment);
|
||||
return definiteAssignment.isDefinitelyAssigned() &&
|
||||
|
||||
+27
@@ -16,7 +16,10 @@
|
||||
package com.siyeh.ig.psiutils;
|
||||
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.search.searches.ReferencesSearch;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.util.Processor;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -79,6 +82,30 @@ public class VariableAccessUtils {
|
||||
return visitor.isPassed();
|
||||
}
|
||||
|
||||
public static boolean variableIsAssigned(@NotNull PsiVariable variable) {
|
||||
if (variable instanceof PsiField) {
|
||||
if (variable.hasModifierProperty(PsiModifier.PRIVATE)) {
|
||||
final PsiClass aClass = PsiUtil.getTopLevelClass(variable);
|
||||
return variableIsAssigned(variable, aClass);
|
||||
}
|
||||
return !ReferencesSearch.search(variable, variable.getUseScope()).forEach(new Processor<PsiReference>() {
|
||||
@Override
|
||||
public boolean process(PsiReference reference) {
|
||||
final PsiElement element = reference.getElement();
|
||||
if (!(element instanceof PsiExpression)) {
|
||||
return true;
|
||||
}
|
||||
final PsiExpression expression = (PsiExpression)element;
|
||||
return !PsiUtil.isAccessedForWriting(expression);
|
||||
}
|
||||
});
|
||||
}
|
||||
final PsiElement context =
|
||||
PsiTreeUtil.getParentOfType(variable, PsiCodeBlock.class, PsiMethod.class, PsiLambdaExpression.class,
|
||||
PsiCatchSection.class, PsiForStatement.class, PsiForeachStatement.class);
|
||||
return variableIsAssigned(variable, context);
|
||||
}
|
||||
|
||||
public static boolean variableIsAssigned(
|
||||
@NotNull PsiVariable variable, @Nullable PsiElement context) {
|
||||
if (context == null) {
|
||||
|
||||
+12
@@ -886,6 +886,18 @@ class T58 {
|
||||
x = 3;
|
||||
}
|
||||
}
|
||||
class T59 {
|
||||
private int i = 0;
|
||||
{
|
||||
assert true : i++;
|
||||
}
|
||||
}
|
||||
class T60 {
|
||||
private int i = 1;
|
||||
{
|
||||
if (false) i = 2;
|
||||
}
|
||||
}
|
||||
class Foo {
|
||||
|
||||
public interface Accessor<T> {
|
||||
|
||||
Reference in New Issue
Block a user