Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 659ed614 authored by Adam Lesinski's avatar Adam Lesinski Committed by Android Git Automerger
Browse files

am 79e04686: Merge "AAPT2: Support static lib referencing static lib" into mnc-dev

* commit '79e04686':
  AAPT2: Support static lib referencing static lib
parents af486470 79e04686
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@ sources := \
	BinaryXmlPullParser.cpp \
	BindingXmlPullParser.cpp \
	ConfigDescription.cpp \
	Debug.cpp \
	Files.cpp \
	Flag.cpp \
	JavaClassGenerator.cpp \
+29 −14
Original line number Diff line number Diff line
@@ -475,10 +475,17 @@ bool BinaryResourceParser::parsePublic(const ResChunk_header* chunk) {
            source.line = entry->sourceLine;
        }

        if (!mTable->markPublic(name, resId, source)) {
        if (!mTable->markPublicAllowMangled(name, resId, source)) {
            return false;
        }

        // Add this resource name->id mapping to the index so
        // that we can resolve all ID references to name references.
        auto cacheIter = mIdIndex.find(resId);
        if (cacheIter == mIdIndex.end()) {
            mIdIndex.insert({ resId, name });
        }

        entry++;
    }
    return true;
@@ -611,12 +618,12 @@ bool BinaryResourceParser::parseType(const ResChunk_header* chunk) {
            source.line = sourceBlock->line;
        }

        if (!mTable->addResource(name, config, source, std::move(resourceValue))) {
        if (!mTable->addResourceAllowMangled(name, config, source, std::move(resourceValue))) {
            return false;
        }

        if ((entry->flags & ResTable_entry::FLAG_PUBLIC) != 0) {
            if (!mTable->markPublic(name, resId, mSource.line(0))) {
            if (!mTable->markPublicAllowMangled(name, resId, mSource.line(0))) {
                return false;
            }
        }
@@ -635,6 +642,10 @@ std::unique_ptr<Item> BinaryResourceParser::parseValue(const ResourceNameRef& na
                                                       const ConfigDescription& config,
                                                       const Res_value* value,
                                                       uint16_t flags) {
    if (name.type == ResourceType::kId) {
        return util::make_unique<Id>();
    }

    if (value->dataType == Res_value::TYPE_STRING) {
        StringPiece16 str = util::getString(mValuePool, value->data);

@@ -697,13 +708,6 @@ std::unique_ptr<Item> BinaryResourceParser::parseValue(const ResourceNameRef& na
                                                    StringPool::Context{ 1, config }));
    }

    if (name.type == ResourceType::kId ||
            (value->dataType == Res_value::TYPE_NULL &&
            value->data == Res_value::DATA_NULL_UNDEFINED &&
            (flags & ResTable_entry::FLAG_WEAK) != 0)) {
        return util::make_unique<Id>();
    }

    // Treat this as a raw binary primitive.
    return util::make_unique<BinaryPrimitive>(*value);
}
@@ -789,10 +793,21 @@ std::unique_ptr<Attribute> BinaryResourceParser::parseAttr(const ResourceNameRef
                continue;
            }

            attr->symbols.push_back(Attribute::Symbol{
                    Reference(mapEntry.name.ident),
                    mapEntry.value.data
            });
            Attribute::Symbol symbol;
            symbol.value = mapEntry.value.data;
            if (mapEntry.name.ident == 0) {
                // The map entry's key (id) is not set. This must be
                // a symbol reference, so resolve it.
                ResourceNameRef symbolName;
                bool result = getSymbol(&mapEntry.name.ident, &symbolName);
                assert(result);
                symbol.symbol.name = symbolName.toResourceName();
            } else {
                // The map entry's key (id) is a regular reference.
                symbol.symbol.id = mapEntry.name.ident;
            }

            attr->symbols.push_back(std::move(symbol));
        }
    }

tools/aapt2/Debug.cpp

0 → 100644
+181 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2015 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "Debug.h"
#include "ResourceTable.h"
#include "ResourceValues.h"
#include "Util.h"

#include <algorithm>
#include <iostream>
#include <map>
#include <memory>
#include <set>
#include <vector>

