1 /* 2 * Copyright (C) 2016 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 #include "Scope.h" 18 19 #include "Interface.h" 20 21 #include <android-base/logging.h> 22 #include <hidl-util/Formatter.h> 23 #include <vector> 24 25 namespace android { 26 27 Scope::Scope(const char *localName, 28 const Location &location) 29 : NamedType(localName, location) { 30 } 31 Scope::~Scope(){} 32 33 bool Scope::addType(NamedType *type, std::string *errorMsg) { 34 const std::string &localName = type->localName(); 35 36 auto it = mTypeIndexByName.find(localName); 37 38 if (it != mTypeIndexByName.end()) { 39 *errorMsg = "A type named '"; 40 (*errorMsg) += localName; 41 (*errorMsg) += "' is already declared in the current scope."; 42 43 return false; 44 } 45 46 size_t index = mTypes.size(); 47 mTypes.push_back(type); 48 mTypeIndexByName[localName] = index; 49 50 return true; 51 } 52 53 NamedType *Scope::lookupType(const FQName &fqName) const { 54 CHECK(fqName.package().empty() && fqName.version().empty()); 55 if (!fqName.valueName().empty()) { 56 LOG(WARNING) << fqName.string() << " does not refer to a type."; 57 return nullptr; 58 } 59 std::vector<std::string> names = fqName.names(); 60 CHECK_GT(names.size(), 0u); 61 auto it = mTypeIndexByName.find(names[0]); 62 63 if (it == mTypeIndexByName.end()) { 64 return nullptr; 65 } 66 67 NamedType *outerType = mTypes[it->second]; 68 if (names.size() == 1) { 69 return outerType; 70 } 71 if (!outerType->isScope()) { 72 // more than one names, but the first name is not a scope 73 return nullptr; 74 } 75 Scope *outerScope = static_cast<Scope *>(outerType); 76 // *slowly* pop first element 77 names.erase(names.begin()); 78 FQName innerName(names); 79 return outerScope->lookupType(innerName); 80 } 81 82 LocalIdentifier *Scope::lookupIdentifier(const std::string & /*name*/) const { 83 return NULL; 84 } 85 86 bool Scope::isScope() const { 87 return true; 88 } 89 90 Interface *Scope::getInterface() const { 91 if (mTypes.size() == 1 && mTypes[0]->isInterface()) { 92 return static_cast<Interface *>(mTypes[0]); 93 } 94 95 return NULL; 96 } 97 98 bool Scope::containsSingleInterface(std::string *ifaceName) const { 99 Interface *iface = getInterface(); 100 101 if (iface != NULL) { 102 *ifaceName = iface->localName(); 103 return true; 104 } 105 106 return false; 107 } 108 109 bool Scope::containsInterfaces() const { 110 for (const NamedType *type : mTypes) { 111 if (type->isInterface()) { 112 return true; 113 } 114 } 115 116 return false; 117 } 118 119 status_t Scope::forEachType(std::function<status_t(Type *)> func) const { 120 for (size_t i = 0; i < mTypes.size(); ++i) { 121 status_t err = func(mTypes[i]); 122 123 if (err != OK) { 124 return err; 125 } 126 } 127 128 return OK; 129 } 130 131 status_t Scope::emitTypeDeclarations(Formatter &out) const { 132 return forEachType([&](Type *type) { 133 return type->emitTypeDeclarations(out); 134 }); 135 } 136 137 status_t Scope::emitGlobalTypeDeclarations(Formatter &out) const { 138 return forEachType([&](Type *type) { 139 return type->emitGlobalTypeDeclarations(out); 140 }); 141 } 142 143 status_t Scope::emitGlobalHwDeclarations(Formatter &out) const { 144 return forEachType([&](Type *type) { 145 return type->emitGlobalHwDeclarations(out); 146 }); 147 } 148 149 status_t Scope::emitJavaTypeDeclarations( 150 Formatter &out, bool atTopLevel) const { 151 return forEachType([&](Type *type) { 152 return type->emitJavaTypeDeclarations(out, atTopLevel); 153 }); 154 } 155 156 status_t Scope::emitTypeDefinitions( 157 Formatter &out, const std::string prefix) const { 158 return forEachType([&](Type *type) { 159 return type->emitTypeDefinitions(out, prefix); 160 }); 161 } 162 163 const std::vector<NamedType *> &Scope::getSubTypes() const { 164 return mTypes; 165 } 166 167 status_t Scope::emitVtsTypeDeclarations(Formatter &out) const { 168 return forEachType([&](Type *type) { 169 return type->emitVtsTypeDeclarations(out); 170 }); 171 } 172 173 bool Scope::isJavaCompatible() const { 174 for (const auto &type : mTypes) { 175 if (!type->isJavaCompatible()) { 176 return false; 177 } 178 } 179 180 return true; 181 } 182 183 bool Scope::containsPointer() const { 184 for (const auto &type : mTypes) { 185 if (type->containsPointer()) { 186 return true; 187 } 188 } 189 190 return false; 191 } 192 193 void Scope::appendToExportedTypesVector( 194 std::vector<const Type *> *exportedTypes) const { 195 forEachType([&](Type *type) { 196 type->appendToExportedTypesVector(exportedTypes); 197 return OK; 198 }); 199 } 200 201 LocalIdentifier::LocalIdentifier(){} 202 LocalIdentifier::~LocalIdentifier(){} 203 204 bool LocalIdentifier::isEnumValue() const { 205 return false; 206 } 207 208 } // namespace android 209 210