Search in sources :

Example 1 with GrClosureType

use of org.jetbrains.plugins.groovy.lang.psi.impl.GrClosureType in project intellij-community by JetBrains.

the class ConvertClosureToMethodIntention method processIntention.

@Override
protected void processIntention(@NotNull PsiElement element, @NotNull Project project, Editor editor) throws IncorrectOperationException {
    final GrField field;
    if (element.getParent() instanceof GrField) {
        field = (GrField) element.getParent();
    } else {
        final PsiReference ref = element.getReference();
        LOG.assertTrue(ref != null);
        PsiElement resolved = ref.resolve();
        if (resolved instanceof GrAccessorMethod) {
            resolved = ((GrAccessorMethod) resolved).getProperty();
        }
        LOG.assertTrue(resolved instanceof GrField);
        field = (GrField) resolved;
    }
    final HashSet<PsiReference> usages = new HashSet<>();
    usages.addAll(ReferencesSearch.search(field).findAll());
    final GrAccessorMethod[] getters = field.getGetters();
    for (GrAccessorMethod getter : getters) {
        usages.addAll(MethodReferencesSearch.search(getter).findAll());
    }
    final GrAccessorMethod setter = field.getSetter();
    if (setter != null) {
        usages.addAll(MethodReferencesSearch.search(setter).findAll());
    }
    final String fieldName = field.getName();
    LOG.assertTrue(fieldName != null);
    final Collection<PsiElement> fieldUsages = new HashSet<>();
    MultiMap<PsiElement, String> conflicts = new MultiMap<>();
    for (PsiReference usage : usages) {
        final PsiElement psiElement = usage.getElement();
        if (PsiUtil.isMethodUsage(psiElement))
            continue;
        if (!GroovyLanguage.INSTANCE.equals(psiElement.getLanguage())) {
            conflicts.putValue(psiElement, GroovyIntentionsBundle.message("closure.is.accessed.outside.of.groovy", fieldName));
        } else {
            if (psiElement instanceof GrReferenceExpression) {
                fieldUsages.add(psiElement);
                if (PsiUtil.isAccessedForWriting((GrExpression) psiElement)) {
                    conflicts.putValue(psiElement, GroovyIntentionsBundle.message("write.access.to.closure.variable", fieldName));
                }
            } else if (psiElement instanceof GrArgumentLabel) {
                conflicts.putValue(psiElement, GroovyIntentionsBundle.message("field.is.used.in.argument.label", fieldName));
            }
        }
    }
    final PsiClass containingClass = field.getContainingClass();
    final GrExpression initializer = field.getInitializerGroovy();
    LOG.assertTrue(initializer != null);
    final PsiType type = initializer.getType();
    LOG.assertTrue(type instanceof GrClosureType);
    final GrSignature signature = ((GrClosureType) type).getSignature();
    final List<MethodSignature> signatures = GrClosureSignatureUtil.generateAllMethodSignaturesBySignature(fieldName, signature);
    for (MethodSignature s : signatures) {
        final PsiMethod method = MethodSignatureUtil.findMethodBySignature(containingClass, s, true);
        if (method != null) {
            conflicts.putValue(method, GroovyIntentionsBundle.message("method.with.signature.already.exists", GroovyPresentationUtil.getSignaturePresentation(s)));
        }
    }
    if (!conflicts.isEmpty()) {
        final ConflictsDialog conflictsDialog = new ConflictsDialog(project, conflicts, () -> execute(field, fieldUsages));
        conflictsDialog.show();
        if (conflictsDialog.getExitCode() != DialogWrapper.OK_EXIT_CODE)
            return;
    }
    execute(field, fieldUsages);
}
Also used : GrField(org.jetbrains.plugins.groovy.lang.psi.api.statements.GrField) MethodSignature(com.intellij.psi.util.MethodSignature) GrArgumentLabel(org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentLabel) GrExpression(org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression) GrReferenceExpression(org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression) GrAccessorMethod(org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrAccessorMethod) MultiMap(com.intellij.util.containers.MultiMap) ConflictsDialog(com.intellij.refactoring.ui.ConflictsDialog) GrSignature(org.jetbrains.plugins.groovy.lang.psi.api.signatures.GrSignature) HashSet(com.intellij.util.containers.HashSet) GrClosureType(org.jetbrains.plugins.groovy.lang.psi.impl.GrClosureType)

