• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 &params,
95                   const lexer::SourcePosition &pos);
96     void LogWarning(const diagnostic::DiagnosticKind &kind, const util::DiagnosticMessageParams &params,
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