Search in sources :

Example 1 with UElement

use of org.jetbrains.uast.UElement in project kotlin by JetBrains.

the class ServiceCastDetector method visitMethod.

@Override
public void visitMethod(@NonNull JavaContext context, @Nullable UastVisitor visitor, @NonNull UCallExpression call, @NonNull UMethod method) {
    UElement parent = LintUtils.skipParentheses(UastUtils.getQualifiedParentOrThis(call).getUastParent());
    if (UastExpressionUtils.isTypeCast(parent)) {
        UBinaryExpressionWithType cast = (UBinaryExpressionWithType) parent;
        List<UExpression> args = call.getValueArguments();
        if (args.size() == 1 && args.get(0) instanceof UReferenceExpression) {
            PsiElement resolvedServiceConst = ((UReferenceExpression) args.get(0)).resolve();
            if (!(resolvedServiceConst instanceof PsiField)) {
                return;
            }
            String name = ((PsiField) resolvedServiceConst).getName();
            String expectedClass = getExpectedType(name);
            if (expectedClass != null && cast != null) {
                String castType = cast.getType().getCanonicalText();
                if (castType.indexOf('.') == -1) {
                    expectedClass = stripPackage(expectedClass);
                }
                if (!castType.equals(expectedClass)) {
                    // android.content.ClipboardManager and android.text.ClipboardManager
                    if (isClipboard(castType) && isClipboard(expectedClass)) {
                        return;
                    }
                    String message = String.format("Suspicious cast to `%1$s` for a `%2$s`: expected `%3$s`", stripPackage(castType), name, stripPackage(expectedClass));
                    context.report(ISSUE, call, context.getUastLocation(cast), message);
                }
            }
        }
    }
}
Also used : UExpression(org.jetbrains.uast.UExpression) PsiField(com.intellij.psi.PsiField) UElement(org.jetbrains.uast.UElement) UReferenceExpression(org.jetbrains.uast.UReferenceExpression) UBinaryExpressionWithType(org.jetbrains.uast.UBinaryExpressionWithType) PsiElement(com.intellij.psi.PsiElement)

Example 2 with UElement

use of org.jetbrains.uast.UElement in project kotlin by JetBrains.

the class ResourceEvaluator method getResourceTypes.

/**
     * Evaluates the given node and returns the resource types applicable to the
     * node, if any.
     *
     * @param element the element to compute the types for
     * @return the corresponding resource types
     */
