Search in sources :

Example 1 with ResourceUrl

use of com.android.ide.common.resources.ResourceUrl 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 PsiElement element) {
    if (element == null) {
        return null;
    }
    if (element instanceof PsiConditionalExpression) {
        PsiConditionalExpression expression = (PsiConditionalExpression) 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 PsiParenthesizedExpression) {
        PsiParenthesizedExpression parenthesizedExpression = (PsiParenthesizedExpression) element;
        return getResource(parenthesizedExpression.getExpression());
    } else if (element instanceof PsiMethodCallExpression && mAllowDereference) {
        PsiMethodCallExpression call = (PsiMethodCallExpression) element;
        PsiReferenceExpression expression = call.getMethodExpression();
        PsiMethod method = call.resolveMethod();
        if (method != null && method.getContainingClass() != null) {
            String qualifiedName = method.getContainingClass().getQualifiedName();
            String name = expression.getReferenceName();
            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")) {
                PsiExpression[] args = call.getArgumentList().getExpressions();
                if (args.length > 0) {
                    return getResource(args[0]);
                }
            }
        }
    } else if (element instanceof PsiReference) {
        ResourceUrl url = getResourceConstant(element);
        if (url != null) {
            return url;
        }
        PsiElement resolved = ((PsiReference) element).resolve();
        if (resolved instanceof PsiField) {
            url = getResourceConstant(resolved);
            if (url != null) {
                return url;
            }
            PsiField field = (PsiField) resolved;
            if (field.getInitializer() != null) {
                return getResource(field.getInitializer());
            }
            return null;
        } else if (resolved instanceof PsiLocalVariable) {
            PsiLocalVariable variable = (PsiLocalVariable) resolved;
            PsiStatement statement = PsiTreeUtil.getParentOfType(element, PsiStatement.class, false);
            if (statement != null) {
                PsiStatement prev = PsiTreeUtil.getPrevSiblingOfType(statement, PsiStatement.class);
                String targetName = variable.getName();
                if (targetName == null) {
                    return null;
                }
                while (prev != null) {
                    if (prev instanceof PsiDeclarationStatement) {
                        PsiDeclarationStatement prevStatement = (PsiDeclarationStatement) prev;
                        for (PsiElement e : prevStatement.getDeclaredElements()) {
                            if (variable.equals(e)) {
                                return getResource(variable.getInitializer());
                            }
                        }
                    } else if (prev instanceof PsiExpressionStatement) {
                        PsiExpression expression = ((PsiExpressionStatement) prev).getExpression();
                        if (expression instanceof PsiAssignmentExpression) {
                            PsiAssignmentExpression assign = (PsiAssignmentExpression) expression;
                            PsiExpression lhs = assign.getLExpression();
                            if (lhs instanceof PsiReferenceExpression) {
                                PsiReferenceExpression reference = (PsiReferenceExpression) lhs;
                                if (targetName.equals(reference.getReferenceName()) && reference.getQualifier() == null) {
                                    return getResource(assign.getRExpression());
                                }
                            }
                        }
                    }
                    prev = PsiTreeUtil.getPrevSiblingOfType(prev, PsiStatement.class);
                }
            }
        }
    }
    return null;
}
Also used : PsiStatement(com.intellij.psi.PsiStatement) PsiDeclarationStatement(com.intellij.psi.PsiDeclarationStatement) PsiExpression(com.intellij.psi.PsiExpression) PsiMethod(com.intellij.psi.PsiMethod) PsiReferenceExpression(com.intellij.psi.PsiReferenceExpression) PsiReference(com.intellij.psi.PsiReference) PsiAssignmentExpression(com.intellij.psi.PsiAssignmentExpression) PsiLocalVariable(com.intellij.psi.PsiLocalVariable) PsiConditionalExpression(com.intellij.psi.PsiConditionalExpression) PsiMethodCallExpression(com.intellij.psi.PsiMethodCallExpression) PsiExpressionStatement(com.intellij.psi.PsiExpressionStatement) PsiField(com.intellij.psi.PsiField) PsiParenthesizedExpression(com.intellij.psi.PsiParenthesizedExpression) ResourceUrl(com.android.ide.common.resources.ResourceUrl) PsiElement(com.intellij.psi.PsiElement) Nullable(com.android.annotations.Nullable)

Example 2 with ResourceUrl

