Search in sources :

Example 1 with ClosureSyntheticParameter

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

the class GroovyCodeFragmentFactory method externalParameters.

public static Pair<Map<String, String>, GroovyFile> externalParameters(String text, @NotNull final PsiElement context) {
    final GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(context.getProject());
    final GroovyFile toEval = factory.createGroovyFile(text, false, context);
    final GrClosableBlock closure = PsiTreeUtil.getParentOfType(context, GrClosableBlock.class);
    final Map<String, String> parameters = new THashMap<>();
    final Map<GrExpression, String> replacements = new HashMap<>();
    toEval.accept(new GroovyRecursiveElementVisitor() {

        @Override
        public void visitReferenceExpression(@NotNull GrReferenceExpression referenceExpression) {
            super.visitReferenceExpression(referenceExpression);
            if (PsiUtil.isThisReference(referenceExpression) || PsiUtil.isSuperReference(referenceExpression)) {
                replaceWithReference(referenceExpression, "delegate");
                return;
            }
            PsiElement resolved = referenceExpression.resolve();
            if (resolved instanceof PsiMember && (resolved instanceof PsiClass || ((PsiMember) resolved).hasModifierProperty(PsiModifier.STATIC))) {
                String qName = com.intellij.psi.util.PsiUtil.getMemberQualifiedName((PsiMember) resolved);
                if (qName != null && qName.contains(".") && !referenceExpression.isQualified()) {
                    replaceWithReference(referenceExpression, qName);
                    return;
                }
            }
            if (shouldDelegate(referenceExpression, resolved)) {
                replaceWithReference(referenceExpression, "delegate." + referenceExpression.getReferenceName());
                return;
            }
            if (resolved instanceof GrVariable && !(resolved instanceof GrField) && !PsiTreeUtil.isAncestor(toEval, resolved, false)) {
                final String name = ((GrVariable) resolved).getName();
                if (resolved instanceof ClosureSyntheticParameter && PsiTreeUtil.isAncestor(toEval, ((ClosureSyntheticParameter) resolved).getClosure(), false)) {
                    return;
                }
                if (resolved instanceof GrBindingVariable && !PsiTreeUtil.isAncestor(resolved.getContainingFile(), toEval, false)) {
                    return;
                }
                String value;
                if (closure != null && PsiTreeUtil.findCommonParent(resolved, closure) != closure && !(resolved instanceof ClosureSyntheticParameter)) {
                    // Evaluating inside closure for outer variable definitions
                    // All non-local variables are accessed by references
                    value = "this." + name;
                } else {
                    value = name;
                }
                parameters.put(name, value);
                return;
            }
            if (resolved instanceof PsiLocalVariable || resolved instanceof PsiParameter && !(resolved instanceof GrParameter)) {
                String name = referenceExpression.getReferenceName();
                parameters.put(name, name);
            }
        }

        private boolean shouldDelegate(GrReferenceExpression referenceExpression, @Nullable PsiElement resolved) {
            if (referenceExpression.isQualified()) {
                return false;
            }
            if (resolved instanceof GrField) {
                return true;
            }
            if (resolved instanceof PsiMethod) {
                String methodName = ((PsiMethod) resolved).getName();
                if (closure != null && "getDelegate".equals(methodName) || "call".equals(methodName)) {
                    return true;
                }
            }
            return closure != null && resolved instanceof GrLightVariable && "owner".equals(((GrLightVariable) resolved).getName());
        }

        private void replaceWithReference(GrExpression expr, final String exprText) {
            replacements.put(expr, exprText);
        }

        @Override
        public void visitCodeReferenceElement(@NotNull GrCodeReferenceElement refElement) {
            super.visitCodeReferenceElement(refElement);
            if (refElement.getQualifier() == null) {
                PsiElement resolved = refElement.resolve();
                if (resolved instanceof PsiClass) {
                    String qName = ((PsiClass) resolved).getQualifiedName();
                    if (qName != null) {
                        int dotIndex = qName.lastIndexOf(".");
                        if (dotIndex < 0)
                            return;
                        String packageName = qName.substring(0, dotIndex);
                        refElement.setQualifier(factory.createReferenceElementFromText(packageName));
                    }
                }
            }
        }
    });
    for (GrExpression expression : replacements.keySet()) {
        expression.replaceWithExpression(factory.createExpressionFromText(replacements.get(expression)), false);
    }
    return Pair.create(parameters, toEval);
}
Also used : GrField(org.jetbrains.plugins.groovy.lang.psi.api.statements.GrField) THashMap(gnu.trove.THashMap) GrParameter(org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameter) GrVariable(org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariable) THashMap(gnu.trove.THashMap) GrBindingVariable(org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.GrBindingVariable) GrClosableBlock(org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock) GrExpression(org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression) GroovyRecursiveElementVisitor(org.jetbrains.plugins.groovy.lang.psi.GroovyRecursiveElementVisitor) ClosureSyntheticParameter(org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.ClosureSyntheticParameter) GrReferenceExpression(org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression) GroovyPsiElementFactory(org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory) GrCodeReferenceElement(org.jetbrains.plugins.groovy.lang.psi.api.types.GrCodeReferenceElement) GrLightVariable(org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.GrLightVariable) GroovyFile(org.jetbrains.plugins.groovy.lang.psi.GroovyFile)

