Search in sources :

Example 6 with GrClosureSignature

use of org.jetbrains.plugins.groovy.lang.psi.api.signatures.GrClosureSignature in project intellij-community by JetBrains.

the class TypeProvider method inferMethodParameters.

@NotNull
private PsiType[] inferMethodParameters(@NotNull GrMethod method) {
    PsiType[] psiTypes = inferredTypes.get(method);
    if (psiTypes != null)
        return psiTypes;
    final GrParameter[] parameters = method.getParameters();
    final TIntArrayList paramInds = new TIntArrayList(parameters.length);
    final PsiType[] types = PsiType.createArray(parameters.length);
    for (int i = 0; i < parameters.length; i++) {
        if (parameters[i].getTypeElementGroovy() == null) {
            paramInds.add(i);
        } else {
            types[i] = parameters[i].getType();
        }
    }
    if (!paramInds.isEmpty()) {
        final GrClosureSignature signature = GrClosureSignatureUtil.createSignature(method, PsiSubstitutor.EMPTY);
        MethodReferencesSearch.search(method, true).forEach(psiReference -> {
            final PsiElement element = psiReference.getElement();
            final PsiManager manager = element.getManager();
            final GlobalSearchScope resolveScope = element.getResolveScope();
            if (element instanceof GrReferenceExpression) {
                final GrCall call = (GrCall) element.getParent();
                final GrClosureSignatureUtil.ArgInfo<PsiElement>[] argInfos = GrClosureSignatureUtil.mapParametersToArguments(signature, call);
                if (argInfos == null)
                    return true;
                paramInds.forEach(new TIntProcedure() {

                    @Override
                    public boolean execute(int i) {
                        PsiType type = GrClosureSignatureUtil.getTypeByArg(argInfos[i], manager, resolveScope);
                        types[i] = TypesUtil.getLeastUpperBoundNullable(type, types[i], manager);
                        return true;
                    }
                });
            }
            return true;
        });
    }
    paramInds.forEach(new TIntProcedure() {

        @Override
        public boolean execute(int i) {
            if (types[i] == null || types[i] == PsiType.NULL) {
                types[i] = parameters[i].getType();
            }
            return true;
        }
    });
    inferredTypes.put(method, types);
    return types;
}
Also used : TIntProcedure(gnu.trove.TIntProcedure) GrCall(org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrCall) GrParameter(org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameter) TIntArrayList(gnu.trove.TIntArrayList) GrReferenceExpression(org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression) GlobalSearchScope(com.intellij.psi.search.GlobalSearchScope) GrClosureSignature(org.jetbrains.plugins.groovy.lang.psi.api.signatures.GrClosureSignature) NotNull(org.jetbrains.annotations.NotNull)

Example 7 with GrClosureSignature

use of org.jetbrains.plugins.groovy.lang.psi.api.signatures.GrClosureSignature in project intellij-community by JetBrains.

the class AnonymousFromMapGenerator method writeAnonymousMap.

