Home | History | Annotate | Download | only in hidl
      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