1/**
2 * Copyright (c) 2021-2024 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
23namespace ark::es2panda::declgen_ets2ts {
24
25// Consume program after checker stage and generate out_path typescript file with declarations
26bool GenerateTsDeclarations(checker::ETSChecker *checker, const ark::es2panda::parser::Program *program,
27                            const std::string &outPath);
28
29class TSDeclGen {
30public:
31    TSDeclGen(checker::ETSChecker *checker, const ark::es2panda::parser::Program *program)
32        : checker_(checker), program_(program)
33    {
34    }
35
36    std::stringstream &Output()
37    {
38        return output_;
39    }
40
41    void Generate();
42
43    static constexpr std::string_view INDENT = "    ";
44
45private:
46    void ThrowError(std::string_view message, const lexer::SourcePosition &pos);
47    const ir::Identifier *GetKeyIdent(const ir::Expression *key);
48
49    void GenType(const checker::Type *checkerType);
50    void GenFunctionType(const checker::ETSFunctionType *functionType, const ir::MethodDefinition *methodDef = nullptr);
51    void GenFunctionBody(const ir::MethodDefinition *methodDef, const checker::Signature *sig, const bool isConstructor,
52                         const bool isSetter);
53    void GenObjectType(const checker::ETSObjectType *objectType);
54    void GenEnumType(const checker::ETSIntEnumType *enumType);
55    void GenUnionType(const checker::ETSUnionType *unionType);
56
57    void GenImportDeclaration(const ir::ETSImportDeclaration *importDeclaration);
58    void GenTypeAliasDeclaration(const ir::TSTypeAliasDeclaration *typeAlias);
59    void GenEnumDeclaration(const ir::TSEnumDeclaration *enumDecl);
60    void GenInterfaceDeclaration(const ir::TSInterfaceDeclaration *interfaceDecl);
61    void GenClassDeclaration(const ir::ClassDeclaration *classDecl);
62    void GenMethodDeclaration(const ir::MethodDefinition *methodDef);
63    void GenPropDeclaration(const ir::ClassProperty *classProp);
64    void GenGlobalVarDeclaration(const ir::ClassProperty *globalVar);
65    void GenLiteral(const ir::Literal *literal);
66
67    template <class T>
68    void GenModifier(const T *node);
69    void GenTypeParameters(const ir::TSTypeParameterDeclaration *typeParams);
70    void GenExport(const ir::Identifier *symbol);
71    void GenExport(const ir::Identifier *symbol, const std::string &alias);
72    void GenDefaultExport(const ir::Identifier *symbol);
73    void ExportIfNeeded(const ir::Identifier *symbol);
74
75    template <class T, class CB>
76    void GenSeparated(const T &container, const CB &cb, const char *separator = ", ");
77
78    void Out() {}
79    template <class F, class... T>
80    void Out(F &&first, T &&...rest)
81    {
82        output_ << first;
83        Out(std::forward<T>(rest)...);
84    }
85    void OutEndl(const std::size_t count = 1)
86    {
87        ark::os::file::File::GetEndLine(output_, count);
88    }
89
90    void ResetState()
91    {
92        state_ = GenState();
93    }
94
95    struct GenState {
96        const ir::Expression *super {nullptr};
97        bool inInterface {false};
98        bool inGlobalClass {false};
99        std::string currentClassDescriptor {};
100    } state_ {};
101
102    std::stringstream output_ {};
103    checker::ETSChecker *checker_ {};
104    const ark::es2panda::parser::Program *program_ {};
105};
106}  // namespace ark::es2panda::declgen_ets2ts
107
108#endif  // ES2PANDA_DECLGEN_ETS2TS_H
109