From 3cc2d83851fa6321b4c60549f65b311009107010 Mon Sep 17 00:00:00 2001 From: UNV Date: Thu, 8 May 2025 10:08:26 +0300 Subject: [PATCH] Replacing CommonClassNames with JavaClassNames (part 4). Refactoring. --- .../WrapObjectWithOptionalOfNullableFix.java | 73 +++++----- .../dataFlow/TypeConstraints.java | 127 +++++++++--------- .../dataFlow/inliner/TransformInliner.java | 4 +- .../SuspiciousMethodCallUtil.java | 45 ++++--- .../siyeh/ig/psiutils/SideEffectChecker.java | 48 ++++--- .../impl/psi/impl/cache/TypeInfo.java | 50 +++---- .../completion/SmartCastProvider.java | 91 ++++++++----- .../SwitchStatementPostfixTemplate.java | 26 ++-- .../ThrowExceptionPostfixTemplate.java | 7 +- ...ReplaceComputeWithComputeIfPresentFix.java | 12 +- .../WrapWithMutableCollectionFix.java | 43 +++--- 11 files changed, 280 insertions(+), 246 deletions(-) diff --git a/java-analysis-impl/src/main/java/com/intellij/java/analysis/impl/codeInsight/daemon/impl/quickfix/WrapObjectWithOptionalOfNullableFix.java b/java-analysis-impl/src/main/java/com/intellij/java/analysis/impl/codeInsight/daemon/impl/quickfix/WrapObjectWithOptionalOfNullableFix.java index 04ef281c7..c64f8e313 100644 --- a/java-analysis-impl/src/main/java/com/intellij/java/analysis/impl/codeInsight/daemon/impl/quickfix/WrapObjectWithOptionalOfNullableFix.java +++ b/java-analysis-impl/src/main/java/com/intellij/java/analysis/impl/codeInsight/daemon/impl/quickfix/WrapObjectWithOptionalOfNullableFix.java @@ -20,8 +20,10 @@ import com.intellij.java.language.psi.*; import com.intellij.java.language.psi.util.PsiUtil; import com.intellij.java.language.psi.util.TypeConversionUtil; +import consulo.annotation.access.RequiredReadAction; import consulo.codeEditor.Editor; -import consulo.java.analysis.impl.JavaQuickFixBundle; +import consulo.java.analysis.impl.localize.JavaQuickFixLocalize; +import consulo.java.language.module.util.JavaClassNames; import consulo.language.editor.inspection.LocalQuickFixAndIntentionActionOnPsiElement; import consulo.language.editor.intention.BaseIntentionAction; import consulo.language.editor.intention.HighPriorityAction; @@ -31,8 +33,6 @@ import consulo.language.util.IncorrectOperationException; import consulo.project.Project; import consulo.util.collection.ContainerUtil; -import org.jetbrains.annotations.Nls; - import jakarta.annotation.Nonnull; import jakarta.annotation.Nullable; @@ -45,10 +45,10 @@ public class WrapObjectWithOptionalOfNullableFix extends MethodArgumentFix imple public static final ArgumentFixerActionFactory REGISTAR = new MyFixerActionFactory(); protected WrapObjectWithOptionalOfNullableFix( - final @Nonnull PsiExpressionList list, - final int i, - final @Nonnull PsiType toType, - final @Nonnull ArgumentFixerActionFactory fixerActionFactory + @Nonnull PsiExpressionList list, + int i, + @Nonnull PsiType toType, + @Nonnull ArgumentFixerActionFactory fixerActionFactory ) { super(list, i, toType, fixerActionFactory); } @@ -57,14 +57,15 @@ protected WrapObjectWithOptionalOfNullableFix( @Override public String getText() { if (myArgList.getExpressionCount() == 1) { - return JavaQuickFixBundle.message("wrap.with.optional.single.parameter.text"); + return JavaQuickFixLocalize.wrapWithOptionalSingleParameterText().get(); } else { - return JavaQuickFixBundle.message("wrap.with.optional.parameter.text", myIndex + 1); + return JavaQuickFixLocalize.wrapWithOptionalParameterText(myIndex + 1).get(); } } @Override + @RequiredReadAction public boolean isAvailable(@Nonnull Project project, Editor editor, PsiFile file) { return PsiUtil.isLanguageLevel8OrHigher(file) && super.isAvailable(project, editor, file); } @@ -75,13 +76,13 @@ protected MyFix(@Nullable PsiElement element) { super(element); } - @Nls @Nonnull @Override public String getFamilyName() { - return JavaQuickFixBundle.message("wrap.with.optional.single.parameter.text"); + return JavaQuickFixLocalize.wrapWithOptionalSingleParameterText().get(); } + @RequiredReadAction @Override public void invoke( @Nonnull Project project, @@ -94,14 +95,16 @@ public void invoke( } @Override + @RequiredReadAction public boolean isAvailable( @Nonnull Project project, @Nonnull PsiFile file, @Nonnull PsiElement startElement, @Nonnull PsiElement endElement ) { - return BaseIntentionAction.canModify(startElement) && - PsiUtil.isLanguageLevel8OrHigher(startElement) && areConvertible(((PsiExpression)startElement).getType(), type); + return BaseIntentionAction.canModify(startElement) + && PsiUtil.isLanguageLevel8OrHigher(startElement) + && areConvertible(((PsiExpression)startElement).getType(), type); } @Nonnull @@ -117,61 +120,57 @@ public static class MyFixerActionFactory extends ArgumentFixerActionFactory { @Nullable @Override - protected PsiExpression getModifiedArgument( - final PsiExpression expression, - final PsiType toType - ) throws IncorrectOperationException { + @RequiredReadAction + protected PsiExpression getModifiedArgument(PsiExpression expression, PsiType toType) throws IncorrectOperationException { return getModifiedExpression(expression); } @Override public boolean areTypesConvertible( - @Nonnull final PsiType exprType, - @Nonnull final PsiType parameterType, - @Nonnull final PsiElement context + @Nonnull PsiType exprType, + @Nonnull PsiType parameterType, + @Nonnull PsiElement context ) { return parameterType.isConvertibleFrom(exprType) || areConvertible(exprType, parameterType); } @Override - public MethodArgumentFix createFix(final PsiExpressionList list, final int i, final PsiType toType) { + public MethodArgumentFix createFix(PsiExpressionList list, int i, PsiType toType) { return new WrapObjectWithOptionalOfNullableFix(list, i, toType, this); } } private static boolean areConvertible(@Nullable PsiType exprType, @Nullable PsiType parameterType) { - if (exprType == null || - !exprType.isValid() || - !(parameterType instanceof PsiClassType) || - !parameterType.isValid()) { + if (exprType == null + || !exprType.isValid() + || !(parameterType instanceof PsiClassType) + || !parameterType.isValid()) { return false; } - final PsiClassType.ClassResolveResult resolve = ((PsiClassType)parameterType).resolveGenerics(); - final PsiClass resolvedClass = resolve.getElement(); - if (resolvedClass == null || !CommonClassNames.JAVA_UTIL_OPTIONAL.equals(resolvedClass.getQualifiedName())) { + PsiClassType.ClassResolveResult resolve = ((PsiClassType)parameterType).resolveGenerics(); + PsiClass resolvedClass = resolve.getElement(); + if (resolvedClass == null || !JavaClassNames.JAVA_UTIL_OPTIONAL.equals(resolvedClass.getQualifiedName())) { return false; } - final Collection values = resolve.getSubstitutor().getSubstitutionMap().values(); + Collection values = resolve.getSubstitutor().getSubstitutionMap().values(); if (values.isEmpty()) { return true; } if (values.size() > 1) { return false; } - final PsiType optionalTypeParameter = ContainerUtil.getFirstItem(values); - if (optionalTypeParameter == null) { - return false; - } - return TypeConversionUtil.isAssignable(optionalTypeParameter, exprType); + PsiType optionalTypeParameter = ContainerUtil.getFirstItem(values); + return optionalTypeParameter != null && TypeConversionUtil.isAssignable(optionalTypeParameter, exprType); } @Nonnull + @RequiredReadAction private static PsiExpression getModifiedExpression(PsiExpression expression) { - final Project project = expression.getProject(); - final Nullability nullability = NullabilityUtil.getExpressionNullability(expression, true); + Project project = expression.getProject(); + Nullability nullability = NullabilityUtil.getExpressionNullability(expression, true); String methodName = nullability == Nullability.NOT_NULL ? "of" : "ofNullable"; - final String newExpressionText = CommonClassNames.JAVA_UTIL_OPTIONAL + "." + methodName + "(" + expression.getText() + ")"; + String newExpressionText = JavaClassNames.JAVA_UTIL_OPTIONAL + "." + methodName + "(" + expression.getText() + ")"; return JavaPsiFacade.getElementFactory(project).createExpressionFromText(newExpressionText, expression); } } diff --git a/java-analysis-impl/src/main/java/com/intellij/java/analysis/impl/codeInspection/dataFlow/TypeConstraints.java b/java-analysis-impl/src/main/java/com/intellij/java/analysis/impl/codeInspection/dataFlow/TypeConstraints.java index 3ddd4dc89..2e2d0ee7f 100644 --- a/java-analysis-impl/src/main/java/com/intellij/java/analysis/impl/codeInspection/dataFlow/TypeConstraints.java +++ b/java-analysis-impl/src/main/java/com/intellij/java/analysis/impl/codeInspection/dataFlow/TypeConstraints.java @@ -5,6 +5,8 @@ import com.intellij.java.language.psi.util.InheritanceUtil; import com.intellij.java.language.psi.util.PsiTypesUtil; import com.intellij.java.language.psi.util.TypeConversionUtil; +import consulo.annotation.access.RequiredReadAction; +import consulo.java.language.module.util.JavaClassNames; import consulo.language.psi.PsiManager; import consulo.project.Project; import one.util.streamex.StreamEx; @@ -117,19 +119,19 @@ public TypeConstraint notInstanceOf() { @Override public String toString() { - return CommonClassNames.JAVA_LANG_OBJECT; + return JavaClassNames.JAVA_LANG_OBJECT; } @Override public PsiType getPsiType(Project project) { - return JavaPsiFacade.getElementFactory(project).createTypeByFQClassName(CommonClassNames.JAVA_LANG_OBJECT); + return JavaPsiFacade.getElementFactory(project).createTypeByFQClassName(JavaClassNames.JAVA_LANG_OBJECT); } }; @Nullable private static TypeConstraint.Exact createExact(@Nonnull PsiType type) { - if (type instanceof PsiArrayType) { - PsiType componentType = ((PsiArrayType)type).getComponentType(); + if (type instanceof PsiArrayType arrayType) { + PsiType componentType = arrayType.getComponentType(); if (componentType instanceof PsiPrimitiveType) { for (PrimitiveArray p : PrimitiveArray.values()) { if (p.getType().equals(componentType)) { @@ -141,8 +143,8 @@ private static TypeConstraint.Exact createExact(@Nonnull PsiType type) { TypeConstraint.Exact componentConstraint = createExact(componentType); return componentConstraint == null ? null : new ExactArray(componentConstraint); } - if (type instanceof PsiClassType) { - PsiClass psiClass = ((PsiClassType)type).resolve(); + if (type instanceof PsiClassType classType) { + PsiClass psiClass = classType.resolve(); if (psiClass == null) { return new Unresolved(type.getCanonicalText()); } @@ -180,11 +182,11 @@ public static TypeConstraint instanceOf(@Nonnull PsiType type) { return TOP; } type = normalizeType(type); - if (type instanceof PsiDisjunctionType) { - type = ((PsiDisjunctionType)type).getLeastUpperBound(); + if (type instanceof PsiDisjunctionType disjunctionType) { + type = disjunctionType.getLeastUpperBound(); } - if (type instanceof PsiIntersectionType) { - PsiType[] conjuncts = ((PsiIntersectionType)type).getConjuncts(); + if (type instanceof PsiIntersectionType intersectionType) { + PsiType[] conjuncts = intersectionType.getConjuncts(); TypeConstraint result = TOP; for (PsiType conjunct : conjuncts) { TypeConstraint.Exact exact = createExact(conjunct); @@ -207,21 +209,22 @@ private static PsiType normalizeType(@Nonnull PsiType psiType) { if (psiType instanceof PsiArrayType) { return PsiTypesUtil.createArrayType(normalizeType(psiType.getDeepComponentType()), psiType.getArrayDimensions()); } - if (psiType instanceof PsiWildcardType) { - return normalizeType(((PsiWildcardType)psiType).getExtendsBound()); + if (psiType instanceof PsiWildcardType wildcardType) { + return normalizeType(wildcardType.getExtendsBound()); } - if (psiType instanceof PsiCapturedWildcardType) { - return normalizeType(((PsiCapturedWildcardType)psiType).getUpperBound()); + if (psiType instanceof PsiCapturedWildcardType capturedWildcardType) { + return normalizeType(capturedWildcardType.getUpperBound()); } - if (psiType instanceof PsiIntersectionType) { - PsiType[] types = - StreamEx.of(((PsiIntersectionType)psiType).getConjuncts()).map(TypeConstraints::normalizeType).toArray(PsiType.EMPTY_ARRAY); + if (psiType instanceof PsiIntersectionType intersectionType) { + PsiType[] types = StreamEx.of(intersectionType.getConjuncts()) + .map(TypeConstraints::normalizeType) + .toArray(PsiType.EMPTY_ARRAY); if (types.length > 0) { return PsiIntersectionType.createIntersection(true, types); } } - if (psiType instanceof PsiClassType) { - return normalizeClassType((PsiClassType)psiType, new HashSet<>()); + if (psiType instanceof PsiClassType classType) { + return normalizeClassType(classType, new HashSet<>()); } return psiType; } @@ -252,11 +255,11 @@ private static TypeConstraint.Exact exactClass(@Nonnull PsiClass psiClass) { String name = psiClass.getQualifiedName(); if (name != null) { switch (name) { - case CommonClassNames.JAVA_LANG_OBJECT: + case JavaClassNames.JAVA_LANG_OBJECT: return EXACTLY_OBJECT; - case CommonClassNames.JAVA_LANG_CLONEABLE: + case JavaClassNames.JAVA_LANG_CLONEABLE: return ArraySuperInterface.CLONEABLE; - case CommonClassNames.JAVA_IO_SERIALIZABLE: + case JavaClassNames.JAVA_IO_SERIALIZABLE: return ArraySuperInterface.SERIALIZABLE; } } @@ -316,11 +319,10 @@ public boolean isConvertibleFrom(@Nonnull Exact other) { } private enum ArraySuperInterface implements TypeConstraint.Exact { - CLONEABLE(CommonClassNames.JAVA_LANG_CLONEABLE), - SERIALIZABLE(CommonClassNames.JAVA_IO_SERIALIZABLE); - private final + CLONEABLE(JavaClassNames.JAVA_LANG_CLONEABLE), + SERIALIZABLE(JavaClassNames.JAVA_IO_SERIALIZABLE); @Nonnull - String myReference; + private final String myReference; ArraySuperInterface(@Nonnull String reference) { myReference = reference; @@ -356,8 +358,9 @@ public boolean isAssignableFrom(@Nonnull Exact other) { if (other instanceof PrimitiveArray || other instanceof ExactArray || other instanceof Unresolved) { return true; } - if (other instanceof ExactClass) { - return InheritanceUtil.isInheritor(((ExactClass)other).myClass, myReference); + //noinspection SimplifiableIfStatement + if (other instanceof ExactClass exactClass) { + return InheritanceUtil.isInheritor(exactClass.myClass, myReference); } return false; } @@ -385,11 +388,12 @@ private static final class ExactClass implements TypeConstraint.Exact { @Override public boolean equals(Object obj) { - return obj == this || obj instanceof ExactClass && - myClass.getManager().areElementsEquivalent(myClass, ((ExactClass)obj).myClass); + return obj == this + || obj instanceof ExactClass exactClass && myClass.getManager().areElementsEquivalent(myClass, exactClass.myClass); } @Override + @RequiredReadAction public int hashCode() { return Objects.hashCode(myClass.getName()); } @@ -398,14 +402,14 @@ public int hashCode() { public boolean canBeInstantiated() { // Abstract final type is incorrect. We, however, assume that final wins: it can be instantiated // otherwise TypeConstraints.instanceOf(type) would return impossible type - return (myClass.hasModifierProperty(PsiModifier.FINAL) || !myClass.hasModifierProperty(PsiModifier.ABSTRACT)) && - !CommonClassNames.JAVA_LANG_VOID.equals(myClass.getQualifiedName()); + return (myClass.isFinal() || !myClass.isAbstract()) + && !JavaClassNames.JAVA_LANG_VOID.equals(myClass.getQualifiedName()); } @Override public boolean isComparedByEquals() { String name = myClass.getQualifiedName(); - return name != null && (CommonClassNames.JAVA_LANG_STRING.equals(name) || TypeConversionUtil.isPrimitiveWrapper(name)); + return name != null && (JavaClassNames.JAVA_LANG_STRING.equals(name) || TypeConversionUtil.isPrimitiveWrapper(name)); } @Nonnull @@ -416,13 +420,14 @@ public PsiType getPsiType(Project project) { @Nonnull @Override + @RequiredReadAction public String toString() { String name = myClass.getQualifiedName(); if (name == null) { name = myClass.getName(); } - if (name == null && myClass instanceof PsiAnonymousClass) { - PsiClassType baseClassType = ((PsiAnonymousClass)myClass).getBaseClassType(); + if (name == null && myClass instanceof PsiAnonymousClass anonymousClass) { + PsiClassType baseClassType = anonymousClass.getBaseClassType(); name = "anonymous " + createExact(baseClassType); } return String.valueOf(name); @@ -430,14 +435,14 @@ public String toString() { @Override public boolean isFinal() { - return myClass.hasModifierProperty(PsiModifier.FINAL); + return myClass.isFinal(); } @Override public StreamEx superTypes() { List superTypes = new ArrayList<>(); InheritanceUtil.processSupers(myClass, false, t -> { - if (!t.hasModifierProperty(PsiModifier.FINAL)) { + if (!t.isFinal()) { superTypes.add(exactClass(t)); } return true; @@ -450,8 +455,9 @@ public boolean isAssignableFrom(@Nonnull Exact other) { if (equals(other) || other instanceof Unresolved) { return true; } - if (other instanceof ExactClass) { - return InheritanceUtil.isInheritorOrSelf(((ExactClass)other).myClass, myClass, true); + //noinspection SimplifiableIfStatement + if (other instanceof ExactClass exactClass) { + return InheritanceUtil.isInheritorOrSelf(exactClass.myClass, myClass, true); } return false; } @@ -461,30 +467,25 @@ public boolean isConvertibleFrom(@Nonnull Exact other) { if (equals(other) || other instanceof Unresolved || other == EXACTLY_OBJECT) { return true; } - if (other instanceof ArraySuperInterface) { - if (myClass.isInterface()) { - return true; - } - if (!myClass.hasModifierProperty(PsiModifier.FINAL)) { - return true; - } - return InheritanceUtil.isInheritor(myClass, ((ArraySuperInterface)other).myReference); + if (other instanceof ArraySuperInterface arraySuperInterface) { + return myClass.isInterface() || !myClass.isFinal() + || InheritanceUtil.isInheritor(myClass, arraySuperInterface.myReference); } - if (other instanceof ExactClass) { - PsiClass otherClass = ((ExactClass)other).myClass; + if (other instanceof ExactClass exactClass) { + PsiClass otherClass = exactClass.myClass; if (myClass.isInterface() && otherClass.isInterface()) { return true; } - if (myClass.isInterface() && !otherClass.hasModifierProperty(PsiModifier.FINAL)) { + if (myClass.isInterface() && !otherClass.isFinal()) { return true; } - if (otherClass.isInterface() && !myClass.hasModifierProperty(PsiModifier.FINAL)) { + if (otherClass.isInterface() && !myClass.isFinal()) { return true; } PsiManager manager = myClass.getManager(); - return manager.areElementsEquivalent(myClass, otherClass) || - otherClass.isInheritor(myClass, true) || - myClass.isInheritor(otherClass, true); + return manager.areElementsEquivalent(myClass, otherClass) + || otherClass.isInheritor(myClass, true) + || myClass.isInheritor(otherClass, true); } return false; } @@ -508,7 +509,7 @@ public PsiType getPsiType(Project project) { @Override public boolean equals(Object obj) { - return obj == this || obj instanceof ExactArray && myComponent.equals(((ExactArray)obj).myComponent); + return obj == this || obj instanceof ExactArray exactArray && myComponent.equals(exactArray.myComponent); } @Override @@ -534,22 +535,20 @@ public StreamEx superTypes() { @Override public boolean isAssignableFrom(@Nonnull Exact other) { - if (!(other instanceof ExactArray)) { - return false; - } - return myComponent.isAssignableFrom(((ExactArray)other).myComponent); + return other instanceof ExactArray exactArray && myComponent.isAssignableFrom(exactArray.myComponent); } @Override public boolean isConvertibleFrom(@Nonnull Exact other) { - if (other instanceof ExactArray) { - return myComponent.isConvertibleFrom(((ExactArray)other).myComponent); + if (other instanceof ExactArray exactArray) { + return myComponent.isConvertibleFrom(exactArray.myComponent); } if (other instanceof ArraySuperInterface) { return true; } - if (other instanceof ExactClass) { - return CommonClassNames.JAVA_LANG_OBJECT.equals(((ExactClass)other).myClass.getQualifiedName()); + //noinspection SimplifiableIfStatement + if (other instanceof ExactClass exactClass) { + return JavaClassNames.JAVA_LANG_OBJECT.equals(exactClass.myClass.getQualifiedName()); } return false; } @@ -578,7 +577,7 @@ public boolean isResolved() { @Override public boolean equals(Object obj) { - return obj == this || obj instanceof Unresolved && myReference.equals(((Unresolved)obj).myReference); + return obj == this || obj instanceof Unresolved unresolved && myReference.equals(unresolved.myReference); } @Override diff --git a/java-analysis-impl/src/main/java/com/intellij/java/analysis/impl/codeInspection/dataFlow/inliner/TransformInliner.java b/java-analysis-impl/src/main/java/com/intellij/java/analysis/impl/codeInspection/dataFlow/inliner/TransformInliner.java index efbcda15b..30d6aad5c 100644 --- a/java-analysis-impl/src/main/java/com/intellij/java/analysis/impl/codeInspection/dataFlow/inliner/TransformInliner.java +++ b/java-analysis-impl/src/main/java/com/intellij/java/analysis/impl/codeInspection/dataFlow/inliner/TransformInliner.java @@ -2,10 +2,10 @@ package com.intellij.java.analysis.impl.codeInspection.dataFlow.inliner; import com.intellij.java.analysis.impl.codeInspection.dataFlow.CFGBuilder; -import com.intellij.java.language.psi.CommonClassNames; import com.intellij.java.language.psi.PsiExpression; import com.intellij.java.language.psi.PsiMethodCallExpression; import com.siyeh.ig.callMatcher.CallMatcher; +import consulo.java.language.module.util.JavaClassNames; import jakarta.annotation.Nonnull; public class TransformInliner implements CallInliner { @@ -23,7 +23,7 @@ public class TransformInliner implements CallInliner { CallMatcher.instanceCall("io.reactivex.rxjava3.core.Maybe", "to").parameterCount(1), CallMatcher.instanceCall("io.reactivex.rxjava3.core.Observable", "to").parameterCount(1), CallMatcher.instanceCall("io.reactivex.rxjava3.core.Single", "to").parameterCount(1), - CallMatcher.instanceCall(CommonClassNames.JAVA_LANG_STRING, "transform").parameterCount(1), + CallMatcher.instanceCall(JavaClassNames.JAVA_LANG_STRING, "transform").parameterCount(1), CallMatcher.instanceCall("one.util.streamex.BaseStreamEx", "chain").parameterCount(1) ); diff --git a/java-analysis-impl/src/main/java/com/intellij/java/analysis/impl/codeInspection/miscGenerics/SuspiciousMethodCallUtil.java b/java-analysis-impl/src/main/java/com/intellij/java/analysis/impl/codeInspection/miscGenerics/SuspiciousMethodCallUtil.java index e6c880dde..c136b6d4a 100644 --- a/java-analysis-impl/src/main/java/com/intellij/java/analysis/impl/codeInspection/miscGenerics/SuspiciousMethodCallUtil.java +++ b/java-analysis-impl/src/main/java/com/intellij/java/analysis/impl/codeInspection/miscGenerics/SuspiciousMethodCallUtil.java @@ -8,7 +8,9 @@ import com.siyeh.ig.callMatcher.CallMatcher; import com.siyeh.ig.psiutils.ExpressionUtils; import com.siyeh.ig.psiutils.TypeUtils; +import consulo.annotation.access.RequiredReadAction; import consulo.application.util.NullableLazyValue; +import consulo.java.language.module.util.JavaClassNames; import consulo.language.editor.inspection.InspectionsBundle; import consulo.language.editor.inspection.localize.InspectionLocalize; import consulo.language.psi.PsiElement; @@ -28,11 +30,12 @@ public class SuspiciousMethodCallUtil { // List.of/Set.of are unnecessary here as they don't accept nulls private static final CallMatcher.Simple SINGLETON_COLLECTION = - CallMatcher.staticCall(CommonClassNames.JAVA_UTIL_COLLECTIONS, "singletonList", "singleton").parameterCount(1); + CallMatcher.staticCall(JavaClassNames.JAVA_UTIL_COLLECTIONS, "singletonList", "singleton").parameterCount(1); + @RequiredReadAction private static void setupPatternMethods(PsiManager manager, GlobalSearchScope searchScope, List patternMethods) { - final JavaPsiFacade javaPsiFacade = JavaPsiFacade.getInstance(manager.getProject()); - final PsiClass collectionClass = javaPsiFacade.findClass(CommonClassNames.JAVA_UTIL_COLLECTION, searchScope); + JavaPsiFacade javaPsiFacade = JavaPsiFacade.getInstance(manager.getProject()); + PsiClass collectionClass = javaPsiFacade.findClass(JavaClassNames.JAVA_UTIL_COLLECTION, searchScope); PsiClassType object = PsiType.getJavaLangObject(manager, searchScope); PsiType[] javaLangObject = {object}; PsiType[] twoObjects = { @@ -55,13 +58,13 @@ private static void setupPatternMethods(PsiManager manager, GlobalSearchScope se } } - final PsiClass listClass = javaPsiFacade.findClass(CommonClassNames.JAVA_UTIL_LIST, searchScope); + PsiClass listClass = javaPsiFacade.findClass(JavaClassNames.JAVA_UTIL_LIST, searchScope); if (listClass != null) { addSingleParameterMethod(patternMethods, listClass, "indexOf", object); addSingleParameterMethod(patternMethods, listClass, "lastIndexOf", object); } - final PsiClass mapClass = javaPsiFacade.findClass(CommonClassNames.JAVA_UTIL_MAP, searchScope); + PsiClass mapClass = javaPsiFacade.findClass(JavaClassNames.JAVA_UTIL_MAP, searchScope); if (mapClass != null) { PsiMethod remove = MethodSignatureUtil.findMethodBySignature(mapClass, removeSignature, false); addMethod(remove, 0, patternMethods, 0); @@ -101,7 +104,7 @@ private static void setupPatternMethods(PsiManager manager, GlobalSearchScope se addMethod(containsValue, 1, patternMethods, 0); } - final PsiClass concurrentMapClass = javaPsiFacade.findClass(CommonClassNames.JAVA_UTIL_CONCURRENT_HASH_MAP, searchScope); + PsiClass concurrentMapClass = javaPsiFacade.findClass(JavaClassNames.JAVA_UTIL_CONCURRENT_HASH_MAP, searchScope); if (concurrentMapClass != null) { MethodSignature containsSignature = MethodSignatureUtil.createMethodSignature("contains", javaLangObject, PsiTypeParameter.EMPTY_ARRAY, PsiSubstitutor.EMPTY); @@ -238,7 +241,7 @@ private static void addSingleParameterMethod( } private static void addMethod( - final PsiMethod patternMethod, + PsiMethod patternMethod, int typeParamIndex, List patternMethods, int argIdx @@ -260,6 +263,7 @@ private static boolean isInheritorOrSelf(PsiMethod inheritorCandidate, PsiMethod } @Nullable + @RequiredReadAction public static String getSuspiciousMethodCallMessage( @Nonnull PsiMethodCallExpression methodCall, PsiExpression arg, @@ -268,11 +272,11 @@ public static String getSuspiciousMethodCallMessage( @Nonnull List patternMethods, int idx ) { - final PsiReferenceExpression methodExpression = methodCall.getMethodExpression(); + PsiReferenceExpression methodExpression = methodCall.getMethodExpression(); if (arg instanceof PsiConditionalExpression && argType != null - && argType.equalsToText(CommonClassNames.JAVA_LANG_OBJECT) + && argType.equalsToText(JavaClassNames.JAVA_LANG_OBJECT) && PsiPolyExpressionUtil.isPolyExpression(arg)) { return null; } @@ -280,6 +284,7 @@ public static String getSuspiciousMethodCallMessage( } @Nullable + @RequiredReadAction public static String getSuspiciousMethodCallMessage( PsiReferenceExpression methodExpression, PsiType argType, @@ -287,7 +292,7 @@ public static String getSuspiciousMethodCallMessage( @Nonnull List patternMethods, int argIdx ) { - final PsiExpression qualifier = methodExpression.getQualifierExpression(); + PsiExpression qualifier = methodExpression.getQualifierExpression(); if (qualifier == null || qualifier instanceof PsiThisExpression || qualifier instanceof PsiSuperExpression) { return null; } @@ -299,12 +304,11 @@ public static String getSuspiciousMethodCallMessage( return null; } - final JavaResolveResult resolveResult = methodExpression.advancedResolve(false); + JavaResolveResult resolveResult = methodExpression.advancedResolve(false); PsiElement element = resolveResult.getElement(); - if (!(element instanceof PsiMethod)) { + if (!(element instanceof PsiMethod calleeMethod)) { return null; } - PsiMethod calleeMethod = (PsiMethod)element; NullableLazyValue lazyContextMethod = NullableLazyValue.createValue(() -> PsiTreeUtil.getParentOfType(methodExpression, PsiMethod.class)); @@ -330,9 +334,9 @@ public static String getSuspiciousMethodCallMessage( return null; } - final PsiClass calleeClass = calleeMethod.getContainingClass(); + PsiClass calleeClass = calleeMethod.getContainingClass(); PsiSubstitutor substitutor = resolveResult.getSubstitutor(); - final PsiClass patternClass = method.getContainingClass(); + PsiClass patternClass = method.getContainingClass(); assert patternClass != null; assert calleeClass != null; substitutor = TypeConversionUtil.getClassSubstitutor(patternClass, calleeClass, substitutor); @@ -348,7 +352,7 @@ public static String getSuspiciousMethodCallMessage( if (typeParameters.length <= patternMethod.typeParameterIdx) { return null; } - final PsiTypeParameter typeParameter = typeParameters[patternMethod.typeParameterIdx]; + PsiTypeParameter typeParameter = typeParameters[patternMethod.typeParameterIdx]; PsiType typeParamMapping = substitutor.substitute(typeParameter); if (typeParamMapping == null) { return null; @@ -357,11 +361,11 @@ public static String getSuspiciousMethodCallMessage( PsiParameter[] parameters = method.getParameterList().getParameters(); if (parameters.length == 1 && ("removeAll".equals(method.getName()) || "retainAll".equals(method.getName()))) { PsiType paramType = parameters[0].getType(); - if (InheritanceUtil.isInheritor(paramType, CommonClassNames.JAVA_UTIL_COLLECTION)) { + if (InheritanceUtil.isInheritor(paramType, JavaClassNames.JAVA_UTIL_COLLECTION)) { PsiType qualifierType = qualifier.getType(); if (qualifierType != null) { - final PsiType itemType = JavaGenericsUtil.getCollectionItemType(argType, calleeMethod.getResolveScope()); - final PsiType qualifierItemType = + PsiType itemType = JavaGenericsUtil.getCollectionItemType(argType, calleeMethod.getResolveScope()); + PsiType qualifierItemType = JavaGenericsUtil.getCollectionItemType(qualifierType, calleeMethod.getResolveScope()); if (qualifierItemType != null && itemType != null && !qualifierItemType.isAssignableFrom(itemType)) { if (TypeUtils.isJavaLangObject(itemType) && hasNullCollectionArg(methodExpression)) { @@ -418,13 +422,14 @@ public static String getSuspiciousMethodCallMessage( } private static String getPreciseObjectTitle(PsiClass patternClass, int index) { - if (InheritanceUtil.isInheritor(patternClass, CommonClassNames.JAVA_UTIL_MAP)) { + if (InheritanceUtil.isInheritor(patternClass, JavaClassNames.JAVA_UTIL_MAP)) { return index == 0 ? "keys" : "values"; } return "objects"; } + @RequiredReadAction private static boolean hasNullCollectionArg(PsiReferenceExpression methodExpression) { PsiMethodCallExpression call = ObjectUtil.tryCast(methodExpression.getParent(), PsiMethodCallExpression.class); if (call != null) { diff --git a/java-analysis-impl/src/main/java/com/siyeh/ig/psiutils/SideEffectChecker.java b/java-analysis-impl/src/main/java/com/siyeh/ig/psiutils/SideEffectChecker.java index 6ffd6ad2d..dcb0832df 100644 --- a/java-analysis-impl/src/main/java/com/siyeh/ig/psiutils/SideEffectChecker.java +++ b/java-analysis-impl/src/main/java/com/siyeh/ig/psiutils/SideEffectChecker.java @@ -21,6 +21,7 @@ import com.intellij.java.language.psi.util.InheritanceUtil; import com.intellij.java.language.psi.util.PropertyUtil; import com.intellij.java.language.psi.util.PsiUtil; +import consulo.annotation.access.RequiredReadAction; import consulo.java.language.module.util.JavaClassNames; import consulo.language.ast.IElementType; import consulo.language.psi.PsiDirectory; @@ -29,10 +30,9 @@ import consulo.language.psi.PsiPackage; import consulo.language.psi.util.PsiTreeUtil; import consulo.util.collection.SmartList; -import one.util.streamex.StreamEx; - import jakarta.annotation.Nonnull; import jakarta.annotation.Nullable; +import one.util.streamex.StreamEx; import java.util.*; import java.util.function.Predicate; @@ -72,13 +72,17 @@ private SideEffectChecker() { } public static boolean mayHaveSideEffects(@Nonnull PsiExpression exp) { - final SideEffectsVisitor visitor = new SideEffectsVisitor(null, exp); + SideEffectsVisitor visitor = new SideEffectsVisitor(null, exp); exp.accept(visitor); return visitor.mayHaveSideEffects(); } - public static boolean mayHaveSideEffects(@Nonnull PsiElement element, Predicate shouldIgnoreElement) { - final SideEffectsVisitor visitor = new SideEffectsVisitor(null, element, shouldIgnoreElement); + @RequiredReadAction + public static boolean mayHaveSideEffects( + @Nonnull PsiElement element, + @RequiredReadAction Predicate shouldIgnoreElement + ) { + SideEffectsVisitor visitor = new SideEffectsVisitor(null, element, shouldIgnoreElement); element.accept(visitor); return visitor.mayHaveSideEffects(); } @@ -90,14 +94,14 @@ public static boolean mayHaveSideEffects(@Nonnull PsiElement element, Predicate< * @param element element to check * @return true if element execution may cause non-local side-effect. */ + @RequiredReadAction public static boolean mayHaveNonLocalSideEffects(@Nonnull PsiElement element) { return mayHaveSideEffects(element, SideEffectChecker::isLocalSideEffect); } + @RequiredReadAction private static boolean isLocalSideEffect(PsiElement e) { - if (e instanceof PsiContinueStatement || - e instanceof PsiReturnStatement || - e instanceof PsiThrowStatement) { + if (e instanceof PsiContinueStatement || e instanceof PsiReturnStatement || e instanceof PsiThrowStatement) { return true; } if (e instanceof PsiLocalVariable) { @@ -105,12 +109,11 @@ private static boolean isLocalSideEffect(PsiElement e) { } PsiReferenceExpression ref = null; - if (e instanceof PsiAssignmentExpression) { - PsiAssignmentExpression assignment = (PsiAssignmentExpression)e; + if (e instanceof PsiAssignmentExpression assignment) { ref = tryCast(PsiUtil.skipParenthesizedExprDown(assignment.getLExpression()), PsiReferenceExpression.class); } - if (e instanceof PsiUnaryExpression) { - PsiExpression operand = ((PsiUnaryExpression)e).getOperand(); + if (e instanceof PsiUnaryExpression unaryExpr) { + PsiExpression operand = unaryExpr.getOperand(); ref = tryCast(PsiUtil.skipParenthesizedExprDown(operand), PsiReferenceExpression.class); } if (ref != null) { @@ -131,7 +134,7 @@ public static boolean checkSideEffects( @Nullable List sideEffects, @Nonnull Predicate ignoreElement ) { - final SideEffectsVisitor visitor = new SideEffectsVisitor(sideEffects, element, ignoreElement); + SideEffectsVisitor visitor = new SideEffectsVisitor(sideEffects, element, ignoreElement); element.accept(visitor); return visitor.mayHaveSideEffects(); } @@ -192,7 +195,7 @@ public void visitAssignmentExpression(@Nonnull PsiAssignmentExpression expressio @Override public void visitMethodCallExpression(@Nonnull PsiMethodCallExpression expression) { - final PsiMethod method = expression.resolveMethod(); + PsiMethod method = expression.resolveMethod(); if (!isPure(method)) { if (addSideEffect(expression)) { return; @@ -213,6 +216,7 @@ protected boolean isPure(PsiMethod method) { } @Override + @RequiredReadAction public void visitNewExpression(@Nonnull PsiNewExpression expression) { if (!expression.isArrayCreation() && !isSideEffectFreeConstructor(expression)) { if (addSideEffect(expression)) { @@ -224,7 +228,7 @@ public void visitNewExpression(@Nonnull PsiNewExpression expression) { @Override public void visitUnaryExpression(@Nonnull PsiUnaryExpression expression) { - final IElementType tokenType = expression.getOperationTokenType(); + IElementType tokenType = expression.getOperationTokenType(); if (tokenType.equals(JavaTokenType.PLUSPLUS) || tokenType.equals(JavaTokenType.MINUSMINUS)) { if (addSideEffect(expression)) { return; @@ -234,7 +238,7 @@ public void visitUnaryExpression(@Nonnull PsiUnaryExpression expression) { } @Override - public void visitVariable(PsiVariable variable) { + public void visitVariable(@Nonnull PsiVariable variable) { if (addSideEffect(variable)) { return; } @@ -253,7 +257,7 @@ public void visitBreakStatement(PsiBreakStatement statement) { } @Override - public void visitClass(PsiClass aClass) { + public void visitClass(@Nonnull PsiClass aClass) { // local or anonymous class declaration is not side effect per se (unless it's instantiated) } @@ -270,7 +274,7 @@ public void visitContinueStatement(PsiContinueStatement statement) { } @Override - public void visitReturnStatement(PsiReturnStatement statement) { + public void visitReturnStatement(@Nonnull PsiReturnStatement statement) { if (addSideEffect(statement)) { return; } @@ -278,7 +282,7 @@ public void visitReturnStatement(PsiReturnStatement statement) { } @Override - public void visitThrowStatement(PsiThrowStatement statement) { + public void visitThrowStatement(@Nonnull PsiThrowStatement statement) { if (addSideEffect(statement)) { return; } @@ -286,7 +290,7 @@ public void visitThrowStatement(PsiThrowStatement statement) { } @Override - public void visitLambdaExpression(PsiLambdaExpression expression) { + public void visitLambdaExpression(@Nonnull PsiLambdaExpression expression) { // lambda is not side effect per se (unless it's called) } @@ -308,6 +312,7 @@ public static boolean mayHaveExceptionalSideEffect(PsiMethod method) { return true; } PsiClass aClass = method.getContainingClass(); + //noinspection SimplifiableIfStatement if (InheritanceUtil.isInheritor(aClass, "org.assertj.core.api.Descriptable")) { // See com.intellij.codeInsight.DefaultInferredAnnotationProvider#getHardcodedContractAnnotation return true; @@ -317,6 +322,7 @@ public static boolean mayHaveExceptionalSideEffect(PsiMethod method) { .anyMatch(mc -> mc.getReturnValue().isFail()); } + @RequiredReadAction private static boolean isSideEffectFreeConstructor(@Nonnull PsiNewExpression newExpression) { PsiAnonymousClass anonymousClass = newExpression.getAnonymousClass(); if (anonymousClass != null && anonymousClass.getInitializers().length == 0) { @@ -341,7 +347,7 @@ private static boolean isSideEffectFreeConstructor(@Nonnull PsiNewExpression new String packageName = classPackage == null ? null : classPackage.getQualifiedName(); // all Throwable descendants from java.lang are side effects free - if (CommonClassNames.DEFAULT_PACKAGE.equals(packageName) || "java.io".equals(packageName)) { + if (JavaClassNames.DEFAULT_PACKAGE.equals(packageName) || "java.io".equals(packageName)) { PsiClass throwableClass = JavaPsiFacade.getInstance(aClass.getProject()).findClass(JavaClassNames.JAVA_LANG_THROWABLE, aClass.getResolveScope()); if (throwableClass != null && InheritanceUtil.isInheritorOrSelf(aClass, throwableClass, true)) { diff --git a/java-language-impl/src/main/java/com/intellij/java/language/impl/psi/impl/cache/TypeInfo.java b/java-language-impl/src/main/java/com/intellij/java/language/impl/psi/impl/cache/TypeInfo.java index 6fcf73026..97f773fa1 100644 --- a/java-language-impl/src/main/java/com/intellij/java/language/impl/psi/impl/cache/TypeInfo.java +++ b/java-language-impl/src/main/java/com/intellij/java/language/impl/psi/impl/cache/TypeInfo.java @@ -3,8 +3,8 @@ import com.intellij.java.language.impl.psi.impl.java.stubs.impl.PsiClassStubImpl; import com.intellij.java.language.impl.psi.impl.source.tree.JavaElementType; -import com.intellij.java.language.psi.CommonClassNames; import com.intellij.java.language.psi.JavaTokenType; +import consulo.java.language.module.util.JavaClassNames; import consulo.language.ast.*; import consulo.language.psi.stub.StubElement; import consulo.language.psi.stub.StubInputStream; @@ -48,10 +48,10 @@ "null", "short", "void", - CommonClassNames.JAVA_LANG_OBJECT_SHORT, - CommonClassNames.JAVA_LANG_OBJECT, - CommonClassNames.JAVA_LANG_STRING_SHORT, - CommonClassNames.JAVA_LANG_STRING + JavaClassNames.JAVA_LANG_OBJECT_SHORT, + JavaClassNames.JAVA_LANG_OBJECT, + JavaClassNames.JAVA_LANG_STRING_SHORT, + JavaClassNames.JAVA_LANG_STRING }; ourFrequentTypeIndex = ObjectMaps.newObjectIntHashMap(); @@ -92,16 +92,16 @@ public enum TypeKind { GENERIC, // References to widely used classes (skip encoding the class name) - JAVA_LANG_OBJECT(CommonClassNames.JAVA_LANG_OBJECT), - JAVA_LANG_STRING(CommonClassNames.JAVA_LANG_STRING), - JAVA_LANG_THROWABLE(CommonClassNames.JAVA_LANG_THROWABLE), - JAVA_LANG_EXCEPTION(CommonClassNames.JAVA_LANG_EXCEPTION), - JAVA_UTIL_COLLECTION(CommonClassNames.JAVA_UTIL_COLLECTION), - JAVA_UTIL_LIST(CommonClassNames.JAVA_UTIL_LIST), - JAVA_LANG_ITERABLE(CommonClassNames.JAVA_LANG_ITERABLE), - JAVA_UTIL_ITERATOR(CommonClassNames.JAVA_UTIL_ITERATOR), - JAVA_UTIL_MAP(CommonClassNames.JAVA_UTIL_MAP), - JAVA_LANG_ANNOTATION_ANNOTATION(CommonClassNames.JAVA_LANG_ANNOTATION_ANNOTATION), + JAVA_LANG_OBJECT(JavaClassNames.JAVA_LANG_OBJECT), + JAVA_LANG_STRING(JavaClassNames.JAVA_LANG_STRING), + JAVA_LANG_THROWABLE(JavaClassNames.JAVA_LANG_THROWABLE), + JAVA_LANG_EXCEPTION(JavaClassNames.JAVA_LANG_EXCEPTION), + JAVA_UTIL_COLLECTION(JavaClassNames.JAVA_UTIL_COLLECTION), + JAVA_UTIL_LIST(JavaClassNames.JAVA_UTIL_LIST), + JAVA_LANG_ITERABLE(JavaClassNames.JAVA_LANG_ITERABLE), + JAVA_UTIL_ITERATOR(JavaClassNames.JAVA_UTIL_ITERATOR), + JAVA_UTIL_MAP(JavaClassNames.JAVA_UTIL_MAP), + JAVA_LANG_ANNOTATION_ANNOTATION(JavaClassNames.JAVA_LANG_ANNOTATION_ANNOTATION), /** * Reference with outer class (which may probably be inner as well, or have generic parameters), @@ -414,7 +414,7 @@ public static TypeInfo create(@Nonnull LighterAST tree, @Nonnull LighterASTNode if (element.getTokenType() == JavaElementType.ENUM_CONSTANT) { return ((PsiClassStubImpl)parentStub).getQualifiedNameTypeInfo(); } - for (final LighterASTNode child : tree.getChildren(element)) { + for (LighterASTNode child : tree.getChildren(element)) { IElementType type = child.getTokenType(); if (type == JavaElementType.TYPE) { typeElement = child; @@ -470,7 +470,7 @@ private static void collectAnnotations( if (tokenType == JavaTokenType.EXTENDS_KEYWORD || tokenType == JavaTokenType.SUPER_KEYWORD) { bound = true; } - if (tokenType == JavaElementType.TYPE && info instanceof DerivedTypeInfo) { + if (tokenType == JavaElementType.TYPE && info instanceof DerivedTypeInfo derivedTypeInfo) { byte[] newPrefix; if (bound) { newPrefix = Arrays.copyOf(prefix, prefix.length + 1); @@ -480,7 +480,7 @@ private static void collectAnnotations( newPrefix = Arrays.copyOf(prefix, prefix.length + arrayCount); Arrays.fill(newPrefix, prefix.length, newPrefix.length, TypeAnnotationContainer.Collector.ARRAY_ELEMENT); } - collectAnnotations(((DerivedTypeInfo)info).child(), collector, tree, child, newPrefix); + collectAnnotations(derivedTypeInfo.child(), collector, tree, child, newPrefix); } else if (tokenType == JavaTokenType.LBRACKET) { nestingLevel++; @@ -710,19 +710,19 @@ public static void writeTYPE(@Nonnull StubOutputStream dataStream, @Nonnull Type boolean hasTypeAnnotations = typeInfo.myTypeAnnotations != null && !typeInfo.myTypeAnnotations.isEmpty(); dataStream.writeByte(typeInfo.kind.ordinal() | (hasTypeAnnotations ? HAS_TYPE_ANNOTATIONS : 0)); - if (typeInfo instanceof DerivedTypeInfo) { - writeTYPE(dataStream, ((DerivedTypeInfo)typeInfo).myChild); + if (typeInfo instanceof DerivedTypeInfo derivedTypeInfo) { + writeTYPE(dataStream, derivedTypeInfo.myChild); } - else if (typeInfo instanceof RefTypeInfo && typeInfo.kind.text == null) { + else if (typeInfo instanceof RefTypeInfo refTypeInfo && typeInfo.kind.text == null) { if (typeInfo.kind == TypeKind.INNER_SIMPLE) { - dataStream.writeName(Objects.requireNonNull(((RefTypeInfo)typeInfo).myOuter).myName); + dataStream.writeName(Objects.requireNonNull(refTypeInfo.myOuter).myName); } if (typeInfo.kind == TypeKind.INNER || typeInfo.kind == TypeKind.INNER_GENERIC) { - writeTYPE(dataStream, Objects.requireNonNull(((RefTypeInfo)typeInfo).myOuter)); + writeTYPE(dataStream, Objects.requireNonNull(refTypeInfo.myOuter)); } - dataStream.writeName(((RefTypeInfo)typeInfo).myName); + dataStream.writeName(refTypeInfo.myName); if (typeInfo.kind == TypeKind.INNER_GENERIC || typeInfo.kind == TypeKind.GENERIC) { - TypeInfo[] components = ((RefTypeInfo)typeInfo).myComponents; + TypeInfo[] components = refTypeInfo.myComponents; dataStream.writeByte(components.length); for (TypeInfo component : components) { writeTYPE(dataStream, component); diff --git a/plugin/src/main/java/com/intellij/java/impl/codeInsight/completion/SmartCastProvider.java b/plugin/src/main/java/com/intellij/java/impl/codeInsight/completion/SmartCastProvider.java index 35e43465f..a398e9340 100644 --- a/plugin/src/main/java/com/intellij/java/impl/codeInsight/completion/SmartCastProvider.java +++ b/plugin/src/main/java/com/intellij/java/impl/codeInsight/completion/SmartCastProvider.java @@ -17,6 +17,7 @@ import consulo.codeEditor.ScrollType; import consulo.document.Document; import consulo.externalService.statistic.FeatureUsageTracker; +import consulo.java.language.module.util.JavaClassNames; import consulo.language.codeStyle.CommonCodeStyleSettings; import consulo.language.codeStyle.PostprocessReformattingAspect; import consulo.language.editor.completion.*; @@ -46,33 +47,37 @@ class SmartCastProvider implements CompletionProvider { static final ElementPattern TYPECAST_TYPE_CANDIDATE = psiElement().afterLeaf("("); + @RequiredReadAction static boolean shouldSuggestCast(CompletionParameters parameters) { PsiElement position = parameters.getPosition(); PsiElement parent = getParenthesisOwner(position); if (parent instanceof PsiTypeCastExpression) { return true; } + //noinspection SimplifiableIfStatement if (parent instanceof PsiParenthesizedExpression) { return parameters.getOffset() == position.getTextRange().getStartOffset(); } return false; } + @RequiredReadAction private static PsiElement getParenthesisOwner(PsiElement position) { PsiElement lParen = PsiTreeUtil.prevVisibleLeaf(position); return lParen == null || !lParen.textMatches("(") ? null : lParen.getParent(); } - @RequiredReadAction @Override + @RequiredReadAction public void addCompletions( - @Nonnull final CompletionParameters parameters, - @Nonnull final ProcessingContext context, - @Nonnull final CompletionResultSet result + @Nonnull CompletionParameters parameters, + @Nonnull ProcessingContext context, + @Nonnull CompletionResultSet result ) { addCastVariants(parameters, result.getPrefixMatcher(), result, false); } + @RequiredReadAction static void addCastVariants( @Nonnull CompletionParameters parameters, PrefixMatcher matcher, @@ -85,14 +90,14 @@ static void addCastVariants( PsiElement position = parameters.getPosition(); PsiElement parenthesisOwner = getParenthesisOwner(position); - final boolean insideCast = parenthesisOwner instanceof PsiTypeCastExpression; + boolean insideCast = parenthesisOwner instanceof PsiTypeCastExpression; if (insideCast) { PsiElement parent = parenthesisOwner.getParent(); - if (parent instanceof PsiParenthesizedExpression) { - if (parent.getParent() instanceof PsiReferenceExpression) { - for (ExpectedTypeInfo info : ExpectedTypesProvider.getExpectedTypes((PsiParenthesizedExpression)parent, false)) { - result.accept(PsiTypeLookupItem.createLookupItem(info.getType(), parent)); + if (parent instanceof PsiParenthesizedExpression parenthesized) { + if (parenthesized.getParent() instanceof PsiReferenceExpression) { + for (ExpectedTypeInfo info : ExpectedTypesProvider.getExpectedTypes(parenthesized, false)) { + result.accept(PsiTypeLookupItem.createLookupItem(info.getType(), parenthesized)); } } for (ExpectedTypeInfo info : getParenthesizedCastExpectationByOperandType(position)) { @@ -108,20 +113,20 @@ static void addCastVariants( } } - for (final ExpectedTypeInfo info : JavaSmartCompletionContributor.getExpectedTypes(parameters)) { + for (ExpectedTypeInfo info : JavaSmartCompletionContributor.getExpectedTypes(parameters)) { PsiType type = info.getDefaultType(); - if (type instanceof PsiWildcardType) { - type = ((PsiWildcardType)type).getBound(); + if (type instanceof PsiWildcardType wildcardType) { + type = wildcardType.getBound(); } if (type == null || PsiType.VOID.equals(type)) { continue; } - if (type instanceof PsiPrimitiveType) { - final PsiType castedType = getCastedExpressionType(parenthesisOwner); + if (type instanceof PsiPrimitiveType primitiveType) { + PsiType castedType = getCastedExpressionType(parenthesisOwner); if (castedType != null && !(castedType instanceof PsiPrimitiveType)) { - final PsiClassType boxedType = ((PsiPrimitiveType)type).getBoxedType(position); + PsiClassType boxedType = primitiveType.getBoxedType(position); if (boxedType != null) { type = boxedType; } @@ -132,6 +137,7 @@ static void addCastVariants( } @Nonnull + @RequiredReadAction static List getParenthesizedCastExpectationByOperandType(PsiElement position) { PsiElement parenthesisOwner = getParenthesisOwner(position); PsiExpression operand = getCastedExpression(parenthesisOwner); @@ -146,7 +152,7 @@ static List getParenthesizedCastExpectationByOperandType(PsiEl } PsiType type = operand.getType(); - return type == null || type.equalsToText(CommonClassNames.JAVA_LANG_OBJECT) + return type == null || type.equalsToText(JavaClassNames.JAVA_LANG_OBJECT) ? Collections.emptyList() : Collections.singletonList(new ExpectedTypeInfoImpl( type, @@ -168,40 +174,51 @@ private static void addHierarchyTypes( PsiType infoType = info.getType(); PsiClass infoClass = PsiUtil.resolveClassInClassTypeOnly(infoType); if (info.getKind() == ExpectedTypeInfo.TYPE_OR_SUPERTYPE) { - InheritanceUtil.processSupers(infoClass, true, superClass -> { - if (!CommonClassNames.JAVA_LANG_OBJECT.equals(superClass.getQualifiedName())) { - result.accept(JavaPsiFacade.getElementFactory(superClass.getProject()) - .createType(CompletionUtilCore.getOriginalOrSelf(superClass))); + InheritanceUtil.processSupers( + infoClass, + true, + superClass -> { + if (!JavaClassNames.JAVA_LANG_OBJECT.equals(superClass.getQualifiedName())) { + result.accept(JavaPsiFacade.getElementFactory(superClass.getProject()) + .createType(CompletionUtilCore.getOriginalOrSelf(superClass))); + } + return true; } - return true; - }); + ); } - else if (infoType instanceof PsiClassType && !quick) { - JavaInheritorsGetter.processInheritors(parameters, Collections.singleton((PsiClassType)infoType), matcher, type -> { - if (!infoType.equals(type)) { - result.accept(type); + else if (infoType instanceof PsiClassType classType && !quick) { + JavaInheritorsGetter.processInheritors( + parameters, + Collections.singleton(classType), + matcher, + type -> { + if (!infoType.equals(type)) { + result.accept(type); + } } - }); + ); } } + @RequiredReadAction private static PsiType getCastedExpressionType(PsiElement parenthesisOwner) { PsiExpression operand = getCastedExpression(parenthesisOwner); return operand == null ? null : operand.getType(); } + @RequiredReadAction private static PsiExpression getCastedExpression(PsiElement parenthesisOwner) { - if (parenthesisOwner instanceof PsiTypeCastExpression) { - return ((PsiTypeCastExpression)parenthesisOwner).getOperand(); + if (parenthesisOwner instanceof PsiTypeCastExpression typeCast) { + return typeCast.getOperand(); } if (parenthesisOwner instanceof PsiParenthesizedExpression) { PsiElement next = parenthesisOwner.getNextSibling(); - while ((next instanceof PsiEmptyExpressionImpl || next instanceof PsiErrorElement || next instanceof PsiWhiteSpace)) { + while (next instanceof PsiEmptyExpressionImpl || next instanceof PsiErrorElement || next instanceof PsiWhiteSpace) { next = next.getNextSibling(); } - if (next instanceof PsiExpression) { - return (PsiExpression)next; + if (next instanceof PsiExpression expression) { + return expression; } } return null; @@ -212,15 +229,15 @@ private static LookupElement createSmartCastElement( final boolean overwrite, final PsiType type ) { - return AutoCompletionPolicy.ALWAYS_AUTOCOMPLETE.applyPolicy(new LookupElementDecorator( + return AutoCompletionPolicy.ALWAYS_AUTOCOMPLETE.applyPolicy(new LookupElementDecorator<>( PsiTypeLookupItem.createLookupItem(type, parameters.getPosition())) { @Override public void handleInsert(@Nonnull InsertionContext context) { FeatureUsageTracker.getInstance().triggerFeatureUsed("editing.completion.smarttype.casting"); - final Editor editor = context.getEditor(); - final Document document = editor.getDocument(); + Editor editor = context.getEditor(); + Document document = editor.getDocument(); if (overwrite) { document.deleteString( context.getSelectionEndOffset(), @@ -228,8 +245,8 @@ public void handleInsert(@Nonnull InsertionContext context) { ); } - final CommonCodeStyleSettings csSettings = CompletionStyleUtil.getCodeStyleSettings(context); - final int oldTail = context.getTailOffset(); + CommonCodeStyleSettings csSettings = CompletionStyleUtil.getCodeStyleSettings(context); + int oldTail = context.getTailOffset(); context.setTailOffset(RParenthTailType.addRParenth(editor, oldTail, csSettings.SPACE_WITHIN_CAST_PARENTHESES)); getDelegate().handleInsert(CompletionUtilCore.newContext(context, getDelegate(), context.getStartOffset(), oldTail)); diff --git a/plugin/src/main/java/com/intellij/java/impl/codeInsight/template/postfix/templates/SwitchStatementPostfixTemplate.java b/plugin/src/main/java/com/intellij/java/impl/codeInsight/template/postfix/templates/SwitchStatementPostfixTemplate.java index 5edab920e..257f8799c 100644 --- a/plugin/src/main/java/com/intellij/java/impl/codeInsight/template/postfix/templates/SwitchStatementPostfixTemplate.java +++ b/plugin/src/main/java/com/intellij/java/impl/codeInsight/template/postfix/templates/SwitchStatementPostfixTemplate.java @@ -6,11 +6,13 @@ import com.intellij.java.language.JavaFeature; import com.intellij.java.language.psi.*; import com.intellij.java.language.psi.util.PsiUtil; +import consulo.annotation.access.RequiredReadAction; import consulo.application.dumb.DumbAware; import consulo.codeEditor.Editor; import consulo.document.Document; import consulo.document.util.TextRange; import consulo.java.impl.JavaBundle; +import consulo.java.language.module.util.JavaClassNames; import consulo.language.codeStyle.CodeStyleManager; import consulo.language.editor.CodeInsightUtilCore; import consulo.language.editor.refactoring.postfixTemplate.PostfixTemplateExpressionSelector; @@ -36,7 +38,7 @@ public class SwitchStatementPostfixTemplate extends SurroundPostfixTemplateBase } return DumbService.getInstance(expression.getProject()).computeWithAlternativeResolveEnabled(() -> { - final PsiType type = expression.getType(); + PsiType type = expression.getType(); if (type == null) { return false; @@ -49,13 +51,13 @@ public class SwitchStatementPostfixTemplate extends SurroundPostfixTemplateBase return true; } - final PsiClass psiClass = classType.resolve(); + PsiClass psiClass = classType.resolve(); if (psiClass != null && psiClass.isEnum()) { return true; } } - if (type.equalsToText(CommonClassNames.JAVA_LANG_STRING) && expression.getContainingFile() instanceof PsiJavaFile javaFile) { + if (type.equalsToText(JavaClassNames.JAVA_LANG_STRING) && expression.getContainingFile() instanceof PsiJavaFile javaFile) { if (PsiUtil.isAvailable(JavaFeature.STRING_SWITCH, javaFile)) { return true; } @@ -79,6 +81,7 @@ public boolean isApplicable(PsiExpression expr) { } @Override + @RequiredReadAction public TextRange surroundExpression(Project project, Editor editor, PsiExpression expr) throws IncorrectOperationException { PsiElementFactory factory = JavaPsiFacade.getElementFactory(project); CodeStyleManager codeStyleManager = CodeStyleManager.getInstance(project); @@ -98,6 +101,7 @@ else if (PsiUtil.isAvailable(JavaFeature.ENHANCED_SWITCH, expr)) { } @Nonnull + @RequiredReadAction private static TextRange postprocessSwitch( Editor editor, PsiExpression expr, @@ -135,6 +139,7 @@ public String getTemplateDescription() { public static PostfixTemplateExpressionSelector selectorTopmost(Predicate additionalFilter) { return new PostfixTemplateExpressionSelectorBase(additionalFilter) { @Override + @RequiredReadAction protected List getNonFilteredExpressions(@Nonnull PsiElement context, @Nonnull Document document, int offset) { boolean isEnhancedSwitchAvailable = PsiUtil.isAvailable(JavaFeature.ENHANCED_SWITCH, context); List result = new ArrayList<>(); @@ -145,10 +150,11 @@ protected List getNonFilteredExpressions(@Nonnull PsiElement context if (parent instanceof PsiExpressionStatement) { result.add(element); } - else if (isEnhancedSwitchAvailable && (isVariableInitializer(element, parent) || - isRightSideOfAssignment(element, parent) || - isReturnValue(element, parent) || - isArgumentList(parent))) { + else if (isEnhancedSwitchAvailable + && (isVariableInitializer(element, parent) + || isRightSideOfAssignment(element, parent) + || isReturnValue(element, parent) + || isArgumentList(parent))) { result.add(element); } } @@ -167,15 +173,15 @@ public Function getRenderer() { } private static boolean isVariableInitializer(PsiElement element, PsiElement parent) { - return parent instanceof PsiVariable && ((PsiVariable)parent).getInitializer() == element; + return parent instanceof PsiVariable variable && variable.getInitializer() == element; } private static boolean isRightSideOfAssignment(PsiElement element, PsiElement parent) { - return parent instanceof PsiAssignmentExpression && ((PsiAssignmentExpression)parent).getRExpression() == element; + return parent instanceof PsiAssignmentExpression assignment && assignment.getRExpression() == element; } private static boolean isReturnValue(PsiElement element, PsiElement parent) { - return parent instanceof PsiReturnStatement && ((PsiReturnStatement)parent).getReturnValue() == element; + return parent instanceof PsiReturnStatement returnStmt && returnStmt.getReturnValue() == element; } private static boolean isArgumentList(PsiElement parent) { diff --git a/plugin/src/main/java/com/intellij/java/impl/codeInsight/template/postfix/templates/ThrowExceptionPostfixTemplate.java b/plugin/src/main/java/com/intellij/java/impl/codeInsight/template/postfix/templates/ThrowExceptionPostfixTemplate.java index 750f12358..535b56483 100644 --- a/plugin/src/main/java/com/intellij/java/impl/codeInsight/template/postfix/templates/ThrowExceptionPostfixTemplate.java +++ b/plugin/src/main/java/com/intellij/java/impl/codeInsight/template/postfix/templates/ThrowExceptionPostfixTemplate.java @@ -2,19 +2,20 @@ package com.intellij.java.impl.codeInsight.template.postfix.templates; import com.intellij.java.language.LanguageLevel; -import com.intellij.java.language.psi.CommonClassNames; import consulo.application.dumb.DumbAware; +import consulo.java.language.module.util.JavaClassNames; import jakarta.annotation.Nonnull; import java.util.Collections; public class ThrowExceptionPostfixTemplate extends JavaEditablePostfixTemplate implements DumbAware { public ThrowExceptionPostfixTemplate(@Nonnull JavaPostfixTemplateProvider provider) { - super("throw", + super( + "throw", "throw $EXPR$;$END$", "throw expr", Collections.singleton( - new JavaPostfixTemplateExpressionCondition.JavaPostfixTemplateExpressionFqnCondition(CommonClassNames.JAVA_LANG_THROWABLE) + new JavaPostfixTemplateExpressionCondition.JavaPostfixTemplateExpressionFqnCondition(JavaClassNames.JAVA_LANG_THROWABLE) ), LanguageLevel.JDK_1_3, true, provider ); diff --git a/plugin/src/main/java/com/intellij/java/impl/codeInspection/ReplaceComputeWithComputeIfPresentFix.java b/plugin/src/main/java/com/intellij/java/impl/codeInspection/ReplaceComputeWithComputeIfPresentFix.java index 32a155e7e..3dfe2a30c 100644 --- a/plugin/src/main/java/com/intellij/java/impl/codeInspection/ReplaceComputeWithComputeIfPresentFix.java +++ b/plugin/src/main/java/com/intellij/java/impl/codeInspection/ReplaceComputeWithComputeIfPresentFix.java @@ -4,7 +4,9 @@ import com.intellij.java.language.psi.*; import com.siyeh.ig.callMatcher.CallMatcher; import com.siyeh.ig.psiutils.ExpressionUtils; +import consulo.annotation.access.RequiredReadAction; import consulo.java.analysis.impl.codeInsight.JavaInspectionsBundle; +import consulo.java.language.module.util.JavaClassNames; import consulo.language.editor.inspection.LocalQuickFix; import consulo.language.editor.inspection.ProblemDescriptor; import consulo.language.editor.intention.HighPriorityAction; @@ -18,8 +20,8 @@ import static consulo.util.lang.ObjectUtil.tryCast; public class ReplaceComputeWithComputeIfPresentFix implements LocalQuickFix, HighPriorityAction { - private static final CallMatcher MAP_COMPUTE = CallMatcher.instanceCall(CommonClassNames.JAVA_UTIL_MAP, "compute"). - parameterTypes("K", CommonClassNames.JAVA_UTIL_FUNCTION_BI_FUNCTION); + private static final CallMatcher MAP_COMPUTE = CallMatcher.instanceCall(JavaClassNames.JAVA_UTIL_MAP, "compute"). + parameterTypes("K", JavaClassNames.JAVA_UTIL_FUNCTION_BI_FUNCTION); @Override @Nonnull @@ -28,6 +30,7 @@ public String getFamilyName() { } @Override + @RequiredReadAction public void applyFix(@Nonnull Project project, @Nonnull ProblemDescriptor descriptor) { PsiLambdaExpression lambda = PsiTreeUtil.getParentOfType(descriptor.getStartElement(), PsiLambdaExpression.class); if (lambda == null) { @@ -41,11 +44,12 @@ public void applyFix(@Nonnull Project project, @Nonnull ProblemDescriptor descri } @Contract("null -> null") + @RequiredReadAction public static ReplaceComputeWithComputeIfPresentFix makeFix(PsiElement reference) { - if (!(reference instanceof PsiReferenceExpression)) { + if (!(reference instanceof PsiReferenceExpression refExpr)) { return null; } - PsiParameter parameter = tryCast(((PsiReferenceExpression)reference).resolve(), PsiParameter.class); + PsiParameter parameter = tryCast(refExpr.resolve(), PsiParameter.class); if (parameter == null) { return null; } diff --git a/plugin/src/main/java/com/intellij/java/impl/codeInspection/WrapWithMutableCollectionFix.java b/plugin/src/main/java/com/intellij/java/impl/codeInspection/WrapWithMutableCollectionFix.java index 9d3c0bc5a..4f1b29443 100644 --- a/plugin/src/main/java/com/intellij/java/impl/codeInspection/WrapWithMutableCollectionFix.java +++ b/plugin/src/main/java/com/intellij/java/impl/codeInspection/WrapWithMutableCollectionFix.java @@ -8,6 +8,8 @@ import com.intellij.java.language.psi.util.PsiUtil; import com.siyeh.ig.psiutils.CommentTracker; import com.siyeh.ig.psiutils.ExpressionUtils; +import consulo.annotation.access.RequiredReadAction; +import consulo.java.language.module.util.JavaClassNames; import consulo.language.editor.inspection.LocalQuickFix; import consulo.language.editor.inspection.ProblemDescriptor; import consulo.language.psi.PsiElement; @@ -60,15 +62,15 @@ public void applyFix(@Nonnull Project project, @Nonnull ProblemDescriptor descri return; } String typeParameters = ""; - if (myCollectionName.equals(CommonClassNames.JAVA_UTIL_HASH_MAP)) { - PsiType keyParameter = PsiUtil.substituteTypeParameter(type, CommonClassNames.JAVA_UTIL_MAP, 0, false); - PsiType valueParameter = PsiUtil.substituteTypeParameter(type, CommonClassNames.JAVA_UTIL_MAP, 1, false); + if (myCollectionName.equals(JavaClassNames.JAVA_UTIL_HASH_MAP)) { + PsiType keyParameter = PsiUtil.substituteTypeParameter(type, JavaClassNames.JAVA_UTIL_MAP, 0, false); + PsiType valueParameter = PsiUtil.substituteTypeParameter(type, JavaClassNames.JAVA_UTIL_MAP, 1, false); if (keyParameter != null && valueParameter != null) { typeParameters = "<" + keyParameter.getCanonicalText() + "," + valueParameter.getCanonicalText() + ">"; } } else { - PsiType elementParameter = PsiUtil.substituteTypeParameter(type, CommonClassNames.JAVA_LANG_ITERABLE, 0, false); + PsiType elementParameter = PsiUtil.substituteTypeParameter(type, JavaClassNames.JAVA_LANG_ITERABLE, 0, false); if (elementParameter != null) { typeParameters = "<" + elementParameter.getCanonicalText() + ">"; } @@ -83,6 +85,7 @@ public void applyFix(@Nonnull Project project, @Nonnull ProblemDescriptor descri } @Nullable + @RequiredReadAction public static WrapWithMutableCollectionFix createFix(@Nonnull PsiElement anchor, boolean onTheFly) { PsiLocalVariable variable = getVariable(anchor); if (variable == null) { @@ -107,23 +110,21 @@ public static WrapWithMutableCollectionFix createFix(@Nonnull PsiElement anchor, } @Nullable + @RequiredReadAction private static PsiLocalVariable getVariable(@Nonnull PsiElement anchor) { - if (anchor.getParent() instanceof PsiReferenceExpression && anchor.getParent().getParent() instanceof PsiCallExpression) { - anchor = ((PsiReferenceExpression)anchor.getParent()).getQualifierExpression(); + if (anchor.getParent() instanceof PsiReferenceExpression refExpr && refExpr.getParent() instanceof PsiCallExpression) { + anchor = refExpr.getQualifierExpression(); } - if (!(anchor instanceof PsiExpression)) { - return null; - } - return ExpressionUtils.resolveLocalVariable((PsiExpression)anchor); + return anchor instanceof PsiExpression expression ? ExpressionUtils.resolveLocalVariable(expression) : null; } @Contract("null -> null") @Nullable private static String getWrapperByType(PsiType type) { - if (!(type instanceof PsiClassType)) { + if (!(type instanceof PsiClassType classType)) { return null; } - PsiClass aClass = ((PsiClassType)type).resolve(); + PsiClass aClass = classType.resolve(); if (aClass == null) { return null; } @@ -131,16 +132,12 @@ private static String getWrapperByType(PsiType type) { if (name == null) { return null; } - switch (name) { - case CommonClassNames.JAVA_LANG_ITERABLE: - case CommonClassNames.JAVA_UTIL_COLLECTION: - case CommonClassNames.JAVA_UTIL_LIST: - return CommonClassNames.JAVA_UTIL_ARRAY_LIST; - case CommonClassNames.JAVA_UTIL_SET: - return CommonClassNames.JAVA_UTIL_HASH_SET; - case CommonClassNames.JAVA_UTIL_MAP: - return CommonClassNames.JAVA_UTIL_HASH_MAP; - } - return null; + return switch (name) { + case JavaClassNames.JAVA_LANG_ITERABLE, JavaClassNames.JAVA_UTIL_COLLECTION, JavaClassNames.JAVA_UTIL_LIST -> + JavaClassNames.JAVA_UTIL_ARRAY_LIST; + case JavaClassNames.JAVA_UTIL_SET -> JavaClassNames.JAVA_UTIL_HASH_SET; + case JavaClassNames.JAVA_UTIL_MAP -> JavaClassNames.JAVA_UTIL_HASH_MAP; + default -> null; + }; } }