use of com.android.ide.common.resources.ResourceUrl 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 PsiElement element) {
    if (element == null) {
        return null;
    }
    if (element instanceof PsiConditionalExpression) {
        PsiConditionalExpression expression = (PsiConditionalExpression) 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 PsiParenthesizedExpression) {
        PsiParenthesizedExpression parenthesizedExpression = (PsiParenthesizedExpression) element;
        return getResourceTypes(parenthesizedExpression.getExpression());
    } else if (element instanceof PsiMethodCallExpression && mAllowDereference) {
        PsiMethodCallExpression call = (PsiMethodCallExpression) element;
        PsiReferenceExpression expression = call.getMethodExpression();
        PsiMethod method = call.resolveMethod();
        if (method != null && method.getContainingClass() != null) {
            EnumSet<ResourceType> types = getTypesFromAnnotations(method);
            if (types != null) {
                return types;
            }
            String qualifiedName = method.getContainingClass().getQualifiedName();
            String name = expression.getReferenceName();
            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")) {
                PsiExpression[] args = call.getArgumentList().getExpressions();
                if (args.length > 0) {
                    types = getResourceTypes(args[0]);
                    if (types != null) {
                        return types;
                    }
                }
            }
        }
    } else if (element instanceof PsiReference) {
        ResourceUrl url = getResourceConstant(element);
        if (url != null) {
            return EnumSet.of(url.type);
        }
        PsiElement resolved = ((PsiReference) element).resolve();
        if (resolved instanceof PsiField) {
            url = getResourceConstant(resolved);
            if (url != null) {
                return EnumSet.of(url.type);
            }
            PsiField field = (PsiField) resolved;
            if (field.getInitializer() != null) {
                return getResourceTypes(field.getInitializer());
            }
            return null;
        } else if (resolved instanceof PsiParameter) {
            return getTypesFromAnnotations((PsiParameter) resolved);
        } else if (resolved instanceof PsiLocalVariable) {
            PsiLocalVariable variable = (PsiLocalVariable) resolved;
            PsiStatement statement = PsiTreeUtil.getParentOfType(element, PsiStatement.class, false);
            if (statement != null) {
                PsiStatement prev = PsiTreeUtil.getPrevSiblingOfType(statement, PsiStatement.class);
                String targetName = variable.getName();
                if (targetName == null) {
                    return null;
                }
                while (prev != null) {
                    if (prev instanceof PsiDeclarationStatement) {
                        PsiDeclarationStatement prevStatement = (PsiDeclarationStatement) prev;
                        for (PsiElement e : prevStatement.getDeclaredElements()) {
                            if (variable.equals(e)) {
                                return getResourceTypes(variable.getInitializer());
                            }
                        }
                    } else if (prev instanceof PsiExpressionStatement) {
                        PsiExpression expression = ((PsiExpressionStatement) prev).getExpression();
                        if (expression instanceof PsiAssignmentExpression) {
                            PsiAssignmentExpression assign = (PsiAssignmentExpression) expression;
                            PsiExpression lhs = assign.getLExpression();
                            if (lhs instanceof PsiReferenceExpression) {
                                PsiReferenceExpression reference = (PsiReferenceExpression) lhs;
                                if (targetName.equals(reference.getReferenceName()) && reference.getQualifier() == null) {
                                    return getResourceTypes(assign.getRExpression());
                                }
                            }
                        }
                    }
                    prev = PsiTreeUtil.getPrevSiblingOfType(prev, PsiStatement.class);
                }
            }
        }
    }
    return null;
}
Also used : PsiStatement(com.intellij.psi.PsiStatement) PsiDeclarationStatement(com.intellij.psi.PsiDeclarationStatement) PsiExpression(com.intellij.psi.PsiExpression) PsiMethod(com.intellij.psi.PsiMethod) PsiReferenceExpression(com.intellij.psi.PsiReferenceExpression) EnumSet(java.util.EnumSet) PsiReference(com.intellij.psi.PsiReference) ResourceType(com.android.resources.ResourceType) PsiAssignmentExpression(com.intellij.psi.PsiAssignmentExpression) PsiLocalVariable(com.intellij.psi.PsiLocalVariable) PsiConditionalExpression(com.intellij.psi.PsiConditionalExpression) PsiMethodCallExpression(com.intellij.psi.PsiMethodCallExpression) PsiParameter(com.intellij.psi.PsiParameter) PsiExpressionStatement(com.intellij.psi.PsiExpressionStatement) PsiField(com.intellij.psi.PsiField) PsiParenthesizedExpression(com.intellij.psi.PsiParenthesizedExpression) ResourceUrl(com.android.ide.common.resources.ResourceUrl) PsiElement(com.intellij.psi.PsiElement) Nullable(com.android.annotations.Nullable)

