Merge "AAPT2: Include package name of attributes in styleable from another package" into mnc-dev

This commit is contained in:
Adam Lesinski
2015-05-04 23:57:21 +00:00
committed by Android (Google) Code Review
7 changed files with 143 additions and 69 deletions

View File

@@ -94,12 +94,12 @@ void JavaClassGenerator::visit(const Styleable& styleable, ValueVisitorArgs& a)
std::u16string* entryName = static_cast<GenArgs&>(a).entryName;
// This must be sorted by resource ID.
std::vector<std::pair<ResourceId, StringPiece16>> sortedAttributes;
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");
assert(attr.name.isValid() && "no name set for Styleable entry");
sortedAttributes.emplace_back(attr.id, attr.name.entry);
sortedAttributes.emplace_back(attr.id, attr.name);
}
std::sort(sortedAttributes.begin(), sortedAttributes.end());
@@ -124,8 +124,15 @@ void JavaClassGenerator::visit(const Styleable& styleable, ValueVisitorArgs& a)
for (size_t i = 0; i < attrCount; i++) {
*out << " "
<< "public static" << finalModifier
<< " int " << transform(*entryName) << "_" << transform(sortedAttributes[i].second)
<< " = " << i << ";" << std::endl;
<< " int " << transform(*entryName);
// 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()) {
*out << "_" << transform(itemName.package);
}
*out << "_" << transform(itemName.entry) << " = " << i << ";" << std::endl;
}
}

View File

@@ -16,8 +16,9 @@
#include "JavaClassGenerator.h"
#include "Linker.h"
#include "Resolver.h"
#include "MockResolver.h"
#include "ResourceTable.h"
#include "ResourceTableResolver.h"
#include "ResourceValues.h"
#include "Util.h"
@@ -84,7 +85,7 @@ TEST_F(JavaClassGeneratorTest, TransformInvalidJavaIdentifierCharacter) {
output.find("public static final int hey_dude_cool_attr = 0;"));
}
/*
TEST_F(JavaClassGeneratorTest, EmitPackageMangledSymbols) {
ASSERT_TRUE(addResource(ResourceName{ {}, ResourceType::kId, u"foo" },
ResourceId{ 0x01, 0x02, 0x0000 }));
@@ -94,9 +95,8 @@ TEST_F(JavaClassGeneratorTest, EmitPackageMangledSymbols) {
SourceLine{ "lib.xml", 33 }, util::make_unique<Id>()));
ASSERT_TRUE(mTable->merge(std::move(table)));
std::shared_ptr<Resolver> resolver = std::make_shared<Resolver>(mTable,
std::make_shared<const android::AssetManager>());
Linker linker(mTable, resolver);
Linker linker(mTable, std::make_shared<MockResolver>(mTable,
std::map<ResourceName, ResourceId>()));
ASSERT_TRUE(linker.linkAndValidate());
JavaClassGenerator generator(mTable, {});
@@ -112,6 +112,34 @@ TEST_F(JavaClassGeneratorTest, EmitPackageMangledSymbols) {
output = out.str();
EXPECT_NE(std::string::npos, output.find("int test ="));
EXPECT_EQ(std::string::npos, output.find("int foo ="));
}*/
}
TEST_F(JavaClassGeneratorTest, EmitOtherPackagesAttributesInStyleable) {
std::unique_ptr<Styleable> styleable = util::make_unique<Styleable>();
styleable->entries.emplace_back(ResourceNameRef{ mTable->getPackage(),
ResourceType::kAttr,
u"bar" });
styleable->entries.emplace_back(ResourceNameRef{ u"com.lib", ResourceType::kAttr, u"bar" });
ASSERT_TRUE(mTable->addResource(ResourceName{ {}, ResourceType::kStyleable, u"Foo" }, {}, {},
std::move(styleable)));
std::shared_ptr<IResolver> resolver = std::make_shared<MockResolver>(mTable,
std::map<ResourceName, ResourceId>({
{ ResourceName{ u"android", ResourceType::kAttr, u"bar" },
ResourceId{ 0x01, 0x01, 0x0000 } },
{ ResourceName{ u"com.lib", ResourceType::kAttr, u"bar" },
ResourceId{ 0x02, 0x01, 0x0000 } }}));
Linker linker(mTable, resolver);
ASSERT_TRUE(linker.linkAndValidate());
JavaClassGenerator generator(mTable, {});
std::stringstream out;
EXPECT_TRUE(generator.generate(mTable->getPackage(), out));
std::string output = out.str();
EXPECT_NE(std::string::npos, output.find("int Foo_bar ="));
EXPECT_NE(std::string::npos, output.find("int Foo_com_lib_bar ="));
}
} // namespace aapt

View File

