Search in sources :

Example 51 with GroovyPsiElement

use of org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement in project android by JetBrains.

the class GradleGroovyFile method getValueStatic.

/**
   * Returns the value in the file for the given key, or null if not present.
   */
@Nullable
static Object getValueStatic(@NotNull GrStatementOwner root, @NotNull BuildFileKey key) {
    GrMethodCall method = getMethodCallByPath(root, key.getPath());
    if (method == null) {
        return null;
    }
    GroovyPsiElement arg = key.getType() == BuildFileKeyType.CLOSURE ? getMethodClosureArgument(method) : getFirstArgument(method);
    if (arg == null) {
        return null;
    }
    return key.getValue(arg);
}
Also used : GroovyPsiElement(org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement) GrMethodCall(org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrMethodCall) Nullable(org.jetbrains.annotations.Nullable)

Example 52 with GroovyPsiElement

use of org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement in project android by JetBrains.

the class GradleGroovyFile method setValueStatic.

/**
   * Sets the value for the given key
   */
static void setValueStatic(@NotNull GrStatementOwner root, @NotNull BuildFileKey key, @NotNull Object value, boolean reformatClosure, @Nullable ValueFactory.KeyFilter filter) {
    if (value == GradleBuildFile.UNRECOGNIZED_VALUE) {
        return;
    }
    GrMethodCall method = getMethodCallByPath(root, key.getPath());
    if (method == null) {
        method = createNewValue(root, key, value, reformatClosure);
        if (key.getType() != BuildFileKeyType.CLOSURE) {
            return;
        }
    }
    if (method != null) {
        GroovyPsiElement arg = key.getType() == BuildFileKeyType.CLOSURE ? getMethodClosureArgument(method) : getFirstArgument(method);
        if (arg == null) {
            return;
        }
        key.setValue(arg, value, filter);
    }
}
Also used : GroovyPsiElement(org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement) GrMethodCall(org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrMethodCall)

Example 53 with GroovyPsiElement

use of org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement in project android by JetBrains.

the class GradleEditorModelParserFacade method fillContext.

/**
   * Processes given PSI file and fills given context
   * by {@link GradleEditorModelParseContext#getAssignments(Variable) corresponding assignments}.
   *
   * @param context  context to fill
   * @param psiFile  psi file to parse
   */
