Search in sources :

Example 66 with ResourceType

use of com.android.resources.ResourceType in project bazel by bazelbuild.

the class ResourceUsageAnalyzer method recordMapping.

private void recordMapping(@Nullable Path mapping) throws IOException {
    if (mapping == null || !mapping.toFile().exists()) {
        return;
    }
    final String arrowIndicator = " -> ";
    final String resourceIndicator = ".R$";
    Map<String, String> nameMap = null;
    for (String line : Files.readLines(mapping.toFile(), UTF_8)) {
        if (line.startsWith(" ") || line.startsWith("\t")) {
            if (nameMap != null) {
                // We're processing the members of a resource class: record names into the map
                int n = line.length();
                int i = 0;
                for (; i < n; i++) {
                    if (!Character.isWhitespace(line.charAt(i))) {
                        break;
                    }
                }
                if (i < n && line.startsWith("int", i)) {
                    // int or int[]
                    int start = line.indexOf(' ', i + 3) + 1;
                    int arrow = line.indexOf(arrowIndicator);
                    if (start > 0 && arrow != -1) {
                        int end = line.indexOf(' ', start + 1);
                        if (end != -1) {
                            String oldName = line.substring(start, end);
                            String newName = line.substring(arrow + arrowIndicator.length()).trim();
                            if (!newName.equals(oldName)) {
                                nameMap.put(newName, oldName);
                            }
                        }
                    }
                }
            }
            continue;
        } else {
            nameMap = null;
        }
        int index = line.indexOf(resourceIndicator);
        if (index == -1) {
            // resource name reflection
            if (line.startsWith("android.support.v7.widget.SuggestionsAdapter ")) {
                suggestionsAdapter = line.substring(line.indexOf(arrowIndicator) + arrowIndicator.length(), line.indexOf(':') != -1 ? line.indexOf(':') : line.length()).trim().replace('.', '/') + DOT_CLASS;
            } else if (line.startsWith("android.support.v7.internal.widget.ResourcesWrapper ") || line.startsWith("android.support.v7.widget.ResourcesWrapper ") || (// Recently wrapper moved
            resourcesWrapper == null && line.startsWith("android.support.v7.widget.TintContextWrapper$TintResources "))) {
                resourcesWrapper = line.substring(line.indexOf(arrowIndicator) + arrowIndicator.length(), line.indexOf(':') != -1 ? line.indexOf(':') : line.length()).trim().replace('.', '/') + DOT_CLASS;
            }
            continue;
        }
        int arrow = line.indexOf(arrowIndicator, index + 3);
        if (arrow == -1) {
            continue;
        }
        String typeName = line.substring(index + resourceIndicator.length(), arrow);
        ResourceType type = ResourceType.getEnum(typeName);
        if (type == null) {
            continue;
        }
        int end = line.indexOf(':', arrow + arrowIndicator.length());
        if (end == -1) {
            end = line.length();
        }
        String target = line.substring(arrow + arrowIndicator.length(), end).trim();
        String ownerName = AsmUtils.toInternalName(target);
        nameMap = Maps.newHashMap();
        Pair<ResourceType, Map<String, String>> pair = Pair.of(type, nameMap);
        resourceObfuscation.put(ownerName, pair);
        // For fast lookup in isResourceClass
        resourceObfuscation.put(ownerName + DOT_CLASS, pair);
    }
}
Also used : ResourceType(com.android.resources.ResourceType) Map(java.util.Map) NamedNodeMap(org.w3c.dom.NamedNodeMap)

Example 67 with ResourceType

use of com.android.resources.ResourceType in project bazel by bazelbuild.

the class ResourceUsageAnalyzer method stripUnused.

private void stripUnused(Element element, List<Resource> removed) {
    ResourceType type = ResourceUsageModel.getResourceType(element);
    if (type == ResourceType.ATTR) {
        // Not yet properly handled
        return;
    }
    Resource resource = model.getResource(element);
    if (resource != null) {
        if (resource.type == ResourceType.DECLARE_STYLEABLE || resource.type == ResourceType.ATTR) {
            // tracking field references of the R_styleable_attr fields yet
            return;
        }
        if (!resource.isReachable() && (resource.type == ResourceType.STYLE || resource.type == ResourceType.PLURALS || resource.type == ResourceType.ARRAY)) {
            NodeList children = element.getChildNodes();
            for (int i = children.getLength() - 1; i >= 0; i--) {
                Node child = children.item(i);
                element.removeChild(child);
            }
        }
    }
    NodeList children = element.getChildNodes();
    for (int i = children.getLength() - 1; i >= 0; i--) {
        Node child = children.item(i);
        if (child.getNodeType() == Node.ELEMENT_NODE) {
            stripUnused((Element) child, removed);
        }
    }
    if (resource != null && !resource.isReachable() && resource.type != ResourceType.ID) {
        removed.add(resource);
        Node parent = element.getParentNode();
        parent.removeChild(element);
    }
}
Also used : NodeList(org.w3c.dom.NodeList) Node(org.w3c.dom.Node) Resource(com.android.tools.lint.checks.ResourceUsageModel.Resource) ResourceType(com.android.resources.ResourceType)

