From cd72be6365de7fd94ce7ee36d4c1e5d7c5d6be37 Mon Sep 17 00:00:00 2001 From: "Roman.Ivanov" Date: Wed, 23 May 2018 18:54:01 +0700 Subject: [PATCH] make isDenotableType compliant to specification --- .../daemon/impl/quickfix/AddTypeCastFix.java | 2 +- .../VariableTypeCanBeExplicitInspection.java | 2 +- .../JavacQuirksInspectionVisitor.java | 2 +- .../quickfix/AddNewArrayExpressionFix.java | 10 +++---- .../impl/quickfix/SurroundWithArrayFix.java | 2 +- ...VariableAccessFromInnerClassJava10Fix.java | 2 +- .../util/LambdaRefactoringUtil.java | 2 +- .../com/intellij/psi/util/PsiTypesUtil.java | 29 +++++++++---------- ...aCanBeReplacedWithAnonymousInspection.java | 4 +-- .../psi/impl/LambdaToAnonymousTransformer.kt | 4 +-- 10 files changed, 28 insertions(+), 31 deletions(-) diff --git a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/AddTypeCastFix.java b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/AddTypeCastFix.java index 10395ee83584..909f2445f98a 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/AddTypeCastFix.java +++ b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/AddTypeCastFix.java @@ -58,7 +58,7 @@ public class AddTypeCastFix extends LocalQuickFixAndIntentionActionOnPsiElement @NotNull PsiElement startElement, @NotNull PsiElement endElement) { return myType.isValid() && - PsiTypesUtil.isDenotableType(myType) && + PsiTypesUtil.isDenotableType(myType, startElement) && PsiTypesUtil.allTypeParametersResolved(startElement, myType) && startElement.getManager().isInProject(startElement); } diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/VariableTypeCanBeExplicitInspection.java b/java/java-analysis-impl/src/com/intellij/codeInspection/VariableTypeCanBeExplicitInspection.java index eab82794d3bf..6144e9a63632 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/VariableTypeCanBeExplicitInspection.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/VariableTypeCanBeExplicitInspection.java @@ -23,7 +23,7 @@ public class VariableTypeCanBeExplicitInspection extends AbstractBaseJavaLocalIn PsiTypeElement typeElement = variable.getTypeElement(); if (typeElement != null && typeElement.isInferredType()) { PsiType type = variable.getType(); - if (!PsiTypesUtil.isNonDenotableType(type, variable)) { + if (PsiTypesUtil.isDenotableType(type, variable)) { holder.registerProblem(typeElement, "'var' can be replaced with explicit type", ProblemHighlightType.GENERIC_ERROR_OR_WARNING, diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/compiler/JavacQuirksInspectionVisitor.java b/java/java-analysis-impl/src/com/intellij/codeInspection/compiler/JavacQuirksInspectionVisitor.java index 4eebdac160b2..a0d2c1c9fd8d 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/compiler/JavacQuirksInspectionVisitor.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/compiler/JavacQuirksInspectionVisitor.java @@ -140,7 +140,7 @@ public class JavacQuirksInspectionVisitor extends JavaElementVisitor { if (method.isVarArgs() && method.hasTypeParameters() && args.length > method.getParameterList().getParametersCount() + 50) { PsiSubstitutor substitutor = resolveResult.getSubstitutor(); for (PsiTypeParameter typeParameter : method.getTypeParameters()) { - if (!PsiTypesUtil.isDenotableType(substitutor.substitute(typeParameter))) { + if (!PsiTypesUtil.isDenotableType(substitutor.substitute(typeParameter), typeParameter)) { return; } } diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/AddNewArrayExpressionFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/AddNewArrayExpressionFix.java index c7d83c7ae485..9003064a14a7 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/AddNewArrayExpressionFix.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/AddNewArrayExpressionFix.java @@ -79,20 +79,20 @@ public class AddNewArrayExpressionFix implements IntentionAction { final PsiElement parent = myInitializer.getParent(); if (!(parent instanceof PsiAssignmentExpression)) { if (initializers.length <= 0) return null; - return validateType(initializers[0].getType()); + return validateType(initializers[0].getType(), parent); } final PsiAssignmentExpression assignmentExpression = (PsiAssignmentExpression)parent; final PsiType type = assignmentExpression.getType(); if (!(type instanceof PsiArrayType)) { if (initializers.length <= 0) return null; - return validateType(initializers[0].getType()); + return validateType(initializers[0].getType(), parent); } - return validateType(((PsiArrayType)type).getComponentType()); + return validateType(((PsiArrayType)type).getComponentType(), parent); } - private static PsiType validateType(PsiType type) { + private static PsiType validateType(PsiType type, @NotNull PsiElement context) { if (PsiType.NULL.equals(type)) return null; - return LambdaUtil.notInferredType(type) || !PsiTypesUtil.isDenotableType(type) ? null + return LambdaUtil.notInferredType(type) || !PsiTypesUtil.isDenotableType(type, context) ? null : TypeConversionUtil.erasure(type); } diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/SurroundWithArrayFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/SurroundWithArrayFix.java index 63dc7e650859..ad1b48da0e39 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/SurroundWithArrayFix.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/SurroundWithArrayFix.java @@ -92,7 +92,7 @@ public class SurroundWithArrayFix extends PsiElementBaseIntentionAction { final PsiType paramType = psiParameters[idx].getType(); if (paramType instanceof PsiArrayType) { final PsiType expressionType = TypeConversionUtil.erasure(expression.getType()); - if (expressionType != null && PsiTypesUtil.isDenotableType(expressionType) && expressionType != PsiType.NULL) { + if (expressionType != null && PsiTypesUtil.isDenotableType(expressionType, element) && expressionType != PsiType.NULL) { final PsiType componentType = ((PsiArrayType)paramType).getComponentType(); if (TypeConversionUtil.isAssignable(componentType, expressionType)) { return expression; diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/VariableAccessFromInnerClassJava10Fix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/VariableAccessFromInnerClassJava10Fix.java index 884a69970f1a..e97f537da9fd 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/VariableAccessFromInnerClassJava10Fix.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/VariableAccessFromInnerClassJava10Fix.java @@ -67,7 +67,7 @@ public class VariableAccessFromInnerClassJava10Fix extends BaseIntentionAction { if (name == null) return false; PsiType type = variable.getType(); - if (PsiTypesUtil.isNonDenotableType(type, variable)) { + if (!PsiTypesUtil.isDenotableType(type, variable)) { return false; } setText(QuickFixBundle.message("convert.variable.to.field.in.anonymous.class.fix.name", name)); diff --git a/java/java-impl/src/com/intellij/refactoring/util/LambdaRefactoringUtil.java b/java/java-impl/src/com/intellij/refactoring/util/LambdaRefactoringUtil.java index cb6853a6eb63..21437d9e8091 100644 --- a/java/java-impl/src/com/intellij/refactoring/util/LambdaRefactoringUtil.java +++ b/java/java-impl/src/com/intellij/refactoring/util/LambdaRefactoringUtil.java @@ -315,7 +315,7 @@ public class LambdaRefactoringUtil { for (int i = 0; i < parameters.length; i++) { PsiType psiType = substitutor.substitute(parameters[i].getType()); if (psiType == null) return null; - if (!PsiTypesUtil.isDenotableType(psiType)) { + if (!PsiTypesUtil.isDenotableType(psiType, interfaceMethod)) { return null; } diff --git a/java/java-psi-api/src/com/intellij/psi/util/PsiTypesUtil.java b/java/java-psi-api/src/com/intellij/psi/util/PsiTypesUtil.java index c75566699065..c7eed1812664 100644 --- a/java/java-psi-api/src/com/intellij/psi/util/PsiTypesUtil.java +++ b/java/java-psi-api/src/com/intellij/psi/util/PsiTypesUtil.java @@ -320,8 +320,19 @@ public class PsiTypesUtil { return Comparing.equal(leftType, rightType); } - public static boolean isDenotableType(PsiType type) { - return !(type instanceof PsiWildcardType || type instanceof PsiCapturedWildcardType); + /** + * @param context in which type should be checked + * @return false if type is null or has no explicit canonical type representation (e. g. intersection type) + */ + public static boolean isDenotableType(@Nullable PsiType type, @NotNull PsiElement context) { + if (type == null) return false; + PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(context.getProject()); + try { + PsiType typeAfterReplacement = elementFactory.createTypeElementFromText(type.getCanonicalText(), context).getType(); + return type.equals(typeAfterReplacement); + } catch (IncorrectOperationException e) { + return false; + } } public static boolean hasUnresolvedComponents(@NotNull PsiType type) { @@ -468,18 +479,4 @@ public class PsiTypesUtil { return false; } } - - /** - * @param context in which type should be checked - * @return true if type has no explicit canonical type representation (e. g. intersection type) - */ - public static boolean isNonDenotableType(@NotNull PsiType type, @NotNull PsiElement context) { - PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(context.getProject()); - try { - PsiType typeAfterReplacement = elementFactory.createTypeElementFromText(type.getCanonicalText(), context).getType(); - return !type.equals(typeAfterReplacement); - } catch (IncorrectOperationException e) { - return true; - } - } } diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/style/LambdaCanBeReplacedWithAnonymousInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/style/LambdaCanBeReplacedWithAnonymousInspection.java index d9ae08b09427..0589cb53bb49 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/style/LambdaCanBeReplacedWithAnonymousInspection.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/style/LambdaCanBeReplacedWithAnonymousInspection.java @@ -228,12 +228,12 @@ public class LambdaCanBeReplacedWithAnonymousInspection extends BaseInspection { final PsiSubstitutor substitutor = LambdaUtil.getSubstitutor(interfaceMethod, PsiUtil.resolveGenericsClassInType(functionalInterfaceType)); for (PsiType type : interfaceMethod.getSignature(substitutor).getParameterTypes()) { - if (!PsiTypesUtil.isDenotableType(type)) { + if (!PsiTypesUtil.isDenotableType(type, parent)) { return false; } } final PsiType returnType = LambdaUtil.getFunctionalInterfaceReturnType(functionalInterfaceType); - return PsiTypesUtil.isDenotableType(returnType); + return PsiTypesUtil.isDenotableType(returnType, parent); } } } diff --git a/plugins/stream-debugger/src/com/intellij/debugger/streams/psi/impl/LambdaToAnonymousTransformer.kt b/plugins/stream-debugger/src/com/intellij/debugger/streams/psi/impl/LambdaToAnonymousTransformer.kt index c9d2b626b99a..1a6ab6f450fc 100644 --- a/plugins/stream-debugger/src/com/intellij/debugger/streams/psi/impl/LambdaToAnonymousTransformer.kt +++ b/plugins/stream-debugger/src/com/intellij/debugger/streams/psi/impl/LambdaToAnonymousTransformer.kt @@ -161,9 +161,9 @@ object LambdaToAnonymousTransformer : PsiElementTransformer.Base() { val interfaceMethod = LambdaUtil.getFunctionalInterfaceMethod(functionalInterfaceType) if (interfaceMethod != null) { val substitutor = LambdaUtil.getSubstitutor(interfaceMethod, PsiUtil.resolveGenericsClassInType(functionalInterfaceType)) - if (interfaceMethod.getSignature(substitutor).parameterTypes.any { !PsiTypesUtil.isDenotableType(it) }) return false + if (interfaceMethod.getSignature(substitutor).parameterTypes.any { !PsiTypesUtil.isDenotableType(it, lambdaExpression) }) return false val returnType = LambdaUtil.getFunctionalInterfaceReturnType(functionalInterfaceType) - return PsiTypesUtil.isDenotableType(returnType) + return PsiTypesUtil.isDenotableType(returnType, lambdaExpression) } }