private static void fillContext(@NotNull final GradleEditorModelParseContext context, @NotNull PsiFile psiFile) {
    psiFile.acceptChildren(new GroovyPsiElementVisitor(new GroovyRecursiveElementVisitor() {

        @Override
        public void visitMethodCallExpression(GrMethodCallExpression methodCallExpression) {
            Pair<String, TextRange> pair = GradleEditorValueExtractor.extractMethodName(methodCallExpression);
            GrClosableBlock[] closureArguments = methodCallExpression.getClosureArguments();
            if (pair == null || closureArguments.length > 1) {
                super.visitMethodCallExpression(methodCallExpression);
                return;
            }
            if (closureArguments.length == 0) {
                if (methodCallExpression.getArgumentList().getAllArguments().length == 0) {
                    // This is a no-args method, so, we just register it for cases like 'mavenCentral()' or 'jcenter()'.
                    context.addCachedValue(NO_ARGS_METHOD_ASSIGNMENT_VALUE, TextRange.create(pair.second.getEndOffset(), methodCallExpression.getTextRange().getEndOffset()));
                    context.registerAssignmentFromCachedData(pair.first, pair.second, methodCallExpression);
                }
                return;
            }
            context.onMethodEnter(pair.getFirst());
            try {
                super.visitClosure(closureArguments[0]);
            } finally {
                context.onMethodExit();
            }
        }

        @Override
        public void visitApplicationStatement(GrApplicationStatement applicationStatement) {
            Pair<String, TextRange> methodName = GradleEditorValueExtractor.extractMethodName(applicationStatement);
            if (methodName == null) {
                return;
            }
            GroovyPsiElement[] allArguments = applicationStatement.getArgumentList().getAllArguments();
            if (allArguments.length == 1) {
                context.resetCaches();
                extractValueOrVariable(allArguments[0], context);
                context.registerAssignmentFromCachedData(methodName.getFirst(), methodName.getSecond(), applicationStatement.getArgumentList());
            }
        }

        @Override
        public void visitAssignmentExpression(GrAssignmentExpression expression) {
            // General idea is to try to extract variable from the given expression and, in case of success, try to extract rvalue and
            // register corresponding assignment with them.
            context.resetCaches();
            extractValueOrVariable(expression.getLValue(), context);
            Multimap<Variable, Location> vars = context.getCachedVariables();
            if (vars.size() != 1) {
                context.resetCaches();
                return;
            }
            Map.Entry<Variable, Location> entry = vars.entries().iterator().next();
            Variable lVariable = entry.getKey();
            Location lVariableLocation = entry.getValue();
            context.resetCaches();
            GrExpression rValue = expression.getRValue();
            if (rValue == null) {
                return;
            }
            extractValueOrVariable(rValue, context);
            if (context.getCachedValues().size() > 1) {
                Value value = new Value("", new Location(context.getCurrentFile(), GradleEditorModelUtil.interestedRange(rValue)));
                context.setCachedValues(Collections.singletonList(value));
            }
            context.registerAssignmentFromCachedData(lVariable, lVariableLocation, rValue);
            context.resetCaches();
        }

        @Override
        public void visitVariable(GrVariable variable) {
            TextRange nameRange = null;
            boolean lookForInitializer = false;
            ParserDefinition parserDefinition = LanguageParserDefinitions.INSTANCE.findSingle(GroovyLanguage.INSTANCE);
            for (PsiElement e = variable.getFirstChild(); e != null; e = e.getNextSibling()) {
                ASTNode node = e.getNode();
                if (node == null) {
                    continue;
                }
                if (!lookForInitializer) {
                    if (node.getElementType() == GroovyTokenTypes.mIDENT) {
                        nameRange = e.getTextRange();
                    } else if (node.getElementType() == GroovyTokenTypes.mASSIGN) {
                        if (nameRange == null) {
                            return;
                        }
                        lookForInitializer = true;
                    }
                    continue;
                }
                if (node.getElementType() == GroovyTokenTypes.mNLS || node.getElementType() == GroovyTokenTypes.mSEMI) {
                    break;
                }
                if (parserDefinition.getWhitespaceTokens().contains(node.getElementType())) {
                    continue;
                }
                extractValueOrVariable(e, context);
                if (context.getCachedValues().size() > 1) {
                    Value value = new Value("", new Location(context.getCurrentFile(), GradleEditorModelUtil.interestedRange(e)));
                    context.setCachedValues(Collections.singletonList(value));
                }
                if (context.registerAssignmentFromCachedData(variable.getName(), nameRange, e)) {
                    return;
                }
            }
        }
    }));
}
Also used : GroovyPsiElement(org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement) GrVariable(org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariable) GrClosableBlock(org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock) GroovyRecursiveElementVisitor(org.jetbrains.plugins.groovy.lang.psi.GroovyRecursiveElementVisitor) TextRange(com.intellij.openapi.util.TextRange) GrExpression(org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression) GrApplicationStatement(org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrApplicationStatement) GrVariable(org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariable) ParserDefinition(com.intellij.lang.ParserDefinition) GrMethodCallExpression(org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrMethodCallExpression) GrAssignmentExpression(org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrAssignmentExpression) GroovyPsiElementVisitor(org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementVisitor) ASTNode(com.intellij.lang.ASTNode) Map(java.util.Map) PsiElement(com.intellij.psi.PsiElement) GroovyPsiElement(org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement)

Example 54 with GroovyPsiElement

use of org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement in project android by JetBrains.

the class LintIdeGradleDetector method visitBuildScript.