Example 2 with GrClosureType

use of org.jetbrains.plugins.groovy.lang.psi.impl.GrClosureType in project intellij-community by JetBrains.

the class GroovyTypeCheckVisitor method checkMethodApplicability.

private <T extends GroovyPsiElement> boolean checkMethodApplicability(@NotNull final GroovyResolveResult methodResolveResult, boolean checkUnknownArgs, @NotNull final CallInfo<T> info) {
    final PsiElement element = methodResolveResult.getElement();
    if (!(element instanceof PsiMethod))
        return true;
    if (element instanceof GrBuilderMethod)
        return true;
    final PsiMethod method = (PsiMethod) element;
    if ("call".equals(method.getName()) && info.getInvokedExpression() instanceof GrReferenceExpression) {
        final GrExpression qualifierExpression = ((GrReferenceExpression) info.getInvokedExpression()).getQualifierExpression();
        if (qualifierExpression != null) {
            final PsiType type = qualifierExpression.getType();
            if (type instanceof GrClosureType) {
                GrClosureSignatureUtil.ApplicabilityResult result = PsiUtil.isApplicableConcrete(info.getArgumentTypes(), (GrClosureType) type, info.getInvokedExpression());
                switch(result) {
                    case inapplicable:
                        highlightInapplicableMethodUsage(methodResolveResult, info, method);
                        return false;
                    case //q(1,2)
                    canBeApplicable:
                        if (checkUnknownArgs) {
                            highlightUnknownArgs(info);
                        }
                        return !checkUnknownArgs;
                    default:
                        return true;
                }
            }
        }
    }
    if (method instanceof GrGdkMethod && info.getInvokedExpression() instanceof GrReferenceExpression) {
        final GrReferenceExpression invoked = (GrReferenceExpression) info.getInvokedExpression();
        final GrExpression qualifier = PsiImplUtil.getRuntimeQualifier(invoked);
        if (qualifier == null && method.getName().equals("call")) {
            GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(invoked.getProject());
            final GrReferenceExpression callRef = factory.createReferenceExpressionFromText("qualifier.call", invoked);
            callRef.setQualifier(invoked);
            return checkMethodApplicability(methodResolveResult, checkUnknownArgs, new DelegatingCallInfo<T>(info) {

                @Nullable
                @Override
                public GrExpression getInvokedExpression() {
                    return callRef;
                }

                @NotNull
                @Override
                public GroovyResolveResult advancedResolve() {
                    return methodResolveResult;
                }

                @NotNull
                @Override
                public GroovyResolveResult[] multiResolve() {
                    return new GroovyResolveResult[] { methodResolveResult };
                }

                @Nullable
                @Override
                public PsiType getQualifierInstanceType() {
                    return info.getInvokedExpression().getType();
                }
            });
        }
        final PsiMethod staticMethod = ((GrGdkMethod) method).getStaticMethod();
        PsiType qualifierType = info.getQualifierInstanceType();
        if (method.hasModifierProperty(PsiModifier.STATIC)) {
            qualifierType = ResolveUtil.unwrapClassType(qualifierType);
        }
        //check methods processed by @Category(ClassWhichProcessMethod) annotation
        if (qualifierType != null && !GdkMethodUtil.isCategoryMethod(staticMethod, qualifierType, qualifier, methodResolveResult.getSubstitutor()) && !checkCategoryQualifier(invoked, qualifier, staticMethod, methodResolveResult.getSubstitutor())) {
            registerError(info.getHighlightElementForCategoryQualifier(), ProblemHighlightType.GENERIC_ERROR, GroovyInspectionBundle.message("category.method.0.cannot.be.applied.to.1", method.getName(), qualifierType.getCanonicalText()));
            return false;
        }
    }
    if (info.getArgumentTypes() == null)
        return true;
    GrClosureSignatureUtil.ApplicabilityResult applicable = PsiUtil.isApplicableConcrete(info.getArgumentTypes(), method, methodResolveResult.getSubstitutor(), info.getCall(), false);
    switch(applicable) {
        case inapplicable:
            highlightInapplicableMethodUsage(methodResolveResult, info, method);
            return false;
        case canBeApplicable:
            if (checkUnknownArgs) {
                highlightUnknownArgs(info);
            }
            return !checkUnknownArgs;
        default:
            return true;
    }
}
Also used : NotNull(org.jetbrains.annotations.NotNull) GrClosureSignatureUtil(org.jetbrains.plugins.groovy.lang.psi.impl.signatures.GrClosureSignatureUtil) GroovyPsiElementFactory(org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory) GroovyResolveResult(org.jetbrains.plugins.groovy.lang.psi.api.GroovyResolveResult) GrBuilderMethod(org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrBuilderMethod) GrGdkMethod(org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrGdkMethod) GroovyPsiElement(org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement) Nullable(org.jetbrains.annotations.Nullable) GrClosureType(org.jetbrains.plugins.groovy.lang.psi.impl.GrClosureType)

