diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DataFlowInspectionBase.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DataFlowInspectionBase.java index d98335648379..0fcb81313b30 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DataFlowInspectionBase.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DataFlowInspectionBase.java @@ -3,6 +3,7 @@ package com.intellij.codeInspection.dataFlow; import com.intellij.codeInsight.AnnotationUtil; +import com.intellij.codeInsight.ExpressionUtil; import com.intellij.codeInsight.NullableNotNullManager; import com.intellij.codeInsight.PsiEquivalenceUtil; import com.intellij.codeInsight.daemon.GroupNames; @@ -312,7 +313,7 @@ public class DataFlowInspectionBase extends AbstractBaseJavaLocalInspectionTool PsiReferenceExpression ref = (PsiReferenceExpression)expr; PsiElement target = ref.resolve(); if (target instanceof PsiField && - (((PsiField)target).hasModifierProperty(PsiModifier.STATIC) || ExpressionUtils.isEffectivelyUnqualified(ref)) && + (((PsiField)target).hasModifierProperty(PsiModifier.STATIC) || ExpressionUtil.isEffectivelyUnqualified(ref)) && ((PsiField)target).getContainingClass() == ((PsiClassInitializer)context).getContainingClass()) { return; } diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaUtil.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaUtil.java index 51b0217acd53..c9cf40ed72e4 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaUtil.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaUtil.java @@ -15,6 +15,7 @@ */ package com.intellij.codeInspection.dataFlow; +import com.intellij.codeInsight.ExpressionUtil; import com.intellij.codeInspection.dataFlow.instructions.*; import com.intellij.codeInspection.dataFlow.value.DfaValue; import com.intellij.codeInspection.dataFlow.value.DfaValueFactory; @@ -258,7 +259,7 @@ public class DfaUtil { if (!(e instanceof PsiMethodCallExpression)) return false; PsiMethodCallExpression call = (PsiMethodCallExpression)e; return call.getMethodExpression().isReferenceTo(referrer) && - (isStatic || ExpressionUtils.isEffectivelyUnqualified(call.getMethodExpression())); + (isStatic || ExpressionUtil.isEffectivelyUnqualified(call.getMethodExpression())); }; if (ExpressionUtils.isMatchingChildAlwaysExecuted(initializer, callToMethod)) { // current method is definitely called from some field initialization diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/value/DfaExpressionFactory.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/value/DfaExpressionFactory.java index 60160475373e..e968c35ebd1b 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/value/DfaExpressionFactory.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/value/DfaExpressionFactory.java @@ -16,6 +16,7 @@ package com.intellij.codeInspection.dataFlow.value; import com.intellij.codeInsight.AnnotationUtil; +import com.intellij.codeInsight.ExpressionUtil; import com.intellij.codeInspection.dataFlow.*; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.util.Condition; @@ -142,7 +143,7 @@ public class DfaExpressionFactory { if (constValue != null && !maybeUninitializedConstant(constValue, refExpr, var)) return constValue; } - if (ExpressionUtils.isEffectivelyUnqualified(refExpr) || isStaticFinalConstantWithoutInitializationHacks(var) || + if (ExpressionUtil.isEffectivelyUnqualified(refExpr) || isStaticFinalConstantWithoutInitializationHacks(var) || (var instanceof PsiMethod && var.hasModifierProperty(PsiModifier.STATIC))) { return myFactory.getVarFactory().createVariableValue(var, refExpr.getType(), false, null); } diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/CheckInitialized.java b/java/java-impl/src/com/intellij/codeInsight/completion/CheckInitialized.java index c3981152553d..156a1f6e3987 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/CheckInitialized.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/CheckInitialized.java @@ -15,6 +15,7 @@ */ package com.intellij.codeInsight.completion; +import com.intellij.codeInsight.ExpressionUtil; import com.intellij.codeInsight.daemon.ImplicitUsageProvider; import com.intellij.psi.*; import com.intellij.psi.filters.ElementFilter; @@ -68,7 +69,7 @@ class CheckInitialized implements ElementFilter { } PsiElement parent = element.getParent(); - if (parent instanceof PsiReferenceExpression && !ExpressionUtils.isEffectivelyUnqualified((PsiReferenceExpression)parent)) { + if (parent instanceof PsiReferenceExpression && !ExpressionUtil.isEffectivelyUnqualified((PsiReferenceExpression)parent)) { return Collections.emptySet(); } @@ -103,7 +104,7 @@ class CheckInitialized implements ElementFilter { @Override public void visitAssignmentExpression(PsiAssignmentExpression expression) { PsiExpression lExpression = expression.getLExpression(); - if (lExpression instanceof PsiReferenceExpression && ExpressionUtils.isEffectivelyUnqualified((PsiReferenceExpression)lExpression)) { + if (lExpression instanceof PsiReferenceExpression && ExpressionUtil.isEffectivelyUnqualified((PsiReferenceExpression)lExpression)) { PsiElement target = ((PsiReferenceExpression)lExpression).resolve(); if (target instanceof PsiField) { if (expression.getTextRange().getStartOffset() < statement.getTextRange().getStartOffset()) { diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateFromUsageUtils.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateFromUsageUtils.java index a56798d5285b..dd67d3f7eb6b 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateFromUsageUtils.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateFromUsageUtils.java @@ -25,6 +25,7 @@ import com.intellij.codeInsight.intention.impl.CreateClassDialog; import com.intellij.codeInsight.lookup.LookupElement; import com.intellij.codeInsight.lookup.LookupElementBuilder; import com.intellij.codeInsight.template.*; +import com.intellij.codeInsight.template.ExpressionUtil; import com.intellij.ide.fileTemplates.FileTemplate; import com.intellij.ide.fileTemplates.FileTemplateManager; import com.intellij.ide.fileTemplates.FileTemplateUtil; diff --git a/java/java-impl/src/com/intellij/codeInspection/SimplifyStreamApiCallChainsInspection.java b/java/java-impl/src/com/intellij/codeInspection/SimplifyStreamApiCallChainsInspection.java index 3d9f9ca603a6..db6dddc4de44 100644 --- a/java/java-impl/src/com/intellij/codeInspection/SimplifyStreamApiCallChainsInspection.java +++ b/java/java-impl/src/com/intellij/codeInspection/SimplifyStreamApiCallChainsInspection.java @@ -1,6 +1,7 @@ // Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. package com.intellij.codeInspection; +import com.intellij.codeInsight.ExpressionUtil; import com.intellij.codeInsight.NullableNotNullManager; import com.intellij.codeInsight.intention.impl.StreamRefactoringUtil; import com.intellij.codeInspection.dataFlow.DfaUtil; @@ -664,13 +665,13 @@ public class SimplifyStreamApiCallChainsInspection extends AbstractBaseJavaLocal } static boolean isParentNegated(PsiMethodCallExpression methodCall) { - if (ExpressionUtils.isEffectivelyUnqualified(methodCall.getMethodExpression())) return false; + if (ExpressionUtil.isEffectivelyUnqualified(methodCall.getMethodExpression())) return false; PsiElement parent = PsiUtil.skipParenthesizedExprUp(methodCall.getParent()); return parent instanceof PsiExpression && BoolUtils.isNegation((PsiExpression)parent); } static boolean isArgumentLambdaNegated(PsiMethodCallExpression methodCall) { - if (ExpressionUtils.isEffectivelyUnqualified(methodCall.getMethodExpression())) return false; + if (ExpressionUtil.isEffectivelyUnqualified(methodCall.getMethodExpression())) return false; PsiExpression[] expressions = methodCall.getArgumentList().getExpressions(); if(expressions.length != 1) return false; PsiExpression arg = expressions[0]; @@ -1650,7 +1651,7 @@ public class SimplifyStreamApiCallChainsInspection extends AbstractBaseJavaLocal PsiMethodReferenceExpression methodRef = (PsiMethodReferenceExpression)arg; if (COLLECTION_CONTAINS.methodReferenceMatches(methodRef) && !PsiMethodReferenceUtil.isStaticallyReferenced(methodRef) && - !ExpressionUtils.isEffectivelyUnqualified(methodRef)) { + !ExpressionUtil.isEffectivelyUnqualified(methodRef)) { return methodRef.getQualifierExpression(); } } @@ -1663,7 +1664,7 @@ public class SimplifyStreamApiCallChainsInspection extends AbstractBaseJavaLocal PsiMethodCallExpression call = tryCast(expression, PsiMethodCallExpression.class); if (COLLECTION_CONTAINS.test(call) && ExpressionUtils.isReferenceTo(call.getArgumentList().getExpressions()[0], parameter) && - !ExpressionUtils.isEffectivelyUnqualified(call.getMethodExpression())) { + !ExpressionUtil.isEffectivelyUnqualified(call.getMethodExpression())) { return call.getMethodExpression().getQualifierExpression(); } } @@ -1674,7 +1675,7 @@ public class SimplifyStreamApiCallChainsInspection extends AbstractBaseJavaLocal @Nullable private static PsiExpression extractLeft(PsiMethodCallExpression call) { PsiMethodCallExpression qualifierCall = getQualifierMethodCall(call); - if (!COLLECTION_STREAM.test(qualifierCall) || ExpressionUtils.isEffectivelyUnqualified(qualifierCall.getMethodExpression())) { + if (!COLLECTION_STREAM.test(qualifierCall) || ExpressionUtil.isEffectivelyUnqualified(qualifierCall.getMethodExpression())) { return null; } return PsiUtil.skipParenthesizedExprDown(qualifierCall.getMethodExpression().getQualifierExpression()); diff --git a/java/java-impl/src/com/intellij/refactoring/inline/InlineMethodProcessor.java b/java/java-impl/src/com/intellij/refactoring/inline/InlineMethodProcessor.java index 03b502a80c4a..f9de47768ebe 100644 --- a/java/java-impl/src/com/intellij/refactoring/inline/InlineMethodProcessor.java +++ b/java/java-impl/src/com/intellij/refactoring/inline/InlineMethodProcessor.java @@ -3,6 +3,7 @@ package com.intellij.refactoring.inline; import com.intellij.codeInsight.AnnotationUtil; import com.intellij.codeInsight.ChangeContextUtil; +import com.intellij.codeInsight.ExpressionUtil; import com.intellij.codeInsight.daemon.impl.quickfix.RemoveUnusedVariableUtil; import com.intellij.history.LocalHistory; import com.intellij.history.LocalHistoryAction; @@ -288,7 +289,7 @@ public class InlineMethodProcessor extends BaseRefactoringProcessor { PsiUtil.getEnclosingStaticElement(element, targetContainingClass) != null)) { targetContainingClasses.add(targetContainingClass); } - else if (element instanceof PsiReferenceExpression && !ControlFlowUtil.isUnqualified((PsiReferenceExpression)element)) { + else if (element instanceof PsiReferenceExpression && !ExpressionUtil.isEffectivelyUnqualified((PsiReferenceExpression)element)) { qualifiedCall = ((PsiReferenceExpression)element).getQualifierExpression(); } } diff --git a/java/java-psi-impl/src/com/intellij/codeInsight/ExpressionUtil.java b/java/java-psi-impl/src/com/intellij/codeInsight/ExpressionUtil.java new file mode 100644 index 000000000000..69311d74c02b --- /dev/null +++ b/java/java-psi-impl/src/com/intellij/codeInsight/ExpressionUtil.java @@ -0,0 +1,27 @@ +/* + * Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. + */ +package com.intellij.codeInsight; + +import com.intellij.psi.*; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.psi.util.PsiUtil; + +public class ExpressionUtil { + /** + * @return true if refExpression has no qualifier or has this qualifier corresponding to the inner most containing class + */ + public static boolean isEffectivelyUnqualified(PsiReferenceExpression refExpression) { + PsiExpression qualifier = PsiUtil.deparenthesizeExpression(refExpression.getQualifierExpression()); + if (qualifier == null) { + return true; + } + if (qualifier instanceof PsiThisExpression || qualifier instanceof PsiSuperExpression) { + final PsiJavaCodeReferenceElement thisQualifier = ((PsiQualifiedExpression)qualifier).getQualifier(); + if (thisQualifier == null) return true; + final PsiClass innerMostClass = PsiTreeUtil.getParentOfType(refExpression, PsiClass.class); + return innerMostClass == thisQualifier.resolve(); + } + return false; + } +} diff --git a/java/java-psi-impl/src/com/intellij/psi/controlFlow/ControlFlowUtil.java b/java/java-psi-impl/src/com/intellij/psi/controlFlow/ControlFlowUtil.java index 6a188a411a6a..2d15baf8efa4 100644 --- a/java/java-psi-impl/src/com/intellij/psi/controlFlow/ControlFlowUtil.java +++ b/java/java-psi-impl/src/com/intellij/psi/controlFlow/ControlFlowUtil.java @@ -16,6 +16,7 @@ package com.intellij.psi.controlFlow; import com.intellij.codeInsight.ExceptionUtil; +import com.intellij.codeInsight.ExpressionUtil; import com.intellij.openapi.diagnostic.Logger; import com.intellij.psi.*; import com.intellij.psi.impl.source.DummyHolder; @@ -1226,7 +1227,7 @@ public class ControlFlowUtil { private static PsiReferenceExpression findReferenceTo(PsiElement element, PsiVariable variable) { if (element instanceof PsiReferenceExpression - && isUnqualified((PsiReferenceExpression)element) + && ExpressionUtil.isEffectivelyUnqualified((PsiReferenceExpression)element) && ((PsiReferenceExpression)element).resolve() == variable) { return (PsiReferenceExpression)element; } @@ -1238,14 +1239,6 @@ public class ControlFlowUtil { return null; } - public static boolean isUnqualified(PsiReferenceExpression element) { - if (element.isQualified()) { - final PsiExpression qualifierExpression = PsiUtil.deparenthesizeExpression(element.getQualifierExpression()); - return qualifierExpression instanceof PsiThisExpression && ((PsiThisExpression)qualifierExpression).getQualifier() == null; - } - return true; - } - public static boolean isVariableDefinitelyAssigned(@NotNull final PsiVariable variable, @NotNull final ControlFlow flow) { class MyVisitor extends InstructionClientVisitor { diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/ExpressionUtils.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/ExpressionUtils.java index 3b615f089720..325c1f8fa557 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/ExpressionUtils.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/ExpressionUtils.java @@ -16,6 +16,7 @@ package com.siyeh.ig.psiutils; import com.intellij.codeInsight.AnnotationUtil; +import com.intellij.codeInsight.ExpressionUtil; import com.intellij.codeInsight.NullableNotNullManager; import com.intellij.codeInsight.PsiEquivalenceUtil; import com.intellij.openapi.project.Project; @@ -1112,18 +1113,12 @@ public class ExpressionUtils { return expression != null && nonStructuralChildren(expression).allMatch(PsiNewExpression.class::isInstance); } + /** + * Use {@link ExpressionUtil#isEffectivelyUnqualified} instead + */ + @Deprecated public static boolean isEffectivelyUnqualified(PsiReferenceExpression refExpression) { - PsiExpression qualifier = PsiUtil.deparenthesizeExpression(refExpression.getQualifierExpression()); - if (qualifier == null) { - return true; - } - if (qualifier instanceof PsiThisExpression || qualifier instanceof PsiSuperExpression) { - final PsiJavaCodeReferenceElement thisQualifier = ((PsiQualifiedExpression)qualifier).getQualifier(); - if (thisQualifier == null) return true; - final PsiClass innerMostClass = PsiTreeUtil.getParentOfType(refExpression, PsiClass.class); - return innerMostClass == thisQualifier.resolve(); - } - return false; + return ExpressionUtil.isEffectivelyUnqualified(refExpression); } /** diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/threading/NonAtomicOperationOnVolatileFieldInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/threading/NonAtomicOperationOnVolatileFieldInspection.java index db38d13eeac6..2cb35798aa4c 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/threading/NonAtomicOperationOnVolatileFieldInspection.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/threading/NonAtomicOperationOnVolatileFieldInspection.java @@ -15,8 +15,8 @@ */ package com.siyeh.ig.threading; +import com.intellij.codeInsight.ExpressionUtil; import com.intellij.psi.*; -import com.intellij.psi.controlFlow.ControlFlowUtil; import com.intellij.psi.tree.IElementType; import com.intellij.psi.util.PsiUtil; import com.siyeh.InspectionGadgetsBundle; @@ -81,7 +81,7 @@ public class NonAtomicOperationOnVolatileFieldInspection extends BaseInspection rhs.accept(new JavaRecursiveElementWalkingVisitor() { @Override public void visitReferenceExpression(PsiReferenceExpression reference) { - if (reference.isReferenceTo(volatileField) && ControlFlowUtil.isUnqualified(reference)) { + if (reference.isReferenceTo(volatileField) && ExpressionUtil.isEffectivelyUnqualified(reference)) { stopWalking(); final PsiElement referenceNameElement = ((PsiJavaCodeReferenceElement)lhs).getReferenceNameElement(); if (referenceNameElement != null) { @@ -117,7 +117,7 @@ public class NonAtomicOperationOnVolatileFieldInspection extends BaseInspection return null; } final PsiReferenceExpression reference = (PsiReferenceExpression)expression; - if (!ControlFlowUtil.isUnqualified(reference)) { + if (!ExpressionUtil.isEffectivelyUnqualified(reference)) { return null; } final PsiElement referent = reference.resolve();