Example 2 with ClosureSyntheticParameter

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

the class ExpressionGenerator method visitReferenceExpression.

@Override
public void visitReferenceExpression(@NotNull GrReferenceExpression referenceExpression) {
    final GrExpression qualifier = referenceExpression.getQualifier();
    final GroovyResolveResult resolveResult = referenceExpression.advancedResolve();
    final PsiElement resolved = resolveResult.getElement();
    final String referenceName = referenceExpression.getReferenceName();
    if (PsiUtil.isThisOrSuperRef(referenceExpression)) {
        writeThisOrSuperRef(referenceExpression, qualifier, referenceName);
        return;
    }
    if (ResolveUtil.isClassReference(referenceExpression)) {
        // just delegate to qualifier
        LOG.assertTrue(qualifier != null);
        qualifier.accept(this);
        return;
    }
    if (resolved instanceof PsiClass) {
        builder.append(((PsiClass) resolved).getQualifiedName());
        if (PsiUtil.isExpressionUsed(referenceExpression)) {
            builder.append(".class");
        }
        return;
    }
    //don't try to resolve local vars that are provided my this generator (they are listed in myUsedVarNames)
    if (resolved == null && qualifier == null && context.myUsedVarNames.contains(referenceName)) {
        builder.append(referenceName);
        return;
    }
    //all refs in script that are not resolved are saved in 'binding' of the script
    if (qualifier == null && (resolved == null || resolved instanceof GrBindingVariable || resolved instanceof LightElement && !(resolved instanceof ClosureSyntheticParameter)) && (referenceExpression.getParent() instanceof GrIndexProperty || !(referenceExpression.getParent() instanceof GrCall)) && PsiUtil.getContextClass(referenceExpression) instanceof GroovyScriptClass) {
        final GrExpression thisExpr = factory.createExpressionFromText("this", referenceExpression);
        thisExpr.accept(this);
        builder.append(".getBinding().getProperty(\"").append(referenceExpression.getReferenceName()).append("\")");
        return;
    }
    final IElementType type = referenceExpression.getDotTokenType();
    GrExpression qualifierToUse = qualifier;
    if (type == GroovyTokenTypes.mMEMBER_POINTER) {
        LOG.assertTrue(qualifier != null);
        builder.append("new ").append(GroovyCommonClassNames.ORG_CODEHAUS_GROOVY_RUNTIME_METHOD_CLOSURE).append('(');
        qualifier.accept(this);
        builder.append(", \"").append(referenceName).append("\")");
        return;
    }
    if (type == GroovyTokenTypes.mOPTIONAL_DOT) {
        LOG.assertTrue(qualifier != null);
        String qualifierName = createVarByInitializer(qualifier);
        builder.append('(').append(qualifierName).append(" == null ? null : ");
        qualifierToUse = factory.createReferenceExpressionFromText(qualifierName, referenceExpression);
    }
    if (resolveResult.isInvokedOnProperty()) {
        //property-style access to accessor (e.g. qual.prop should be translated to qual.getProp())
        LOG.assertTrue(resolved instanceof PsiMethod);
        LOG.assertTrue(GroovyPropertyUtils.isSimplePropertyGetter((PsiMethod) resolved));
        invokeMethodOn(((PsiMethod) resolved), qualifierToUse, GrExpression.EMPTY_ARRAY, GrNamedArgument.EMPTY_ARRAY, GrClosableBlock.EMPTY_ARRAY, resolveResult.getSubstitutor(), referenceExpression);
    } else {
        if (qualifierToUse != null) {
            qualifierToUse.accept(this);
            builder.append('.');
        }
        if (resolved instanceof PsiNamedElement && !(resolved instanceof GrBindingVariable)) {
            final String refName = ((PsiNamedElement) resolved).getName();
            if (resolved instanceof GrVariable && context.analyzedVars.toWrap((GrVariable) resolved)) {
                //this var should be wrapped by groovy.lang.Reference. so we add .get() tail.
                builder.append(context.analyzedVars.toVarName((GrVariable) resolved));
                if (!PsiUtil.isAccessedForWriting(referenceExpression)) {
                    builder.append(".get()");
                }
            } else {
                builder.append(refName);
            }
        } else {
            //unresolved reference
            if (referenceName != null) {
                if (PsiUtil.isAccessedForWriting(referenceExpression)) {
                    builder.append(referenceName);
                } else {
                    PsiType stringType = PsiType.getJavaLangString(referenceExpression.getManager(), referenceExpression.getResolveScope());
                    PsiType qualifierType = PsiImplUtil.getQualifierType(referenceExpression);
                    GroovyResolveResult[] candidates = qualifierType != null ? ResolveUtil.getMethodCandidates(qualifierType, "getProperty", referenceExpression, stringType) : GroovyResolveResult.EMPTY_ARRAY;
                    final PsiElement method = PsiImplUtil.extractUniqueElement(candidates);
                    if (method != null) {
                        builder.append("getProperty(\"").append(referenceName).append("\")");
                    } else {
                        builder.append(referenceName);
                    }
                }
            } else {
                final PsiElement nameElement = referenceExpression.getReferenceNameElement();
                if (nameElement instanceof GrExpression) {
                    ((GrExpression) nameElement).accept(this);
                } else if (nameElement != null) {
                    builder.append(nameElement.toString());
                }
            }
        }
    }
    if (type == GroovyTokenTypes.mOPTIONAL_DOT) {
        builder.append(')');
    }
}
Also used : GrIndexProperty(org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrIndexProperty) GrString(org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.literals.GrString) LightElement(com.intellij.psi.impl.light.LightElement) ClosureSyntheticParameter(org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.ClosureSyntheticParameter) IElementType(com.intellij.psi.tree.IElementType) GrVariable(org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariable) GroovyResolveResult(org.jetbrains.plugins.groovy.lang.psi.api.GroovyResolveResult) GroovyScriptClass(org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.GroovyScriptClass) GrBindingVariable(org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.GrBindingVariable) GroovyPsiElement(org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement)