Example 3 with GrClosureType

use of org.jetbrains.plugins.groovy.lang.psi.impl.GrClosureType in project intellij-community by JetBrains.

the class GrClosureSignatureUtil method createSignature.

@Nullable
public static GrClosureSignature createSignature(GrCall call) {
    if (call instanceof GrMethodCall) {
        final GrExpression invokedExpression = ((GrMethodCall) call).getInvokedExpression();
        final PsiType type = invokedExpression.getType();
        if (type instanceof GrClosureType) {
            final GrSignature signature = ((GrClosureType) type).getSignature();
            final Trinity<GrClosureSignature, ArgInfo<PsiType>[], ApplicabilityResult> trinity = getApplicableSignature(signature, PsiUtil.getArgumentTypes(invokedExpression, true), call);
            if (trinity != null) {
                return trinity.first;
            }
            return null;
        }
    }
    final GroovyResolveResult resolveResult = call.advancedResolve();
    final PsiElement element = resolveResult.getElement();
    if (element instanceof PsiMethod) {
        return createSignature((PsiMethod) element, resolveResult.getSubstitutor());
    }
    return null;
}
Also used : GroovyResolveResult(org.jetbrains.plugins.groovy.lang.psi.api.GroovyResolveResult) GrMethodCall(org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrMethodCall) GrClosureSignature(org.jetbrains.plugins.groovy.lang.psi.api.signatures.GrClosureSignature) GrExpression(org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression) GrSignature(org.jetbrains.plugins.groovy.lang.psi.api.signatures.GrSignature) GroovyPsiElement(org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement) GrClosureType(org.jetbrains.plugins.groovy.lang.psi.impl.GrClosureType) Nullable(org.jetbrains.annotations.Nullable)

Example 4 with GrClosureType

use of org.jetbrains.plugins.groovy.lang.psi.impl.GrClosureType in project intellij-community by JetBrains.

the class DefaultCallExpressionTypeCalculator method getClosureMethodsReturnType.