namespace aapt {

struct PrintVisitor : ConstValueVisitor {
    void visit(const Attribute& attr, ValueVisitorArgs&) override {
        std::cout << "(attr) type=";
        attr.printMask(std::cout);
        static constexpr uint32_t kMask = android::ResTable_map::TYPE_ENUM |
            android::ResTable_map::TYPE_FLAGS;
        if (attr.typeMask & kMask) {
            for (const auto& symbol : attr.symbols) {
                std::cout << "\n        "
                          << symbol.symbol.name.entry << " (" << symbol.symbol.id << ") = "
                          << symbol.value;
            }
        }
    }

    void visit(const Style& style, ValueVisitorArgs&) override {
        std::cout << "(style)";
        if (style.parent.name.isValid() || style.parent.id.isValid()) {
            std::cout << " parent=";
            if (style.parent.name.isValid()) {
                std::cout << style.parent.name << " ";
            }

            if (style.parent.id.isValid()) {
                std::cout << style.parent.id;
            }
        }

        for (const auto& entry : style.entries) {
            std::cout << "\n        ";
            if (entry.key.name.isValid()) {
                std::cout << entry.key.name.package << ":" << entry.key.name.entry;
            }

            if (entry.key.id.isValid()) {
                std::cout << "(" << entry.key.id << ")";
            }

            std::cout << "=" << *entry.value;
        }
    }

    void visit(const Array& array, ValueVisitorArgs&) override {
        array.print(std::cout);
    }

    void visit(const Plural& plural, ValueVisitorArgs&) override {
        plural.print(std::cout);
    }

    void visit(const Styleable& styleable, ValueVisitorArgs&) override {
        styleable.print(std::cout);
    }

    void visitItem(const Item& item, ValueVisitorArgs& args) override {
        item.print(std::cout);
    }
};

void Debug::printTable(const std::shared_ptr<ResourceTable>& table) {
    std::cout << "Package name=" << table->getPackage();
    if (table->getPackageId() != ResourceTable::kUnsetPackageId) {
        std::cout << " id=" << std::hex << table->getPackageId() << std::dec;
    }
    std::cout << std::endl;

    for (const auto& type : *table) {
        std::cout << "  type " << type->type;
        if (type->typeId != ResourceTableType::kUnsetTypeId) {
            std::cout << " id=" << std::hex << type->typeId << std::dec;
        }
        std::cout << " entryCount=" << type->entries.size() << std::endl;

        std::vector<const ResourceEntry*> sortedEntries;
        for (const auto& entry : type->entries) {
            auto iter = std::lower_bound(sortedEntries.begin(), sortedEntries.end(), entry.get(),
                    [](const ResourceEntry* a, const ResourceEntry* b) -> bool {
                        return a->entryId < b->entryId;
                    });
            sortedEntries.insert(iter, entry.get());
        }

        for (const ResourceEntry* entry : sortedEntries) {
            ResourceId id = { table->getPackageId(), type->typeId, entry->entryId };
            ResourceName name = { table->getPackage(), type->type, entry->name };
            std::cout << "    spec resource " << id << " " << name;
            if (entry->publicStatus.isPublic) {
                std::cout << " PUBLIC";
            }
            std::cout << std::endl;

            PrintVisitor visitor;
            for (const auto& value : entry->values) {
                std::cout << "      (" << value.config << ") ";
                value.value->accept(visitor, {});
                std::cout << std::endl;
            }
        }
    }
}

static size_t getNodeIndex(const std::vector<ResourceName>& names, const ResourceName& name) {
    auto iter = std::lower_bound(names.begin(), names.end(), name);
    assert(iter != names.end() && *iter == name);
    return std::distance(names.begin(), iter);
}

void Debug::printStyleGraph(const std::shared_ptr<ResourceTable>& table) {
    std::vector<ResourceName> names;
    std::map<ResourceName, std::set<ResourceName>> graph;

    for (const auto& type : *table) {
        for (const auto& entry : type->entries) {
            ResourceName name = { table->getPackage(), type->type, entry->name };
            for (const auto& value : entry->values) {
                visitFunc<Style>(*value.value, [&](const Style& style) {
                    if (style.parent.name.isValid()) {
                        names.push_back(style.parent.name);
                        names.push_back(name);
                        graph[style.parent.name].insert(name);
                    }
                });
            }
        }
    }

    std::sort(names.begin(), names.end());
    auto it1 = std::unique(names.begin(), names.end());
    names.resize(std::distance(names.begin(), it1));

    std::cout << "digraph styles {\n";

    for (const auto& name : names) {
        std::cout << "  node_" << getNodeIndex(names, name)
                  << " [label=\"" << name.entry << "\"];\n";
    }

    for (const auto& entry : graph) {
        const ResourceName& parent = entry.first;
        size_t parentNodeIndex = getNodeIndex(names, parent);

        for (const auto& childName : entry.second) {
            std::cout << "node_" << getNodeIndex(names, childName) << " -> "
                      << "node_" << parentNodeIndex << ";\n";
        }
    }

    std::cout << "}" << std::endl;
}

} // namespace aapt