Example 3 with ResourceUrl

use of com.android.ide.common.resources.ResourceUrl in project kotlin by JetBrains.

the class LintUtils method getStyleAttributes.

/**
     * Looks up the resource values for the given attribute given a style. Note that
     * this only looks project-level style values, it does not resume into the framework
     * styles.
     */
@Nullable
public static List<ResourceValue> getStyleAttributes(@NonNull Project project, @NonNull LintClient client, @NonNull String styleUrl, @NonNull String namespace, @NonNull String attribute) {
    if (!client.supportsProjectResources()) {
        return null;
    }
    AbstractResourceRepository resources = client.getProjectResources(project, true);
    if (resources == null) {
        return null;
    }
    ResourceUrl style = ResourceUrl.parse(styleUrl);
    if (style == null || style.framework) {
        return null;
    }
    List<ResourceValue> result = null;
    Queue<ResourceValue> queue = new ArrayDeque<ResourceValue>();
    queue.add(new ResourceValue(style.type, style.name, false));
    Set<String> seen = Sets.newHashSet();
    int count = 0;
    boolean isFrameworkAttribute = ANDROID_URI.equals(namespace);
    while (count < 30 && !queue.isEmpty()) {
        ResourceValue front = queue.remove();
        String name = front.getName();
        seen.add(name);
        List<ResourceItem> items = resources.getResourceItem(front.getResourceType(), name);
        if (items != null) {
            for (ResourceItem item : items) {
                ResourceValue rv = item.getResourceValue(false);
                if (rv instanceof StyleResourceValue) {
                    StyleResourceValue srv = (StyleResourceValue) rv;
                    ItemResourceValue value = srv.getItem(attribute, isFrameworkAttribute);
                    if (value != null) {
                        if (result == null) {
                            result = Lists.newArrayList();
                        }
                        if (!result.contains(value)) {
                            result.add(value);
                        }
                    }
                    String parent = srv.getParentStyle();
                    if (parent != null && !parent.startsWith(ANDROID_PREFIX)) {
                        ResourceUrl p = ResourceUrl.parse(parent);
                        if (p != null && !p.framework && !seen.contains(p.name)) {
                            seen.add(p.name);
                            queue.add(new ResourceValue(ResourceType.STYLE, p.name, false));
                        }
                    }
                    int index = name.lastIndexOf('.');
                    if (index > 0) {
                        String parentName = name.substring(0, index);
                        if (!seen.contains(parentName)) {
                            seen.add(parentName);
                            queue.add(new ResourceValue(ResourceType.STYLE, parentName, false));
                        }
                    }
                }
            }
        }
        count++;
    }
    return result;
}
Also used : StyleResourceValue(com.android.ide.common.rendering.api.StyleResourceValue) AbstractResourceRepository(com.android.ide.common.res2.AbstractResourceRepository) ItemResourceValue(com.android.ide.common.rendering.api.ItemResourceValue) StyleResourceValue(com.android.ide.common.rendering.api.StyleResourceValue) ItemResourceValue(com.android.ide.common.rendering.api.ItemResourceValue) ResourceValue(com.android.ide.common.rendering.api.ResourceValue) ResourceItem(com.android.ide.common.res2.ResourceItem) ResourceUrl(com.android.ide.common.resources.ResourceUrl) Nullable(com.android.annotations.Nullable)

Example 4 with ResourceUrl

use of com.android.ide.common.resources.ResourceUrl in project kotlin by JetBrains.

the class StringFormatDetector method checkStringFormatCall.

/**
     * Check the given String.format call (with the given arguments) to see if the string format is
     * being used correctly
     *  @param context           the context to report errors to
     * @param calledMethod      the method being called
     * @param call              the AST node for the {@link String#format}
     * @param specifiesLocale   whether the first parameter is a locale string, shifting the
     */