static void writeAnonymousMap(GrListOrMap operand, GrTypeElement typeElement, final StringBuilder builder, ExpressionContext context) {
    final PsiType type = typeElement.getType();
    final PsiClass psiClass;
    final PsiSubstitutor substitutor;
    if (type instanceof PsiClassType) {
        final PsiClassType.ClassResolveResult resolveResult = ((PsiClassType) type).resolveGenerics();
        psiClass = resolveResult.getElement();
        substitutor = resolveResult.getSubstitutor();
    } else {
        psiClass = null;
        substitutor = PsiSubstitutor.EMPTY;
    }
    builder.append("new ");
    TypeWriter.writeTypeForNew(builder, type, operand);
    builder.append("() {\n");
    final GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(operand.getProject());
    final GrExpression caller = factory.createExpressionFromText("this");
    for (GrNamedArgument arg : operand.getNamedArguments()) {
        final String name = arg.getLabelName();
        final GrExpression expression = arg.getExpression();
        if (name == null || expression == null || !(expression instanceof GrClosableBlock))
            continue;
        final GrClosableBlock closure = (GrClosableBlock) expression;
        final GrParameter[] allParameters = closure.getAllParameters();
        List<GrParameter> actual = new ArrayList<>(Arrays.asList(allParameters));
        final PsiType clReturnType = context.typeProvider.getReturnType(closure);
        GrExpression[] args = new GrExpression[allParameters.length];
        for (int i = 0; i < allParameters.length; i++) {
            args[i] = factory.createExpressionFromText(allParameters[i].getName());
        }
        for (int param = allParameters.length; param >= 0; param--) {
            if (param < allParameters.length && !actual.get(param).isOptional())
                continue;
            if (param < allParameters.length) {
                final GrParameter opt = actual.remove(param);
                args[param] = opt.getInitializerGroovy();
            }
            final GrParameter[] parameters = actual.toArray(new GrParameter[actual.size()]);
            final GrClosureSignature signature = GrClosureSignatureUtil.createSignature(parameters, clReturnType);
            final GrMethod pattern = factory.createMethodFromSignature(name, signature);
            PsiMethod found = null;
            if (psiClass != null) {
                found = psiClass.findMethodBySignature(pattern, true);
            }
            if (found != null) {
                ModifierListGenerator.writeModifiers(builder, found.getModifierList(), ModifierListGenerator.JAVA_MODIFIERS_WITHOUT_ABSTRACT);
            } else {
                builder.append("public ");
            }
            PsiType returnType;
            if (found != null) {
                returnType = substitutor.substitute(context.typeProvider.getReturnType(found));
            } else {
                returnType = signature.getReturnType();
            }
            TypeWriter.writeType(builder, returnType, operand);
            builder.append(' ').append(name);
            GenerationUtil.writeParameterList(builder, parameters, new GeneratorClassNameProvider(), context);
            final ExpressionContext extended = context.extend();
            extended.setInAnonymousContext(true);
            if (param == allParameters.length) {
                new CodeBlockGenerator(builder, extended).generateCodeBlock(allParameters, closure, false);
            } else {
                builder.append("{\n");
                final ExpressionGenerator expressionGenerator = new ExpressionGenerator(builder, extended);
                GenerationUtil.invokeMethodByName(caller, name, args, GrNamedArgument.EMPTY_ARRAY, GrClosableBlock.EMPTY_ARRAY, expressionGenerator, arg);
                builder.append(";\n}\n");
            }
        }
    }
    builder.append("}");
}
Also used : GrNamedArgument(org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrNamedArgument) ArrayList(java.util.ArrayList) GrMethod(org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod) GrClosableBlock(org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock) GrExpression(org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression) GrParameter(org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameter) GroovyPsiElementFactory(org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory) GrClosureSignature(org.jetbrains.plugins.groovy.lang.psi.api.signatures.GrClosureSignature)

Example 8 with GrClosureSignature

use of org.jetbrains.plugins.groovy.lang.psi.api.signatures.GrClosureSignature in project intellij-community by JetBrains.

the class ConvertParameterToMapEntryIntention method performRefactoring.

