Search in sources :

Example 71 with Nullable

use of com.android.annotations.Nullable in project kotlin by JetBrains.

the class ResourceEvaluator method getResource.

/**
     * Evaluates the given node and returns the resource reference (type and name) it
     * points to, if any
     *
     * @param element the node to compute the constant value for
     * @return the corresponding constant value - a String, an Integer, a Float, and so on
     */
@Nullable
public ResourceUrl getResource(@Nullable UElement element) {
    if (element == null) {
        return null;
    }
    if (element instanceof UIfExpression) {
        UIfExpression expression = (UIfExpression) element;
        Object known = ConstantEvaluator.evaluate(null, expression.getCondition());
        if (known == Boolean.TRUE && expression.getThenExpression() != null) {
            return getResource(expression.getThenExpression());
        } else if (known == Boolean.FALSE && expression.getElseExpression() != null) {
            return getResource(expression.getElseExpression());
        }
    } else if (element instanceof UParenthesizedExpression) {
        UParenthesizedExpression parenthesizedExpression = (UParenthesizedExpression) element;
        return getResource(parenthesizedExpression.getExpression());
    } else if (mAllowDereference && element instanceof UQualifiedReferenceExpression) {
        UQualifiedReferenceExpression qualifiedExpression = (UQualifiedReferenceExpression) element;
        UExpression selector = qualifiedExpression.getSelector();
        if ((selector instanceof UCallExpression)) {
            UCallExpression call = (UCallExpression) selector;
            PsiMethod function = call.resolve();
            PsiClass containingClass = UastUtils.getContainingClass(function);
            if (function != null && containingClass != null) {
                String qualifiedName = containingClass.getQualifiedName();
                String name = call.getMethodName();
                if ((CLASS_RESOURCES.equals(qualifiedName) || CLASS_CONTEXT.equals(qualifiedName) || CLASS_FRAGMENT.equals(qualifiedName) || CLASS_V4_FRAGMENT.equals(qualifiedName) || CLS_TYPED_ARRAY.equals(qualifiedName)) && name != null && name.startsWith("get")) {
                    List<UExpression> args = call.getValueArguments();
                    if (!args.isEmpty()) {
                        return getResource(args.get(0));
                    }
                }
            }
        }
    }
    if (element instanceof UReferenceExpression) {
        ResourceUrl url = getResourceConstant(element);
        if (url != null) {
            return url;
        }
        PsiElement resolved = ((UReferenceExpression) element).resolve();
        if (resolved instanceof PsiVariable) {
            PsiVariable variable = (PsiVariable) resolved;
            UElement lastAssignment = UastLintUtils.findLastAssignment(variable, element, mContext);
            if (lastAssignment != null) {
                return getResource(lastAssignment);
            }
            return null;
        }
    }
    return null;
}
Also used : PsiVariable(com.intellij.psi.PsiVariable) PsiMethod(com.intellij.psi.PsiMethod) UParenthesizedExpression(org.jetbrains.uast.UParenthesizedExpression) UQualifiedReferenceExpression(org.jetbrains.uast.UQualifiedReferenceExpression) PsiClass(com.intellij.psi.PsiClass) UCallExpression(org.jetbrains.uast.UCallExpression) UExpression(org.jetbrains.uast.UExpression) UReferenceExpression(org.jetbrains.uast.UReferenceExpression) UElement(org.jetbrains.uast.UElement) ResourceUrl(com.android.ide.common.resources.ResourceUrl) PsiElement(com.intellij.psi.PsiElement) UIfExpression(org.jetbrains.uast.UIfExpression) Nullable(com.android.annotations.Nullable)

Example 72 with Nullable

use of com.android.annotations.Nullable in project kotlin by JetBrains.

the class ResourceEvaluator method getResourceConstant.