@Override
public void visitBuildScript(@NonNull final Context context, Map<String, Object> sharedData) {
    ApplicationManager.getApplication().runReadAction(new Runnable() {

        @Override
        public void run() {
            final PsiFile psiFile = LintIdeUtils.getPsiFile(context);
            if (!(psiFile instanceof GroovyFile)) {
                return;
            }
            GroovyFile groovyFile = (GroovyFile) psiFile;
            groovyFile.accept(new GroovyRecursiveElementVisitor() {

                @Override
                public void visitClosure(GrClosableBlock closure) {
                    String parentName = getClosureName(closure);
                    String parentParentName = null;
                    if (parentName != null) {
                        GrClosableBlock block = PsiTreeUtil.getParentOfType(closure, GrClosableBlock.class, true);
                        if (block != null) {
                            parentParentName = getClosureName(block);
                        }
                    }
                    if (parentName != null && isInterestingBlock(parentName, parentParentName)) {
                        for (PsiElement element : closure.getChildren()) {
                            if (element instanceof GrApplicationStatement) {
                                GrApplicationStatement call = (GrApplicationStatement) element;
                                GrExpression propertyExpression = call.getInvokedExpression();
                                GrCommandArgumentList argumentList = call.getArgumentList();
                                if (propertyExpression instanceof GrReferenceExpression) {
                                    GrReferenceExpression propertyRef = (GrReferenceExpression) propertyExpression;
                                    String property = propertyRef.getReferenceName();
                                    //noinspection ConstantConditions
                                    if (property != null && isInterestingProperty(property, parentName, parentParentName) && argumentList != null) {
                                        String value = argumentList.getText();
                                        checkDslPropertyAssignment(context, property, value, parentName, parentParentName, argumentList, call);
                                    }
                                }
                            } else if (element instanceof GrAssignmentExpression) {
                                GrAssignmentExpression assignment = (GrAssignmentExpression) element;
                                GrExpression lValue = assignment.getLValue();
                                if (lValue instanceof GrReferenceExpression) {
                                    GrReferenceExpression propertyRef = (GrReferenceExpression) lValue;
                                    String property = propertyRef.getReferenceName();
                                    if (property != null && isInterestingProperty(property, parentName, parentParentName)) {
                                        GrExpression rValue = assignment.getRValue();
                                        if (rValue != null) {
                                            String value = rValue.getText();
                                            checkDslPropertyAssignment(context, property, value, parentName, parentParentName, rValue, assignment);
                                            // handle it here.
                                            if (property.equals(ATTR_MIN_SDK_VERSION) || property.equals(ATTR_TARGET_SDK_VERSION)) {
                                                int lValueEnd = lValue.getTextRange().getEndOffset();
                                                int rValueStart = rValue.getTextRange().getStartOffset();
                                                assert lValueEnd <= rValueStart;
                                                DefaultPosition startPosition = new DefaultPosition(-1, -1, lValueEnd);
                                                DefaultPosition endPosition = new DefaultPosition(-1, -1, rValueStart);
                                                Location location = Location.create(context.file, startPosition, endPosition);
                                                String message = String.format("Do not use assignment with the %1$s property (remove the '=')", property);
                                                context.report(GradleDetector.IDE_SUPPORT, location, message, null);
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                    super.visitClosure(closure);
                }

                @Override
                public void visitApplicationStatement(GrApplicationStatement applicationStatement) {
                    GrClosableBlock block = PsiTreeUtil.getParentOfType(applicationStatement, GrClosableBlock.class, true);
                    String parentName = block != null ? getClosureName(block) : null;
                    String statementName = applicationStatement.getInvokedExpression().getText();
                    if (isInterestingStatement(statementName, parentName)) {
                        GrCommandArgumentList argumentList = applicationStatement.getArgumentList();
                        Map<String, String> namedArguments = Maps.newHashMap();
                        List<String> unnamedArguments = Lists.newArrayList();
                        for (GroovyPsiElement groovyPsiElement : argumentList.getAllArguments()) {
                            if (groovyPsiElement instanceof GrNamedArgument) {
                                GrNamedArgument namedArgument = (GrNamedArgument) groovyPsiElement;
                                GrExpression expression = namedArgument.getExpression();
                                if (expression == null || !(expression instanceof GrLiteral)) {
                                    continue;
                                }
                                Object value = ((GrLiteral) expression).getValue();
                                if (value == null) {
                                    continue;
                                }
                                namedArguments.put(namedArgument.getLabelName(), value.toString());
                            } else if (groovyPsiElement instanceof GrExpression) {
                                unnamedArguments.add(groovyPsiElement.getText());
                            }
                        }
                        checkMethodCall(context, statementName, parentName, namedArguments, unnamedArguments, applicationStatement);
                    }
                    super.visitApplicationStatement(applicationStatement);
                }
            });
        }
    });
}
Also used : GroovyPsiElement(org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement) GrNamedArgument(org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrNamedArgument) GrClosableBlock(org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock) GroovyRecursiveElementVisitor(org.jetbrains.plugins.groovy.lang.psi.GroovyRecursiveElementVisitor) PsiFile(com.intellij.psi.PsiFile) GrLiteral(org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.literals.GrLiteral) GroovyFile(org.jetbrains.plugins.groovy.lang.psi.GroovyFile) PsiElement(com.intellij.psi.PsiElement) GroovyPsiElement(org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement)

Example 55 with GroovyPsiElement

use of org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement in project android by JetBrains.

the class GradleDslElement method deleteIfEmpty.

protected static void deleteIfEmpty(@Nullable PsiElement element) {
    if (element == null || !element.isValid()) {
        return;
    }
    PsiElement parent = element.getParent();
    if (element instanceof GrAssignmentExpression) {
        if (((GrAssignmentExpression) element).getRValue() == null) {
            element.delete();
        }
    } else if (element instanceof GrApplicationStatement) {
        if (((GrApplicationStatement) element).getArgumentList() == null) {
            element.delete();
        }
    } else if (element instanceof GrClosableBlock) {
        final Boolean[] isEmpty = new Boolean[] { true };
        ((GrClosableBlock) element).acceptChildren(new GroovyElementVisitor() {

            @Override
            public void visitElement(GroovyPsiElement child) {
                if (child instanceof GrParameterList) {
                    if (((GrParameterList) child).getParameters().length == 0) {
                        // Ignore the empty parameter list.
                        return;
                    }
                }
                isEmpty[0] = false;
            }
        });
        if (isEmpty[0]) {
            element.delete();
        }
    } else if (element instanceof GrMethodCallExpression) {
        GrMethodCallExpression call = ((GrMethodCallExpression) element);
        GrArgumentList argumentList;
        try {
            argumentList = call.getArgumentList();
        } catch (AssertionError e) {
            // We will get this exception if the argument list is already deleted.
            argumentList = null;
        }
        GrClosableBlock[] closureArguments = call.getClosureArguments();
        if ((argumentList == null || argumentList.getAllArguments().length == 0) && closureArguments.length == 0) {
            element.delete();
        }
    } else if (element instanceof GrCommandArgumentList) {
        GrCommandArgumentList commandArgumentList = (GrCommandArgumentList) element;
        if (commandArgumentList.getAllArguments().length == 0) {
            commandArgumentList.delete();
        }
    } else if (element instanceof GrListOrMap) {
        GrListOrMap listOrMap = (GrListOrMap) element;
        if ((listOrMap.isMap() && listOrMap.getNamedArguments().length == 0) || (!listOrMap.isMap() && listOrMap.getInitializers().length == 0)) {
            listOrMap.delete();
        }
    }
    if (!element.isValid()) {
        // If this element is deleted, also delete the parent if it is empty.
        deleteIfEmpty(parent);
    }
}
Also used : GrParameterList(org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameterList) GrCommandArgumentList(org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrCommandArgumentList) GroovyPsiElement(org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement) GrClosableBlock(org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock) GrListOrMap(org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.GrListOrMap) GrApplicationStatement(org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrApplicationStatement) GroovyElementVisitor(org.jetbrains.plugins.groovy.lang.psi.GroovyElementVisitor) GrAssignmentExpression(org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrAssignmentExpression) GrMethodCallExpression(org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrMethodCallExpression) GrArgumentList(org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentList) PsiElement(com.intellij.psi.PsiElement) GroovyPsiElement(org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement)

Aggregations

GroovyPsiElement (org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement)98 PsiElement (com.intellij.psi.PsiElement)34 Nullable (org.jetbrains.annotations.Nullable)17 GrExpression (org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression)17 GroovyPsiElementFactory (org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory)16 GrReferenceExpression (org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression)13 GrArgumentList (org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentList)12 GrClosableBlock (org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock)11 GrMethod (org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod)9 GrListOrMap (org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.GrListOrMap)8 GrNamedArgument (org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrNamedArgument)8 GrApplicationStatement (org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrApplicationStatement)8 GrMethodCallExpression (org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrMethodCallExpression)8 GrTypeDefinition (org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinition)8 Project (com.intellij.openapi.project.Project)7 TextRange (com.intellij.openapi.util.TextRange)7 NotNull (org.jetbrains.annotations.NotNull)7 GroovyRecursiveElementVisitor (org.jetbrains.plugins.groovy.lang.psi.GroovyRecursiveElementVisitor)7 GrVariable (org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariable)7 GroovyResolveResult (org.jetbrains.plugins.groovy.lang.psi.api.GroovyResolveResult)6