@Nullable
public EnumSet<ResourceType> getResourceTypes(@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 getResourceTypes(expression.getThenExpression());
        } else if (known == Boolean.FALSE && expression.getElseExpression() != null) {
            return getResourceTypes(expression.getElseExpression());
        } else {
            EnumSet<ResourceType> left = getResourceTypes(expression.getThenExpression());
            EnumSet<ResourceType> right = getResourceTypes(expression.getElseExpression());
            if (left == null) {
                return right;
            } else if (right == null) {
                return left;
            } else {
                EnumSet<ResourceType> copy = EnumSet.copyOf(left);
                copy.addAll(right);
                return copy;
            }
        }
    } else if (element instanceof UParenthesizedExpression) {
        UParenthesizedExpression parenthesizedExpression = (UParenthesizedExpression) element;
        return getResourceTypes(parenthesizedExpression.getExpression());
    } else if ((element instanceof UQualifiedReferenceExpression && mAllowDereference) || element instanceof UCallExpression) {
        UElement probablyCallExpression = element;
        if (element instanceof UQualifiedReferenceExpression) {
            UQualifiedReferenceExpression qualifiedExpression = (UQualifiedReferenceExpression) element;
            probablyCallExpression = qualifiedExpression.getSelector();
        }
        if ((probablyCallExpression instanceof UCallExpression)) {
            UCallExpression call = (UCallExpression) probablyCallExpression;
            PsiMethod method = call.resolve();
            PsiClass containingClass = UastUtils.getContainingClass(method);
            if (method != null && containingClass != null) {
                EnumSet<ResourceType> types = getTypesFromAnnotations(method);
                if (types != null) {
                    return types;
                }
                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()) {
                        types = getResourceTypes(args.get(0));
                        if (types != null) {
                            return types;
                        }
                    }
                }
            }
        }
    }
    if (element instanceof UReferenceExpression) {
        ResourceUrl url = getResourceConstant(element);
        if (url != null) {
            return EnumSet.of(url.type);
        }
        PsiElement resolved = ((UReferenceExpression) element).resolve();
        if (resolved instanceof PsiVariable) {
            PsiVariable variable = (PsiVariable) resolved;
            UElement lastAssignment = UastLintUtils.findLastAssignment(variable, element, mContext);
            if (lastAssignment != null) {
                return getResourceTypes(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) EnumSet(java.util.EnumSet) PsiClass(com.intellij.psi.PsiClass) ResourceType(com.android.resources.ResourceType) UCallExpression(org.jetbrains.uast.UCallExpression) UExpression(org.jetbrains.uast.UExpression) UElement(org.jetbrains.uast.UElement) UReferenceExpression(org.jetbrains.uast.UReferenceExpression) ResourceUrl(com.android.ide.common.resources.ResourceUrl) PsiElement(com.intellij.psi.PsiElement) UIfExpression(org.jetbrains.uast.UIfExpression) Nullable(com.android.annotations.Nullable)

Example 3 with UElement

use of org.jetbrains.uast.UElement 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 4 with UElement

use of org.jetbrains.uast.UElement in project kotlin by JetBrains.

the class AddJavascriptInterfaceDetector method visitMethod.

@Override
public void visitMethod(@NonNull JavaContext context, @Nullable UastVisitor visitor, @NonNull UCallExpression call, @NonNull UMethod method) {
    // Ignore the issue if we never build for any API less than 17.
    if (context.getMainProject().getMinSdk() >= 17) {
        return;
    }
    JavaEvaluator evaluator = context.getEvaluator();
    if (!evaluator.methodMatches(method, WEB_VIEW, true, TYPE_OBJECT, TYPE_STRING)) {
        return;
    }
    String message = "`WebView.addJavascriptInterface` should not be called with minSdkVersion < 17 for security reasons: " + "JavaScript can use reflection to manipulate application";
    UElement reportElement = call.getMethodIdentifier();
    if (reportElement == null) {
        reportElement = call;
    }
    context.reportUast(ISSUE, reportElement, context.getUastNameLocation(reportElement), message);
}
Also used : UElement(org.jetbrains.uast.UElement) JavaEvaluator(com.android.tools.klint.client.api.JavaEvaluator)

Example 5 with UElement

use of org.jetbrains.uast.UElement in project Conductor by bluelinelabs.

the class ControllerIssueDetector method createUastHandler.

@Override
public UElementHandler createUastHandler(final JavaContext context) {
    final JavaEvaluator evaluator = context.getEvaluator();
    return new UElementHandler() {

        @Override
        public void visitClass(UClass node) {
            if (evaluator.isAbstract(node)) {
                return;
            }
            boolean hasSuperType = false;
            for (UTypeReferenceExpression superType : node.getUastSuperTypes()) {
                if (CLASS_NAME.equals(superType.asRenderString())) {
                    hasSuperType = true;
                    break;
                }
            }
            if (!hasSuperType) {
                return;
            }
            if (!evaluator.isPublic(node)) {
                String message = String.format("This Controller class should be public (%1$s)", node.getQualifiedName());
                context.report(ISSUE, node, context.getLocation((UElement) node), message);
                return;
            }
            if (node.getContainingClass() != null && !evaluator.isStatic(node)) {
                String message = String.format("This Controller inner class should be static (%1$s)", node.getQualifiedName());
                context.report(ISSUE, node, context.getLocation((UElement) node), message);
                return;
            }
            boolean hasConstructor = false;
            boolean hasDefaultConstructor = false;
            boolean hasBundleConstructor = false;
            for (UMethod method : node.getMethods()) {
                if (method.isConstructor()) {
                    hasConstructor = true;
                    if (evaluator.isPublic(method)) {
                        List<UParameter> parameters = method.getUastParameters();
                        if (parameters.size() == 0) {
                            hasDefaultConstructor = true;
                            break;
                        } else if (parameters.size() == 1 && (parameters.get(0).getType().equalsToText(SdkConstants.CLASS_BUNDLE)) || parameters.get(0).getType().equalsToText("Bundle")) {
                            hasBundleConstructor = true;
                        }
                    }
                }
            }
            if (hasConstructor && !hasDefaultConstructor && !hasBundleConstructor) {
                String message = String.format("This Controller needs to have either a public default constructor or a" + " public single-argument constructor that takes a Bundle. (`%1$s`)", node.getQualifiedName());
                context.report(ISSUE, node, context.getLocation((UElement) node), message);
            }
        }
    };
}
Also used : UParameter(org.jetbrains.uast.UParameter) UElement(org.jetbrains.uast.UElement) UTypeReferenceExpression(org.jetbrains.uast.UTypeReferenceExpression) UMethod(org.jetbrains.uast.UMethod) JavaEvaluator(com.android.tools.lint.client.api.JavaEvaluator) UClass(org.jetbrains.uast.UClass) UElementHandler(com.android.tools.lint.client.api.UElementHandler)

Aggregations

UElement (org.jetbrains.uast.UElement)6 PsiElement (com.intellij.psi.PsiElement)3 UExpression (org.jetbrains.uast.UExpression)3 UReferenceExpression (org.jetbrains.uast.UReferenceExpression)3 Nullable (com.android.annotations.Nullable)2 ResourceUrl (com.android.ide.common.resources.ResourceUrl)2 JavaEvaluator (com.android.tools.lint.client.api.JavaEvaluator)2 UElementHandler (com.android.tools.lint.client.api.UElementHandler)2 PsiClass (com.intellij.psi.PsiClass)2 PsiMethod (com.intellij.psi.PsiMethod)2 PsiVariable (com.intellij.psi.PsiVariable)2 UCallExpression (org.jetbrains.uast.UCallExpression)2 UClass (org.jetbrains.uast.UClass)2 UIfExpression (org.jetbrains.uast.UIfExpression)2 UMethod (org.jetbrains.uast.UMethod)2 UParenthesizedExpression (org.jetbrains.uast.UParenthesizedExpression)2 UQualifiedReferenceExpression (org.jetbrains.uast.UQualifiedReferenceExpression)2 UTypeReferenceExpression (org.jetbrains.uast.UTypeReferenceExpression)2 ResourceType (com.android.resources.ResourceType)1 JavaEvaluator (com.android.tools.klint.client.api.JavaEvaluator)1