tools/aapt2/Debug.h

0 → 100644
+33 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2015 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef AAPT_DEBUG_H
#define AAPT_DEBUG_H

#include "ResourceTable.h"

#include <memory>

namespace aapt {

struct Debug {
    static void printTable(const std::shared_ptr<ResourceTable>& table);
    static void printStyleGraph(const std::shared_ptr<ResourceTable>& table);
};

} // namespace aapt

#endif // AAPT_DEBUG_H
+9 −4
Original line number Diff line number Diff line
@@ -81,23 +81,28 @@ static std::u16string transform(const StringPiece16& symbol) {
}

struct GenArgs : ValueVisitorArgs {
    GenArgs(std::ostream* o, std::u16string* e) : out(o), entryName(e) {
    GenArgs(std::ostream* o, const std::u16string* p, std::u16string* e) :
            out(o), package(p), entryName(e) {
    }

    std::ostream* out;
    const std::u16string* package;
    std::u16string* entryName;
};

void JavaClassGenerator::visit(const Styleable& styleable, ValueVisitorArgs& a) {
    const StringPiece finalModifier = mOptions.useFinal ? " final" : "";
    std::ostream* out = static_cast<GenArgs&>(a).out;
    const std::u16string* package = static_cast<GenArgs&>(a).package;
    std::u16string* entryName = static_cast<GenArgs&>(a).entryName;

    // This must be sorted by resource ID.
    std::vector<std::pair<ResourceId, ResourceNameRef>> sortedAttributes;
    sortedAttributes.reserve(styleable.entries.size());
    for (const auto& attr : styleable.entries) {
        assert(attr.id.isValid() && "no ID set for Styleable entry");
        // If we are not encoding final attributes, the styleable entry may have no ID
        // if we are building a static library.
        assert((!mOptions.useFinal || attr.id.isValid()) && "no ID set for Styleable entry");
        assert(attr.name.isValid() && "no name set for Styleable entry");
        sortedAttributes.emplace_back(attr.id, attr.name);
    }
@@ -129,7 +134,7 @@ void JavaClassGenerator::visit(const Styleable& styleable, ValueVisitorArgs& a)
        // We may reference IDs from other packages, so prefix the entry name with
        // the package.
        const ResourceNameRef& itemName = sortedAttributes[i].second;
        if (itemName.package != mTable->getPackage()) {
        if (itemName.package != *package) {
            *out << "_" << transform(itemName.package);
        }
        *out << "_" << transform(itemName.entry) << " = " << i << ";" << std::endl;
@@ -172,7 +177,7 @@ bool JavaClassGenerator::generateType(const std::u16string& package, size_t pack

        if (type.type == ResourceType::kStyleable) {
            assert(!entry->values.empty());
            entry->values.front().value->accept(*this, GenArgs{ &out, &unmangledName });
            entry->values.front().value->accept(*this, GenArgs{ &out, &package, &unmangledName });
        } else {
            out << "        " << "public static" << finalModifier
                << " int " << transform(unmangledName) << " = " << id << ";" << std::endl;
Loading