/** Returns a resource URL based on the field reference in the code */
@Nullable
public static ResourceUrl getResourceConstant(@NonNull PsiElement node) {
    // R.type.name
    if (node instanceof PsiReferenceExpression) {
        PsiReferenceExpression expression = (PsiReferenceExpression) node;
        if (expression.getQualifier() instanceof PsiReferenceExpression) {
            PsiReferenceExpression select = (PsiReferenceExpression) expression.getQualifier();
            if (select.getQualifier() instanceof PsiReferenceExpression) {
                PsiReferenceExpression reference = (PsiReferenceExpression) select.getQualifier();
                if (R_CLASS.equals(reference.getReferenceName())) {
                    String typeName = select.getReferenceName();
                    String name = expression.getReferenceName();
                    ResourceType type = ResourceType.getEnum(typeName);
                    if (type != null && name != null) {
                        boolean isFramework = reference.getQualifier() instanceof PsiReferenceExpression && ANDROID_PKG.equals(((PsiReferenceExpression) reference.getQualifier()).getReferenceName());
                        return ResourceUrl.create(type, name, isFramework, false);
                    }
                }
            }
        }
    } else if (node instanceof PsiField) {
        PsiField field = (PsiField) node;
        PsiClass typeClass = field.getContainingClass();
        if (typeClass != null) {
            PsiClass rClass = typeClass.getContainingClass();
            if (rClass != null && R_CLASS.equals(rClass.getName())) {
                String name = field.getName();
                ResourceType type = ResourceType.getEnum(typeClass.getName());
                if (type != null && name != null) {
                    String qualifiedName = rClass.getQualifiedName();
                    boolean isFramework = qualifiedName != null && qualifiedName.startsWith(ANDROID_PKG_PREFIX);
                    return ResourceUrl.create(type, name, isFramework, false);
                }
            }
        }
    }
    return null;
}
Also used : PsiReferenceExpression(com.intellij.psi.PsiReferenceExpression) PsiField(com.intellij.psi.PsiField) PsiClass(com.intellij.psi.PsiClass) ResourceType(com.android.resources.ResourceType) Nullable(com.android.annotations.Nullable)

Example 73 with Nullable

use of com.android.annotations.Nullable in project kotlin by JetBrains.

the class TypeEvaluator method evaluate.

/**
     * Returns the inferred type of the given node
     * @deprecated Use {@link #evaluate(PsiElement)} instead
     */
