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