Search in sources :

Example 11 with UExpression

use of org.jetbrains.uast.UExpression in project Signal-Android by WhisperSystems.

the class AlertDialogBuilderDetector method quickFixIssueAlertDialogBuilder.

private LintFix quickFixIssueAlertDialogBuilder(@NotNull UCallExpression alertBuilderCall) {
    List<UExpression> arguments = alertBuilderCall.getValueArguments();
    UExpression context = arguments.get(0);
    String fixSource = "new com.google.android.material.dialog.MaterialAlertDialogBuilder";
    switch(arguments.size()) {
        case 1:
            fixSource += String.format("(%s)", context);
            break;
        case 2:
            UExpression themeOverride = arguments.get(1);
            fixSource += String.format("(%s, %s)", context, themeOverride);
            break;
        default:
            throw new IllegalStateException("MaterialAlertDialogBuilder overloads should have 1 or 2 arguments");
    }
    String builderCallSource = alertBuilderCall.asSourceString();
    LintFix.GroupBuilder fixGrouper = fix().group();
    fixGrouper.add(fix().replace().text(builderCallSource).shortenNames().reformat(true).with(fixSource).build());
    return fixGrouper.build();
}
Also used : UExpression(org.jetbrains.uast.UExpression) LintFix(com.android.tools.lint.detector.api.LintFix)

Example 12 with UExpression

use of org.jetbrains.uast.UExpression in project Signal-Android by WhisperSystems.

the class SignalLogDetector method visitMethodCall.

@Override
public void visitMethodCall(JavaContext context, @NotNull UCallExpression call, @NotNull PsiMethod method) {
    JavaEvaluator evaluator = context.getEvaluator();
    if (evaluator.isMemberInClass(method, "android.util.Log")) {
        LintFix fix = quickFixIssueLog(call);
        context.report(LOG_NOT_SIGNAL, call, context.getLocation(call), "Using 'android.util.Log' instead of a Signal Logger", fix);
    }
    if (evaluator.isMemberInClass(method, "org.signal.glide.Log")) {
        LintFix fix = quickFixIssueLog(call);
        context.report(LOG_NOT_SIGNAL, call, context.getLocation(call), "Using 'org.signal.glide.Log' instead of a Signal Logger", fix);
    }
    if (evaluator.isMemberInClass(method, "org.whispersystems.libsignal.logging.Log")) {
        LintFix fix = quickFixIssueLog(call);
        context.report(LOG_NOT_APP, call, context.getLocation(call), "Using Signal server logger instead of app level Logger", fix);
    }
    if (evaluator.isMemberInClass(method, "org.signal.core.util.logging.Log")) {
        List<UExpression> arguments = call.getValueArguments();
        UExpression tag = arguments.get(0);
        if (!(tag instanceof JavaUSimpleNameReferenceExpression || tag instanceof KotlinUSimpleReferenceExpression || tag instanceof KotlinUQualifiedReferenceExpression)) {
            context.report(INLINE_TAG, call, context.getLocation(call), "Not using a tag constant");
        }
    }
}
Also used : UExpression(org.jetbrains.uast.UExpression) KotlinUQualifiedReferenceExpression(org.jetbrains.uast.kotlin.KotlinUQualifiedReferenceExpression) LintFix(com.android.tools.lint.detector.api.LintFix) KotlinUSimpleReferenceExpression(org.jetbrains.uast.kotlin.KotlinUSimpleReferenceExpression) JavaUSimpleNameReferenceExpression(org.jetbrains.uast.java.JavaUSimpleNameReferenceExpression) JavaEvaluator(com.android.tools.lint.client.api.JavaEvaluator)

Example 13 with UExpression

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

the class WrongCallDetector method visitMethod.

@Override
public void visitMethod(@NonNull JavaContext context, @Nullable UastVisitor visitor, @NonNull UCallExpression node, @NonNull UMethod calledMethod) {
    // Call is only allowed if it is both only called on the super class (invoke special)
    // as well as within the same overriding method (e.g. you can't call super.onLayout
    // from the onMeasure method)
    UExpression operand = node.getReceiver();
    if (!(operand instanceof USuperExpression)) {
        report(context, node, calledMethod);
        return;
    }
    PsiMethod method = UastUtils.getParentOfType(node, UMethod.class, true);
    if (method != null) {
        String callName = node.getMethodName();
        if (callName != null && !callName.equals(method.getName())) {
            report(context, node, calledMethod);
        }
    }
}
Also used : UExpression(org.jetbrains.uast.UExpression) USuperExpression(org.jetbrains.uast.USuperExpression) PsiMethod(com.intellij.psi.PsiMethod)

Example 14 with UExpression

use of org.jetbrains.uast.UExpression 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 15 with UExpression

use of org.jetbrains.uast.UExpression 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)

Aggregations

UExpression (org.jetbrains.uast.UExpression)25 Location (com.android.tools.klint.detector.api.Location)8 JavaEvaluator (com.android.tools.klint.client.api.JavaEvaluator)7 PsiElement (com.intellij.psi.PsiElement)6 PsiMethod (com.intellij.psi.PsiMethod)6 PsiClass (com.intellij.psi.PsiClass)5 UCallExpression (org.jetbrains.uast.UCallExpression)5 ResourceUrl (com.android.ide.common.resources.ResourceUrl)4 PsiClassType (com.intellij.psi.PsiClassType)4 PsiType (com.intellij.psi.PsiType)4 UReferenceExpression (org.jetbrains.uast.UReferenceExpression)4 Nullable (com.android.annotations.Nullable)3 LintFix (com.android.tools.lint.detector.api.LintFix)3 PsiVariable (com.intellij.psi.PsiVariable)3 UElement (org.jetbrains.uast.UElement)3 ULiteralExpression (org.jetbrains.uast.ULiteralExpression)3 PsiField (com.intellij.psi.PsiField)2 UIfExpression (org.jetbrains.uast.UIfExpression)2 UParenthesizedExpression (org.jetbrains.uast.UParenthesizedExpression)2 UQualifiedReferenceExpression (org.jetbrains.uast.UQualifiedReferenceExpression)2