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