private static void performRefactoring(final PsiElement element, final GrParametersOwner owner, final Collection<PsiElement> occurrences, final boolean createNewFirstParam, @Nullable final String mapParamName, final boolean specifyMapType) {
    final GrParameter param = getAppropriateParameter(element);
    assert param != null;
    final String paramName = param.getName();
    final String mapName = createNewFirstParam ? mapParamName : getFirstParameter(owner).getName();
    final Project project = element.getProject();
    final Runnable runnable = () -> {
        final GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(project);
        final GrParameterList list = owner.getParameterList();
        assert list != null;
        final int index = list.getParameterNumber(param);
        if (!createNewFirstParam && index <= 0) {
            // bad undo
            return;
        }
        //final List<GrCall> calls = getCallOccurrences(occurrences);
        try {
            for (PsiElement occurrence : occurrences) {
                GrReferenceExpression refExpr = null;
                GroovyResolveResult resolveResult = null;
                boolean isExplicitGetterCall = false;
                if (occurrence instanceof GrReferenceExpression) {
                    final PsiElement parent = occurrence.getParent();
                    if (parent instanceof GrCall) {
                        refExpr = (GrReferenceExpression) occurrence;
                        resolveResult = refExpr.advancedResolve();
                        final PsiElement resolved = resolveResult.getElement();
                        if (resolved instanceof PsiMethod && GroovyPropertyUtils.isSimplePropertyGetter(((PsiMethod) resolved)) && //check for explicit getter call
                        ((PsiMethod) resolved).getName().equals(refExpr.getReferenceName())) {
                            isExplicitGetterCall = true;
                        }
                    } else if (parent instanceof GrReferenceExpression) {
                        resolveResult = ((GrReferenceExpression) parent).advancedResolve();
                        final PsiElement resolved = resolveResult.getElement();
                        if (resolved instanceof PsiMethod && "call".equals(((PsiMethod) resolved).getName())) {
                            refExpr = (GrReferenceExpression) parent;
                        }
                    }
                }
                if (refExpr == null)
                    continue;
                final GrClosureSignature signature = generateSignature(owner, refExpr);
                if (signature == null)
                    continue;
                GrCall call;
                if (isExplicitGetterCall) {
                    PsiElement parent = refExpr.getParent();
                    LOG.assertTrue(parent instanceof GrCall);
                    parent = parent.getParent();
                    if (parent instanceof GrReferenceExpression && "call".equals(((GrReferenceExpression) parent).getReferenceName())) {
                        parent = parent.getParent();
                    }
                    if (parent instanceof GrCall) {
                        call = (GrCall) parent;
                    } else {
                        continue;
                    }
                } else {
                    call = (GrCall) refExpr.getParent();
                }
                if (resolveResult.isInvokedOnProperty()) {
                    final PsiElement parent = call.getParent();
                    if (parent instanceof GrCall) {
                        call = (GrCall) parent;
                    } else if (parent instanceof GrReferenceExpression && parent.getParent() instanceof GrCall) {
                        final PsiElement resolved = ((GrReferenceExpression) parent).resolve();
                        if (resolved instanceof PsiMethod && "call".equals(((PsiMethod) resolved).getName())) {
                            call = (GrCall) parent.getParent();
                        } else {
                            continue;
                        }
                    }
                }
                final GrClosureSignatureUtil.ArgInfo<PsiElement>[] argInfos = GrClosureSignatureUtil.mapParametersToArguments(signature, call);
                if (argInfos == null)
                    continue;
                final GrClosureSignatureUtil.ArgInfo<PsiElement> argInfo = argInfos[index];
                final GrNamedArgument namedArg;
                if (argInfo.isMultiArg) {
                    if (argInfo.args.isEmpty())
                        continue;
                    String arg = "[" + StringUtil.join(ContainerUtil.map(argInfo.args, element1 -> element1.getText()), ", ") + "]";
                    for (PsiElement psiElement : argInfo.args) {
                        psiElement.delete();
                    }
                    namedArg = factory.createNamedArgument(paramName, factory.createExpressionFromText(arg));
                } else {
                    if (argInfo.args.isEmpty())
                        continue;
                    final PsiElement argument = argInfo.args.iterator().next();
                    assert argument instanceof GrExpression;
                    namedArg = factory.createNamedArgument(paramName, (GrExpression) argument);
                    argument.delete();
                }
                call.addNamedArgument(namedArg);
            }
        } catch (IncorrectOperationException e) {
            LOG.error(e);
        }
        //Replace of occurrences of old parameter in closure/method
        final Collection<PsiReference> references = ReferencesSearch.search(param).findAll();
        for (PsiReference ref : references) {
            final PsiElement elt = ref.getElement();
            if (elt instanceof GrReferenceExpression) {
                GrReferenceExpression expr = (GrReferenceExpression) elt;
                final GrExpression newExpr = factory.createExpressionFromText(mapName + "." + paramName);
                expr.replaceWithExpression(newExpr, true);
            }
        }
        //Add new map parameter to closure/method if it's necessary
        if (createNewFirstParam) {
            try {
                final GrParameter newParam = factory.createParameter(mapName, specifyMapType ? MAP_TYPE_TEXT : "", null);
                list.addAfter(newParam, null);
            } catch (IncorrectOperationException e) {
                LOG.error(e);
            }
        }
        //Eliminate obsolete parameter from parameter list
        param.delete();
    };
    CommandProcessor.getInstance().executeCommand(project, () -> ApplicationManager.getApplication().runWriteAction(runnable), REFACTORING_NAME, null);
}
Also used : GrParameterList(org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameterList) GrNamedArgument(org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrNamedArgument) GrCall(org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrCall) GrExpression(org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression) GrParameter(org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameter) GrReferenceExpression(org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression) GroovyPsiElementFactory(org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory) GrClosureSignatureUtil(org.jetbrains.plugins.groovy.lang.psi.impl.signatures.GrClosureSignatureUtil) Project(com.intellij.openapi.project.Project) GroovyResolveResult(org.jetbrains.plugins.groovy.lang.psi.api.GroovyResolveResult) GrClosureSignature(org.jetbrains.plugins.groovy.lang.psi.api.signatures.GrClosureSignature) Collection(java.util.Collection) IncorrectOperationException(com.intellij.util.IncorrectOperationException)