private void checkStringFormatCall(JavaContext context, PsiMethod calledMethod, UCallExpression call, boolean specifiesLocale) {
    int argIndex = specifiesLocale ? 1 : 0;
    List<UExpression> args = call.getValueArguments();
    if (args.size() <= argIndex) {
        return;
    }
    UExpression argument = args.get(argIndex);
    ResourceUrl resource = ResourceEvaluator.getResource(context, argument);
    if (resource == null || resource.framework || resource.type != ResourceType.STRING) {
        return;
    }
    String name = resource.name;
    if (mIgnoreStrings != null && mIgnoreStrings.contains(name)) {
        return;
    }
    boolean passingVarArgsArray = false;
    int callCount = args.size() - 1 - argIndex;
    if (callCount == 1) {
        // If instead of a varargs call like
        //    getString(R.string.foo, arg1, arg2, arg3)
        // the code is calling the varargs method with a packed Object array, as in
        //    getString(R.string.foo, new Object[] { arg1, arg2, arg3 })
        // we'll need to handle that such that we don't think this is a single
        // argument
        UExpression lastArg = args.get(args.size() - 1);
        PsiParameterList parameterList = calledMethod.getParameterList();
        int parameterCount = parameterList.getParametersCount();
        if (parameterCount > 0 && parameterList.getParameters()[parameterCount - 1].isVarArgs()) {
            boolean knownArity = false;
            boolean argWasReference = false;
            if (lastArg instanceof UReferenceExpression) {
                PsiElement resolved = ((UReferenceExpression) lastArg).resolve();
                if (resolved instanceof PsiVariable) {
                    UExpression initializer = context.getUastContext().getInitializerBody((PsiVariable) resolved);
                    if (initializer != null && (UastExpressionUtils.isNewArray(initializer) || UastExpressionUtils.isArrayInitializer(initializer))) {
                        argWasReference = true;
                        // Now handled by check below
                        lastArg = initializer;
                    }
                }
            }
            if (UastExpressionUtils.isNewArray(lastArg) || UastExpressionUtils.isArrayInitializer(lastArg)) {
                UCallExpression arrayInitializer = (UCallExpression) lastArg;
                if (UastExpressionUtils.isNewArrayWithInitializer(lastArg) || UastExpressionUtils.isArrayInitializer(lastArg)) {
                    callCount = arrayInitializer.getValueArgumentCount();
                    knownArity = true;
                } else if (UastExpressionUtils.isNewArrayWithDimensions(lastArg)) {
                    List<UExpression> arrayDimensions = arrayInitializer.getValueArguments();
                    if (arrayDimensions.size() == 1) {
                        UExpression first = arrayDimensions.get(0);
                        if (first instanceof ULiteralExpression) {
                            Object o = ((ULiteralExpression) first).getValue();
                            if (o instanceof Integer) {
                                callCount = (Integer) o;
                                knownArity = true;
                            }
                        }
                    }
                }
                if (!knownArity) {
                    if (!argWasReference) {
                        return;
                    }
                } else {
                    passingVarArgsArray = true;
                }
            }
        }
    }
    if (callCount > 0 && mNotFormatStrings.containsKey(name)) {
        checkNotFormattedHandle(context, call, name, mNotFormatStrings.get(name));
        return;
    }
    List<Pair<Handle, String>> list = mFormatStrings != null ? mFormatStrings.get(name) : null;
    if (list == null) {
        LintClient client = context.getClient();
        if (client.supportsProjectResources() && !context.getScope().contains(Scope.RESOURCE_FILE)) {
            AbstractResourceRepository resources = client.getProjectResources(context.getMainProject(), true);
            List<ResourceItem> items;
            if (resources != null) {
                items = resources.getResourceItem(ResourceType.STRING, name);
            } else {
                // Must be a non-Android module
                items = null;
            }
            if (items != null) {
                for (final ResourceItem item : items) {
                    ResourceValue v = item.getResourceValue(false);
                    if (v != null) {
                        String value = v.getRawXmlValue();
                        if (value != null) {
                            // Make sure it's really a formatting string,
                            // not for example "Battery remaining: 90%"
                            boolean isFormattingString = value.indexOf('%') != -1;
                            for (int j = 0, m = value.length(); j < m && isFormattingString; j++) {
                                char c = value.charAt(j);
                                if (c == '\\') {
                                    j++;
                                } else if (c == '%') {
                                    Matcher matcher = FORMAT.matcher(value);
                                    if (!matcher.find(j)) {
                                        isFormattingString = false;
                                    } else {
                                        String conversion = matcher.group(6);
                                        int conversionClass = getConversionClass(conversion.charAt(0));
                                        if (conversionClass == CONVERSION_CLASS_UNKNOWN || matcher.group(5) != null) {
                                            // Some date format etc - don't process
                                            return;
                                        }
                                    }
                                    // Don't process second % in a %%
                                    j++;
                                }
                            // If the user marked the string with
                            }
                            Handle handle = client.createResourceItemHandle(item);
                            if (isFormattingString) {
                                if (list == null) {
                                    list = Lists.newArrayList();
                                    if (mFormatStrings == null) {
                                        mFormatStrings = Maps.newHashMap();
                                    }
                                    mFormatStrings.put(name, list);
                                }
                                list.add(Pair.of(handle, value));
                            } else if (callCount > 0) {
                                checkNotFormattedHandle(context, call, name, handle);
                            }
                        }
                    }
                }
            }
        } else {
            return;
        }
    }
    if (list != null) {
        Set<String> reported = null;
        for (Pair<Handle, String> pair : list) {
            String s = pair.getSecond();
            if (reported != null && reported.contains(s)) {
                continue;
            }
            int count = getFormatArgumentCount(s, null);
            Handle handle = pair.getFirst();
            if (count != callCount) {
                Location location = context.getUastLocation(call);
                Location secondary = handle.resolve();
                secondary.setMessage(String.format("This definition requires %1$d arguments", count));
                location.setSecondary(secondary);
                String message = String.format("Wrong argument count, format string `%1$s` requires `%2$d` but format " + "call supplies `%3$d`", name, count, callCount);
                context.report(ARG_TYPES, call, location, message);
                if (reported == null) {
                    reported = Sets.newHashSet();
                }
                reported.add(s);
            } else {
                if (passingVarArgsArray) {
                    // flag parameters on the Object[] instead of the wrapped parameters
                    return;
                }
                for (int i = 1; i <= count; i++) {
                    int argumentIndex = i + argIndex;
                    PsiType type = args.get(argumentIndex).getExpressionType();
                    if (type != null) {
                        boolean valid = true;
                        String formatType = getFormatArgumentType(s, i);
                        if (formatType == null) {
                            continue;
                        }
                        char last = formatType.charAt(formatType.length() - 1);
                        if (formatType.length() >= 2 && Character.toLowerCase(formatType.charAt(formatType.length() - 2)) == 't') {
                            // TODO
                            continue;
                        }
                        switch(last) {
                            // unusual and probably not intended.
                            case 'b':
                            case 'B':
                                valid = isBooleanType(type);
                                break;
                            // Numeric: integer and floats in various formats
                            case 'x':
                            case 'X':
                            case 'd':
                            case 'o':
                            case 'e':
                            case 'E':
                            case 'f':
                            case 'g':
                            case 'G':
                            case 'a':
                            case 'A':
                                valid = isNumericType(type, true);
                                break;
                            case 'c':
                            case 'C':
                                // Unicode character
                                valid = isCharacterType(type);
                                break;
                            case 'h':
                            // Hex print of hash code of objects
                            case 'H':
                            case 's':
                            case 'S':
                                // String. Can pass anything, but warn about
                                // numbers since you may have meant more
                                // specific formatting. Use special issue
                                // explanation for this?
                                valid = !isBooleanType(type) && !isNumericType(type, false);
                                break;
                        }
                        if (!valid) {
                            Location location = context.getUastLocation(args.get(argumentIndex));
                            Location secondary = handle.resolve();
                            secondary.setMessage("Conflicting argument declaration here");
                            location.setSecondary(secondary);
                            String suggestion = null;
                            if (isBooleanType(type)) {
                                suggestion = "`b`";
                            } else if (isCharacterType(type)) {
                                suggestion = "'c'";
                            } else if (PsiType.INT.equals(type) || PsiType.LONG.equals(type) || PsiType.BYTE.equals(type) || PsiType.SHORT.equals(type)) {
                                suggestion = "`d`, 'o' or `x`";
                            } else if (PsiType.FLOAT.equals(type) || PsiType.DOUBLE.equals(type)) {
                                suggestion = "`e`, 'f', 'g' or `a`";
                            } else if (type instanceof PsiClassType) {
                                String fqn = type.getCanonicalText();
                                if (TYPE_INTEGER_WRAPPER.equals(fqn) || TYPE_LONG_WRAPPER.equals(fqn) || TYPE_BYTE_WRAPPER.equals(fqn) || TYPE_SHORT_WRAPPER.equals(fqn)) {
                                    suggestion = "`d`, 'o' or `x`";
                                } else if (TYPE_FLOAT_WRAPPER.equals(fqn) || TYPE_DOUBLE_WRAPPER.equals(fqn)) {
                                    suggestion = "`d`, 'o' or `x`";
                                } else if (TYPE_OBJECT.equals(fqn)) {
                                    suggestion = "'s' or 'h'";
                                }
                            }
                            if (suggestion != null) {
                                suggestion = " (Did you mean formatting character " + suggestion + "?)";
                            } else {
                                suggestion = "";
                            }
                            String canonicalText = type.getCanonicalText();
                            canonicalText = canonicalText.substring(canonicalText.lastIndexOf('.') + 1);
                            String message = String.format("Wrong argument type for formatting argument '#%1$d' " + "in `%2$s`: conversion is '`%3$s`', received `%4$s` " + "(argument #%5$d in method call)%6$s", i, name, formatType, canonicalText, argumentIndex + 1, suggestion);
                            context.report(ARG_TYPES, call, location, message);
                            if (reported == null) {
                                reported = Sets.newHashSet();
                            }
                            reported.add(s);
                        }
                    }
                }
            }
        }
    }
}
Also used : ULiteralExpression(org.jetbrains.uast.ULiteralExpression) Matcher(java.util.regex.Matcher) UCallExpression(org.jetbrains.uast.UCallExpression) AbstractResourceRepository(com.android.ide.common.res2.AbstractResourceRepository) ResourceValue(com.android.ide.common.rendering.api.ResourceValue) List(java.util.List) ArrayList(java.util.ArrayList) ImmutableList(com.google.common.collect.ImmutableList) NodeList(org.w3c.dom.NodeList) PsiParameterList(com.intellij.psi.PsiParameterList) ResourceUrl(com.android.ide.common.resources.ResourceUrl) PsiElement(com.intellij.psi.PsiElement) Pair(com.android.utils.Pair) PsiType(com.intellij.psi.PsiType) PsiVariable(com.intellij.psi.PsiVariable) LintClient(com.android.tools.klint.client.api.LintClient) Handle(com.android.tools.klint.detector.api.Location.Handle) UExpression(org.jetbrains.uast.UExpression) PsiClassType(com.intellij.psi.PsiClassType) UReferenceExpression(org.jetbrains.uast.UReferenceExpression) PsiParameterList(com.intellij.psi.PsiParameterList) ResourceItem(com.android.ide.common.res2.ResourceItem) Location(com.android.tools.klint.detector.api.Location)