@Nullable
private static PsiType getClosureMethodsReturnType(GrMethodCall callExpression, GrReferenceExpression refExpr, PsiMethod resolved) {
    PsiClass clazz = resolved.getContainingClass();
    if (clazz == null || !GroovyCommonClassNames.GROOVY_LANG_CLOSURE.equals(clazz.getQualifiedName()))
        return null;
    if (!CLOSURE_METHODS.contains(resolved.getName()))
        return null;
    GrExpression qualifier = refExpr.getQualifierExpression();
    if (qualifier == null)
        return null;
    PsiType qType = qualifier.getType();
    if (!(qType instanceof GrClosureType))
        return null;
    if ("call".equals(resolved.getName())) {
        return GrClosureSignatureUtil.getReturnType(((GrClosureType) qType).getSignature(), callExpression);
    } else if ("curry".equals(resolved.getName()) || "trampoline".equals(resolved.getName())) {
        return ((GrClosureType) qType).curry(PsiUtil.getArgumentTypes(refExpr, false), 0, callExpression);
    } else if ("memoize".equals(resolved.getName())) {
        return qType;
    } else if ("rcurry".equals(resolved.getName())) {
        return ((GrClosureType) qType).curry(PsiUtil.getArgumentTypes(refExpr, false), -1, callExpression);
    } else if ("ncurry".equals(resolved.getName())) {
        final GrArgumentList argList = callExpression.getArgumentList();
        final GrExpression[] arguments = argList.getExpressionArguments();
        if (arguments.length > 0) {
            final GrExpression first = arguments[0];
            if (first instanceof GrLiteral) {
                final Object value = ((GrLiteral) first).getValue();
                if (value instanceof Integer) {
                    final PsiType[] argTypes = PsiUtil.getArgumentTypes(refExpr, false);
                    if (argTypes != null) {
                        return ((GrClosureType) qType).curry(ArrayUtil.remove(argTypes, 0), (Integer) value, callExpression);
                    }
                }
            }
        }
        return qType;
    }
    return null;
}
Also used : GrArgumentList(org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentList) GrExpression(org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression) GrLiteral(org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.literals.GrLiteral) GrClosureType(org.jetbrains.plugins.groovy.lang.psi.impl.GrClosureType) Nullable(org.jetbrains.annotations.Nullable)

Example 5 with GrClosureType

use of org.jetbrains.plugins.groovy.lang.psi.impl.GrClosureType in project intellij-community by JetBrains.

the class ClosureToSamConverter method isConvertible.

@Override
public Boolean isConvertible(@NotNull PsiType ltype, @NotNull PsiType rtype, @NotNull final GroovyPsiElement context) {
    if (rtype instanceof GrClosureType && ltype instanceof PsiClassType && isSamConversionAllowed(context) && !TypesUtil.isClassType(ltype, GroovyCommonClassNames.GROOVY_LANG_CLOSURE)) {
        MethodSignature signature = findSAMSignature(ltype);
        if (signature != null) {
            final PsiType[] samParameterTypes = signature.getParameterTypes();
            GrSignature closureSignature = ((GrClosureType) rtype).getSignature();
            boolean raw = ((PsiClassType) ltype).isRaw();
            if (raw)
                return true;
            if (GrClosureSignatureUtil.isSignatureApplicable(closureSignature, samParameterTypes, context)) {
                return true;
            }
        }
    }
    return null;
}
Also used : MethodSignature(com.intellij.psi.util.MethodSignature) GrSignature(org.jetbrains.plugins.groovy.lang.psi.api.signatures.GrSignature) GrClosureType(org.jetbrains.plugins.groovy.lang.psi.impl.GrClosureType)

Aggregations

GrClosureType (org.jetbrains.plugins.groovy.lang.psi.impl.GrClosureType)11 Nullable (org.jetbrains.annotations.Nullable)6 GrSignature (org.jetbrains.plugins.groovy.lang.psi.api.signatures.GrSignature)6 GrExpression (org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression)6 GroovyPsiElement (org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement)4 GroovyResolveResult (org.jetbrains.plugins.groovy.lang.psi.api.GroovyResolveResult)4 MethodSignature (com.intellij.psi.util.MethodSignature)3 GrClosureSignature (org.jetbrains.plugins.groovy.lang.psi.api.signatures.GrClosureSignature)2 GrArgumentList (org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentList)2 GrMethodCall (org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrMethodCall)2 GrReferenceExpression (org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression)2 GrAccessorMethod (org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrAccessorMethod)2 PsiElement (com.intellij.psi.PsiElement)1 ConflictsDialog (com.intellij.refactoring.ui.ConflictsDialog)1 HashSet (com.intellij.util.containers.HashSet)1 MultiMap (com.intellij.util.containers.MultiMap)1 NotNull (org.jetbrains.annotations.NotNull)1 GroovyPsiElementFactory (org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory)1 GrRecursiveSignatureVisitor (org.jetbrains.plugins.groovy.lang.psi.api.signatures.GrRecursiveSignatureVisitor)1 GrField (org.jetbrains.plugins.groovy.lang.psi.api.statements.GrField)1