Example 9 with GrClosureSignature

use of org.jetbrains.plugins.groovy.lang.psi.api.signatures.GrClosureSignature in project intellij-community by JetBrains.

the class GroovyTypeCheckVisitorHelper method genCastFixes.

@NotNull
public static LocalQuickFix[] genCastFixes(@NotNull GrSignature signature, @NotNull PsiType[] argumentTypes, @Nullable GrArgumentList argumentList) {
    if (argumentList == null)
        return LocalQuickFix.EMPTY_ARRAY;
    final List<GrExpression> args = getExpressionArgumentsOfCall(argumentList);
    if (args == null)
        return LocalQuickFix.EMPTY_ARRAY;
    final List<Pair<Integer, PsiType>> allErrors = new ArrayList<>();
    final List<GrClosureSignature> signatures = GrClosureSignatureUtil.generateSimpleSignatures(signature);
    for (GrClosureSignature closureSignature : signatures) {
        final GrClosureSignatureUtil.MapResultWithError<PsiType> map = GrClosureSignatureUtil.mapSimpleSignatureWithErrors(closureSignature, argumentTypes, id, argumentList, 1);
        if (map != null) {
            final List<Pair<Integer, PsiType>> errors = map.getErrors();
            for (Pair<Integer, PsiType> error : errors) {
                if (!(error.first == 0 && PsiImplUtil.hasNamedArguments(argumentList))) {
                    allErrors.add(error);
                }
            }
        }
    }
    final ArrayList<LocalQuickFix> fixes = new ArrayList<>();
    for (Pair<Integer, PsiType> error : allErrors) {
        if (args.size() > error.first && error.second != null) {
            fixes.add(new ParameterCastFix(error.first, error.second, args.get(error.first)));
        }
    }
    return fixes.toArray(new LocalQuickFix[fixes.size()]);
}
Also used : ArrayList(java.util.ArrayList) LocalQuickFix(com.intellij.codeInspection.LocalQuickFix) GrExpression(org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression) GrClosureSignatureUtil(org.jetbrains.plugins.groovy.lang.psi.impl.signatures.GrClosureSignatureUtil) ParameterCastFix(org.jetbrains.plugins.groovy.codeInspection.assignment.ParameterCastFix) GrClosureSignature(org.jetbrains.plugins.groovy.lang.psi.api.signatures.GrClosureSignature) Pair(com.intellij.openapi.util.Pair) NotNull(org.jetbrains.annotations.NotNull)