Example 68 with ResourceType

use of com.android.resources.ResourceType in project bazel by bazelbuild.

the class DataResourceXml method parse.

/**
   * Parses xml resources from a Path to the provided overwritable and combining collections.
   *
   * <p>This method is a bit tricky in the service of performance -- creating several collections
   * and merging them was more expensive than writing to mutable collections directly.
   *
   * @param xmlInputFactory Used to create an XMLEventReader from the supplied resource path.
   * @param path The path to the xml resource to be parsed.
   * @param fqnFactory Used to create {@link FullyQualifiedName}s from the resource names.
   * @param overwritingConsumer A consumer for overwritable {@link DataResourceXml}s.
   * @param combiningConsumer A consumer for combining {@link DataResourceXml}s.
   * @throws XMLStreamException Thrown with the resource format is invalid.
   * @throws FactoryConfigurationError Thrown with the {@link XMLInputFactory} is misconfigured.
   * @throws IOException Thrown when there is an error reading a file.
   */
public static void parse(XMLInputFactory xmlInputFactory, Path path, Factory fqnFactory, KeyValueConsumer<DataKey, DataResource> overwritingConsumer, KeyValueConsumer<DataKey, DataResource> combiningConsumer) throws XMLStreamException, FactoryConfigurationError, IOException {
    XMLEventReader eventReader = xmlInputFactory.createXMLEventReader(new BufferedInputStream(Files.newInputStream(path)), StandardCharsets.UTF_8.toString());
    try {
        // TODO(corysmith): Make the xml parsing more readable.
        for (StartElement resources = XmlResourceValues.moveToResources(eventReader); resources != null; resources = XmlResourceValues.moveToResources(eventReader)) {
            // Record attributes on the <resources> tag.
            Iterator<Attribute> attributes = XmlResourceValues.iterateAttributesFrom(resources);
            while (attributes.hasNext()) {
                Attribute attribute = attributes.next();
                Namespaces namespaces = Namespaces.from(attribute.getName());
                String attributeName = attribute.getName().getNamespaceURI().isEmpty() ? attribute.getName().getLocalPart() : attribute.getName().getPrefix() + ":" + attribute.getName().getLocalPart();
                overwritingConsumer.consume(fqnFactory.create(VirtualType.RESOURCES_ATTRIBUTE, attributeName), DataResourceXml.createWithNamespaces(path, ResourcesAttribute.of(attributeName, attribute.getValue()), namespaces));
            }
            // Process resource declarations.
            for (StartElement start = XmlResourceValues.findNextStart(eventReader); start != null; start = XmlResourceValues.findNextStart(eventReader)) {
                Namespaces.Collector namespacesCollector = Namespaces.collector();
                if (XmlResourceValues.isEatComment(start) || XmlResourceValues.isSkip(start)) {
                    continue;
                }
                ResourceType resourceType = getResourceType(start);
                if (resourceType == null) {
                    throw new XMLStreamException(path + " contains an unrecognized resource type: " + start, start.getLocation());
                }
                if (resourceType == DECLARE_STYLEABLE) {
                    // Styleables are special, as they produce multiple overwrite and combining values,
                    // so we let the value handle the assignments.
                    XmlResourceValues.parseDeclareStyleable(fqnFactory, path, overwritingConsumer, combiningConsumer, eventReader, start);
                } else {
                    // Of simple resources, only IDs and Public are combining.
                    KeyValueConsumer<DataKey, DataResource> consumer = (resourceType == ID || resourceType == PUBLIC) ? combiningConsumer : overwritingConsumer;
                    String elementName = XmlResourceValues.getElementName(start);
                    if (elementName == null) {
                        throw new XMLStreamException(String.format("resource name is required for %s", resourceType), start.getLocation());
                    }
                    FullyQualifiedName key = fqnFactory.create(resourceType, elementName);
                    XmlResourceValue xmlResourceValue = parseXmlElements(resourceType, eventReader, start, namespacesCollector);
                    consumer.consume(key, DataResourceXml.createWithNamespaces(path, xmlResourceValue, namespacesCollector.toNamespaces()));
                }
            }
        }
    } catch (XMLStreamException e) {
        throw new XMLStreamException(path + ": " + e.getMessage(), e.getLocation(), e);
    } catch (RuntimeException e) {
        throw new RuntimeException("Error parsing " + path, e);
    }
}
Also used : Namespaces(com.google.devtools.build.android.xml.Namespaces) Attribute(javax.xml.stream.events.Attribute) ResourcesAttribute(com.google.devtools.build.android.xml.ResourcesAttribute) ResourceType(com.android.resources.ResourceType) StartElement(javax.xml.stream.events.StartElement) StyleableXmlResourceValue(com.google.devtools.build.android.xml.StyleableXmlResourceValue) PublicXmlResourceValue(com.google.devtools.build.android.xml.PublicXmlResourceValue) SimpleXmlResourceValue(com.google.devtools.build.android.xml.SimpleXmlResourceValue) StyleXmlResourceValue(com.google.devtools.build.android.xml.StyleXmlResourceValue) ArrayXmlResourceValue(com.google.devtools.build.android.xml.ArrayXmlResourceValue) IdXmlResourceValue(com.google.devtools.build.android.xml.IdXmlResourceValue) AttrXmlResourceValue(com.google.devtools.build.android.xml.AttrXmlResourceValue) PluralXmlResourceValue(com.google.devtools.build.android.xml.PluralXmlResourceValue) XMLStreamException(javax.xml.stream.XMLStreamException) BufferedInputStream(java.io.BufferedInputStream) XMLEventReader(javax.xml.stream.XMLEventReader)

