1 /**
2 * Copyright (c) 2022-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 #include "options.h"
17
18 #include "os/filesystem.h"
19 #include "utils/pandargs.h"
20
21 #include "arktsconfig.h"
22
23 #include <random>
24 #include <utility>
25
26 #ifdef PANDA_WITH_BYTECODE_OPTIMIZER
27 #include "bytecode_optimizer/bytecodeopt_options.h"
28 #include "compiler/compiler_options.h"
29 #endif
30
31 namespace ark::es2panda::util {
32 template <class T>
RemoveExtension(T const & filename)33 T RemoveExtension(T const &filename)
34 {
35 typename T::size_type const p(filename.find_last_of('.'));
36 return p > 0 && p != T::npos ? filename.substr(0, p) : filename;
37 }
38
39 // Options
40
Options()41 Options::Options() : argparser_(new ark::PandArgParser()) {}
42
~Options()43 Options::~Options()
44 {
45 delete argparser_;
46 }
47
SplitToStringVector(std::string const & str)48 static std::vector<std::string> SplitToStringVector(std::string const &str)
49 {
50 std::vector<std::string> res;
51 std::string_view currStr {str};
52 auto ix = currStr.find(',');
53 while (ix != std::string::npos) {
54 if (ix != 0) {
55 res.emplace_back(currStr.substr(0, ix));
56 }
57 currStr = currStr.substr(ix + 1);
58 ix = currStr.find(',');
59 }
60
61 if (!currStr.empty()) {
62 res.emplace_back(currStr);
63 }
64 return res;
65 }
66
SplitToStringSet(std::string const & str)67 static std::unordered_set<std::string> SplitToStringSet(std::string const &str)
68 {
69 std::vector<std::string> vec = SplitToStringVector(str);
70 std::unordered_set<std::string> res;
71 for (auto &elem : vec) {
72 res.emplace(elem);
73 }
74 return res;
75 }
76
77 // NOLINTNEXTLINE(modernize-avoid-c-arrays, hicpp-avoid-c-arrays)
SplitArgs(int argc,const char * argv[],std::vector<std::string> & es2pandaArgs,std::vector<std::string> & bcoCompilerArgs,std::vector<std::string> & bytecodeoptArgs)78 static void SplitArgs(int argc, const char *argv[], std::vector<std::string> &es2pandaArgs,
79 std::vector<std::string> &bcoCompilerArgs, std::vector<std::string> &bytecodeoptArgs)
80 {
81 constexpr std::string_view COMPILER_PREFIX = "--bco-compiler";
82 constexpr std::string_view OPTIMIZER_PREFIX = "--bco-optimizer";
83
84 enum class OptState { ES2PANDA, JIT_COMPILER, OPTIMIZER };
85 OptState optState = OptState::ES2PANDA;
86
87 std::unordered_map<OptState, std::vector<std::string> *> argsMap = {{OptState::ES2PANDA, &es2pandaArgs},
88 {OptState::JIT_COMPILER, &bcoCompilerArgs},
89 {OptState::OPTIMIZER, &bytecodeoptArgs}};
90
91 for (int i = 1; i < argc; i++) {
92 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
93 const char *argI = argv[i];
94 if (COMPILER_PREFIX == argI) {
95 optState = OptState::JIT_COMPILER;
96 continue;
97 }
98
99 if (OPTIMIZER_PREFIX == argI) {
100 optState = OptState::OPTIMIZER;
101 continue;
102 }
103
104 argsMap[optState]->emplace_back(argI);
105 optState = OptState::ES2PANDA;
106 }
107 }
108
109 template <class T>
ParseComponentArgs(const std::vector<std::string> & args,T & options)110 static bool ParseComponentArgs(const std::vector<std::string> &args, T &options)
111 {
112 ark::PandArgParser parser;
113 options.AddOptions(&parser);
114 if (!parser.Parse(args)) {
115 std::cerr << parser.GetErrorString();
116 std::cerr << parser.GetHelpString();
117 return false;
118 }
119
120 if (auto optionsErr = options.Validate(); optionsErr) {
121 std::cerr << "Error: " << optionsErr.value().GetMessage() << std::endl;
122 return false;
123 }
124
125 return true;
126 }
127
ParseBCOCompilerOptions(const std::vector<std::string> & compilerArgs,const std::vector<std::string> & bytecodeoptArgs)128 static bool ParseBCOCompilerOptions([[maybe_unused]] const std::vector<std::string> &compilerArgs,
129 [[maybe_unused]] const std::vector<std::string> &bytecodeoptArgs)
130 {
131 #ifdef PANDA_WITH_BYTECODE_OPTIMIZER
132 if (!ParseComponentArgs(compilerArgs, ark::compiler::g_options)) {
133 return false;
134 }
135 if (!ParseComponentArgs(bytecodeoptArgs, ark::bytecodeopt::g_options)) {
136 return false;
137 }
138 #endif
139
140 return true;
141 }
142
ETSWarningsGroupSetter(const ark::PandArg<bool> & option)143 static inline bool ETSWarningsGroupSetter(const ark::PandArg<bool> &option)
144 {
145 return !option.WasSet() || (option.WasSet() && option.GetValue());
146 }
147
SplitPath(std::string_view path)148 static std::tuple<std::string_view, std::string_view, std::string_view> SplitPath(std::string_view path)
149 {
150 std::string_view fileDirectory;
151 std::string_view fileBaseName = path;
152 auto lastDelimPos = fileBaseName.find_last_of(ark::os::file::File::GetPathDelim());
153 if (lastDelimPos != std::string_view::npos) {
154 ++lastDelimPos;
155 fileDirectory = fileBaseName.substr(0, lastDelimPos);
156 fileBaseName = fileBaseName.substr(lastDelimPos);
157 }
158
159 // Save all extensions.
160 std::string_view fileExtensions;
161 auto fileBaseNamePos = fileBaseName.find_first_of('.');
162 if (fileBaseNamePos > 0 && fileBaseNamePos != std::string_view::npos) {
163 fileExtensions = fileBaseName.substr(fileBaseNamePos);
164 fileBaseName = fileBaseName.substr(0, fileBaseNamePos);
165 }
166
167 return {fileDirectory, fileBaseName, fileExtensions};
168 }
169
170 /**
171 * @brief Generate evaluated expression wrapping code.
172 * @param sourceFilePath used for generating a unique package name.
173 * @param input expression source code file stream.
174 * @param output stream for generating expression wrapper.
175 */
GenerateEvaluationWrapper(std::string_view sourceFilePath,std::ifstream & input,std::stringstream & output)176 static void GenerateEvaluationWrapper(std::string_view sourceFilePath, std::ifstream &input, std::stringstream &output)
177 {
178 static constexpr std::string_view EVAL_PREFIX = "eval_";
179 static constexpr std::string_view EVAL_SUFFIX = "_eval";
180
181 auto splittedPath = SplitPath(sourceFilePath);
182 auto fileBaseName = std::get<1>(splittedPath);
183
184 std::random_device rd;
185 std::stringstream ss;
186 ss << EVAL_PREFIX << fileBaseName << '_' << rd() << EVAL_SUFFIX;
187 auto methodName = ss.str();
188
189 output << "package " << methodName << "; class " << methodName << " { private static " << methodName << "() { "
190 << input.rdbuf() << " } }";
191 }
192
193 static auto constexpr DEFAULT_THREAD_COUNT = 0;
194
195 struct AllArgs {
196 // NOLINTBEGIN(misc-non-private-member-variables-in-classes)
197 ark::PandArg<bool> opHelp {"help", false, "Print this message and exit"};
198 ark::PandArg<bool> opVersion {"version", false, "Print message with version and exit"};
199
200 // parser
201 ark::PandArg<std::string> inputExtension {"extension", "",
202 "Parse the input as the given extension (options: js | ts | as | sts)"};
203 ark::PandArg<bool> opModule {"module", false, "Parse the input as module (JS only option)"};
204 ark::PandArg<bool> opParseOnly {"parse-only", false, "Parse the input only"};
205 ark::PandArg<bool> opDumpAst {"dump-ast", false, "Dump the parsed AST"};
206 ark::PandArg<bool> opDumpAstOnlySilent {"dump-ast-only-silent", false,
207 "Dump parsed AST with all dumpers available but don't print to stdout"};
208 ark::PandArg<bool> opDumpCheckedAst {"dump-dynamic-ast", false,
209 "Dump AST with synthetic nodes for dynamic languages"};
210 ark::PandArg<bool> opListFiles {"list-files", false, "Print names of files that are part of compilation"};
211
212 // compiler
213 ark::PandArg<bool> opDumpAssembly {"dump-assembly", false, "Dump pandasm"};
214 ark::PandArg<bool> opDebugInfo {"debug-info", false, "Compile with debug info"};
215 ark::PandArg<bool> opDumpDebugInfo {"dump-debug-info", false, "Dump debug info"};
216 ark::PandArg<int> opOptLevel {"opt-level", 0, "Compiler optimization level (options: 0 | 1 | 2)", 0, MAX_OPT_LEVEL};
217 ark::PandArg<bool> opEtsModule {"ets-module", false, "Compile the input as ets-module"};
218
219 // ETS-warnings
220 ark::PandArg<bool> opEtsEnableAll {"ets-warnings-all", false, "Show performance-related ets-warnings"};
221 ark::PandArg<bool> opEtsWerror {"ets-werror", false, "Treat all enabled performance-related ets-warnings as error"};
222 ark::PandArg<bool> opEtsSubsetWarnings {"ets-subset-warnings", false, "Show ETS-warnings that keep you in subset"};
223 ark::PandArg<bool> opEtsNonsubsetWarnings {"ets-nonsubset-warnings", false,
224 "Show ETS-warnings that do not keep you in subset"};
225 ark::PandArg<bool> opEtsSuggestFinal {"ets-suggest-final", false,
226 "Suggest final keyword warning - ETS non-subset warning"};
227 ark::PandArg<bool> opEtsProhibitTopLevelStatements {"ets-prohibit-top-level-statements", false,
228 "Prohibit top-level statements - ETS subset Warning"};
229 ark::PandArg<bool> opEtsBoostEqualityStatement {"ets-boost-equality-statement", false,
230 "Suggest boosting Equality Statements - ETS Subset Warning"};
231 ark::PandArg<bool> opEtsRemoveAsync {
232 "ets-remove-async", false, "Suggests replacing async functions with coroutines - ETS Non Subset Warnings"};
233 ark::PandArg<bool> opEtsRemoveLambda {"ets-remove-lambda", false,
234 "Suggestions to replace lambda with regular functions - ETS Subset Warning"};
235 ark::PandArg<bool> opEtsImplicitBoxingUnboxing {
236 "ets-implicit-boxing-unboxing", false,
237 "Check if a program contains implicit boxing or unboxing - ETS Subset Warning"};
238
239 ark::PandArg<bool> opDebuggerEvalMode {"debugger-eval-mode", false, "Compile given file in evaluation mode"};
240 ark::PandArg<uint64_t> opDebuggerEvalLine {
241 "debugger-eval-line", 0, "Debugger evaluation mode, line in the source file code where evaluate occurs."};
242 ark::PandArg<std::string> opDebuggerEvalSource {"debugger-eval-source", "",
243 "Debugger evaluation mode, path to evaluation mode source file"};
244 ark::PandArg<std::string> opDebuggerEvalPandaFiles {
245 "debugger-eval-panda-files", "",
246 "Debugger evaluation mode, paths to evaluation mode (.abc) files, must be accessible"};
247
248 ark::PandArg<int> opThreadCount {"thread", DEFAULT_THREAD_COUNT, "Number of worker threads"};
249 ark::PandArg<bool> opSizeStat {"dump-size-stat", false, "Dump size statistics"};
250 ark::PandArg<std::string> outputFile {"output", "", "Compiler binary output (.abc)"};
251 ark::PandArg<std::string> logLevel {"log-level", "error", "Log-level"};
252 ark::PandArg<std::string> stdLib {"stdlib", "", "Path to standard library"};
253 ark::PandArg<bool> genStdLib {"gen-stdlib", false, "Gen standard library"};
254 ark::PandArg<std::string> plugins {"plugins", "", "Plugins"};
255 ark::PandArg<std::string> skipPhases {"skip-phases", "", "Phases to skip"};
256 ark::PandArg<std::string> verifierWarnings {
257 "verifier-warnings", "CheckInfiniteLoopForAll",
258 "Print errors and continue compilation if AST tree is incorrect. "
259 "Possible values: "
260 "NodeHasParentForAll,EveryChildHasValidParentForAll,VariableHasScopeForAll,NodeHasTypeForAll,"
261 "IdentifierHasVariableForAll,ArithmeticOperationValidForAll,SequenceExpressionHasLastTypeForAll, "
262 "CheckInfiniteLoopForAll,"
263 "ForLoopCorrectlyInitializedForAll,VariableHasEnclosingScopeForAll,ModifierAccessValidForAll,"
264 "ImportExportAccessValid,NodeHasSourceRangeForAll,EveryChildInParentRangeForAll,"
265 "ReferenceTypeAnnotationIsNullForAll,VariableNameIdentifierNameSameForAll,CheckAbstractMethodForAll,"
266 "GetterSetterValidationForAll,CheckScopeDeclarationForAll,CheckConstPropertiesForAll"};
267 ark::PandArg<std::string> verifierErrors {
268 "verifier-errors",
269 "ForLoopCorrectlyInitializedForAll,SequenceExpressionHasLastTypeForAll,NodeHasTypeForAll,NodeHasParentForAll,"
270 "EveryChildHasValidParentForAll,ModifierAccessValidForAll,ArithmeticOperationValidForAll,"
271 "VariableHasScopeForAll,IdentifierHasVariableForAll,VariableHasEnclosingScopeForAll,"
272 "ReferenceTypeAnnotationIsNullForAll,VariableNameIdentifierNameSameForAll,CheckAbstractMethodForAll,"
273 "GetterSetterValidationForAll,CheckScopeDeclarationForAll,CheckConstPropertiesForAll",
274 "Print errors and stop compilation if AST tree is incorrect. "
275 "Possible values: "
276 "NodeHasParentForAll,EveryChildHasValidParentForAll,VariableHasScopeForAll,NodeHasTypeForAll,"
277 "IdentifierHasVariableForAll,ArithmeticOperationValidForAll,SequenceExpressionHasLastTypeForAll,"
278 "CheckInfiniteLoopForAll,"
279 "ForLoopCorrectlyInitializedForAll,VariableHasEnclosingScopeForAll,ModifierAccessValidForAll,"
280 "ImportExportAccessValid,NodeHasSourceRangeForAll,EveryChildInParentRangeForAll,"
281 "ReferenceTypeAnnotationIsNullForAll,VariableNameIdentifierNameSameForAll,CheckAbstractMethodForAll,"
282 "GetterSetterValidationForAll,CheckScopeDeclarationForAll,CheckConstPropertiesForAll"};
283 ark::PandArg<bool> verifierAllChecks {
284 "verifier-all-checks", false,
285 "Run verifier checks on every phase, monotonically expanding them on every phase"};
286 ark::PandArg<bool> verifierFullProgram {"verifier-full-program", false,
287 "Analyze full program, including program AST and it's dependencies"};
288 ark::PandArg<std::string> dumpBeforePhases {"dump-before-phases", "",
289 "Generate program dump before running phases in the list"};
290 ark::PandArg<std::string> dumpEtsSrcBeforePhases {
291 "dump-ets-src-before-phases", "", "Generate program dump as ets source code before running phases in the list"};
292 ark::PandArg<std::string> dumpEtsSrcAfterPhases {
293 "dump-ets-src-after-phases", "", "Generate program dump as ets source code after running phases in the list"};
294 ark::PandArg<std::string> exitBeforePhase {"exit-before-phase", "",
295 "Exit compilation before running the provided phase"};
296 ark::PandArg<std::string> exitAfterPhase {"exit-after-phase", "",
297 "Exit compilation after running the provided phase"};
298 ark::PandArg<std::string> dumpAfterPhases {"dump-after-phases", "",
299 "Generate program dump after running phases in the list"};
300 ark::PandArg<bool> opListPhases {"list-phases", false, "Dump list of available phases"};
301
302 // tail arguments
303 ark::PandArg<std::string> inputFile {"input", "", "input file"};
304
305 ark::PandArg<std::string> arktsConfig;
306 // NOLINTEND(misc-non-private-member-variables-in-classes)
307
AllArgsark::es2panda::util::AllArgs308 explicit AllArgs(const char *argv0)
309 : arktsConfig {"arktsconfig", ark::es2panda::JoinPaths(ark::es2panda::ParentPath(argv0), "arktsconfig.json"),
310 "Path to arkts configuration file"}
311 {
312 }
313
ParseInputOutputark::es2panda::util::AllArgs314 bool ParseInputOutput(CompilationMode compilationMode, std::string &errorMsg, std::string &sourceFile,
315 std::string &parserInput, std::string &compilerOutput) const
316 {
317 auto isDebuggerEvalMode = opDebuggerEvalMode.GetValue();
318 if (isDebuggerEvalMode && compilationMode != CompilationMode::SINGLE_FILE) {
319 errorMsg = "Error: When compiling with --debugger-eval-mode single input file must be provided";
320 return false;
321 }
322
323 sourceFile = inputFile.GetValue();
324 if (compilationMode == CompilationMode::SINGLE_FILE) {
325 sourceFile = os::GetAbsolutePath(inputFile.GetValue());
326 std::ifstream inputStream(sourceFile.c_str());
327 if (inputStream.fail()) {
328 errorMsg = "Failed to open file: ";
329 errorMsg.append(sourceFile);
330 return false;
331 }
332
333 std::stringstream ss;
334 if (isDebuggerEvalMode) {
335 GenerateEvaluationWrapper(sourceFile, inputStream, ss);
336 } else {
337 ss << inputStream.rdbuf();
338 }
339 parserInput = ss.str();
340 }
341
342 if (!outputFile.GetValue().empty()) {
343 if (compilationMode == CompilationMode::PROJECT) {
344 errorMsg = "Error: When compiling in project mode --output key is not needed";
345 return false;
346 }
347 compilerOutput = outputFile.GetValue();
348 } else {
349 compilerOutput = RemoveExtension(BaseName(sourceFile)).append(".abc");
350 }
351
352 return true;
353 }
354
BindArgsark::es2panda::util::AllArgs355 void BindArgs(ark::PandArgParser &argparser)
356 {
357 argparser.Add(&opHelp);
358 argparser.Add(&opVersion);
359 argparser.Add(&opModule);
360 argparser.Add(&opDumpAst);
361 argparser.Add(&opDumpAstOnlySilent);
362 argparser.Add(&opDumpCheckedAst);
363 argparser.Add(&opParseOnly);
364 argparser.Add(&opDumpAssembly);
365 argparser.Add(&opDebugInfo);
366 argparser.Add(&opDumpDebugInfo);
367
368 argparser.Add(&opOptLevel);
369 argparser.Add(&opEtsModule);
370 argparser.Add(&opThreadCount);
371 argparser.Add(&opSizeStat);
372 argparser.Add(&opListFiles);
373
374 argparser.Add(&inputExtension);
375 argparser.Add(&outputFile);
376 argparser.Add(&logLevel);
377 argparser.Add(&stdLib);
378 argparser.Add(&genStdLib);
379 argparser.Add(&plugins);
380 argparser.Add(&skipPhases);
381 argparser.Add(&verifierAllChecks);
382 argparser.Add(&verifierFullProgram);
383 argparser.Add(&verifierWarnings);
384 argparser.Add(&verifierErrors);
385 argparser.Add(&dumpBeforePhases);
386 argparser.Add(&dumpEtsSrcBeforePhases);
387 argparser.Add(&exitBeforePhase);
388 argparser.Add(&dumpAfterPhases);
389 argparser.Add(&dumpEtsSrcAfterPhases);
390 argparser.Add(&exitAfterPhase);
391 argparser.Add(&opListPhases);
392 argparser.Add(&arktsConfig);
393
394 argparser.Add(&opEtsEnableAll);
395 argparser.Add(&opEtsWerror);
396 argparser.Add(&opEtsSubsetWarnings);
397 argparser.Add(&opEtsNonsubsetWarnings);
398
399 // ETS-subset warnings
400 argparser.Add(&opEtsProhibitTopLevelStatements);
401 argparser.Add(&opEtsBoostEqualityStatement);
402 argparser.Add(&opEtsRemoveLambda);
403 argparser.Add(&opEtsImplicitBoxingUnboxing);
404
405 // ETS-non-subset warnings
406 argparser.Add(&opEtsSuggestFinal);
407 argparser.Add(&opEtsRemoveAsync);
408
409 AddDebuggerEvaluationOptions(argparser);
410
411 argparser.PushBackTail(&inputFile);
412 argparser.EnableTail();
413 argparser.EnableRemainder();
414 }
415
InitCompilerOptionsark::es2panda::util::AllArgs416 void InitCompilerOptions(es2panda::CompilerOptions &compilerOptions, CompilationMode compilationMode) const
417 {
418 compilerOptions.dumpAsm = opDumpAssembly.GetValue();
419 compilerOptions.dumpAst = opDumpAst.GetValue();
420 compilerOptions.opDumpAstOnlySilent = opDumpAstOnlySilent.GetValue();
421 compilerOptions.dumpCheckedAst = opDumpCheckedAst.GetValue();
422 compilerOptions.dumpDebugInfo = opDumpDebugInfo.GetValue();
423 compilerOptions.isDebug = opDebugInfo.GetValue();
424 compilerOptions.parseOnly = opParseOnly.GetValue();
425 compilerOptions.stdLib = stdLib.GetValue();
426 compilerOptions.isEtsModule = opEtsModule.GetValue();
427 compilerOptions.plugins = SplitToStringVector(plugins.GetValue());
428 compilerOptions.skipPhases = SplitToStringSet(skipPhases.GetValue());
429 compilerOptions.verifierFullProgram = verifierFullProgram.GetValue();
430 compilerOptions.verifierAllChecks = verifierAllChecks.GetValue();
431 compilerOptions.verifierWarnings = SplitToStringSet(verifierWarnings.GetValue());
432 compilerOptions.verifierErrors = SplitToStringSet(verifierErrors.GetValue());
433 compilerOptions.dumpBeforePhases = SplitToStringSet(dumpBeforePhases.GetValue());
434 compilerOptions.dumpEtsSrcBeforePhases = SplitToStringSet(dumpEtsSrcBeforePhases.GetValue());
435 compilerOptions.exitBeforePhase = exitBeforePhase.GetValue();
436 compilerOptions.dumpAfterPhases = SplitToStringSet(dumpAfterPhases.GetValue());
437 compilerOptions.dumpEtsSrcAfterPhases = SplitToStringSet(dumpEtsSrcAfterPhases.GetValue());
438 compilerOptions.exitAfterPhase = exitAfterPhase.GetValue();
439
440 // ETS-Warnings
441 compilerOptions.etsSubsetWarnings = opEtsSubsetWarnings.GetValue();
442 compilerOptions.etsWerror = opEtsWerror.GetValue();
443 compilerOptions.etsNonsubsetWarnings = opEtsNonsubsetWarnings.GetValue();
444 compilerOptions.etsEnableAll = opEtsEnableAll.GetValue();
445
446 if (compilerOptions.etsEnableAll || compilerOptions.etsSubsetWarnings) {
447 // Adding subset warnings
448 compilerOptions.etsProhibitTopLevelStatements = ETSWarningsGroupSetter(opEtsProhibitTopLevelStatements);
449 compilerOptions.etsBoostEqualityStatement = ETSWarningsGroupSetter(opEtsBoostEqualityStatement);
450 compilerOptions.etsRemoveLambda = ETSWarningsGroupSetter(opEtsRemoveLambda);
451 compilerOptions.etsImplicitBoxingUnboxing = ETSWarningsGroupSetter(opEtsImplicitBoxingUnboxing);
452 }
453
454 if (compilerOptions.etsEnableAll || compilerOptions.etsNonsubsetWarnings) {
455 // Adding non-subset warnings
456 compilerOptions.etsSuggestFinal = ETSWarningsGroupSetter(opEtsSuggestFinal);
457 compilerOptions.etsRemoveAsync = ETSWarningsGroupSetter(opEtsRemoveAsync);
458 }
459
460 if (!compilerOptions.etsEnableAll && !compilerOptions.etsSubsetWarnings &&
461 !compilerOptions.etsNonsubsetWarnings) {
462 // If no warnings groups enabled - check all if enabled
463 compilerOptions.etsSuggestFinal = opEtsSuggestFinal.GetValue();
464 compilerOptions.etsProhibitTopLevelStatements = opEtsProhibitTopLevelStatements.GetValue();
465 compilerOptions.etsBoostEqualityStatement = opEtsBoostEqualityStatement.GetValue();
466 compilerOptions.etsRemoveAsync = opEtsRemoveAsync.GetValue();
467 compilerOptions.etsRemoveLambda = opEtsRemoveLambda.GetValue();
468 compilerOptions.etsImplicitBoxingUnboxing = opEtsImplicitBoxingUnboxing.GetValue();
469 }
470
471 InitDebuggerEvaluationCompilerOptions(compilerOptions);
472
473 // Pushing enabled warnings to warning collection
474 PushingEnabledWarnings(compilerOptions);
475
476 compilerOptions.compilationMode = compilationMode;
477 }
478
479 private:
PushingEnabledWarningsark::es2panda::util::AllArgs480 static void PushingEnabledWarnings(es2panda::CompilerOptions &compilerOptions)
481 {
482 if (compilerOptions.etsSuggestFinal) {
483 compilerOptions.etsWarningCollection.push_back(ETSWarnings::SUGGEST_FINAL);
484 }
485 if (compilerOptions.etsProhibitTopLevelStatements) {
486 compilerOptions.etsWarningCollection.push_back(ETSWarnings::PROHIBIT_TOP_LEVEL_STATEMENTS);
487 }
488 if (compilerOptions.etsBoostEqualityStatement) {
489 compilerOptions.etsWarningCollection.push_back(ETSWarnings::BOOST_EQUALITY_STATEMENT);
490 }
491 if (compilerOptions.etsRemoveAsync) {
492 compilerOptions.etsWarningCollection.push_back(ETSWarnings::REMOVE_ASYNC_FUNCTIONS);
493 }
494 if (compilerOptions.etsRemoveLambda) {
495 compilerOptions.etsWarningCollection.push_back(ETSWarnings::REMOVE_LAMBDA);
496 }
497 if (compilerOptions.etsImplicitBoxingUnboxing) {
498 compilerOptions.etsWarningCollection.push_back(ETSWarnings::IMPLICIT_BOXING_UNBOXING);
499 }
500 if (!compilerOptions.etsWarningCollection.empty()) {
501 compilerOptions.etsHasWarnings = true;
502 }
503 }
504
AddDebuggerEvaluationOptionsark::es2panda::util::AllArgs505 void AddDebuggerEvaluationOptions(ark::PandArgParser &argparser)
506 {
507 argparser.Add(&opDebuggerEvalMode);
508 argparser.Add(&opDebuggerEvalLine);
509 argparser.Add(&opDebuggerEvalSource);
510 argparser.Add(&opDebuggerEvalPandaFiles);
511 }
512
InitDebuggerEvaluationCompilerOptionsark::es2panda::util::AllArgs513 void InitDebuggerEvaluationCompilerOptions(es2panda::CompilerOptions &compilerOptions) const
514 {
515 compilerOptions.debuggerEvalMode = opDebuggerEvalMode.GetValue();
516 if (compilerOptions.debuggerEvalMode) {
517 compilerOptions.debuggerEvalLine = opDebuggerEvalLine.GetValue();
518 compilerOptions.debuggerEvalSource = opDebuggerEvalSource.GetValue();
519 compilerOptions.debuggerEvalPandaFiles = SplitToStringVector(opDebuggerEvalPandaFiles.GetValue());
520 }
521 }
522 };
523
Usage(const ark::PandArgParser & argparser)524 static std::string Usage(const ark::PandArgParser &argparser)
525 {
526 std::stringstream ss;
527
528 ss << argparser.GetErrorString() << std::endl;
529 ss << "Usage: "
530 << "es2panda"
531 << " [OPTIONS] [input file] -- [arguments]" << std::endl;
532 ss << std::endl;
533 ss << "optional arguments:" << std::endl;
534 ss << argparser.GetHelpString() << std::endl;
535
536 ss << std::endl;
537 ss << "--bco-optimizer: Argument directly to bytecode optimizer can be passed after this prefix" << std::endl;
538 ss << "--bco-compiler: Argument directly to jit-compiler inside bytecode optimizer can be passed after this "
539 "prefix"
540 << std::endl;
541
542 return ss.str();
543 }
544
GetVersion()545 static std::string GetVersion()
546 {
547 std::stringstream ss;
548
549 ss << std::endl;
550 ss << " Es2panda Version " << ES2PANDA_VERSION << std::endl;
551
552 // add check for PANDA_PRODUCT_BUILD after normal version tracking will be implemented
553 #ifdef ES2PANDA_DATE
554 ss << std::endl;
555 ss << " Build date: ";
556 ss << ES2PANDA_DATE;
557 #endif // ES2PANDA_DATE
558 #ifdef ES2PANDA_HASH
559 ss << std::endl;
560 ss << " Last commit hash: ";
561 ss << ES2PANDA_HASH;
562 ss << std::endl;
563 #endif // ES2PANDA_HASH
564
565 return ss.str();
566 }
567
Parse(int argc,const char ** argv)568 bool Options::Parse(int argc, const char **argv)
569 {
570 std::vector<std::string> es2pandaArgs;
571 std::vector<std::string> bcoCompilerArgs;
572 std::vector<std::string> bytecodeoptArgs;
573
574 SplitArgs(argc, argv, es2pandaArgs, bcoCompilerArgs, bytecodeoptArgs);
575 if (!ParseBCOCompilerOptions(bcoCompilerArgs, bytecodeoptArgs)) {
576 return false;
577 }
578
579 AllArgs allArgs(argv[0]); // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
580
581 allArgs.BindArgs(*argparser_);
582 if (!argparser_->Parse(es2pandaArgs) || allArgs.opHelp.GetValue()) {
583 errorMsg_ = Usage(*argparser_);
584 return false;
585 }
586
587 if (allArgs.opVersion.GetValue()) {
588 errorMsg_ = GetVersion();
589 return false;
590 }
591
592 // Determine compilation mode
593 auto compilationMode = DetermineCompilationMode(allArgs.genStdLib, allArgs.inputFile);
594 if (!allArgs.ParseInputOutput(compilationMode, errorMsg_, sourceFile_, parserInput_, compilerOutput_)) {
595 return false;
596 }
597
598 // Determine Extension
599 DetermineExtension(allArgs.inputExtension, allArgs.arktsConfig, compilationMode);
600 if (extension_ == es2panda::ScriptExtension::INVALID) {
601 return false;
602 }
603
604 if (extension_ != es2panda::ScriptExtension::JS && allArgs.opModule.GetValue()) {
605 errorMsg_ = "Error: --module is not supported for this extension.";
606 return false;
607 }
608
609 // Add Option Flags
610 AddOptionFlags(allArgs.opParseOnly, allArgs.opModule, allArgs.opSizeStat);
611
612 if ((allArgs.dumpEtsSrcBeforePhases.GetValue().size() + allArgs.dumpEtsSrcAfterPhases.GetValue().size() > 0) &&
613 extension_ != es2panda::ScriptExtension::ETS) {
614 errorMsg_ = "--dump-ets-src-* option is valid only with ETS extension";
615 return false;
616 }
617
618 DetermineLogLevel(allArgs.logLevel);
619 if (logLevel_ == util::LogLevel::INVALID) {
620 return false;
621 }
622
623 allArgs.InitCompilerOptions(compilerOptions_, compilationMode);
624
625 if (!ProcessEtsSpecificOptions(allArgs.arktsConfig.GetValue(), compilationMode)) {
626 return false;
627 }
628
629 optLevel_ = allArgs.opOptLevel.GetValue();
630 threadCount_ = allArgs.opThreadCount.GetValue();
631 listFiles_ = allArgs.opListFiles.GetValue();
632 listPhases_ = allArgs.opListPhases.GetValue();
633
634 return true;
635 }
636 } // namespace ark::es2panda::util
637