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 "Annotation.h" 20 #include "ConstantExpression.h" 21 #include "Interface.h" 22 23 #include <android-base/logging.h> 24 #include <hidl-util/Formatter.h> 25 #include <hidl-util/StringHelper.h> 26 #include <algorithm> 27 #include <iostream> 28 #include <vector> 29 30 namespace android { 31 32 Scope::Scope(const char* localName, const FQName& fullName, const Location& location, Scope* parent) 33 : NamedType(localName, fullName, location, parent) {} 34 Scope::~Scope(){} 35 36 void Scope::addType(NamedType* type) { 37 size_t index = mTypes.size(); 38 mTypes.push_back(type); 39 mTypeIndexByName[type->localName()] = index; 40 } 41 42 status_t Scope::validateUniqueNames() const { 43 for (const auto* type : mTypes) { 44 if (mTypes[mTypeIndexByName.at(type->localName())] != type) { 45 std::cerr << "ERROR: A type named '" << type->localName() 46 << "' is already declared in the scope at " << type->location() << std::endl; 47 return UNKNOWN_ERROR; 48 } 49 } 50 return OK; 51 } 52 53 NamedType *Scope::lookupType(const FQName &fqName) const { 54 CHECK(fqName.package().empty() && fqName.version().empty()); 55 if (!fqName.valueName().empty()) { 56 std::cerr << "ERROR: " << fqName.string() << " does not refer to a type." << std::endl; 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; 79 CHECK(FQName::parse(StringHelper::JoinStrings(names, "."), &innerName)); 80 return outerScope->lookupType(innerName); 81 } 82 83 LocalIdentifier *Scope::lookupIdentifier(const std::string & /*name*/) const { 84 return NULL; 85 } 86 87 bool Scope::isScope() const { 88 return true; 89 } 90 91 Interface *Scope::getInterface() const { 92 if (mTypes.size() == 1 && mTypes[0]->isInterface()) { 93 return static_cast<Interface *>(mTypes[0]); 94 } 95 96 return NULL; 97 } 98 99 bool Scope::containsInterfaces() const { 100 for (const NamedType *type : mTypes) { 101 if (type->isInterface()) { 102 return true; 103 } 104 } 105 106 return false; 107 } 108 109 const std::vector<Annotation*>& Scope::annotations() const { 110 return mAnnotations; 111 } 112 113 void Scope::setAnnotations(std::vector<Annotation*>* annotations) { 114 CHECK(mAnnotations.empty()); 115 CHECK(annotations != nullptr); 116 mAnnotations = *annotations; 117 } 118 119 std::vector<const Type*> Scope::getDefinedTypes() const { 120 std::vector<const Type*> ret; 121 ret.insert(ret.end(), mTypes.begin(), mTypes.end()); 122 return ret; 123 } 124 125 std::vector<const ConstantExpression*> Scope::getConstantExpressions() const { 126 std::vector<const ConstantExpression*> ret; 127 for (const auto* annotation : mAnnotations) { 128 const auto& retAnnotation = annotation->getConstantExpressions(); 129 ret.insert(ret.end(), retAnnotation.begin(), retAnnotation.end()); 130 } 131 return ret; 132 } 133 134 void Scope::topologicalReorder(const std::unordered_map<const Type*, size_t>& reversedOrder) { 135 auto less = [&](const Type* lhs, const Type* rhs) { 136 return reversedOrder.at(lhs) < reversedOrder.at(rhs); 137 }; 138 139 if (std::is_sorted(mTypes.begin(), mTypes.end(), less)) return; 140 141 mTypeOrderChanged = true; 142 std::sort(mTypes.begin(), mTypes.end(), less); 143 144 for (size_t i = 0; i != mTypes.size(); ++i) { 145 mTypeIndexByName.at(mTypes[i]->localName()) = i; 146 } 147 } 148 149 void Scope::emitTypeDeclarations(Formatter& out) const { 150 if (mTypes.empty()) return; 151 152 out << "// Forward declaration for forward reference support:\n"; 153 for (const Type* type : mTypes) { 154 type->emitTypeForwardDeclaration(out); 155 } 156 out << "\n"; 157 158 if (mTypeOrderChanged) { 159 out << "// Order of inner types was changed for forward reference support.\n\n"; 160 } 161 162 for (const Type* type : mTypes) { 163 type->emitDocComment(out); 164 type->emitTypeDeclarations(out); 165 } 166 } 167 168 void Scope::emitGlobalTypeDeclarations(Formatter& out) const { 169 for (const Type* type : mTypes) { 170 type->emitGlobalTypeDeclarations(out); 171 } 172 } 173 174 void Scope::emitPackageTypeDeclarations(Formatter& out) const { 175 for (const Type* type : mTypes) { 176 type->emitPackageTypeDeclarations(out); 177 } 178 } 179 180 void Scope::emitPackageHwDeclarations(Formatter& out) const { 181 for (const Type* type : mTypes) { 182 type->emitPackageHwDeclarations(out); 183 } 184 } 185 186 void Scope::emitJavaTypeDeclarations(Formatter& out, bool atTopLevel) const { 187 if (mTypeOrderChanged) { 188 out << "// Order of inner types was changed for forward reference support.\n\n"; 189 } 190 191 for (const Type* type : mTypes) { 192 type->emitDocComment(out); 193 type->emitJavaTypeDeclarations(out, atTopLevel); 194 } 195 } 196 197 void Scope::emitTypeDefinitions(Formatter& out, const std::string& prefix) const { 198 for (const Type* type : mTypes) { 199 type->emitTypeDefinitions(out, prefix); 200 } 201 } 202 203 const std::vector<NamedType *> &Scope::getSubTypes() const { 204 return mTypes; 205 } 206 207 void Scope::emitVtsTypeDeclarations(Formatter& out) const { 208 for (const Type* type : mTypes) { 209 type->emitVtsTypeDeclarations(out); 210 } 211 } 212 213 bool Scope::deepIsJavaCompatible(std::unordered_set<const Type*>* visited) const { 214 for (const Type* type : mTypes) { 215 if (!type->isJavaCompatible(visited)) { 216 return false; 217 } 218 } 219 return Type::deepIsJavaCompatible(visited); 220 } 221 222 void Scope::appendToExportedTypesVector( 223 std::vector<const Type *> *exportedTypes) const { 224 for (const Type* type : mTypes) { 225 type->appendToExportedTypesVector(exportedTypes); 226 } 227 } 228 229 //////////////////////////////////////// 230 231 RootScope::RootScope(const char* localName, const FQName& fullName, const Location& location, 232 Scope* parent) 233 : Scope(localName, fullName, location, parent) {} 234 RootScope::~RootScope() {} 235 236 std::string RootScope::typeName() const { 237 return "(root scope)"; 238 } 239 240 status_t RootScope::validate() const { 241 CHECK(annotations().empty()); 242 return Scope::validate(); 243 } 244 245 //////////////////////////////////////// 246 247 LocalIdentifier::LocalIdentifier(){} 248 LocalIdentifier::~LocalIdentifier(){} 249 250 bool LocalIdentifier::isEnumValue() const { 251 return false; 252 } 253 254 const LocalIdentifier* LocalIdentifier::resolve() const { 255 return this; 256 } 257 258 LocalIdentifier* LocalIdentifier::resolve() { 259 return this; 260 } 261 262 ConstantExpression* LocalIdentifier::constExpr() const { 263 return nullptr; 264 } 265 266 } // namespace android 267 268