Example 10 with GrClosureSignature

use of org.jetbrains.plugins.groovy.lang.psi.api.signatures.GrClosureSignature in project intellij-community by JetBrains.

the class ClosureDescriptor method isMethodApplicable.

public boolean isMethodApplicable(PsiMethod method, GroovyPsiElement place) {
    String name = String.valueOf(myMethod.get("name"));
    if (name == null || !name.equals(method.getName()))
        return false;
    List<PsiType> types = new ArrayList<>();
    final Object params = myMethod.get("params");
    if (params instanceof Map) {
        boolean first = true;
        for (Object paramName : ((Map) params).keySet()) {
            Object value = ((Map) params).get(paramName);
            boolean isNamed = first && value instanceof List;
            first = false;
            String typeName = isNamed ? CommonClassNames.JAVA_UTIL_MAP : String.valueOf(value);
            types.add(convertToPsiType(typeName, place));
        }
    } else if (params instanceof List) {
        for (Object param : ((List) params)) {
            PsiTypeParameterList typeParameterList = method.getTypeParameterList();
            types.add(convertToPsiType(String.valueOf(param), typeParameterList != null ? typeParameterList : method));
        }
    }
    final boolean isConstructor = Boolean.TRUE.equals(myMethod.get("constructor"));
    final MethodSignature signature = MethodSignatureUtil.createMethodSignature(name, types.toArray(PsiType.createArray(types.size())), method.getTypeParameters(), PsiSubstitutor.EMPTY, isConstructor);
    final GrClosureSignature closureSignature = GrClosureSignatureUtil.createSignature(signature);
    if (method instanceof ClsMethodImpl)
        method = ((ClsMethodImpl) method).getSourceMirrorMethod();
    final PsiParameter[] parameters = method.getParameterList().getParameters();
    final PsiType[] typeArray = ContainerUtil.map(parameters, parameter -> parameter.getType(), PsiType.createArray(parameters.length));
    return GrClosureSignatureUtil.isSignatureApplicable(closureSignature, typeArray, place);
}
Also used : MethodSignature(com.intellij.psi.util.MethodSignature) ClsMethodImpl(com.intellij.psi.impl.compiled.ClsMethodImpl) ArrayList(java.util.ArrayList) GrClosureSignature(org.jetbrains.plugins.groovy.lang.psi.api.signatures.GrClosureSignature) ArrayList(java.util.ArrayList) List(java.util.List) Map(java.util.Map)

Aggregations

GrClosureSignature (org.jetbrains.plugins.groovy.lang.psi.api.signatures.GrClosureSignature)33 GroovyResolveResult (org.jetbrains.plugins.groovy.lang.psi.api.GroovyResolveResult)13 GrExpression (org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression)9 GrArgumentList (org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentList)8 ArrayList (java.util.ArrayList)6 Nullable (org.jetbrains.annotations.Nullable)6 GroovyPsiElement (org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement)6 GrCall (org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrCall)6 GrClosureParameter (org.jetbrains.plugins.groovy.lang.psi.api.types.GrClosureParameter)6 GrClosureSignatureUtil (org.jetbrains.plugins.groovy.lang.psi.impl.signatures.GrClosureSignatureUtil)6 GlobalSearchScope (com.intellij.psi.search.GlobalSearchScope)5 MethodSignature (com.intellij.psi.util.MethodSignature)4 List (java.util.List)4 GroovyPsiElementFactory (org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory)4 GrRecursiveSignatureVisitor (org.jetbrains.plugins.groovy.lang.psi.api.signatures.GrRecursiveSignatureVisitor)4 GrSignature (org.jetbrains.plugins.groovy.lang.psi.api.signatures.GrSignature)4 GrNamedArgument (org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrNamedArgument)4 GrParameter (org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameter)4 Pair (com.intellij.openapi.util.Pair)3 TIntProcedure (gnu.trove.TIntProcedure)3