Example 5 with ResourceUrl

use of com.android.ide.common.resources.ResourceUrl in project kotlin by JetBrains.

the class PrivateResourceDetector method visitAttribute.

/** Check resource references: accessing a private resource from an upstream library? */
@Override
public void visitAttribute(@NonNull XmlContext context, @NonNull Attr attribute) {
    String value = attribute.getNodeValue();
    if (context.getProject().isGradleProject()) {
        ResourceUrl url = ResourceUrl.parse(value);
        if (isPrivate(context, url)) {
            String message = createUsageErrorMessage(context, url.type, url.name);
            context.report(ISSUE, attribute, context.getValueLocation(attribute), message);
        }
    }
}
Also used : ResourceUrl(com.android.ide.common.resources.ResourceUrl)

Aggregations

ResourceUrl (com.android.ide.common.resources.ResourceUrl)24 PsiElement (com.intellij.psi.PsiElement)7 Nullable (com.android.annotations.Nullable)6 ResourceValue (com.android.ide.common.rendering.api.ResourceValue)5 AbstractResourceRepository (com.android.ide.common.res2.AbstractResourceRepository)5 ResourceItem (com.android.ide.common.res2.ResourceItem)5 ResourceType (com.android.resources.ResourceType)4 PsiMethod (com.intellij.psi.PsiMethod)4 ItemResourceValue (com.android.ide.common.rendering.api.ItemResourceValue)3 LintClient (com.android.tools.klint.client.api.LintClient)3 UExpression (org.jetbrains.uast.UExpression)3 StyleResourceValue (com.android.ide.common.rendering.api.StyleResourceValue)2 Module (com.intellij.openapi.module.Module)2 PsiAssignmentExpression (com.intellij.psi.PsiAssignmentExpression)2 PsiClass (com.intellij.psi.PsiClass)2 PsiConditionalExpression (com.intellij.psi.PsiConditionalExpression)2 PsiDeclarationStatement (com.intellij.psi.PsiDeclarationStatement)2 PsiExpression (com.intellij.psi.PsiExpression)2 PsiExpressionStatement (com.intellij.psi.PsiExpressionStatement)2 PsiField (com.intellij.psi.PsiField)2