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 30namespace android { 31 32Scope::Scope(const char* localName, const FQName& fullName, const Location& location, Scope* parent) 33 : NamedType(localName, fullName, location, parent) {} 34Scope::~Scope(){} 35 36void Scope::addType(NamedType* type) { 37 size_t index = mTypes.size(); 38 mTypes.push_back(type); 39 mTypeIndexByName[type->localName()] = index; 40} 41 42status_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 53NamedType *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 83LocalIdentifier *Scope::lookupIdentifier(const std::string & /*name*/) const { 84 return NULL; 85} 86 87bool Scope::isScope() const { 88 return true; 89} 90 91Interface *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 99bool Scope::containsInterfaces() const { 100 for (const NamedType *type : mTypes) { 101 if (type->isInterface()) { 102 return true; 103 } 104 } 105 106 return false; 107} 108 109const std::vector<Annotation*>& Scope::annotations() const { 110 return mAnnotations; 111} 112 113void Scope::setAnnotations(std::vector<Annotation*>* annotations) { 114 CHECK(mAnnotations.empty()); 115 CHECK(annotations != nullptr); 116 mAnnotations = *annotations; 117} 118 119std::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 125std::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 134void 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 149void 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 168void Scope::emitGlobalTypeDeclarations(Formatter& out) const { 169 for (const Type* type : mTypes) { 170 type->emitGlobalTypeDeclarations(out); 171 } 172} 173 174void Scope::emitPackageTypeDeclarations(Formatter& out) const { 175 for (const Type* type : mTypes) { 176 type->emitPackageTypeDeclarations(out); 177 } 178} 179 180void Scope::emitPackageHwDeclarations(Formatter& out) const { 181 for (const Type* type : mTypes) { 182 type->emitPackageHwDeclarations(out); 183 } 184} 185 186void 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 197void Scope::emitTypeDefinitions(Formatter& out, const std::string& prefix) const { 198 for (const Type* type : mTypes) { 199 type->emitTypeDefinitions(out, prefix); 200 } 201} 202 203const std::vector<NamedType *> &Scope::getSubTypes() const { 204 return mTypes; 205} 206 207void Scope::emitVtsTypeDeclarations(Formatter& out) const { 208 for (const Type* type : mTypes) { 209 type->emitVtsTypeDeclarations(out); 210 } 211} 212 213bool 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 222void Scope::appendToExportedTypesVector( 223 std::vector<const Type *> *exportedTypes) const { 224 for (const Type* type : mTypes) { 225 type->appendToExportedTypesVector(exportedTypes); 226 } 227} 228 229//////////////////////////////////////// 230 231RootScope::RootScope(const char* localName, const FQName& fullName, const Location& location, 232 Scope* parent) 233 : Scope(localName, fullName, location, parent) {} 234RootScope::~RootScope() {} 235 236std::string RootScope::typeName() const { 237 return "(root scope)"; 238} 239 240status_t RootScope::validate() const { 241 CHECK(annotations().empty()); 242 return Scope::validate(); 243} 244 245//////////////////////////////////////// 246 247LocalIdentifier::LocalIdentifier(){} 248LocalIdentifier::~LocalIdentifier(){} 249 250bool LocalIdentifier::isEnumValue() const { 251 return false; 252} 253 254const LocalIdentifier* LocalIdentifier::resolve() const { 255 return this; 256} 257 258LocalIdentifier* LocalIdentifier::resolve() { 259 return this; 260} 261 262ConstantExpression* LocalIdentifier::constExpr() const { 263 return nullptr; 264} 265 266} // namespace android 267 268