1 /** 2 * Copyright (c) 2021-2025 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 #ifndef ES2PANDA_DECLGEN_ETS2TS_H 17 #define ES2PANDA_DECLGEN_ETS2TS_H 18 19 #include "parser/program/program.h" 20 #include "checker/ETSchecker.h" 21 #include "libpandabase/os/file.h" 22 #include "libpandabase/utils/arena_containers.h" 23 #include "util/options.h" 24 #include "util/diagnosticEngine.h" 25 26 namespace ark::es2panda::declgen_ets2ts { 27 28 struct DeclgenOptions { 29 bool exportAll = false; 30 bool isIsolatedDeclgen = false; 31 std::string outputDeclEts; 32 std::string outputEts; 33 std::string recordFile; 34 }; 35 36 // Consume program after checker stage and generate out_path typescript file with declarations 37 bool GenerateTsDeclarations(checker::ETSChecker *checker, const ark::es2panda::parser::Program *program, 38 const DeclgenOptions &declgenOptions); 39 bool ValidateDeclgenOptions(const DeclgenOptions &options, checker::ETSChecker *checker); 40 bool WriteOutputFiles(const DeclgenOptions &options, const std::string &combinedEts, const std::string &combinedDEts, 41 checker::ETSChecker *checker); 42 43 class TSDeclGen { 44 public: TSDeclGen(checker::ETSChecker * checker,const ark::es2panda::parser::Program * program)45 TSDeclGen(checker::ETSChecker *checker, const ark::es2panda::parser::Program *program) 46 : checker_(checker), 47 program_(program), 48 diagnosticEngine_(checker->DiagnosticEngine()), 49 allocator_(SpaceType::SPACE_TYPE_COMPILER, nullptr, true), 50 indirectDependencyObjects_(allocator_.Adapter()), 51 importSet_(allocator_.Adapter()), 52 typeAliasMap_(allocator_.Adapter()), 53 paramDefaultMap_(allocator_.Adapter()) 54 { 55 } 56 SetDeclgenOptions(const DeclgenOptions & options)57 void SetDeclgenOptions(const DeclgenOptions &options) 58 { 59 declgenOptions_ = options; 60 } 61 GetDeclgenOptions()62 const DeclgenOptions &GetDeclgenOptions() 63 { 64 return declgenOptions_; 65 } 66 67 bool Generate(); 68 void GenImportDeclarations(); 69 void GenImportRecordDeclarations(const std::string &source); 70 GetDtsOutput()71 std::string GetDtsOutput() const 72 { 73 return outputDts_.str(); 74 } 75 GetTsOutput()76 std::string GetTsOutput() const 77 { 78 return outputTs_.str(); 79 } 80 ResetDtsOutput()81 void ResetDtsOutput() 82 { 83 outputDts_.str(""); 84 } 85 ResetTsOutput()86 void ResetTsOutput() 87 { 88 outputTs_.str(""); 89 } 90 91 static constexpr std::string_view INDENT = " "; 92 93 private: 94 void LogError(const diagnostic::DiagnosticKind &kind, const util::DiagnosticMessageParams ¶ms, 95 const lexer::SourcePosition &pos); 96 void LogWarning(const diagnostic::DiagnosticKind &kind, const util::DiagnosticMessageParams ¶ms, 97 const lexer::SourcePosition &pos); 98 99 const ir::Identifier *GetKeyIdent(const ir::Expression *key); 100 const checker::Signature *GetFuncSignature(const checker::ETSFunctionType *etsFunctionType, 101 const ir::MethodDefinition *methodDef); 102 103 void SplitUnionTypes(std::string &unionTypeString); 104 void GenType(const checker::Type *checkerType); 105 void GenFunctionType(const checker::ETSFunctionType *functionType, const ir::MethodDefinition *methodDef = nullptr); 106 void ProcessFunctionReturnType(const checker::Signature *sig); 107 bool ProcessTSQualifiedName(const ir::ETSTypeReference *typeReference); 108 void ProcessETSTypeReferenceType(const ir::ETSTypeReference *typeReference, 109 const checker::Type *checkerType = nullptr); 110 bool ProcessTypeAnnotationSpecificTypes(const checker::Type *checkerType); 111 void ProcessTypeAnnotationType(const ir::TypeNode *typeAnnotation, const checker::Type *checkerType = nullptr); 112 void ProcessETSTypeReference(const ir::TypeNode *typeAnnotation, const checker::Type *checkerType); 113 void ProcessETSTuple(const ir::ETSTuple *etsTuple); 114 void ProcessETSUnionType(const ir::ETSUnionType *etsUnionType); 115 void ProcessTSArrayType(const ir::TSArrayType *tsArrayType); 116 void ProcessETSFunctionType(const ir::ETSFunctionType *etsFunction); 117 118 void GenObjectType(const checker::ETSObjectType *objectType); 119 void GenUnionType(const checker::ETSUnionType *unionType); 120 void GenTupleType(const checker::ETSTupleType *tupleType); 121 122 template <class UnionType> 123 std::vector<UnionType *> FilterUnionTypes(const ArenaVector<UnionType *> &originTypes); 124 125 void GenImportDeclaration(const ir::ETSImportDeclaration *importDeclaration); 126 void GenNamespaceImport(const ir::AstNode *specifier, const std::string &source); 127 void GenDefaultImport(const ir::AstNode *specifier, const std::string &source, bool isTypeKind = false); 128 void GenNamedImports(const ir::ETSImportDeclaration *importDeclaration, 129 const ArenaVector<ir::AstNode *> &specifiers, bool isTypeKind = false); 130 void GenDtsImportStatement(std::vector<ir::AstNode *> &specifiers, 131 const ir::ETSImportDeclaration *importDeclaration, bool isTypeKind = false); 132 void GenTsImportStatement(std::vector<ir::AstNode *> &specifiers, const ir::ETSImportDeclaration *importDeclaration, 133 bool isInterface = false); 134 void GenSingleNamedImport(ir::AstNode *specifier, const ir::ETSImportDeclaration *importDeclaration, 135 bool isGlueCode = false); 136 void GenReExportDeclaration(const ir::ETSReExportDeclaration *reExportDeclaration); 137 bool GenNamespaceReExportDeclaration(const ir::AstNode *specifier, 138 const ir::ETSImportDeclaration *importDeclaration); 139 void SeparateInterfaceSpecifiers(const ArenaVector<ir::AstNode *> &specifiers, 140 std::vector<ir::AstNode *> &interfaceSpecifiers, 141 std::vector<ir::AstNode *> &normalSpecifiers); 142 void GenDtsReExportStatement(const ArenaVector<ir::AstNode *> &specifiers, 143 const ir::ETSImportDeclaration *importDeclaration, bool isTypeKind = false); 144 void GenTsReExportStatement(const std::vector<ir::AstNode *> &specifiers, 145 const ir::ETSImportDeclaration *importDeclaration, bool isInterface = false); 146 void GenSingleNamedReExport(ir::AstNode *specifier, const ir::ETSImportDeclaration *importDeclaration, 147 bool isGlueCode = false); 148 void GenTypeAliasDeclaration(const ir::TSTypeAliasDeclaration *typeAlias); 149 void GenEnumDeclaration(const ir::ClassProperty *enumMember); 150 void GenInterfaceDeclaration(const ir::TSInterfaceDeclaration *interfaceDecl); 151 bool GenInterfaceProp(const ir::MethodDefinition *methodDef); 152 void GenClassDeclaration(const ir::ClassDeclaration *classDecl); 153 void GenMethodDeclaration(const ir::MethodDefinition *methodDef); 154 bool GenMethodDeclarationPrefix(const ir::MethodDefinition *methodDef, const ir::Identifier *methodIdent, 155 const std::string &methodName); 156 void GenMethodSignature(const ir::MethodDefinition *methodDef, const ir::Identifier *methodIdent, 157 const std::string &methodName); 158 void GenPropDeclaration(const ir::ClassProperty *classProp); 159 void ProcessClassPropDeclaration(const ir::ClassProperty *classProp); 160 void GenPropAccessor(const ir::ClassProperty *classProp, const std::string &accessorKind); 161 void GenGlobalVarDeclaration(const ir::ClassProperty *globalVar); 162 void GenLiteral(const ir::Literal *literal); 163 164 template <class T> 165 void GenModifier(const T *node, bool isProp = false); 166 167 template <class T> 168 void GenAnnotations(const T *node); 169 void GenAnnotationProperties(const ir::AnnotationUsage *anno); 170 void GenAnnotationPropertyValue(ir::Expression *value); 171 172 void GenTypeParameters(const ir::TSTypeParameterDeclaration *typeParams); 173 void GenExport(const ir::Identifier *symbol); 174 void GenExport(const ir::Identifier *symbol, const std::string &alias); 175 void GenDefaultExport(const ir::Identifier *symbol); 176 bool ShouldEmitDeclarationSymbol(const ir::Identifier *symbol); 177 178 template <class T, class CB> 179 void GenSeparated(const T &container, const CB &cb, const char *separator = ", ", bool isReExport = false, 180 bool isDtsExport = true); 181 182 void PrepareClassDeclaration(const ir::ClassDefinition *classDef); 183 bool ShouldSkipMethodDeclaration(const ir::MethodDefinition *methodDef); 184 bool ShouldSkipClassDeclaration(const std::string_view &className) const; 185 void HandleClassDeclarationTypeInfo(const ir::ClassDefinition *classDef, const std::string_view &className); 186 void HandleClassInherit(const ir::Expression *expr); 187 void ProcessClassBody(const ir::ClassDefinition *classDef); 188 void ProcessParamDefaultToMap(const ir::Statement *stmt); 189 void ProcessParameterName(varbinder::LocalVariable *param); 190 void ProcessFuncParameter(varbinder::LocalVariable *param); 191 void ProcessFuncParameters(const checker::Signature *sig); 192 void ProcessClassPropertyType(const ir::ClassProperty *classProp); 193 std::vector<ir::AstNode *> FilterValidImportSpecifiers(const ArenaVector<ir::AstNode *> &specifiers); 194 std::string ReplaceETSGLOBAL(const std::string &typeName); 195 std::string GetIndent() const; 196 std::string RemoveModuleExtensionName(const std::string &filepath); 197 void GenPartName(std::string &partName); 198 void ProcessIndent(); 199 200 bool GenGlobalDescriptor(); 201 void CollectIndirectExportDependencies(); 202 void ProcessTypeAliasDependencies(const ir::TSTypeAliasDeclaration *typeAliasDecl); 203 void ProcessTypeAnnotationDependencies(const ir::TypeNode *typeAnnotation); 204 void ProcessClassDependencies(const ir::ClassDeclaration *classDecl); 205 void ProcessClassPropDependencies(const ir::ClassDefinition *classDef); 206 void ProcessClassMethodDependencies(const ir::MethodDefinition *methodDef); 207 void ProcessInterfaceDependencies(const ir::TSInterfaceDeclaration *interfaceDecl); 208 void ProcessInterfacePropDependencies(const ir::TSInterfaceDeclaration *interfaceDecl); 209 void ProcessInterfaceMethodDependencies(const ir::MethodDefinition *methodDef); 210 void ProcessETSTypeReferenceDependencies(const ir::ETSTypeReference *typeReference); 211 void AddSuperType(const ir::Expression *super); 212 void AddSuperType(const checker::Type *tsType); 213 void ProcessInterfacesDependencies(const ArenaVector<checker::ETSObjectType *> &interfaces); 214 void AddObjectDependencies(const util::StringView &typeName, const std::string &alias = ""); 215 void GenDeclarations(); 216 void CloseClassBlock(const bool isDts); 217 218 void EmitDeclarationPrefix(const ir::ClassDefinition *classDef, const std::string &typeName, 219 const std::string_view &className); 220 void EmitClassDeclaration(const ir::ClassDefinition *classDef, const std::string_view &className); 221 void EmitClassGlueCode(const ir::ClassDefinition *classDef, const std::string &className); 222 void EmitMethodGlueCode(const std::string &methodName, const ir::Identifier *methodIdentifier); 223 void EmitPropGlueCode(const ir::ClassProperty *classProp, const std::string &propName); 224 225 bool HandleBasicTypes(const checker::Type *checkerType); 226 void HandleFunctionType(const checker::Type *checkerType); 227 bool HandleETSSpecificTypes(const checker::Type *checkerType); 228 bool HandleObjectType(const checker::Type *checkerType); 229 bool HandleSpecificObjectTypes(const checker::ETSObjectType *objectType); 230 void HandleArrayType(const checker::Type *checkerType); 231 void HandleTypeArgument(checker::Type *arg, const std::string &typeStr); 232 233 void ProcessInterfaceBody(const ir::TSInterfaceBody *body); 234 void ProcessInterfaceMethodDefinition(const ir::MethodDefinition *methodDef); 235 void ProcessMethodDefinition(const ir::MethodDefinition *methodDef, 236 std::unordered_set<std::string> &processedMethods); 237 238 void ProcessMethodsFromInterfaces(std::unordered_set<std::string> &processedMethods, 239 const ArenaVector<checker::ETSObjectType *> &interfaces); 240 OutDts()241 void OutDts() {} 242 243 template <class F, class... T> OutDts(F && first,T &&...rest)244 void OutDts(F &&first, T &&...rest) 245 { 246 outputDts_ << first; 247 OutDts(std::forward<T>(rest)...); 248 } 249 OutTs()250 void OutTs() {} 251 252 template <class F, class... T> OutTs(F && first,T &&...rest)253 void OutTs(F &&first, T &&...rest) 254 { 255 outputTs_ << first; 256 OutTs(std::forward<T>(rest)...); 257 } 258 259 void OutEndlDts(const std::size_t count = 1) 260 { 261 ark::os::file::File::GetEndLine(outputDts_, count); 262 } 263 264 void OutEndlTs(const std::size_t count = 1) 265 { 266 ark::os::file::File::GetEndLine(outputTs_, count); 267 } 268 ResetState()269 void ResetState() 270 { 271 state_ = GenState(); 272 } 273 ResetClassNode()274 void ResetClassNode() 275 { 276 classNode_.isStruct = false; 277 classNode_.isIndirect = false; 278 } 279 280 struct GenState { 281 const ir::Expression *super {nullptr}; 282 bool inInterface {false}; 283 bool inGlobalClass {false}; 284 bool inClass {false}; 285 bool inNamespace {false}; 286 bool inEnum {false}; 287 bool isClassInNamespace {false}; 288 bool isInterfaceInNamespace {false}; 289 bool isDeclareNamespace {false}; 290 std::string currentClassDescriptor {}; 291 std::stack<bool> inUnionBodyStack {}; 292 std::string currentTypeAliasName; 293 const ir::TSTypeParameterDeclaration *currentTypeParams {nullptr}; 294 } state_ {}; 295 296 struct ClassNode { 297 bool hasNestedClass {false}; 298 bool isIndirect {false}; 299 bool isStruct {false}; 300 size_t indentLevel {1}; 301 } classNode_ {}; 302 303 const std::unordered_set<std::string_view> numberTypes_ = {"Long", "Float", "Double", "Byte", 304 "Short", "Int", "Number"}; 305 const std::unordered_set<std::string_view> stringTypes_ = {"Char", "String"}; 306 const std::unordered_set<std::string_view> annotationList_ = { 307 "Component", "Builder", "LocalBuilder", "BuilderParam", "Styles", "Extend", "AnimatableExtend", 308 "Require", "Reusable", "State", "Prop", "Link", "Provide", "Consume", 309 "Observed", "ObjectLink", "Watch", "Track", "ObservedV2", "Trace", "ComponentV2", 310 "Local", "Param", "Once", "Event", "Provider", "Consumer", "Monitor", 311 "Computed", "Type"}; 312 const std::unordered_set<std::string_view> stdlibNamespaceList_ = { 313 "StdProcess", "taskpool", "functions", "containers", "Intl", "GC", 314 "jsonx", "proxy", "unsafeMemory", "reflect", "StdDebug", "arktest"}; 315 const std::set<std::string> extensions_ = {".sts", ".ets", ".ts", ".js"}; 316 317 std::stringstream outputDts_; 318 std::stringstream outputTs_; 319 checker::ETSChecker *checker_ {}; 320 const ark::es2panda::parser::Program *program_ {}; 321 util::DiagnosticEngine &diagnosticEngine_; 322 ArenaAllocator allocator_; 323 ArenaSet<std::string> indirectDependencyObjects_; 324 ArenaSet<std::string> importSet_; 325 DeclgenOptions declgenOptions_ {}; 326 std::string globalDesc_; 327 ArenaMap<std::string, std::string> typeAliasMap_; 328 ArenaMap<util::StringView, util::StringView> paramDefaultMap_; 329 }; 330 } // namespace ark::es2panda::declgen_ets2ts 331 332 #endif // ES2PANDA_DECLGEN_ETS2TS_H 333