Example 3 with ClosureSyntheticParameter

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

the class GrVariableInplaceRenamer method renameSynthetic.

@Override
protected void renameSynthetic(String newName) {
    PsiNamedElement elementToRename = getVariable();
    if (elementToRename instanceof ClosureSyntheticParameter && !"it".equals(newName)) {
        final GrClosableBlock closure = ((ClosureSyntheticParameter) elementToRename).getClosure();
        final GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(myProject);
        final PsiType type = ((ClosureSyntheticParameter) elementToRename).getTypeGroovy();
        final GrParameter newParam = factory.createParameter(newName, TypesUtil.unboxPrimitiveTypeWrapper(type));
        final GrParameter added = closure.addParameter(newParam);
        JavaCodeStyleManager.getInstance(added.getProject()).shortenClassReferences(added);
    }
}
Also used : GroovyPsiElementFactory(org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory) PsiNamedElement(com.intellij.psi.PsiNamedElement) GrClosableBlock(org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock) GrParameter(org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameter) ClosureSyntheticParameter(org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.ClosureSyntheticParameter) PsiType(com.intellij.psi.PsiType)

Example 4 with ClosureSyntheticParameter

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

the class ReachingDefinitionsCollector method addClosureUsages.

private static void addClosureUsages(final Map<String, VariableInfo> imap, final Map<String, VariableInfo> omap, final GrStatement first, final GrStatement last, GrControlFlowOwner flowOwner) {
    flowOwner.accept(new GroovyRecursiveElementVisitor() {

        @Override
        public void visitClosure(@NotNull GrClosableBlock closure) {
            addUsagesInClosure(imap, omap, closure, first, last);
            super.visitClosure(closure);
        }

        private void addUsagesInClosure(final Map<String, VariableInfo> imap, final Map<String, VariableInfo> omap, final GrClosableBlock closure, final GrStatement first, final GrStatement last) {
            closure.accept(new GroovyRecursiveElementVisitor() {

                @Override
                public void visitReferenceExpression(@NotNull GrReferenceExpression refExpr) {
                    if (refExpr.isQualified()) {
                        return;
                    }
                    PsiElement resolved = refExpr.resolve();
                    if (!(resolved instanceof GrVariable)) {
                        return;
                    }
                    GrVariable variable = (GrVariable) resolved;
                    if (PsiTreeUtil.isAncestor(closure, variable, true)) {
                        return;
                    }
                    if (variable instanceof ClosureSyntheticParameter && PsiTreeUtil.isAncestor(closure, ((ClosureSyntheticParameter) variable).getClosure(), false)) {
                        return;
                    }
                    String name = variable.getName();
                    if (!(variable instanceof GrField)) {
                        if (!isInFragment(first, last, resolved)) {
                            if (isInFragment(first, last, closure)) {
                                addVariable(name, imap, variable.getManager(), variable.getType());
                            }
                        } else {
                            if (!isInFragment(first, last, closure)) {
                                addVariable(name, omap, variable.getManager(), variable.getType());
                            }
                        }
                    }
                }
            });
        }
    });
}
Also used : GrField(org.jetbrains.plugins.groovy.lang.psi.api.statements.GrField) GrClosableBlock(org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock) GroovyRecursiveElementVisitor(org.jetbrains.plugins.groovy.lang.psi.GroovyRecursiveElementVisitor) NotNull(org.jetbrains.annotations.NotNull) ClosureSyntheticParameter(org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.ClosureSyntheticParameter) GrStatement(org.jetbrains.plugins.groovy.lang.psi.api.statements.GrStatement) GrReferenceExpression(org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression) GrVariable(org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariable) GroovyPsiElement(org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement)

