Java: introduce VariableAccessUtils.getVariableReferences() convenience overload and use it

also adds javadoc

GitOrigin-RevId: b69dfea4b74880a67720c95d7a0695e69978bc24
This commit is contained in:
Bas Leijdekkers
2024-01-22 19:24:24 +00:00
committed by intellij-monorepo-bot
parent 005032695d
commit a9e8828ed9
12 changed files with 43 additions and 34 deletions
@@ -1,4 +1,4 @@
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.codeInspection.dataFlow.java;
import com.intellij.codeInsight.Nullability;
@@ -828,8 +828,7 @@ public class CFGBuilder {
PsiLambdaExpression localLambda =
ObjectUtils.tryCast(PsiUtil.skipParenthesizedExprDown(localFn.getInitializer()), PsiLambdaExpression.class);
if (myAnalyzer.wasAdded(localLambda)) {
PsiElement scope = PsiUtil.getVariableCodeBlock(localFn, null);
List<PsiReferenceExpression> refs = VariableAccessUtils.getVariableReferences(localFn, scope);
List<PsiReferenceExpression> refs = VariableAccessUtils.getVariableReferences(localFn);
if (ContainerUtil.getOnlyItem(refs) == stripped) {
myAnalyzer.removeLambda(localLambda);
return tryInlineLambda(argCount, localLambda, resultNullability, pushArgs);
@@ -1,4 +1,4 @@
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.siyeh.ig.psiutils;
import com.intellij.codeInsight.AnnotationUtil;
@@ -15,7 +15,6 @@ import com.intellij.psi.codeStyle.CodeStyleManager;
import com.intellij.psi.impl.source.PsiFieldImpl;
import com.intellij.psi.impl.source.tree.Factory;
import com.intellij.psi.impl.source.tree.TreeElement;
import com.intellij.psi.search.searches.ReferencesSearch;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.util.InheritanceUtil;
import com.intellij.psi.util.*;
@@ -1017,8 +1016,7 @@ public final class ExpressionUtils {
reference.resolve() instanceof PsiLocalVariable variable &&
!(variable instanceof PsiResourceVariable)) {
PsiExpression initializer = variable.getInitializer();
if (initializer != null &&
List.of(reference).equals(VariableAccessUtils.getVariableReferences(variable, PsiUtil.getVariableCodeBlock(variable, null)))) {
if (initializer != null && List.of(reference).equals(VariableAccessUtils.getVariableReferences(variable))) {
return initializer;
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2003-2020 Dave Griffith, Bas Leijdekkers
* Copyright 2003-2024 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.
@@ -265,6 +265,25 @@ public final class VariableAccessUtils {
return ExpressionUtils.isReferenceTo(expression, variable);
}
/**
* Finds all references to the specified variable in the declaration scope of the variable,
* i.e. everywhere the variable is accessible.
* NOTE: this method will only search in the containing file for the variable. This may lead to incorrect results for fields.
*
* @param variable the variable to find references for
* @return a list of references, empty list if no references were found.
*/
public static List<PsiReferenceExpression> getVariableReferences(@NotNull PsiVariable variable) {
PsiElement scope = variable instanceof PsiField ? variable.getContainingFile() : PsiUtil.getVariableCodeBlock(variable, null);
return getVariableReferences(variable, scope);
}
/**
* Finds all references to the specified variable in the specified context.
* @param variable the variable to find references for
* @param context the context to find references in
* @return a list of references. When the specified context is {@code null}, the result will always be an empty list.
*/
public static List<PsiReferenceExpression> getVariableReferences(@NotNull PsiVariable variable, @Nullable PsiElement context) {
if (context == null) return Collections.emptyList();
List<PsiReferenceExpression> result = new ArrayList<>();
@@ -278,8 +297,7 @@ public final class VariableAccessUtils {
}
@Contract("_, null -> false")
public static boolean variableIsUsed(@NotNull PsiVariable variable,
@Nullable PsiElement context) {
public static boolean variableIsUsed(@NotNull PsiVariable variable, @Nullable PsiElement context) {
return context != null && VariableUsedVisitor.isVariableUsedIn(variable, context);
}
@@ -1,4 +1,4 @@
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.codeInspection;
import com.intellij.codeInsight.daemon.impl.analysis.HighlightingFeature;
@@ -53,8 +53,7 @@ public final class DeconstructionCanBeUsedInspection extends AbstractBaseJavaLoc
PsiRecordComponent[] components = resolved.getRecordComponents();
if (components.length == 0) return Collections.emptyList();
Set<PsiRecordComponent> used = new HashSet<>();
List<PsiReferenceExpression> references =
VariableAccessUtils.getVariableReferences(variable, variable.getDeclarationScope());
List<PsiReferenceExpression> references = VariableAccessUtils.getVariableReferences(variable);
List<List<PsiReferenceExpression>> result = new ArrayList<>();
for (int i = 0; i < components.length; i++) {
result.add(new ArrayList<>());
@@ -125,7 +124,7 @@ public final class DeconstructionCanBeUsedInspection extends AbstractBaseJavaLoc
for (PsiReferenceExpression expression : expressions) {
PsiLocalVariable variable = getVariableFromInitializer(expression);
if (variable != null) {
var references = VariableAccessUtils.getVariableReferences(variable, PsiUtil.getVariableCodeBlock(variable, null));
var references = VariableAccessUtils.getVariableReferences(variable);
for (PsiReferenceExpression ref : references) {
ExpressionUtils.bindReferenceTo(ref, s);
}
@@ -1,4 +1,4 @@
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.codeInspection;
import com.intellij.codeInsight.BlockUtils;
@@ -152,7 +152,7 @@ public final class PatternVariablesCanBeReplacedWithCastInspection extends Abstr
return;
}
List<PsiReferenceExpression> references = VariableAccessUtils.getVariableReferences(variable, variable.getDeclarationScope());
List<PsiReferenceExpression> references = VariableAccessUtils.getVariableReferences(variable);
processReferences(references, variable, expression);
deletePatternFromInstanceOf(expression);
}
@@ -1,4 +1,4 @@
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.codeInspection.streamMigration;
import com.intellij.codeInsight.Nullability;
@@ -189,8 +189,7 @@ class CollectMigration extends BaseStreamApiMigration {
StreamEx<? extends PsiExpression> targetReferences() {
if (myTargetVariable == null) return StreamEx.empty();
List<PsiElement> usedElements = usedElements().toList();
PsiElement block = PsiUtil.getVariableCodeBlock(myTargetVariable, null);
return StreamEx.of(VariableAccessUtils.getVariableReferences(myTargetVariable, block))
return StreamEx.of(VariableAccessUtils.getVariableReferences(myTargetVariable))
.filter(ref -> !ContainerUtil
.exists(usedElements, allowedUsage -> PsiTreeUtil.isAncestor(allowedUsage, ref, false)));
}
@@ -1,4 +1,4 @@
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.codeInspection.varScopeCanBeNarrowed;
import com.intellij.codeInsight.AnnotationUtil;
@@ -494,8 +494,7 @@ public final class FieldCanBeLocalInspection extends AbstractBaseJavaLocalInspec
if (newVariable != null) {
final PsiExpression initializer = PsiUtil.skipParenthesizedExprDown(newVariable.getInitializer());
if (VariableAccessUtils.isLocalVariableCopy(newVariable, initializer)) {
List<PsiReferenceExpression>
references = VariableAccessUtils.getVariableReferences(newVariable, PsiUtil.getVariableCodeBlock(newVariable, null));
List<PsiReferenceExpression> references = VariableAccessUtils.getVariableReferences(newVariable);
for (PsiJavaCodeReferenceElement reference : references) {
CommonJavaInlineUtil.getInstance().inlineVariable(newVariable, initializer, reference, null);
}
@@ -1,4 +1,4 @@
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.refactoring.encapsulateFields;
import com.intellij.codeInsight.generation.GenerateMembersUtil;
@@ -196,7 +196,7 @@ public class EncapsulateFieldsHandler implements PreviewableRefactoringActionHan
final EncapsulateFieldsProcessor processor = new EncapsulateFieldsProcessor(project, descriptor) {
@Override
protected Iterable<PsiReferenceExpression> getFieldReferences(@NotNull PsiField field) {
return VariableAccessUtils.getVariableReferences(field, field.getContainingFile());
return VariableAccessUtils.getVariableReferences(field);
}
};
processor.performRefactoring(processor.findUsages());
@@ -1,4 +1,4 @@
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.codeInsight.daemon.impl.quickfix;
@@ -228,7 +228,7 @@ public class SimplifyBooleanExpressionFix extends PsiUpdateModCommandAction<PsiE
}
private static void retargetPatternVariable(@NotNull PsiExpression subExpression, @NotNull PsiPatternVariable variable) {
List<PsiReferenceExpression> refs = VariableAccessUtils.getVariableReferences(variable, variable.getDeclarationScope());
List<PsiReferenceExpression> refs = VariableAccessUtils.getVariableReferences(variable);
if (refs.isEmpty()) return;
PsiInstanceOfExpression target = newTargetForPatternVariable(subExpression, variable);
if (target == null) return;
@@ -1,4 +1,4 @@
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.codeInsight.daemon.impl.quickfix.makefinal;
import com.intellij.codeInsight.BlockUtils;
@@ -117,9 +117,7 @@ final class MoveInitializerToIfBranchFixer implements EffectivelyFinalFixer {
}
private static @NotNull List<PsiExpressionStatement> initializers(@NotNull PsiLocalVariable var) {
PsiElement block = PsiUtil.getVariableCodeBlock(var, null);
if (block == null) return List.of();
List<PsiReferenceExpression> references = VariableAccessUtils.getVariableReferences(var, block);
List<PsiReferenceExpression> references = VariableAccessUtils.getVariableReferences(var);
List<PsiExpressionStatement> initializers = new ArrayList<>();
for (PsiReferenceExpression reference : references) {
if (!PsiUtil.isAccessedForWriting(reference)) continue;
@@ -113,7 +113,7 @@ public final class FieldMayBeStaticInspection extends BaseInspection {
private static boolean isIdentitySensitive(@NotNull PsiField field) {
if (field.getType() instanceof PsiPrimitiveType) return false;
List<PsiReferenceExpression> refs = VariableAccessUtils.getVariableReferences(field, field.getContainingFile());
List<PsiReferenceExpression> refs = VariableAccessUtils.getVariableReferences(field);
for (PsiReferenceExpression ref : refs) {
PsiElement parent = PsiUtil.skipParenthesizedExprUp(ref.getParent());
if (parent instanceof PsiSynchronizedStatement) return true;
@@ -1,4 +1,4 @@
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.refactoring.typeMigration;
import com.intellij.codeInsight.FileModificationService;
@@ -61,8 +61,7 @@ public final class TypeMigrationVariableTypeFixProvider implements ChangeVariabl
private static boolean typeMigrationMightBeUseful(@NotNull PsiVariable variable, @NotNull PsiType targetType) {
if (!PsiUtil.isJvmLocalVariable(variable)) return true;
PsiElement block = PsiUtil.getVariableCodeBlock(variable, null);
List<PsiReferenceExpression> refs = VariableAccessUtils.getVariableReferences(variable, block);
List<PsiReferenceExpression> refs = VariableAccessUtils.getVariableReferences(variable);
if (refs.isEmpty()) return false;
Project project = variable.getProject();
TypeMigrationRules rules = new TypeMigrationRules(project);