@Deprecated
@Nullable
public TypeDescriptor evaluate(@NonNull Node node) {
    ResolvedNode resolved = null;
    if (mContext != null) {
        resolved = mContext.resolve(node);
    }
    if (resolved instanceof ResolvedMethod) {
        TypeDescriptor type;
        ResolvedMethod method = (ResolvedMethod) resolved;
        if (method.isConstructor()) {
            ResolvedClass containingClass = method.getContainingClass();
            type = containingClass.getType();
        } else {
            type = method.getReturnType();
        }
        return type;
    }
    if (resolved instanceof ResolvedField) {
        ResolvedField field = (ResolvedField) resolved;
        Node astNode = field.findAstNode();
        if (astNode instanceof VariableDeclaration) {
            VariableDeclaration declaration = (VariableDeclaration) astNode;
            VariableDefinition definition = declaration.astDefinition();
            if (definition != null) {
                VariableDefinitionEntry first = definition.astVariables().first();
                if (first != null) {
                    Expression initializer = first.astInitializer();
                    if (initializer != null) {
                        TypeDescriptor type = evaluate(initializer);
                        if (type != null) {
                            return type;
                        }
                    }
                }
            }
        }
        return field.getType();
    }
    if (node instanceof VariableReference) {
        Statement statement = getParentOfType(node, Statement.class, false);
        if (statement != null) {
            ListIterator<Node> iterator = statement.getParent().getChildren().listIterator();
            while (iterator.hasNext()) {
                if (iterator.next() == statement) {
                    if (iterator.hasPrevious()) {
                        // should always be true
                        iterator.previous();
                    }
                    break;
                }
            }
            String targetName = ((VariableReference) node).astIdentifier().astValue();
            while (iterator.hasPrevious()) {
                Node previous = iterator.previous();
                if (previous instanceof VariableDeclaration) {
                    VariableDeclaration declaration = (VariableDeclaration) previous;
                    VariableDefinition definition = declaration.astDefinition();
                    for (VariableDefinitionEntry entry : definition.astVariables()) {
                        if (entry.astInitializer() != null && entry.astName().astValue().equals(targetName)) {
                            return evaluate(entry.astInitializer());
                        }
                    }
                } else if (previous instanceof ExpressionStatement) {
                    ExpressionStatement expressionStatement = (ExpressionStatement) previous;
                    Expression expression = expressionStatement.astExpression();
                    if (expression instanceof BinaryExpression && ((BinaryExpression) expression).astOperator() == BinaryOperator.ASSIGN) {
                        BinaryExpression binaryExpression = (BinaryExpression) expression;
                        if (targetName.equals(binaryExpression.astLeft().toString())) {
                            return evaluate(binaryExpression.astRight());
                        }
                    }
                }
            }
        }
    } else if (node instanceof Cast) {
        Cast cast = (Cast) node;
        if (mContext != null) {
            ResolvedNode typeReference = mContext.resolve(cast.astTypeReference());
            if (typeReference instanceof ResolvedClass) {
                return ((ResolvedClass) typeReference).getType();
            }
        }
        TypeDescriptor viewType = evaluate(cast.astOperand());
        if (viewType != null) {
            return viewType;
        }
    } else if (node instanceof Literal) {
        if (node instanceof NullLiteral) {
            return null;
        } else if (node instanceof BooleanLiteral) {
            return new DefaultTypeDescriptor(TYPE_BOOLEAN);
        } else if (node instanceof StringLiteral) {
            return new DefaultTypeDescriptor(TYPE_STRING);
        } else if (node instanceof CharLiteral) {
            return new DefaultTypeDescriptor(TYPE_CHAR);
        } else if (node instanceof IntegralLiteral) {
            IntegralLiteral literal = (IntegralLiteral) node;
            // Don't combine to ?: since that will promote astIntValue to a long
            if (literal.astMarkedAsLong()) {
                return new DefaultTypeDescriptor(TYPE_LONG);
            } else {
                return new DefaultTypeDescriptor(TYPE_INT);
            }
        } else if (node instanceof FloatingPointLiteral) {
            FloatingPointLiteral literal = (FloatingPointLiteral) node;
            // Don't combine to ?: since that will promote astFloatValue to a double
            if (literal.astMarkedAsFloat()) {
                return new DefaultTypeDescriptor(TYPE_FLOAT);
            } else {
                return new DefaultTypeDescriptor(TYPE_DOUBLE);
            }
        }
    } else if (node instanceof UnaryExpression) {
        return evaluate(((UnaryExpression) node).astOperand());
    } else if (node instanceof InlineIfExpression) {
        InlineIfExpression expression = (InlineIfExpression) node;
        if (expression.astIfTrue() != null) {
            return evaluate(expression.astIfTrue());
        } else if (expression.astIfFalse() != null) {
            return evaluate(expression.astIfFalse());
        }
    } else if (node instanceof BinaryExpression) {
        BinaryExpression expression = (BinaryExpression) node;
        BinaryOperator operator = expression.astOperator();
        switch(operator) {
            case LOGICAL_OR:
            case LOGICAL_AND:
            case EQUALS:
            case NOT_EQUALS:
            case GREATER:
            case GREATER_OR_EQUAL:
            case LESS:
            case LESS_OR_EQUAL:
                return new DefaultTypeDescriptor(TYPE_BOOLEAN);
        }
        TypeDescriptor type = evaluate(expression.astLeft());
        if (type != null) {
            return type;
        }
        return evaluate(expression.astRight());
    }
    if (resolved instanceof ResolvedVariable) {
        ResolvedVariable variable = (ResolvedVariable) resolved;
        return variable.getType();
    }
    return null;
}
Also used : Cast(lombok.ast.Cast) VariableDefinition(lombok.ast.VariableDefinition) BooleanLiteral(lombok.ast.BooleanLiteral) Node(lombok.ast.Node) ResolvedNode(com.android.tools.klint.client.api.JavaParser.ResolvedNode) UnaryExpression(lombok.ast.UnaryExpression) DefaultTypeDescriptor(com.android.tools.klint.client.api.JavaParser.DefaultTypeDescriptor) IntegralLiteral(lombok.ast.IntegralLiteral) ResolvedNode(com.android.tools.klint.client.api.JavaParser.ResolvedNode) ResolvedField(com.android.tools.klint.client.api.JavaParser.ResolvedField) BinaryExpression(lombok.ast.BinaryExpression) IntegralLiteral(lombok.ast.IntegralLiteral) BooleanLiteral(lombok.ast.BooleanLiteral) Literal(lombok.ast.Literal) FloatingPointLiteral(lombok.ast.FloatingPointLiteral) CharLiteral(lombok.ast.CharLiteral) StringLiteral(lombok.ast.StringLiteral) NullLiteral(lombok.ast.NullLiteral) VariableDeclaration(lombok.ast.VariableDeclaration) InlineIfExpression(lombok.ast.InlineIfExpression) BinaryOperator(lombok.ast.BinaryOperator) ResolvedVariable(com.android.tools.klint.client.api.JavaParser.ResolvedVariable) VariableReference(lombok.ast.VariableReference) CharLiteral(lombok.ast.CharLiteral) Statement(lombok.ast.Statement) PsiStatement(com.intellij.psi.PsiStatement) PsiExpressionStatement(com.intellij.psi.PsiExpressionStatement) ExpressionStatement(lombok.ast.ExpressionStatement) PsiDeclarationStatement(com.intellij.psi.PsiDeclarationStatement) ResolvedClass(com.android.tools.klint.client.api.JavaParser.ResolvedClass) ResolvedMethod(com.android.tools.klint.client.api.JavaParser.ResolvedMethod) TypeDescriptor(com.android.tools.klint.client.api.JavaParser.TypeDescriptor) DefaultTypeDescriptor(com.android.tools.klint.client.api.JavaParser.DefaultTypeDescriptor) StringLiteral(lombok.ast.StringLiteral) VariableDefinitionEntry(lombok.ast.VariableDefinitionEntry) UExpression(org.jetbrains.uast.UExpression) UCallExpression(org.jetbrains.uast.UCallExpression) PsiAssignmentExpression(com.intellij.psi.PsiAssignmentExpression) UReferenceExpression(org.jetbrains.uast.UReferenceExpression) UnaryExpression(lombok.ast.UnaryExpression) InlineIfExpression(lombok.ast.InlineIfExpression) PsiExpression(com.intellij.psi.PsiExpression) PsiReferenceExpression(com.intellij.psi.PsiReferenceExpression) Expression(lombok.ast.Expression) BinaryExpression(lombok.ast.BinaryExpression) FloatingPointLiteral(lombok.ast.FloatingPointLiteral) PsiExpressionStatement(com.intellij.psi.PsiExpressionStatement) ExpressionStatement(lombok.ast.ExpressionStatement) NullLiteral(lombok.ast.NullLiteral) Nullable(com.android.annotations.Nullable)

