diff options
author | Adam Lesinski <adamlesinski@google.com> | 2015-11-16 17:35:44 -0800 |
---|---|---|
committer | Adam Lesinski <adamlesinski@google.com> | 2015-11-19 14:46:53 -0800 |
commit | 467f171315f9c2037fcd3eb5edcfabc40671bf7b (patch) | |
tree | 3b14762e3d9e42a660479d0d5722883b391f835b /tools/aapt2/link/XmlReferenceLinker.cpp | |
parent | abf83cbe4f63cd76043aab89cd0e08525560fea2 (diff) |
AAPT2: Fail compiling when private symbols are referenced
Also moved some XML specific stuff into its own directory,
and refactored ReferenceLinker a bit.
Change-Id: I912247a82023c1bbf72dc191fbdaf62858cbec0c
Diffstat (limited to 'tools/aapt2/link/XmlReferenceLinker.cpp')
-rw-r--r-- | tools/aapt2/link/XmlReferenceLinker.cpp | 92 |
1 files changed, 61 insertions, 31 deletions
diff --git a/tools/aapt2/link/XmlReferenceLinker.cpp b/tools/aapt2/link/XmlReferenceLinker.cpp index caab9b8a4684..a26d7637ab3a 100644 --- a/tools/aapt2/link/XmlReferenceLinker.cpp +++ b/tools/aapt2/link/XmlReferenceLinker.cpp @@ -17,51 +17,91 @@ #include "Diagnostics.h" #include "ResourceUtils.h" #include "SdkConstants.h" -#include "XmlDom.h" - #include "link/Linkers.h" -#include "link/ReferenceLinkerVisitor.h" +#include "link/ReferenceLinker.h" #include "process/IResourceTableConsumer.h" #include "process/SymbolTable.h" #include "util/Util.h" +#include "xml/XmlDom.h" namespace aapt { namespace { -class XmlReferenceLinkerVisitor : public xml::PackageAwareVisitor { +/** + * Visits all references (including parents of styles, references in styles, arrays, etc) and + * links their symbolic name to their Resource ID, performing mangling and package aliasing + * as needed. + */ +class ReferenceVisitor : public ValueVisitor { +private: + IAaptContext* mContext; + ISymbolTable* mSymbols; + xml::IPackageDeclStack* mDecls; + CallSite* mCallSite; + bool mError; + +public: + using ValueVisitor::visit; + + ReferenceVisitor(IAaptContext* context, ISymbolTable* symbols, xml::IPackageDeclStack* decls, + CallSite* callSite) : + mContext(context), mSymbols(symbols), mDecls(decls), mCallSite(callSite), + mError(false) { + } + + void visit(Reference* ref) override { + if (!ReferenceLinker::linkReference(ref, mContext, mSymbols, mDecls, mCallSite)) { + mError = true; + } + } + + bool hasError() const { + return mError; + } +}; + +/** + * Visits each xml Element and compiles the attributes within. + */ +class XmlVisitor : public xml::PackageAwareVisitor { private: IAaptContext* mContext; ISymbolTable* mSymbols; Source mSource; std::set<int>* mSdkLevelsFound; - ReferenceLinkerVisitor mReferenceLinkerVisitor; + CallSite* mCallSite; + ReferenceVisitor mReferenceVisitor; bool mError = false; public: using xml::PackageAwareVisitor::visit; - XmlReferenceLinkerVisitor(IAaptContext* context, ISymbolTable* symbols, const Source& source, - std::set<int>* sdkLevelsFound) : + XmlVisitor(IAaptContext* context, ISymbolTable* symbols, const Source& source, + std::set<int>* sdkLevelsFound, CallSite* callSite) : mContext(context), mSymbols(symbols), mSource(source), mSdkLevelsFound(sdkLevelsFound), - mReferenceLinkerVisitor(context, symbols, this) { + mCallSite(callSite), mReferenceVisitor(context, symbols, this, callSite) { } void visit(xml::Element* el) override { const Source source = mSource.withLine(el->lineNumber); for (xml::Attribute& attr : el->attributes) { - Maybe<std::u16string> maybePackage = - util::extractPackageFromNamespace(attr.namespaceUri); + Maybe<xml::ExtractedPackage> maybePackage = + xml::extractPackageFromNamespace(attr.namespaceUri); if (maybePackage) { // There is a valid package name for this attribute. We will look this up. - StringPiece16 package = maybePackage.value(); + StringPiece16 package = maybePackage.value().package; if (package.empty()) { // Empty package means the 'current' or 'local' package. package = mContext->getCompilationPackage(); } - attr.compiledAttribute = compileAttribute( - ResourceName{ package.toString(), ResourceType::kAttr, attr.name }); + Reference attrRef(ResourceNameRef(package, ResourceType::kAttr, attr.name)); + attrRef.privateReference = maybePackage.value().privateNamespace; + + std::string errStr; + attr.compiledAttribute = ReferenceLinker::compileXmlAttribute( + attrRef, mContext->getNameMangler(), mSymbols, mCallSite, &errStr); // Convert the string value into a compiled Value if this is a valid attribute. if (attr.compiledAttribute) { @@ -87,7 +127,7 @@ public: } else { mContext->getDiagnostics()->error(DiagMessage(source) << "attribute '" << package << ":" - << attr.name << "' was not found"); + << attr.name << "' " << errStr); mError = true; } @@ -99,7 +139,7 @@ public: if (attr.compiledValue) { // With a compiledValue, we must resolve the reference and assign it an ID. attr.compiledValue->setSource(source); - attr.compiledValue->accept(&mReferenceLinkerVisitor); + attr.compiledValue->accept(&mReferenceVisitor); } } @@ -107,28 +147,18 @@ public: xml::PackageAwareVisitor::visit(el); } - Maybe<xml::AaptAttribute> compileAttribute(const ResourceName& name) { - Maybe<ResourceName> mangledName = mContext->getNameMangler()->mangleName(name); - if (const ISymbolTable::Symbol* symbol = mSymbols->findByName( - mangledName ? mangledName.value() : name)) { - if (symbol->attribute) { - return xml::AaptAttribute{ symbol->id, *symbol->attribute }; - } - } - return {}; - } - - inline bool hasError() { - return mError || mReferenceLinkerVisitor.hasError(); + bool hasError() { + return mError || mReferenceVisitor.hasError(); } }; } // namespace -bool XmlReferenceLinker::consume(IAaptContext* context, XmlResource* resource) { +bool XmlReferenceLinker::consume(IAaptContext* context, xml::XmlResource* resource) { mSdkLevelsFound.clear(); - XmlReferenceLinkerVisitor visitor(context, context->getExternalSymbols(), resource->file.source, - &mSdkLevelsFound); + CallSite callSite = { resource->file.name }; + XmlVisitor visitor(context, context->getExternalSymbols(), resource->file.source, + &mSdkLevelsFound, &callSite); if (resource->root) { resource->root->accept(&visitor); return !visitor.hasError(); |