Search in sources :

Example 1 with UQualifiedReferenceExpression

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

the class SetTextDetector method checkNode.

private static void checkNode(@NonNull JavaContext context, @Nullable UElement node) {
    if (node instanceof ULiteralExpression) {
        Object value = ((ULiteralExpression) node).getValue();
        if (value instanceof String && value.toString().matches(WORD_PATTERN)) {
            context.report(SET_TEXT_I18N, node, context.getUastLocation(node), "String literal in `setText` can not be translated. Use Android " + "resources instead.");
        }
    } else if (node instanceof UCallExpression) {
        PsiMethod calledMethod = ((UCallExpression) node).resolve();
        if (calledMethod != null && TO_STRING_NAME.equals(calledMethod.getName())) {
            PsiClass containingClass = UastUtils.getContainingClass(calledMethod);
            if (containingClass == null) {
                return;
            }
            PsiClass superClass = containingClass.getSuperClass();
            if (superClass != null && NUMBER_CLS.equals(superClass.getQualifiedName())) {
                context.report(SET_TEXT_I18N, node, context.getUastLocation(node), "Number formatting does not take into account locale settings. " + "Consider using `String.format` instead.");
            }
        }
    } else if (node instanceof UQualifiedReferenceExpression) {
        UQualifiedReferenceExpression expression = (UQualifiedReferenceExpression) node;
        checkNode(context, expression.getReceiver());
        checkNode(context, expression.getSelector());
    } else if (node instanceof UBinaryExpression) {
        UBinaryExpression expression = (UBinaryExpression) node;
        if (expression.getOperator() == UastBinaryOperator.PLUS) {
            context.report(SET_TEXT_I18N, node, context.getUastLocation(node), "Do not concatenate text displayed with `setText`. " + "Use resource string with placeholders.");
        }
        checkNode(context, expression.getLeftOperand());
        checkNode(context, expression.getRightOperand());
    }
}
Also used : ULiteralExpression(org.jetbrains.uast.ULiteralExpression) PsiMethod(com.intellij.psi.PsiMethod) UQualifiedReferenceExpression(org.jetbrains.uast.UQualifiedReferenceExpression) PsiClass(com.intellij.psi.PsiClass) UBinaryExpression(org.jetbrains.uast.UBinaryExpression) UCallExpression(org.jetbrains.uast.UCallExpression)

Example 2 with UQualifiedReferenceExpression

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

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

PsiClass (com.intellij.psi.PsiClass)3 PsiMethod (com.intellij.psi.PsiMethod)3 UCallExpression (org.jetbrains.uast.UCallExpression)3 UQualifiedReferenceExpression (org.jetbrains.uast.UQualifiedReferenceExpression)3 Nullable (com.android.annotations.Nullable)2 ResourceUrl (com.android.ide.common.resources.ResourceUrl)2 PsiElement (com.intellij.psi.PsiElement)2 PsiVariable (com.intellij.psi.PsiVariable)2 UElement (org.jetbrains.uast.UElement)2 UExpression (org.jetbrains.uast.UExpression)2 UIfExpression (org.jetbrains.uast.UIfExpression)2 UParenthesizedExpression (org.jetbrains.uast.UParenthesizedExpression)2 UReferenceExpression (org.jetbrains.uast.UReferenceExpression)2 ResourceType (com.android.resources.ResourceType)1 EnumSet (java.util.EnumSet)1 UBinaryExpression (org.jetbrains.uast.UBinaryExpression)1 ULiteralExpression (org.jetbrains.uast.ULiteralExpression)1