Example 5 with ClosureSyntheticParameter

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

the class AbstractClosureParameterEnhancer method getVariableType.

@Override
public final PsiType getVariableType(GrVariable variable) {
    if (!(variable instanceof GrParameter)) {
        return null;
    }
    GrClosableBlock closure;
    int paramIndex;
    if (variable instanceof ClosureSyntheticParameter) {
        closure = ((ClosureSyntheticParameter) variable).getClosure();
        paramIndex = 0;
    } else {
        PsiElement eParameterList = variable.getParent();
        if (!(eParameterList instanceof GrParameterList))
            return null;
        PsiElement eClosure = eParameterList.getParent();
        if (!(eClosure instanceof GrClosableBlock))
            return null;
        closure = (GrClosableBlock) eClosure;
        GrParameterList parameterList = (GrParameterList) eParameterList;
        paramIndex = parameterList.getParameterNumber((GrParameter) variable);
    }
    PsiType res = getClosureParameterType(closure, paramIndex);
    if (res instanceof PsiPrimitiveType) {
        return ((PsiPrimitiveType) res).getBoxedType(closure);
    }
    return res;
}
Also used : GrParameterList(org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameterList) PsiPrimitiveType(com.intellij.psi.PsiPrimitiveType) GrClosableBlock(org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock) GrParameter(org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameter) ClosureSyntheticParameter(org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.ClosureSyntheticParameter) PsiElement(com.intellij.psi.PsiElement) PsiType(com.intellij.psi.PsiType)

Aggregations

ClosureSyntheticParameter (org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.ClosureSyntheticParameter)5 GrClosableBlock (org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock)4 GrVariable (org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariable)3 GrParameter (org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameter)3 PsiType (com.intellij.psi.PsiType)2 GroovyPsiElement (org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement)2 GroovyPsiElementFactory (org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory)2 GroovyRecursiveElementVisitor (org.jetbrains.plugins.groovy.lang.psi.GroovyRecursiveElementVisitor)2 GrField (org.jetbrains.plugins.groovy.lang.psi.api.statements.GrField)2 GrReferenceExpression (org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression)2 GrBindingVariable (org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.GrBindingVariable)2 PsiElement (com.intellij.psi.PsiElement)1 PsiNamedElement (com.intellij.psi.PsiNamedElement)1 PsiPrimitiveType (com.intellij.psi.PsiPrimitiveType)1 LightElement (com.intellij.psi.impl.light.LightElement)1 IElementType (com.intellij.psi.tree.IElementType)1 THashMap (gnu.trove.THashMap)1 NotNull (org.jetbrains.annotations.NotNull)1 GroovyFile (org.jetbrains.plugins.groovy.lang.psi.GroovyFile)1 GroovyResolveResult (org.jetbrains.plugins.groovy.lang.psi.api.GroovyResolveResult)1