Example 69 with ResourceType

use of com.android.resources.ResourceType in project bazel by bazelbuild.

the class RClassGenerator method getInitializers.

/** Convert the {@link SymbolLoader} data, to a map of {@link FieldInitializer}. */
private static Map<ResourceType, List<FieldInitializer>> getInitializers(Table<String, String, SymbolEntry> symbols, Table<String, String, SymbolEntry> values) {
    Map<ResourceType, List<FieldInitializer>> initializers = new EnumMap<>(ResourceType.class);
    for (String typeName : symbols.rowKeySet()) {
        ResourceType resourceType = ResourceType.getEnum(typeName);
        Preconditions.checkNotNull(resourceType);
        initializers.put(resourceType, getInitializers(typeName, symbols, values));
    }
    return initializers;
}
Also used : ResourceType(com.android.resources.ResourceType) ArrayList(java.util.ArrayList) List(java.util.List) EnumMap(java.util.EnumMap)

Example 70 with ResourceType

use of com.android.resources.ResourceType in project bazel by bazelbuild.

the class AndroidResourceClassWriter method fillInitializers.

private void fillInitializers(Map<ResourceType, List<FieldInitializer>> initializers) throws AttrLookupException {
    Map<ResourceType, Integer> typeIdMap = chooseTypeIds();
    Map<String, Integer> attrAssignments = assignAttrIds(typeIdMap.get(ResourceType.ATTR));
    for (Map.Entry<ResourceType, Set<String>> fieldEntries : innerClasses.entrySet()) {
        ResourceType type = fieldEntries.getKey();
        ImmutableList<String> sortedFields = Ordering.natural().immutableSortedCopy(fieldEntries.getValue());
        List<FieldInitializer> fields;
        if (type == ResourceType.STYLEABLE) {
            fields = getStyleableInitializers(attrAssignments, sortedFields);
        } else if (type == ResourceType.ATTR) {
            fields = getAttrInitializers(attrAssignments, sortedFields);
        } else {
            int typeId = typeIdMap.get(type);
            fields = getResourceInitializers(type, typeId, sortedFields);
        }
        // The maximum number of Java fields is 2^16.
        // See the JVM reference "4.11. Limitations of the Java Virtual Machine."
        Preconditions.checkArgument(fields.size() < (1 << 16));
        initializers.put(type, fields);
    }
}
Also used : TreeSet(java.util.TreeSet) HashSet(java.util.HashSet) ImmutableSet(com.google.common.collect.ImmutableSet) Set(java.util.Set) ResourceType(com.android.resources.ResourceType) FieldInitializer(com.google.devtools.build.android.resources.FieldInitializer) IntArrayFieldInitializer(com.google.devtools.build.android.resources.IntArrayFieldInitializer) IntFieldInitializer(com.google.devtools.build.android.resources.IntFieldInitializer) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) Map(java.util.Map) ImmutableMap(com.google.common.collect.ImmutableMap) EnumMap(java.util.EnumMap) TreeMap(java.util.TreeMap) SortedMap(java.util.SortedMap)

Aggregations

ResourceType (com.android.resources.ResourceType)137 ResourceValue (com.android.ide.common.rendering.api.ResourceValue)31 NotNull (org.jetbrains.annotations.NotNull)16 Field (java.lang.reflect.Field)13 StyleResourceValue (com.android.ide.common.rendering.api.StyleResourceValue)12 BridgeContext (com.android.layoutlib.bridge.android.BridgeContext)11 VirtualFile (com.intellij.openapi.vfs.VirtualFile)10 Map (java.util.Map)10 Nullable (org.jetbrains.annotations.Nullable)10 Nullable (com.android.annotations.Nullable)8 ResourceFolderType (com.android.resources.ResourceFolderType)8 File (java.io.File)8 EnumMap (java.util.EnumMap)7 AndroidFacet (org.jetbrains.android.facet.AndroidFacet)7 Context (android.content.Context)6 View (android.view.View)6 AbsListView (android.widget.AbsListView)6 AdapterView (android.widget.AdapterView)6 ExpandableListView (android.widget.ExpandableListView)6 FrameLayout (android.widget.FrameLayout)6