1 /* 2 * Copyright (C) 2015 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef AAPT_TEST_CONTEXT_H 18 #define AAPT_TEST_CONTEXT_H 19 20 #include "NameMangler.h" 21 #include "util/Util.h" 22 23 #include "process/IResourceTableConsumer.h" 24 #include "process/SymbolTable.h" 25 #include "test/Common.h" 26 27 #include <cassert> 28 #include <list> 29 30 namespace aapt { 31 namespace test { 32 33 class Context : public IAaptContext { 34 public: getExternalSymbols()35 SymbolTable* getExternalSymbols() override { 36 return &mSymbols; 37 } 38 getDiagnostics()39 IDiagnostics* getDiagnostics() override { 40 return &mDiagnostics; 41 } 42 getCompilationPackage()43 const std::u16string& getCompilationPackage() override { 44 assert(mCompilationPackage && "package name not set"); 45 return mCompilationPackage.value(); 46 } 47 getPackageId()48 uint8_t getPackageId() override { 49 assert(mPackageId && "package ID not set"); 50 return mPackageId.value(); 51 } 52 getNameMangler()53 NameMangler* getNameMangler() override { 54 return &mNameMangler; 55 } 56 verbose()57 bool verbose() override { 58 return false; 59 } 60 61 private: 62 friend class ContextBuilder; 63 Context()64 Context() : mNameMangler({}) { 65 } 66 67 Maybe<std::u16string> mCompilationPackage; 68 Maybe<uint8_t> mPackageId; 69 StdErrDiagnostics mDiagnostics; 70 SymbolTable mSymbols; 71 NameMangler mNameMangler; 72 }; 73 74 class ContextBuilder { 75 private: 76 std::unique_ptr<Context> mContext = std::unique_ptr<Context>(new Context()); 77 78 public: setCompilationPackage(const StringPiece16 & package)79 ContextBuilder& setCompilationPackage(const StringPiece16& package) { 80 mContext->mCompilationPackage = package.toString(); 81 return *this; 82 } 83 setPackageId(uint8_t id)84 ContextBuilder& setPackageId(uint8_t id) { 85 mContext->mPackageId = id; 86 return *this; 87 } 88 setNameManglerPolicy(NameManglerPolicy policy)89 ContextBuilder& setNameManglerPolicy(NameManglerPolicy policy) { 90 mContext->mNameMangler = NameMangler(policy); 91 return *this; 92 } 93 addSymbolSource(std::unique_ptr<ISymbolSource> src)94 ContextBuilder& addSymbolSource(std::unique_ptr<ISymbolSource> src) { 95 mContext->getExternalSymbols()->appendSource(std::move(src)); 96 return *this; 97 } 98 build()99 std::unique_ptr<Context> build() { 100 return std::move(mContext); 101 } 102 }; 103 104 class StaticSymbolSourceBuilder { 105 public: 106 StaticSymbolSourceBuilder& addPublicSymbol(const StringPiece16& name, ResourceId id, 107 std::unique_ptr<Attribute> attr = {}) { 108 std::unique_ptr<SymbolTable::Symbol> symbol = util::make_unique<SymbolTable::Symbol>( 109 id, std::move(attr), true); 110 mSymbolSource->mNameMap[parseNameOrDie(name)] = symbol.get(); 111 mSymbolSource->mIdMap[id] = symbol.get(); 112 mSymbolSource->mSymbols.push_back(std::move(symbol)); 113 return *this; 114 } 115 116 StaticSymbolSourceBuilder& addSymbol(const StringPiece16& name, ResourceId id, 117 std::unique_ptr<Attribute> attr = {}) { 118 std::unique_ptr<SymbolTable::Symbol> symbol = util::make_unique<SymbolTable::Symbol>( 119 id, std::move(attr), false); 120 mSymbolSource->mNameMap[parseNameOrDie(name)] = symbol.get(); 121 mSymbolSource->mIdMap[id] = symbol.get(); 122 mSymbolSource->mSymbols.push_back(std::move(symbol)); 123 return *this; 124 } 125 build()126 std::unique_ptr<ISymbolSource> build() { 127 return std::move(mSymbolSource); 128 } 129 130 private: 131 class StaticSymbolSource : public ISymbolSource { 132 public: 133 StaticSymbolSource() = default; 134 findByName(const ResourceName & name)135 std::unique_ptr<SymbolTable::Symbol> findByName(const ResourceName& name) override { 136 auto iter = mNameMap.find(name); 137 if (iter != mNameMap.end()) { 138 return cloneSymbol(iter->second); 139 } 140 return nullptr; 141 } 142 findById(ResourceId id)143 std::unique_ptr<SymbolTable::Symbol> findById(ResourceId id) override { 144 auto iter = mIdMap.find(id); 145 if (iter != mIdMap.end()) { 146 return cloneSymbol(iter->second); 147 } 148 return nullptr; 149 } 150 151 std::list<std::unique_ptr<SymbolTable::Symbol>> mSymbols; 152 std::map<ResourceName, SymbolTable::Symbol*> mNameMap; 153 std::map<ResourceId, SymbolTable::Symbol*> mIdMap; 154 155 private: cloneSymbol(SymbolTable::Symbol * sym)156 std::unique_ptr<SymbolTable::Symbol> cloneSymbol(SymbolTable::Symbol* sym) { 157 std::unique_ptr<SymbolTable::Symbol> clone = util::make_unique<SymbolTable::Symbol>(); 158 clone->id = sym->id; 159 if (sym->attribute) { 160 clone->attribute = std::unique_ptr<Attribute>(sym->attribute->clone(nullptr)); 161 } 162 clone->isPublic = sym->isPublic; 163 return clone; 164 } 165 166 DISALLOW_COPY_AND_ASSIGN(StaticSymbolSource); 167 }; 168 169 std::unique_ptr<StaticSymbolSource> mSymbolSource = util::make_unique<StaticSymbolSource>(); 170 }; 171 172 } // namespace test 173 } // namespace aapt 174 175 #endif /* AAPT_TEST_CONTEXT_H */ 176