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 #ifndef AST_H_ 18 19 #define AST_H_ 20 21 #include <android-base/macros.h> 22 #include <hidl-hash/Hash.h> 23 #include <hidl-util/FQName.h> 24 #include <functional> 25 #include <map> 26 #include <set> 27 #include <string> 28 #include <vector> 29 30 #include "Scope.h" 31 #include "Type.h" 32 33 namespace android { 34 35 struct Coordinator; 36 struct ConstantExpression; 37 struct EnumValue; 38 struct Formatter; 39 struct Interface; 40 struct Location; 41 struct Method; 42 struct NamedType; 43 template <class T> 44 struct NamedReference; 45 struct Type; 46 47 struct AST { 48 AST(const Coordinator* coordinator, const Hash* fileHash); 49 50 bool setPackage(const char *package); 51 bool addImport(const char *import); 52 53 // package and version really. 54 FQName package() const; 55 bool isInterface() const; 56 bool containsInterfaces() const; 57 58 // Adds package, version and scope stack to local name 59 FQName makeFullName(const char* localName, Scope* scope) const; 60 61 void addScopedType(NamedType* type, Scope* scope); 62 63 const std::string& getFilename() const; 64 const Hash* getFileHash() const; 65 66 // Look up local identifier. 67 // It could be plain identifier or enum value as described by lookupEnumValue. 68 LocalIdentifier* lookupLocalIdentifier(const Reference<LocalIdentifier>& ref, Scope* scope); 69 70 // Look up an enum value by "FQName:valueName". 71 EnumValue* lookupEnumValue(const FQName& fqName, std::string* errorMsg, Scope* scope); 72 73 // Look up a type by FQName, "pure" names, i.e. those without package 74 // or version are first looked up in the current scope chain. 75 // After that lookup proceeds to imports. 76 Type* lookupType(const FQName& fqName, Scope* scope); 77 78 void addImportedAST(AST *ast); 79 80 // Calls all passes after parsing required before 81 // being ready to generate output. 82 status_t postParse(); 83 84 // Recursive pass on constant expression tree 85 status_t constantExpressionRecursivePass( 86 const std::function<status_t(ConstantExpression*)>& func, bool processBeforeDependencies); 87 88 // Recursive tree pass that looks up all referenced types 89 status_t lookupTypes(); 90 91 // Recursive tree pass that looks up all referenced local identifiers 92 status_t lookupLocalIdentifiers(); 93 94 // Recursive tree pass that validates that all defined types 95 // have unique names in their scopes. 96 status_t validateDefinedTypesUniqueNames() const; 97 98 // Recursive tree pass that completes type declarations 99 // that depend on super types 100 status_t resolveInheritance(); 101 102 // Recursive tree pass that evaluates constant expressions 103 status_t evaluate(); 104 105 // Recursive tree pass that validates all type-related 106 // syntax restrictions 107 status_t validate() const; 108 109 // Recursive tree pass that ensures that type definitions and references 110 // are acyclic and reorderes type definitions in reversed topological order. 111 status_t topologicalReorder(); 112 113 // Recursive tree pass that ensures that constant expressions 114 // are acyclic. 115 status_t checkAcyclicConstantExpressions() const; 116 117 // Recursive tree pass that checks C++ forward declaration restrictions. 118 status_t checkForwardReferenceRestrictions() const; 119 120 status_t gatherReferencedTypes(); 121 122 void generateCppSource(Formatter& out) const; 123 124 void generateInterfaceHeader(Formatter& out) const; 125 void generateHwBinderHeader(Formatter& out) const; 126 void generateStubHeader(Formatter& out) const; 127 void generateProxyHeader(Formatter& out) const; 128 void generatePassthroughHeader(Formatter& out) const; 129 130 void generateCppImplHeader(Formatter& out) const; 131 void generateCppImplSource(Formatter& out) const; 132 133 void generateCppAdapterHeader(Formatter& out) const; 134 void generateCppAdapterSource(Formatter& out) const; 135 136 void generateJava(Formatter& out, const std::string& limitToType) const; 137 void generateJavaTypes(Formatter& out, const std::string& limitToType) const; 138 139 void generateVts(Formatter& out) const; 140 141 void getImportedPackages(std::set<FQName> *importSet) const; 142 143 // Run getImportedPackages on this, then run getImportedPackages on 144 // each AST in each package referenced in importSet. 145 void getImportedPackagesHierarchy(std::set<FQName> *importSet) const; 146 147 bool isJavaCompatible() const; 148 149 // Warning: this only includes names explicitly referenced in code. 150 // It does not include all names which are imported. 151 // 152 // Currently, there is one valid usecase for this: importing exactly 153 // the names which need to be imported in generated code. If you import 154 // based on getAllImportedNamesGranular instead, you will import things 155 // that aren't actually used in the resultant code. 156 // 157 // Get transitive closure of imported interface/types. This will add 158 // everything exported by a package even if only a single type from 159 // that package was explicitly imported! 160 void getAllImportedNames(std::set<FQName> *allImportSet) const; 161 162 // Get imported types, this includes those explicitly imported as well 163 // as all types defined in imported packages. 164 void getAllImportedNamesGranular(std::set<FQName> *allImportSet) const; 165 166 void appendToExportedTypesVector( 167 std::vector<const Type *> *exportedTypes) const; 168 169 // used by the parser. 170 void addSyntaxError(); 171 size_t syntaxErrors() const; 172 173 bool isIBase() const; 174 175 // or nullptr if not isInterface 176 const Interface *getInterface() const; 177 178 // types or Interface base name (e.x. Foo) 179 std::string getBaseName() const; 180 181 Scope* getRootScope(); 182 183 static void generateCppPackageInclude(Formatter& out, const FQName& package, 184 const std::string& klass); 185 186 void addDefinedTypes(std::set<FQName> *definedTypes) const; 187 void addReferencedTypes(std::set<FQName> *referencedTypes) const; 188 189 void addToImportedNamesGranular(const FQName &fqName); 190 191 private: 192 const Coordinator* mCoordinator; 193 const Hash* mFileHash; 194 195 RootScope mRootScope; 196 197 FQName mPackage; 198 199 // A set of all external interfaces/types that are _actually_ referenced 200 // in this AST, this is a subset of those specified in import statements. 201 // Note that this set only resolves to the granularity of either an 202 // interface type or a whole package. 203 std::set<FQName> mImportedNames; 204 205 // This is the set of actually imported types. 206 std::set<FQName> mImportedNamesGranular; 207 208 // Warning: this only includes names explicitly referenced in code. 209 // It does not include all names which are imported. 210 // 211 // A set of all ASTs we explicitly or implicitly (types.hal) import. 212 std::set<AST *> mImportedASTs; 213 214 // If a single type (instead of the whole AST) is imported, the AST will be 215 // present as a key to this map, with the value being a list of types 216 // imported from this AST. If an AST appears in mImportedASTs but not in 217 // mImportedTypes, then the whole AST is imported. 218 std::map<AST *, std::set<Type *>> mImportedTypes; 219 220 // Types keyed by full names defined in this AST. 221 std::map<FQName, Type *> mDefinedTypesByFullName; 222 223 // used by the parser. 224 size_t mSyntaxErrors = 0; 225 226 std::set<FQName> mReferencedTypeNames; 227 228 // Helper functions for lookupType. 229 Type* lookupTypeLocally(const FQName& fqName, Scope* scope); 230 status_t lookupAutofilledType(const FQName &fqName, Type **returnedType); 231 Type *lookupTypeFromImports(const FQName &fqName); 232 233 // Find a type matching fqName (which may be partial) and if found 234 // return the associated type and fill in the full "matchingName". 235 // Only types defined in this very AST are considered. 236 Type *findDefinedType(const FQName &fqName, FQName *matchingName) const; 237 238 void getPackageComponents(std::vector<std::string> *components) const; 239 240 void getPackageAndVersionComponents( 241 std::vector<std::string> *components, bool cpp_compatible) const; 242 243 std::string makeHeaderGuard(const std::string &baseName, 244 bool indicateGenerated = true) const; 245 void enterLeaveNamespace(Formatter &out, bool enter) const; 246 247 static void generateCheckNonNull(Formatter &out, const std::string &nonNull); 248 249 void generateTypeSource(Formatter& out, const std::string& ifaceName) const; 250 251 // a method, and in which interface is it originally defined. 252 // be careful of the case where method.isHidlReserved(), where interface 253 // is effectively useless. 254 using MethodGenerator = std::function<void(const Method*, const Interface*)>; 255 256 void generateTemplatizationLink(Formatter& out) const; 257 void generateCppTag(Formatter& out, const std::string& tag) const; 258 259 void generateMethods(Formatter& out, const MethodGenerator& gen, 260 bool includeParents = true) const; 261 void generateStubImplMethod(Formatter& out, const std::string& className, 262 const Method* method) const; 263 void generatePassthroughMethod(Formatter& out, const Method* method) const; 264 void generateStaticProxyMethodSource(Formatter& out, const std::string& className, 265 const Method* method) const; 266 void generateProxyMethodSource(Formatter& out, const std::string& className, 267 const Method* method, const Interface* superInterface) const; 268 void generateAdapterMethod(Formatter& out, const Method* method) const; 269 270 void generateFetchSymbol(Formatter &out, const std::string &ifaceName) const; 271 272 void generateProxySource(Formatter& out, const FQName& fqName) const; 273 274 void generateStubSource(Formatter& out, const Interface* iface) const; 275 276 void generateStubSourceForMethod(Formatter& out, const Method* method, 277 const Interface* superInterface) const; 278 void generateStaticStubMethodSource(Formatter& out, const FQName& fqName, 279 const Method* method) const; 280 281 void generatePassthroughSource(Formatter& out) const; 282 283 void generateInterfaceSource(Formatter& out) const; 284 285 enum InstrumentationEvent { 286 SERVER_API_ENTRY = 0, 287 SERVER_API_EXIT, 288 CLIENT_API_ENTRY, 289 CLIENT_API_EXIT, 290 SYNC_CALLBACK_ENTRY, 291 SYNC_CALLBACK_EXIT, 292 ASYNC_CALLBACK_ENTRY, 293 ASYNC_CALLBACK_EXIT, 294 PASSTHROUGH_ENTRY, 295 PASSTHROUGH_EXIT, 296 }; 297 298 void generateCppAtraceCall( 299 Formatter &out, 300 InstrumentationEvent event, 301 const Method *method) const; 302 303 void generateCppInstrumentationCall( 304 Formatter &out, 305 InstrumentationEvent event, 306 const Method *method) const; 307 308 void declareCppReaderLocals(Formatter& out, const std::vector<NamedReference<Type>*>& arg, 309 bool forResults) const; 310 311 void emitCppReaderWriter(Formatter& out, const std::string& parcelObj, bool parcelObjIsPointer, 312 const NamedReference<Type>* arg, bool isReader, Type::ErrorMode mode, 313 bool addPrefixToName) const; 314 315 void emitCppResolveReferences(Formatter& out, const std::string& parcelObj, 316 bool parcelObjIsPointer, const NamedReference<Type>* arg, 317 bool isReader, Type::ErrorMode mode, bool addPrefixToName) const; 318 319 void emitJavaReaderWriter(Formatter& out, const std::string& parcelObj, 320 const NamedReference<Type>* arg, bool isReader, 321 bool addPrefixToName) const; 322 323 void emitTypeDeclarations(Formatter& out) const; 324 void emitJavaTypeDeclarations(Formatter& out) const; 325 void emitVtsTypeDeclarations(Formatter& out) const; 326 327 DISALLOW_COPY_AND_ASSIGN(AST); 328 }; 329 330 } // namespace android 331 332 #endif // AST_H_ 333