Example 74 with Nullable

use of com.android.annotations.Nullable in project kotlin by JetBrains.

the class CallSuperDetector method getRequiredSuperMethod.

/**
     * Checks whether the given method overrides a method which requires the super method
     * to be invoked, and if so, returns it (otherwise returns null)
     */
@Nullable
private static PsiMethod getRequiredSuperMethod(@NonNull JavaContext context, @NonNull PsiMethod method) {
    JavaEvaluator evaluator = context.getEvaluator();
    PsiMethod directSuper = evaluator.getSuperMethod(method);
    if (directSuper == null) {
        return null;
    }
    String name = method.getName();
    if (ON_DETACHED_FROM_WINDOW.equals(name)) {
        // compileSdkVersion >= N).
        if (!evaluator.isMemberInSubClassOf(method, CLASS_VIEW, false)) {
            return null;
        }
        return directSuper;
    } else if (ON_VISIBILITY_CHANGED.equals(name)) {
        // the support library
        if (!evaluator.isMemberInSubClassOf(method, "android.support.wearable.watchface.WatchFaceService.Engine", false)) {
            return null;
        }
        return directSuper;
    }
    // Look up annotations metadata
    PsiMethod superMethod = directSuper;
    while (superMethod != null) {
        PsiAnnotation[] annotations = superMethod.getModifierList().getAnnotations();
        annotations = filterRelevantAnnotations(context.getEvaluator(), annotations);
        for (PsiAnnotation annotation : annotations) {
            String signature = annotation.getQualifiedName();
            if (CALL_SUPER_ANNOTATION.equals(signature)) {
                return directSuper;
            } else if (signature != null && signature.endsWith(".OverrideMustInvoke")) {
                // Handle findbugs annotation on the fly too
                return directSuper;
            }
        }
        superMethod = evaluator.getSuperMethod(superMethod);
    }
    return null;
}
Also used : PsiMethod(com.intellij.psi.PsiMethod) PsiAnnotation(com.intellij.psi.PsiAnnotation) JavaEvaluator(com.android.tools.klint.client.api.JavaEvaluator) Nullable(com.android.annotations.Nullable)

Example 75 with Nullable

use of com.android.annotations.Nullable in project kotlin by JetBrains.

the class IconDetector method getImage.

@Nullable
private BufferedImage getImage(@Nullable File file) throws IOException {
    if (file == null) {
        return null;
    }
    if (mImageCache == null) {
        mImageCache = Maps.newHashMap();
    } else {
        BufferedImage image = mImageCache.get(file);
        if (image != null) {
            return image;
        }
    }
    BufferedImage image = ImageIO.read(file);
    mImageCache.put(file, image);
    return image;
}
Also used : BufferedImage(java.awt.image.BufferedImage) Nullable(com.android.annotations.Nullable)

Aggregations

Nullable (com.android.annotations.Nullable)83 File (java.io.File)21 IOException (java.io.IOException)9 ResourceType (com.android.resources.ResourceType)8 PsiClass (com.intellij.psi.PsiClass)7 PsiElement (com.intellij.psi.PsiElement)7 PsiReferenceExpression (com.intellij.psi.PsiReferenceExpression)7 ResourceUrl (com.android.ide.common.resources.ResourceUrl)6 PsiAssignmentExpression (com.intellij.psi.PsiAssignmentExpression)6 PsiDeclarationStatement (com.intellij.psi.PsiDeclarationStatement)6 PsiExpression (com.intellij.psi.PsiExpression)6 PsiExpressionStatement (com.intellij.psi.PsiExpressionStatement)6 PsiMethod (com.intellij.psi.PsiMethod)6 PsiStatement (com.intellij.psi.PsiStatement)6 ArrayList (java.util.ArrayList)6 PsiField (com.intellij.psi.PsiField)5 PsiFile (com.intellij.psi.PsiFile)4 Node (lombok.ast.Node)4 UReferenceExpression (org.jetbrains.uast.UReferenceExpression)4 AbstractResourceRepository (com.android.ide.common.res2.AbstractResourceRepository)3