@@ -0,0 +1,93 @@
/*
* 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_MOCK_RESOLVER_H
#define AAPT_MOCK_RESOLVER_H
#include "Maybe.h"
#include "Resolver.h"
#include "Resource.h"
#include "ResourceTable.h"
#include "ResourceTableResolver.h"
#include "ResourceValues.h"
#include "StringPiece.h"
#include <map>
#include <string>
namespace aapt {
struct MockResolver : public IResolver {
MockResolver(const std::shared_ptr<ResourceTable>& table,
const std::map<ResourceName, ResourceId>& items) :
mResolver(std::make_shared<ResourceTableResolver>(
table, std::make_shared<const android::AssetManager>())),
mAttr(false, android::ResTable_map::TYPE_ANY), mItems(items) {
}
virtual Maybe<ResourceId> findId(const ResourceName& name) override {
Maybe<ResourceId> result = mResolver->findId(name);
if (result) {
return result;
}
const auto iter = mItems.find(name);
if (iter != mItems.end()) {
return iter->second;
}
return {};
}
virtual Maybe<Entry> findAttribute(const ResourceName& name) override {
Maybe<Entry> tableResult = mResolver->findAttribute(name);
if (tableResult) {
return tableResult;
}
Maybe<ResourceId> result = findId(name);
if (result) {
if (name.type == ResourceType::kAttr) {
return Entry{ result.value(), &mAttr };
} else {
return Entry{ result.value() };
}
}
return {};
}
virtual Maybe<ResourceName> findName(ResourceId resId) override {
Maybe<ResourceName> result = mResolver->findName(resId);
if (result) {
return result;
}
for (auto& p : mItems) {
if (p.second == resId) {
return p.first;
}
}
return {};
}
private:
std::shared_ptr<ResourceTableResolver> mResolver;
Attribute mAttr;
std::map<ResourceName, ResourceId> mItems;
};
} // namespace aapt
#endif // AAPT_MOCK_RESOLVER_H

View File

@@ -51,12 +51,6 @@ public:
const Attribute* attr;
};
/**
* Return the package to use when none is specified. This
* is the package name of the app being built.
*/
virtual const std::u16string& getDefaultPackage() const = 0;
/**
* Returns a ResourceID if the name is found. The ResourceID
* may not be valid if the resource was not assigned an ID.

View File

@@ -96,6 +96,8 @@ struct ResourceNameRef {
ResourceNameRef(ResourceNameRef&&) = default;
ResourceNameRef(const ResourceName& rhs);
ResourceNameRef(const StringPiece16& p, ResourceType t, const StringPiece16& e);
ResourceNameRef& operator=(const ResourceNameRef& rhs) = default;
ResourceNameRef& operator=(ResourceNameRef&& rhs) = default;
ResourceNameRef& operator=(const ResourceName& rhs);
ResourceName toResourceName() const;

View File

@@ -45,8 +45,6 @@ public:
ResourceTableResolver(const ResourceTableResolver&) = delete; // Not copyable.
virtual const std::u16string& getDefaultPackage() const override;
virtual Maybe<ResourceId> findId(const ResourceName& name) override;
virtual Maybe<Entry> findAttribute(const ResourceName& name) override;
@@ -69,10 +67,6 @@ private:
std::unordered_set<std::u16string> mIncludedPackages;
};
inline const std::u16string& ResourceTableResolver::getDefaultPackage() const {
return mTable->getPackage();
}
inline const android::ResTable& ResourceTableResolver::getResTable() const {
return mSources->getResources(false);
}

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
#include "Resolver.h"
#include "MockResolver.h"
#include "ResourceTable.h"
#include "ResourceValues.h"
#include "SourceXmlPullParser.h"
@@ -33,55 +33,11 @@ namespace aapt {
constexpr const char* kXmlPreamble = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";
struct MockResolver : public IResolver {
MockResolver(const StringPiece16& defaultPackage,
const std::map<ResourceName, ResourceId>& items) :
mPackage(defaultPackage.toString()), mAttr(false, ResTable_map::TYPE_ANY),
mItems(items) {
}
virtual const std::u16string& getDefaultPackage() const override {
return mPackage;
}
virtual Maybe<ResourceId> findId(const ResourceName& name) override {
const auto iter = mItems.find(name);
if (iter != mItems.end()) {
return iter->second;
}
return {};
}
virtual Maybe<Entry> findAttribute(const ResourceName& name) override {
Maybe<ResourceId> result = findId(name);
if (result) {
if (name.type == ResourceType::kAttr) {
return Entry{ result.value(), &mAttr };
} else {
return Entry{ result.value() };
}
}
return {};
}
virtual Maybe<ResourceName> findName(ResourceId resId) override {
for (auto& p : mItems) {
if (p.second == resId) {
return p.first;
}
}
return {};
}
std::u16string mPackage;
Attribute mAttr;
std::map<ResourceName, ResourceId> mItems;
};
class XmlFlattenerTest : public ::testing::Test {
public:
virtual void SetUp() override {
std::shared_ptr<IResolver> resolver = std::make_shared<MockResolver>(u"android",
std::shared_ptr<IResolver> resolver = std::make_shared<MockResolver>(
std::make_shared<ResourceTable>(),
std::map<ResourceName, ResourceId>({
{ ResourceName{ u"android", ResourceType::kAttr, u"attr" },
ResourceId{ 0x01010000u } },