• 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 #include <iostream>
17 #include "public/es2panda_lib.h"
18 #include "public/public.h"
19 #include "declgenEts2Ts.h"
20 
21 namespace ark::es2panda::declgen_ets2ts {
22 
PrintUsage()23 static void PrintUsage()
24 {
25     std::cerr << "Usage: declgen_ets2ts [OPTIONS] [input]\n";
26     std::cerr << "    --export-all         Treat all top level statements as exported\n";
27     std::cerr << "    --output-dets=[FILE] Path to output .d.ets file\n";
28     std::cerr << "    --output-ets=[FILE]  Path to output .ets file\n";
29     std::cerr << "    --generate-decl:enable-isolated Generate isolated decl\n";
30     std::cerr << "    --help               Print this message and exit. Default: false\n";
31     std::cerr << "Tail arguments:\n";
32     std::cerr << "input: input file\n";
33 }
34 
FilterArgs(Span<const char * const> args,int & newArgc,const char ** & newArgv)35 void FilterArgs(Span<const char *const> args, int &newArgc, const char **&newArgv)
36 {
37     ES2PANDA_ASSERT(args.size() > 1);
38     std::vector<const char *> filteredArgs;
39     filteredArgs.push_back(args[0]);
40     for (size_t i = 1; i < args.size(); ++i) {
41         if (std::strcmp(args[i], "--export-all") == 0 ||
42             std::strncmp(args[i], "--output-dets", std::strlen("--output-dets")) == 0 ||
43             std::strncmp(args[i], "--output-ets", std::strlen("--output-ets")) == 0) {
44             continue;
45         }
46         filteredArgs.push_back(args[i]);
47     }
48 
49     newArgc = static_cast<int>(filteredArgs.size());
50     if (newArgc <= 0 || static_cast<size_t>(newArgc) > args.size()) {
51         return;
52     }
53     newArgv = new const char *[newArgc];
54     std::copy(filteredArgs.begin(), filteredArgs.end(), newArgv);
55 }
56 
ParseOptions(Span<const char * const> args)57 static DeclgenOptions ParseOptions(Span<const char *const> args)
58 {
59     DeclgenOptions options;
60     for (size_t i = 1; i < args.size(); ++i) {
61         if (std::strcmp(args[i], "--export-all") == 0) {
62             options.exportAll = true;
63         } else if (std::strncmp(args[i], "--output-dets", std::strlen("--output-dets")) == 0 &&
64                    std::strchr(args[i], '=') != nullptr) {
65             std::string arg = args[i];
66             options.outputDeclEts = arg.substr(std::strlen("--output-dets="));
67         } else if (std::strncmp(args[i], "--output-ets", std::strlen("--output-ets")) == 0 &&
68                    std::strchr(args[i], '=') != nullptr) {
69             std::string arg = args[i];
70             options.outputEts = arg.substr(std::strlen("--output-ets="));
71         } else if (std::strcmp(args[i], "--generate-decl:enable-isolated") == 0) {
72             options.isIsolatedDeclgen = true;
73         }
74     }
75     return options;
76 }
77 
DestroyContextAndConfig(const es2panda_Impl * impl,es2panda_Context * ctx,es2panda_Config * cfg,const char ** newArgv)78 static void DestroyContextAndConfig(const es2panda_Impl *impl, es2panda_Context *ctx, es2panda_Config *cfg,
79                                     const char **newArgv)
80 {
81     impl->DestroyContext(ctx);
82     impl->DestroyConfig(cfg);
83     delete[] newArgv;
84 }
85 
Run(int argc,const char ** argv)86 static int Run(int argc, const char **argv)
87 {
88     Span<const char *const> args(argv, static_cast<size_t>(argc));
89     if (args.size() == 1 || std::strcmp(args[1], "--help") == 0) {
90         PrintUsage();
91         return 1;
92     }
93     auto declgenOptions = ParseOptions(args);
94     int newArgc = 0;
95     const char **newArgv = nullptr;
96     FilterArgs(args, newArgc, newArgv);
97     const auto *impl = es2panda_GetImpl(ES2PANDA_LIB_VERSION);
98     auto *cfg = impl->CreateConfig(newArgc, newArgv);
99     if (cfg == nullptr) {
100         return 1;
101     }
102     auto *cfgImpl = reinterpret_cast<ark::es2panda::public_lib::ConfigImpl *>(cfg);
103     auto parserInputCStr = cfgImpl->options->CStrParserInputContents().first;
104     es2panda_Context *ctx =
105         impl->CreateContextFromString(cfg, parserInputCStr, cfgImpl->options->SourceFileName().c_str());
106 
107     auto *ctxImpl = reinterpret_cast<ark::es2panda::public_lib::Context *>(ctx);
108     auto *checker = reinterpret_cast<checker::ETSChecker *>(ctxImpl->checker);
109 
110     auto *isolatedDeclgenChecker = reinterpret_cast<checker::IsolatedDeclgenChecker *>(ctxImpl->isolatedDeclgenChecker);
111     impl->ProceedToState(ctx, ES2PANDA_STATE_BOUND);
112     if (declgenOptions.isIsolatedDeclgen) {
113         isolatedDeclgenChecker->CheckBeforeChecker();
114         if (ctxImpl->diagnosticEngine->IsAnyError()) {
115             DestroyContextAndConfig(impl, ctx, cfg, newArgv);
116             return 1;
117         }
118     }
119 
120     impl->ProceedToState(ctx, ES2PANDA_STATE_CHECKED);
121     if (declgenOptions.isIsolatedDeclgen) {
122         isolatedDeclgenChecker->CheckAfterChecker();
123         if (ctxImpl->diagnosticEngine->IsAnyError()) {
124             DestroyContextAndConfig(impl, ctx, cfg, newArgv);
125             return 1;
126         }
127     }
128 
129     int res = 0;
130     if (!GenerateTsDeclarations(checker, ctxImpl->parserProgram, declgenOptions)) {
131         res = 1;
132     }
133 
134     DestroyContextAndConfig(impl, ctx, cfg, newArgv);
135 
136     return res;
137 }
138 }  // namespace ark::es2panda::declgen_ets2ts
139 
main(int argc,const char ** argv)140 int main(int argc, const char **argv)
141 {
142     return ark::es2panda::declgen_ets2ts::Run(argc, argv);
143 }
144