From a9e8828ed99e5aed37233fc648dee82804a0f64d Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Tue, 16 Jan 2024 16:25:26 +0100 Subject: [PATCH] Java: introduce VariableAccessUtils.getVariableReferences() convenience overload and use it also adds javadoc GitOrigin-RevId: b69dfea4b74880a67720c95d7a0695e69978bc24 --- .../dataFlow/java/CFGBuilder.java | 5 ++-- .../siyeh/ig/psiutils/ExpressionUtils.java | 6 ++--- .../ig/psiutils/VariableAccessUtils.java | 24 ++++++++++++++++--- .../DeconstructionCanBeUsedInspection.java | 7 +++--- ...iablesCanBeReplacedWithCastInspection.java | 4 ++-- .../streamMigration/CollectMigration.java | 5 ++-- .../FieldCanBeLocalInspection.java | 5 ++-- .../EncapsulateFieldsHandler.java | 4 ++-- .../SimplifyBooleanExpressionFix.java | 4 ++-- .../MoveInitializerToIfBranchFixer.java | 6 ++--- .../FieldMayBeStaticInspection.java | 2 +- .../TypeMigrationVariableTypeFixProvider.java | 5 ++-- 12 files changed, 43 insertions(+), 34 deletions(-) diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/java/CFGBuilder.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/java/CFGBuilder.java index ce29c75274ee..791b5a709204 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/java/CFGBuilder.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/java/CFGBuilder.java @@ -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 refs = VariableAccessUtils.getVariableReferences(localFn, scope); + List refs = VariableAccessUtils.getVariableReferences(localFn); if (ContainerUtil.getOnlyItem(refs) == stripped) { myAnalyzer.removeLambda(localLambda); return tryInlineLambda(argCount, localLambda, resultNullability, pushArgs); diff --git a/java/java-analysis-impl/src/com/siyeh/ig/psiutils/ExpressionUtils.java b/java/java-analysis-impl/src/com/siyeh/ig/psiutils/ExpressionUtils.java index a45074f6f830..c8765e66068e 100644 --- a/java/java-analysis-impl/src/com/siyeh/ig/psiutils/ExpressionUtils.java +++ b/java/java-analysis-impl/src/com/siyeh/ig/psiutils/ExpressionUtils.java @@ -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; } } diff --git a/java/java-analysis-impl/src/com/siyeh/ig/psiutils/VariableAccessUtils.java b/java/java-analysis-impl/src/com/siyeh/ig/psiutils/VariableAccessUtils.java index fce543fd57b7..66d97f2ac257 100644 --- a/java/java-analysis-impl/src/com/siyeh/ig/psiutils/VariableAccessUtils.java +++ b/java/java-analysis-impl/src/com/siyeh/ig/psiutils/VariableAccessUtils.java @@ -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 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 getVariableReferences(@NotNull PsiVariable variable, @Nullable PsiElement context) { if (context == null) return Collections.emptyList(); List 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); } diff --git a/java/java-impl-inspections/src/com/intellij/codeInspection/DeconstructionCanBeUsedInspection.java b/java/java-impl-inspections/src/com/intellij/codeInspection/DeconstructionCanBeUsedInspection.java index 3d1f8d01a0aa..6f39ea225c9e 100644 --- a/java/java-impl-inspections/src/com/intellij/codeInspection/DeconstructionCanBeUsedInspection.java +++ b/java/java-impl-inspections/src/com/intellij/codeInspection/DeconstructionCanBeUsedInspection.java @@ -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 used = new HashSet<>(); - List references = - VariableAccessUtils.getVariableReferences(variable, variable.getDeclarationScope()); + List references = VariableAccessUtils.getVariableReferences(variable); List> 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); } diff --git a/java/java-impl-inspections/src/com/intellij/codeInspection/PatternVariablesCanBeReplacedWithCastInspection.java b/java/java-impl-inspections/src/com/intellij/codeInspection/PatternVariablesCanBeReplacedWithCastInspection.java index f351488aa3d5..adfda3d5372e 100644 --- a/java/java-impl-inspections/src/com/intellij/codeInspection/PatternVariablesCanBeReplacedWithCastInspection.java +++ b/java/java-impl-inspections/src/com/intellij/codeInspection/PatternVariablesCanBeReplacedWithCastInspection.java @@ -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 references = VariableAccessUtils.getVariableReferences(variable, variable.getDeclarationScope()); + List references = VariableAccessUtils.getVariableReferences(variable); processReferences(references, variable, expression); deletePatternFromInstanceOf(expression); } diff --git a/java/java-impl-inspections/src/com/intellij/codeInspection/streamMigration/CollectMigration.java b/java/java-impl-inspections/src/com/intellij/codeInspection/streamMigration/CollectMigration.java index c3feb8cecc72..972fa064f0b2 100644 --- a/java/java-impl-inspections/src/com/intellij/codeInspection/streamMigration/CollectMigration.java +++ b/java/java-impl-inspections/src/com/intellij/codeInspection/streamMigration/CollectMigration.java @@ -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 targetReferences() { if (myTargetVariable == null) return StreamEx.empty(); List 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))); } diff --git a/java/java-impl-inspections/src/com/intellij/codeInspection/varScopeCanBeNarrowed/FieldCanBeLocalInspection.java b/java/java-impl-inspections/src/com/intellij/codeInspection/varScopeCanBeNarrowed/FieldCanBeLocalInspection.java index a64f3a7f0502..125c796ae4b9 100644 --- a/java/java-impl-inspections/src/com/intellij/codeInspection/varScopeCanBeNarrowed/FieldCanBeLocalInspection.java +++ b/java/java-impl-inspections/src/com/intellij/codeInspection/varScopeCanBeNarrowed/FieldCanBeLocalInspection.java @@ -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 - references = VariableAccessUtils.getVariableReferences(newVariable, PsiUtil.getVariableCodeBlock(newVariable, null)); + List references = VariableAccessUtils.getVariableReferences(newVariable); for (PsiJavaCodeReferenceElement reference : references) { CommonJavaInlineUtil.getInstance().inlineVariable(newVariable, initializer, reference, null); } diff --git a/java/java-impl-refactorings/src/com/intellij/refactoring/encapsulateFields/EncapsulateFieldsHandler.java b/java/java-impl-refactorings/src/com/intellij/refactoring/encapsulateFields/EncapsulateFieldsHandler.java index eb59601d55c2..29629373823b 100644 --- a/java/java-impl-refactorings/src/com/intellij/refactoring/encapsulateFields/EncapsulateFieldsHandler.java +++ b/java/java-impl-refactorings/src/com/intellij/refactoring/encapsulateFields/EncapsulateFieldsHandler.java @@ -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 getFieldReferences(@NotNull PsiField field) { - return VariableAccessUtils.getVariableReferences(field, field.getContainingFile()); + return VariableAccessUtils.getVariableReferences(field); } }; processor.performRefactoring(processor.findUsages()); diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/SimplifyBooleanExpressionFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/SimplifyBooleanExpressionFix.java index 93fd9e3d7022..448499d40e4f 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/SimplifyBooleanExpressionFix.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/SimplifyBooleanExpressionFix.java @@ -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 refs = VariableAccessUtils.getVariableReferences(variable, variable.getDeclarationScope()); + List refs = VariableAccessUtils.getVariableReferences(variable); if (refs.isEmpty()) return; PsiInstanceOfExpression target = newTargetForPatternVariable(subExpression, variable); if (target == null) return; diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/makefinal/MoveInitializerToIfBranchFixer.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/makefinal/MoveInitializerToIfBranchFixer.java index 98282ee32ae7..9e65c260a480 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/makefinal/MoveInitializerToIfBranchFixer.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/makefinal/MoveInitializerToIfBranchFixer.java @@ -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 initializers(@NotNull PsiLocalVariable var) { - PsiElement block = PsiUtil.getVariableCodeBlock(var, null); - if (block == null) return List.of(); - List references = VariableAccessUtils.getVariableReferences(var, block); + List references = VariableAccessUtils.getVariableReferences(var); List initializers = new ArrayList<>(); for (PsiReferenceExpression reference : references) { if (!PsiUtil.isAccessedForWriting(reference)) continue; diff --git a/java/java-impl/src/com/siyeh/ig/performance/FieldMayBeStaticInspection.java b/java/java-impl/src/com/siyeh/ig/performance/FieldMayBeStaticInspection.java index 62d3e57dd645..0e5a5b468e32 100644 --- a/java/java-impl/src/com/siyeh/ig/performance/FieldMayBeStaticInspection.java +++ b/java/java-impl/src/com/siyeh/ig/performance/FieldMayBeStaticInspection.java @@ -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 refs = VariableAccessUtils.getVariableReferences(field, field.getContainingFile()); + List refs = VariableAccessUtils.getVariableReferences(field); for (PsiReferenceExpression ref : refs) { PsiElement parent = PsiUtil.skipParenthesizedExprUp(ref.getParent()); if (parent instanceof PsiSynchronizedStatement) return true; diff --git a/java/typeMigration/src/com/intellij/refactoring/typeMigration/TypeMigrationVariableTypeFixProvider.java b/java/typeMigration/src/com/intellij/refactoring/typeMigration/TypeMigrationVariableTypeFixProvider.java index 60b3c9715454..b45b14f133d9 100644 --- a/java/typeMigration/src/com/intellij/refactoring/typeMigration/TypeMigrationVariableTypeFixProvider.java +++ b/java/typeMigration/src/com/intellij/refactoring/typeMigration/TypeMigrationVariableTypeFixProvider.java @@ -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 refs = VariableAccessUtils.getVariableReferences(variable, block); + List refs = VariableAccessUtils.getVariableReferences(variable); if (refs.isEmpty()) return false; Project project = variable.getProject(); TypeMigrationRules rules = new TypeMigrationRules(project);