13af6ab5fSopenharmony_ci/* 23af6ab5fSopenharmony_ci * Copyright (c) 2021-2022 Huawei Device Co., Ltd. 33af6ab5fSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 43af6ab5fSopenharmony_ci * you may not use this file except in compliance with the License. 53af6ab5fSopenharmony_ci * You may obtain a copy of the License at 63af6ab5fSopenharmony_ci * 73af6ab5fSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 83af6ab5fSopenharmony_ci * 93af6ab5fSopenharmony_ci * Unless required by applicable law or agreed to in writing, software 103af6ab5fSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 113af6ab5fSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 123af6ab5fSopenharmony_ci * See the License for the specific language governing permissions and 133af6ab5fSopenharmony_ci * limitations under the License. 143af6ab5fSopenharmony_ci */ 153af6ab5fSopenharmony_ci 163af6ab5fSopenharmony_ci#include "options.h" 173af6ab5fSopenharmony_ci 183af6ab5fSopenharmony_ci#include <fstream> 193af6ab5fSopenharmony_ci#include <set> 203af6ab5fSopenharmony_ci#include <sstream> 213af6ab5fSopenharmony_ci#include <utility> 223af6ab5fSopenharmony_ci 233af6ab5fSopenharmony_ci#if defined(PANDA_TARGET_WINDOWS) 243af6ab5fSopenharmony_ci#include <io.h> 253af6ab5fSopenharmony_ci#else 263af6ab5fSopenharmony_ci#include <dirent.h> 273af6ab5fSopenharmony_ci#endif 283af6ab5fSopenharmony_ci 293af6ab5fSopenharmony_ci#include "bytecode_optimizer/bytecodeopt_options.h" 303af6ab5fSopenharmony_ci#include "compiler_options.h" 313af6ab5fSopenharmony_ci#include "os/file.h" 323af6ab5fSopenharmony_ci#include "utils/pandargs.h" 333af6ab5fSopenharmony_ci#include "utils/timers.h" 343af6ab5fSopenharmony_ci 353af6ab5fSopenharmony_ci#include "mergeProgram.h" 363af6ab5fSopenharmony_ci#include "util/helpers.h" 373af6ab5fSopenharmony_ci 383af6ab5fSopenharmony_cinamespace panda::es2panda::aot { 393af6ab5fSopenharmony_ciconstexpr char PROCESS_AS_LIST_MARK = '@'; 403af6ab5fSopenharmony_ci// item list: [filePath; recordName; moduleKind; sourceFile; pkgName; isSharedModule] 413af6ab5fSopenharmony_ciconstexpr size_t ITEM_COUNT_MERGE = 6; 423af6ab5fSopenharmony_ci// item list: [filePath; recordName; moduleKind; sourceFile; outputfile; isSharedModule] 433af6ab5fSopenharmony_ciconstexpr size_t ITEM_COUNT_NOT_MERGE = 6; 443af6ab5fSopenharmony_ciconst std::string LIST_ITEM_SEPERATOR = ";"; 453af6ab5fSopenharmony_ciconst std::set<std::string> VALID_EXTENSIONS = { "js", "ts", "as", "abc" }; 463af6ab5fSopenharmony_ci 473af6ab5fSopenharmony_citemplate <class T> 483af6ab5fSopenharmony_ciT RemoveExtension(T const &filename) 493af6ab5fSopenharmony_ci{ 503af6ab5fSopenharmony_ci typename T::size_type const P(filename.find_last_of('.')); 513af6ab5fSopenharmony_ci return P > 0 && P != T::npos ? filename.substr(0, P) : filename; 523af6ab5fSopenharmony_ci} 533af6ab5fSopenharmony_ci 543af6ab5fSopenharmony_cistatic es2panda::ScriptExtension GetScriptExtensionFromStr(const std::string &extension) 553af6ab5fSopenharmony_ci{ 563af6ab5fSopenharmony_ci if (extension == "js") { 573af6ab5fSopenharmony_ci return es2panda::ScriptExtension::JS; 583af6ab5fSopenharmony_ci } else if (extension == "ts") { 593af6ab5fSopenharmony_ci return es2panda::ScriptExtension::TS; 603af6ab5fSopenharmony_ci } else if (extension == "as") { 613af6ab5fSopenharmony_ci return es2panda::ScriptExtension::AS; 623af6ab5fSopenharmony_ci } else if (extension == "abc") { 633af6ab5fSopenharmony_ci return es2panda::ScriptExtension::ABC; 643af6ab5fSopenharmony_ci } else { 653af6ab5fSopenharmony_ci return es2panda::ScriptExtension::JS; 663af6ab5fSopenharmony_ci } 673af6ab5fSopenharmony_ci} 683af6ab5fSopenharmony_ci 693af6ab5fSopenharmony_cistatic es2panda::ScriptExtension GetScriptExtension(const std::string &filename, const std::string &inputExtension) 703af6ab5fSopenharmony_ci{ 713af6ab5fSopenharmony_ci std::string fileExtension = ""; 723af6ab5fSopenharmony_ci std::string::size_type pos(filename.find_last_of('.')); 733af6ab5fSopenharmony_ci if (pos > 0 && pos != std::string::npos) { 743af6ab5fSopenharmony_ci fileExtension = filename.substr(pos + 1); 753af6ab5fSopenharmony_ci } 763af6ab5fSopenharmony_ci 773af6ab5fSopenharmony_ci if (VALID_EXTENSIONS.find(fileExtension) != VALID_EXTENSIONS.end()) { 783af6ab5fSopenharmony_ci return GetScriptExtensionFromStr(fileExtension); 793af6ab5fSopenharmony_ci } 803af6ab5fSopenharmony_ci 813af6ab5fSopenharmony_ci return GetScriptExtensionFromStr(inputExtension); 823af6ab5fSopenharmony_ci} 833af6ab5fSopenharmony_ci 843af6ab5fSopenharmony_cistatic std::vector<std::string> GetStringItems(std::string &input, const std::string &delimiter) 853af6ab5fSopenharmony_ci{ 863af6ab5fSopenharmony_ci std::vector<std::string> items; 873af6ab5fSopenharmony_ci size_t pos = 0; 883af6ab5fSopenharmony_ci std::string token; 893af6ab5fSopenharmony_ci while ((pos = input.find(delimiter)) != std::string::npos) { 903af6ab5fSopenharmony_ci token = input.substr(0, pos); 913af6ab5fSopenharmony_ci if (!token.empty()) { 923af6ab5fSopenharmony_ci items.push_back(token); 933af6ab5fSopenharmony_ci } 943af6ab5fSopenharmony_ci input.erase(0, pos + delimiter.length()); 953af6ab5fSopenharmony_ci } 963af6ab5fSopenharmony_ci if (!input.empty()) { 973af6ab5fSopenharmony_ci items.push_back(input); 983af6ab5fSopenharmony_ci } 993af6ab5fSopenharmony_ci return items; 1003af6ab5fSopenharmony_ci} 1013af6ab5fSopenharmony_ci 1023af6ab5fSopenharmony_civoid Options::CollectInputAbcFile(const std::vector<std::string> &itemList, const std::string &inputExtension) 1033af6ab5fSopenharmony_ci{ 1043af6ab5fSopenharmony_ci std::string fileName = itemList[0]; 1053af6ab5fSopenharmony_ci // Split the fileInfo string to itemList by the delimiter ';'. If the element is empty, it will not be added to 1063af6ab5fSopenharmony_ci // the itemList. The fileInfo string of the abc file only contains the file path and pkgName, so the index 1073af6ab5fSopenharmony_ci // of pkgName is 1. 1083af6ab5fSopenharmony_ci constexpr uint32_t PKG_NAME_IDX = 1; 1093af6ab5fSopenharmony_ci es2panda::SourceFile src(fileName, "", parser::ScriptKind::SCRIPT, GetScriptExtension(fileName, 1103af6ab5fSopenharmony_ci inputExtension)); 1113af6ab5fSopenharmony_ci src.isSourceMode = false; 1123af6ab5fSopenharmony_ci if (itemList.size() > PKG_NAME_IDX && compilerOptions_.mergeAbc) { 1133af6ab5fSopenharmony_ci src.pkgName = itemList[PKG_NAME_IDX]; 1143af6ab5fSopenharmony_ci } 1153af6ab5fSopenharmony_ci sourceFiles_.push_back(src); 1163af6ab5fSopenharmony_ci} 1173af6ab5fSopenharmony_ci 1183af6ab5fSopenharmony_civoid Options::CollectInputSourceFile(const std::vector<std::string> &itemList, const std::string &inputExtension) 1193af6ab5fSopenharmony_ci{ 1203af6ab5fSopenharmony_ci std::string fileName = itemList[0]; 1213af6ab5fSopenharmony_ci std::string recordName = compilerOptions_.mergeAbc ? itemList[1] : ""; 1223af6ab5fSopenharmony_ci constexpr uint32_t SCRIPT_KIND_IDX = 2; 1233af6ab5fSopenharmony_ci constexpr uint32_t SOURCE_FIEL_IDX = 3; 1243af6ab5fSopenharmony_ci constexpr uint32_t PKG_NAME_IDX = 4; 1253af6ab5fSopenharmony_ci constexpr uint32_t Is_SHARED_MODULE_IDX = 5; 1263af6ab5fSopenharmony_ci parser::ScriptKind scriptKind; 1273af6ab5fSopenharmony_ci if (itemList[SCRIPT_KIND_IDX] == "script") { 1283af6ab5fSopenharmony_ci scriptKind = parser::ScriptKind::SCRIPT; 1293af6ab5fSopenharmony_ci } else if (itemList[SCRIPT_KIND_IDX] == "commonjs") { 1303af6ab5fSopenharmony_ci scriptKind = parser::ScriptKind::COMMONJS; 1313af6ab5fSopenharmony_ci } else { 1323af6ab5fSopenharmony_ci scriptKind = parser::ScriptKind::MODULE; 1333af6ab5fSopenharmony_ci } 1343af6ab5fSopenharmony_ci 1353af6ab5fSopenharmony_ci es2panda::SourceFile src(fileName, recordName, scriptKind, GetScriptExtension(fileName, inputExtension)); 1363af6ab5fSopenharmony_ci src.sourcefile = itemList[SOURCE_FIEL_IDX]; 1373af6ab5fSopenharmony_ci if (compilerOptions_.mergeAbc) { 1383af6ab5fSopenharmony_ci src.pkgName = itemList[PKG_NAME_IDX]; 1393af6ab5fSopenharmony_ci } 1403af6ab5fSopenharmony_ci 1413af6ab5fSopenharmony_ci if (itemList.size() == ITEM_COUNT_MERGE) { 1423af6ab5fSopenharmony_ci src.isSharedModule = itemList[Is_SHARED_MODULE_IDX] == "true"; 1433af6ab5fSopenharmony_ci } 1443af6ab5fSopenharmony_ci 1453af6ab5fSopenharmony_ci sourceFiles_.push_back(src); 1463af6ab5fSopenharmony_ci if (!compilerOptions_.mergeAbc) { 1473af6ab5fSopenharmony_ci outputFiles_.insert({fileName, itemList[PKG_NAME_IDX]}); 1483af6ab5fSopenharmony_ci } 1493af6ab5fSopenharmony_ci} 1503af6ab5fSopenharmony_ci 1513af6ab5fSopenharmony_cibool Options::CheckFilesValidity(const std::string &input, const std::vector<std::string> &itemList, 1523af6ab5fSopenharmony_ci const std::string &line) 1533af6ab5fSopenharmony_ci{ 1543af6ab5fSopenharmony_ci // For compatibility, only throw error when item list's size is bigger than given size. 1553af6ab5fSopenharmony_ci if ((compilerOptions_.mergeAbc && itemList.size() > ITEM_COUNT_MERGE) || 1563af6ab5fSopenharmony_ci (!compilerOptions_.mergeAbc && itemList.size() > ITEM_COUNT_NOT_MERGE) || itemList.empty()) { 1573af6ab5fSopenharmony_ci std::cerr << "Failed to parse line " << line << " of the input file: '" 1583af6ab5fSopenharmony_ci << input << "'." << std::endl 1593af6ab5fSopenharmony_ci << "Expected " << (compilerOptions_.mergeAbc ? ITEM_COUNT_MERGE : ITEM_COUNT_NOT_MERGE) 1603af6ab5fSopenharmony_ci << " items per line, but found " << itemList.size() << " items." << std::endl 1613af6ab5fSopenharmony_ci << "Please check the file format and content for correctness." << std::endl; 1623af6ab5fSopenharmony_ci return false; 1633af6ab5fSopenharmony_ci } 1643af6ab5fSopenharmony_ci return true; 1653af6ab5fSopenharmony_ci} 1663af6ab5fSopenharmony_ci 1673af6ab5fSopenharmony_cibool Options::IsAbcFile(const std::string &fileName, const std::string &inputExtension) 1683af6ab5fSopenharmony_ci{ 1693af6ab5fSopenharmony_ci return (GetScriptExtension(fileName, inputExtension) == es2panda::ScriptExtension::ABC); 1703af6ab5fSopenharmony_ci} 1713af6ab5fSopenharmony_ci 1723af6ab5fSopenharmony_ci// Options 1733af6ab5fSopenharmony_cibool Options::CollectInputFilesFromFileList(const std::string &input, const std::string &inputExtension) 1743af6ab5fSopenharmony_ci{ 1753af6ab5fSopenharmony_ci std::ifstream ifs; 1763af6ab5fSopenharmony_ci std::string line; 1773af6ab5fSopenharmony_ci ifs.open(panda::os::file::File::GetExtendedFilePath(input)); 1783af6ab5fSopenharmony_ci if (!ifs.is_open()) { 1793af6ab5fSopenharmony_ci std::cerr << "Failed to open source list file '" << input << "' during input file collection." << std::endl 1803af6ab5fSopenharmony_ci << "Please check if the file exists or the path is correct, " 1813af6ab5fSopenharmony_ci << "and you have the necessary permissions to access it." << std::endl; 1823af6ab5fSopenharmony_ci return false; 1833af6ab5fSopenharmony_ci } 1843af6ab5fSopenharmony_ci 1853af6ab5fSopenharmony_ci while (std::getline(ifs, line)) { 1863af6ab5fSopenharmony_ci std::vector<std::string> itemList = GetStringItems(line, LIST_ITEM_SEPERATOR); 1873af6ab5fSopenharmony_ci if (!CheckFilesValidity(input, itemList, line)) { 1883af6ab5fSopenharmony_ci return false; 1893af6ab5fSopenharmony_ci } 1903af6ab5fSopenharmony_ci if (IsAbcFile(itemList[0], inputExtension)) { 1913af6ab5fSopenharmony_ci CollectInputAbcFile(itemList, inputExtension); 1923af6ab5fSopenharmony_ci } else { 1933af6ab5fSopenharmony_ci CollectInputSourceFile(itemList, inputExtension); 1943af6ab5fSopenharmony_ci } 1953af6ab5fSopenharmony_ci } 1963af6ab5fSopenharmony_ci return true; 1973af6ab5fSopenharmony_ci} 1983af6ab5fSopenharmony_ci 1993af6ab5fSopenharmony_cibool Options::CollectInputFilesFromFileDirectory(const std::string &input, const std::string &extension) 2003af6ab5fSopenharmony_ci{ 2013af6ab5fSopenharmony_ci std::vector<std::string> files; 2023af6ab5fSopenharmony_ci if (!proto::MergeProgram::GetProtoFiles(input, extension, files)) { 2033af6ab5fSopenharmony_ci return false; 2043af6ab5fSopenharmony_ci } 2053af6ab5fSopenharmony_ci 2063af6ab5fSopenharmony_ci for (const auto &f : files) { 2073af6ab5fSopenharmony_ci es2panda::SourceFile src(f, RemoveExtension(f.substr(input.length() + 1)), 2083af6ab5fSopenharmony_ci scriptKind_, GetScriptExtensionFromStr(extension)); 2093af6ab5fSopenharmony_ci sourceFiles_.push_back(src); 2103af6ab5fSopenharmony_ci } 2113af6ab5fSopenharmony_ci 2123af6ab5fSopenharmony_ci return true; 2133af6ab5fSopenharmony_ci} 2143af6ab5fSopenharmony_ci 2153af6ab5fSopenharmony_civoid Options::ParseCacheFileOption(const std::string &cacheInput) 2163af6ab5fSopenharmony_ci{ 2173af6ab5fSopenharmony_ci if (cacheInput[0] != PROCESS_AS_LIST_MARK) { 2183af6ab5fSopenharmony_ci compilerOptions_.cacheFiles.insert({sourceFile_, cacheInput}); 2193af6ab5fSopenharmony_ci return; 2203af6ab5fSopenharmony_ci } 2213af6ab5fSopenharmony_ci 2223af6ab5fSopenharmony_ci std::ifstream ifs; 2233af6ab5fSopenharmony_ci std::string line; 2243af6ab5fSopenharmony_ci ifs.open(panda::os::file::File::GetExtendedFilePath(cacheInput.substr(1))); 2253af6ab5fSopenharmony_ci if (!ifs.is_open()) { 2263af6ab5fSopenharmony_ci std::cerr << "Failed to open cache file list from the provided path: '" << cacheInput << "'." << std::endl 2273af6ab5fSopenharmony_ci << "Please check if the file exists or the path is correct, " 2283af6ab5fSopenharmony_ci << "and you have the necessary permissions to read the file." << std::endl; 2293af6ab5fSopenharmony_ci return; 2303af6ab5fSopenharmony_ci } 2313af6ab5fSopenharmony_ci 2323af6ab5fSopenharmony_ci constexpr int cacheListItemCount = 2; 2333af6ab5fSopenharmony_ci while (std::getline(ifs, line)) { 2343af6ab5fSopenharmony_ci std::vector<std::string> itemList = GetStringItems(line, LIST_ITEM_SEPERATOR); 2353af6ab5fSopenharmony_ci if (itemList.size() != cacheListItemCount) { 2363af6ab5fSopenharmony_ci continue; 2373af6ab5fSopenharmony_ci } 2383af6ab5fSopenharmony_ci compilerOptions_.cacheFiles.insert({itemList[0], itemList[1]}); 2393af6ab5fSopenharmony_ci } 2403af6ab5fSopenharmony_ci} 2413af6ab5fSopenharmony_ci 2423af6ab5fSopenharmony_civoid Options::ParseUpdateVersionInfo(nlohmann::json &compileContextInfoJson) 2433af6ab5fSopenharmony_ci{ 2443af6ab5fSopenharmony_ci if (compileContextInfoJson.contains("updateVersionInfo") && 2453af6ab5fSopenharmony_ci compileContextInfoJson["updateVersionInfo"].is_object()) { 2463af6ab5fSopenharmony_ci std::unordered_map<std::string, std::unordered_map<std::string, PkgInfo>> updateVersionInfo {}; 2473af6ab5fSopenharmony_ci for (const auto& [abcName, versionInfo] : compileContextInfoJson["updateVersionInfo"].items()) { 2483af6ab5fSopenharmony_ci if (!versionInfo.is_object()) { 2493af6ab5fSopenharmony_ci std::cerr << "The input file '" << compilerOptions_.compileContextInfoPath 2503af6ab5fSopenharmony_ci << "' is incomplete format of json" << std::endl; 2513af6ab5fSopenharmony_ci } 2523af6ab5fSopenharmony_ci std::unordered_map<std::string, PkgInfo> pkgContextMap {}; 2533af6ab5fSopenharmony_ci for (const auto& [pkgName, version] : versionInfo.items()) { 2543af6ab5fSopenharmony_ci PkgInfo pkgInfo; 2553af6ab5fSopenharmony_ci pkgInfo.version = version; 2563af6ab5fSopenharmony_ci pkgInfo.packageName = pkgName; 2573af6ab5fSopenharmony_ci pkgContextMap[pkgName] = pkgInfo; 2583af6ab5fSopenharmony_ci } 2593af6ab5fSopenharmony_ci updateVersionInfo[abcName] = pkgContextMap; 2603af6ab5fSopenharmony_ci } 2613af6ab5fSopenharmony_ci compilerOptions_.compileContextInfo.updateVersionInfo = updateVersionInfo; 2623af6ab5fSopenharmony_ci } else if (compileContextInfoJson.contains("pkgContextInfo") && 2633af6ab5fSopenharmony_ci compileContextInfoJson["pkgContextInfo"].is_object()) { 2643af6ab5fSopenharmony_ci std::unordered_map<std::string, PkgInfo> pkgContextMap {}; 2653af6ab5fSopenharmony_ci for (const auto& [pkgName, pkgContextInfo] : compileContextInfoJson["pkgContextInfo"].items()) { 2663af6ab5fSopenharmony_ci PkgInfo pkgInfo; 2673af6ab5fSopenharmony_ci if (pkgContextInfo.contains("version") && pkgContextInfo["version"].is_string()) { 2683af6ab5fSopenharmony_ci pkgInfo.version = pkgContextInfo["version"]; 2693af6ab5fSopenharmony_ci } else { 2703af6ab5fSopenharmony_ci std::cerr << "Failed to get version from pkgContextInfo." << std::endl; 2713af6ab5fSopenharmony_ci } 2723af6ab5fSopenharmony_ci if (pkgContextInfo.contains("packageName") && pkgContextInfo["packageName"].is_string()) { 2733af6ab5fSopenharmony_ci pkgInfo.packageName = pkgContextInfo["packageName"]; 2743af6ab5fSopenharmony_ci } else { 2753af6ab5fSopenharmony_ci std::cerr << "Failed to get package name from pkgContextInfo." << std::endl; 2763af6ab5fSopenharmony_ci } 2773af6ab5fSopenharmony_ci pkgContextMap[pkgName] = pkgInfo; 2783af6ab5fSopenharmony_ci } 2793af6ab5fSopenharmony_ci compilerOptions_.compileContextInfo.pkgContextInfo = pkgContextMap; 2803af6ab5fSopenharmony_ci } else { 2813af6ab5fSopenharmony_ci UNREACHABLE(); 2823af6ab5fSopenharmony_ci } 2833af6ab5fSopenharmony_ci} 2843af6ab5fSopenharmony_ci 2853af6ab5fSopenharmony_civoid Options::ParseCompileContextInfo(const std::string compileContextInfoPath) 2863af6ab5fSopenharmony_ci{ 2873af6ab5fSopenharmony_ci std::stringstream ss; 2883af6ab5fSopenharmony_ci std::string buffer; 2893af6ab5fSopenharmony_ci if (!util::Helpers::ReadFileToBuffer(compileContextInfoPath, ss)) { 2903af6ab5fSopenharmony_ci return; 2913af6ab5fSopenharmony_ci } 2923af6ab5fSopenharmony_ci 2933af6ab5fSopenharmony_ci buffer = ss.str(); 2943af6ab5fSopenharmony_ci if (buffer.empty() || !nlohmann::json::accept(buffer)) { 2953af6ab5fSopenharmony_ci std::cerr << "The input file '" << compileContextInfoPath <<"' is incomplete format of json" << std::endl; 2963af6ab5fSopenharmony_ci return; 2973af6ab5fSopenharmony_ci } 2983af6ab5fSopenharmony_ci // Parser compile context info base on the input json file. 2993af6ab5fSopenharmony_ci nlohmann::json compileContextInfoJson = nlohmann::json::parse(buffer); 3003af6ab5fSopenharmony_ci if (!compileContextInfoJson.contains("compileEntries") || !compileContextInfoJson.contains("hspPkgNames")) { 3013af6ab5fSopenharmony_ci std::cerr << "The input json file '" << compileContextInfoPath << "' content format is incorrect" << std::endl; 3023af6ab5fSopenharmony_ci return; 3033af6ab5fSopenharmony_ci } 3043af6ab5fSopenharmony_ci if (!compileContextInfoJson["compileEntries"].is_array() || !compileContextInfoJson["hspPkgNames"].is_array()) { 3053af6ab5fSopenharmony_ci std::cerr << "The input json file '" << compileContextInfoPath << "' content type is incorrect" << std::endl; 3063af6ab5fSopenharmony_ci return; 3073af6ab5fSopenharmony_ci } 3083af6ab5fSopenharmony_ci std::set<std::string> externalPkgNames; 3093af6ab5fSopenharmony_ci for (const auto& elem : compileContextInfoJson["hspPkgNames"]) { 3103af6ab5fSopenharmony_ci if (elem.is_string()) { 3113af6ab5fSopenharmony_ci externalPkgNames.insert(elem.get<std::string>()); 3123af6ab5fSopenharmony_ci } 3133af6ab5fSopenharmony_ci } 3143af6ab5fSopenharmony_ci compilerOptions_.compileContextInfo.externalPkgNames = externalPkgNames; 3153af6ab5fSopenharmony_ci compilerOptions_.compileContextInfo.compileEntries = compileContextInfoJson["compileEntries"]; 3163af6ab5fSopenharmony_ci ParseUpdateVersionInfo(compileContextInfoJson); 3173af6ab5fSopenharmony_ci} 3183af6ab5fSopenharmony_ci 3193af6ab5fSopenharmony_ci// Collect dependencies based on the compile entries. 3203af6ab5fSopenharmony_cibool Options::NeedCollectDepsRelation() 3213af6ab5fSopenharmony_ci{ 3223af6ab5fSopenharmony_ci return compilerOptions_.enableAbcInput && !compilerOptions_.compileContextInfo.compileEntries.empty(); 3233af6ab5fSopenharmony_ci} 3243af6ab5fSopenharmony_ci 3253af6ab5fSopenharmony_ci// Remove redundant content from the abc file and remove programs generated from redundant source files. 3263af6ab5fSopenharmony_cibool Options::NeedRemoveRedundantRecord() 3273af6ab5fSopenharmony_ci{ 3283af6ab5fSopenharmony_ci return compilerOptions_.removeRedundantFile && NeedCollectDepsRelation(); 3293af6ab5fSopenharmony_ci} 3303af6ab5fSopenharmony_ci 3313af6ab5fSopenharmony_ciOptions::Options() : argparser_(new panda::PandArgParser()) {} 3323af6ab5fSopenharmony_ci 3333af6ab5fSopenharmony_ciOptions::~Options() 3343af6ab5fSopenharmony_ci{ 3353af6ab5fSopenharmony_ci delete argparser_; 3363af6ab5fSopenharmony_ci} 3373af6ab5fSopenharmony_ci 3383af6ab5fSopenharmony_cibool Options::Parse(int argc, const char **argv) 3393af6ab5fSopenharmony_ci{ 3403af6ab5fSopenharmony_ci panda::PandArg<bool> opHelp("help", false, "Print this message and exit"); 3413af6ab5fSopenharmony_ci 3423af6ab5fSopenharmony_ci // parser 3433af6ab5fSopenharmony_ci panda::PandArg<std::string> inputExtension("extension", "js", 3443af6ab5fSopenharmony_ci "Parse the input as the given extension (options: js | ts | as | abc)"); 3453af6ab5fSopenharmony_ci panda::PandArg<bool> opModule("module", false, "Parse the input as module"); 3463af6ab5fSopenharmony_ci panda::PandArg<bool> opCommonjs("commonjs", false, "Parse the input as commonjs"); 3473af6ab5fSopenharmony_ci panda::PandArg<bool> opParseOnly("parse-only", false, "Parse the input only"); 3483af6ab5fSopenharmony_ci panda::PandArg<bool> opEnableTypeCheck("enable-type-check", false, "Check the type in ts after parse"); 3493af6ab5fSopenharmony_ci panda::PandArg<bool> opDumpAst("dump-ast", false, "Dump the parsed AST"); 3503af6ab5fSopenharmony_ci panda::PandArg<bool> opDumpTransformedAst("dump-transformed-ast", false, "Dump the parsed AST after transform"); 3513af6ab5fSopenharmony_ci panda::PandArg<bool> opCheckTransformedAstStructure("check-transformed-ast-structure", false, 3523af6ab5fSopenharmony_ci "Check the AST structure after transform"); 3533af6ab5fSopenharmony_ci panda::PandArg<bool> opRecordDebugSource("record-debug-source", false, "Record source code to support "\ 3543af6ab5fSopenharmony_ci "multi-platform debugger & detailed backtrace in debug mode"); 3553af6ab5fSopenharmony_ci 3563af6ab5fSopenharmony_ci // compiler 3573af6ab5fSopenharmony_ci panda::PandArg<bool> opEnableAbcInput("enable-abc-input", false, "Allow abc file as input"); 3583af6ab5fSopenharmony_ci panda::PandArg<bool> opDumpAsmProgram("dump-asm-program", false, "Dump program"); 3593af6ab5fSopenharmony_ci std::string descOfDumpNormalizedProg = 3603af6ab5fSopenharmony_ci "Dump program in normalized form to ensure the output of source code compilation is consistent with that of " 3613af6ab5fSopenharmony_ci "abc file compilation.\n" 3623af6ab5fSopenharmony_ci " The normalized form differs mainly as follows:\n" 3633af6ab5fSopenharmony_ci " 1. all instructions will be labled consecutively and all the labels will be dumped\n" 3643af6ab5fSopenharmony_ci " 2. the content of a literal array, rather than its id, will be dumped when the literal array appears in " 3653af6ab5fSopenharmony_ci "an opcode or is nested in another literal array\n" 3663af6ab5fSopenharmony_ci " 3. labels stored in catch blocks will be unified\n" 3673af6ab5fSopenharmony_ci " 4. strings won't be dumped\n" 3683af6ab5fSopenharmony_ci " 5. invalid opcodes won't be dumped, local variables' start and end offset will skip invalid opcodes"; 3693af6ab5fSopenharmony_ci panda::PandArg<bool> opDumpNormalizedAsmProgram("dump-normalized-asm-program", false, descOfDumpNormalizedProg); 3703af6ab5fSopenharmony_ci panda::PandArg<bool> opDumpAssembly("dump-assembly", false, "Dump pandasm"); 3713af6ab5fSopenharmony_ci panda::PandArg<bool> opDebugInfo("debug-info", false, "Compile with debug info"); 3723af6ab5fSopenharmony_ci panda::PandArg<bool> opDumpDebugInfo("dump-debug-info", false, "Dump debug info"); 3733af6ab5fSopenharmony_ci panda::PandArg<int> opOptLevel("opt-level", 2, 3743af6ab5fSopenharmony_ci "Compiler optimization level (options: 0 | 1 | 2). In debug and base64Input mode, optimizer is disabled"); 3753af6ab5fSopenharmony_ci panda::PandArg<int> opFunctionThreadCount("function-threads", 0, "Number of worker threads to compile function"); 3763af6ab5fSopenharmony_ci panda::PandArg<int> opFileThreadCount("file-threads", 0, "Number of worker threads to compile file"); 3773af6ab5fSopenharmony_ci panda::PandArg<int> opAbcClassThreadCount("abc-class-threads", 4, 3783af6ab5fSopenharmony_ci "Number of worker threads to compile classes of abc file"); 3793af6ab5fSopenharmony_ci panda::PandArg<bool> opSizeStat("dump-size-stat", false, "Dump size statistics"); 3803af6ab5fSopenharmony_ci panda::PandArg<bool> opSizePctStat("dump-file-item-size", false, "Dump the size of each kind of file item "\ 3813af6ab5fSopenharmony_ci "of the abc file"); 3823af6ab5fSopenharmony_ci panda::PandArg<bool> opDumpLiteralBuffer("dump-literal-buffer", false, "Dump literal buffer"); 3833af6ab5fSopenharmony_ci panda::PandArg<std::string> outputFile("output", "", "Compiler binary output (.abc)"); 3843af6ab5fSopenharmony_ci panda::PandArg<std::string> recordName("record-name", "", "Specify the record name"); 3853af6ab5fSopenharmony_ci panda::PandArg<bool> debuggerEvaluateExpression("debugger-evaluate-expression", false, 3863af6ab5fSopenharmony_ci "evaluate expression in debugger mode"); 3873af6ab5fSopenharmony_ci panda::PandArg<std::string> base64Input("base64Input", "", "base64 input of js content"); 3883af6ab5fSopenharmony_ci panda::PandArg<bool> base64Output("base64Output", false, "output panda file content as base64 to std out"); 3893af6ab5fSopenharmony_ci panda::PandArg<std::string> sourceFile("source-file", "", 3903af6ab5fSopenharmony_ci "specify the file path info recorded in generated abc"); 3913af6ab5fSopenharmony_ci panda::PandArg<std::string> outputProto("outputProto", "", 3923af6ab5fSopenharmony_ci "specify the output name for serializd protobuf file (.protoBin)"); 3933af6ab5fSopenharmony_ci panda::PandArg<std::string> opCacheFile("cache-file", "", "cache file for incremental compile"); 3943af6ab5fSopenharmony_ci panda::PandArg<std::string> opNpmModuleEntryList("npm-module-entry-list", "", "entry list file for module compile"); 3953af6ab5fSopenharmony_ci panda::PandArg<bool> opMergeAbc("merge-abc", false, "Compile as merge abc"); 3963af6ab5fSopenharmony_ci panda::PandArg<std::string> opPerfFile("perf-file", "perf.txt", "Specify the file path to dump time consuming data"\ 3973af6ab5fSopenharmony_ci " during compilation process, default to 'perf.txt' in the current directory"); 3983af6ab5fSopenharmony_ci panda::PandArg<int> opPerfLevel("perf-level", 0, "Specify the performance data output level:"\ 3993af6ab5fSopenharmony_ci " 0: Output compilation time data(default)"); 4003af6ab5fSopenharmony_ci panda::PandArg<bool> opuseDefineSemantic("use-define-semantic", false, "Compile ts class fields "\ 4013af6ab5fSopenharmony_ci "in accordance with ECMAScript2022"); 4023af6ab5fSopenharmony_ci panda::PandArg<std::string> moduleRecordFieldName("module-record-field-name", "", "Specify the field name "\ 4033af6ab5fSopenharmony_ci "of module record in unmerged abc"); 4043af6ab5fSopenharmony_ci 4053af6ab5fSopenharmony_ci // optimizer 4063af6ab5fSopenharmony_ci panda::PandArg<bool> opBranchElimination("branch-elimination", false, "Enable branch elimination optimization"); 4073af6ab5fSopenharmony_ci panda::PandArg<bool> opOptTryCatchFunc("opt-try-catch-func", true, "Enable optimizations for functions with "\ 4083af6ab5fSopenharmony_ci "try-catch blocks"); 4093af6ab5fSopenharmony_ci 4103af6ab5fSopenharmony_ci // patchfix && hotreload 4113af6ab5fSopenharmony_ci panda::PandArg<std::string> opDumpSymbolTable("dump-symbol-table", "", "dump symbol table to file"); 4123af6ab5fSopenharmony_ci panda::PandArg<std::string> opInputSymbolTable("input-symbol-table", "", "input symbol table file"); 4133af6ab5fSopenharmony_ci panda::PandArg<bool> opGeneratePatch("generate-patch", false, "generate patch abc, default as hotfix mode unless "\ 4143af6ab5fSopenharmony_ci "the cold-fix argument is set"); 4153af6ab5fSopenharmony_ci panda::PandArg<bool> opHotReload("hot-reload", false, "compile as hot-reload mode"); 4163af6ab5fSopenharmony_ci panda::PandArg<bool> opColdReload("cold-reload", false, "compile as cold-reload mode"); 4173af6ab5fSopenharmony_ci panda::PandArg<bool> opColdFix("cold-fix", false, "generate patch abc as cold-fix mode"); 4183af6ab5fSopenharmony_ci 4193af6ab5fSopenharmony_ci // version 4203af6ab5fSopenharmony_ci panda::PandArg<bool> bcVersion("bc-version", false, "Print ark bytecode version. If both bc-version and"\ 4213af6ab5fSopenharmony_ci "bc-min-version are enabled, only bc-version will take effects"); 4223af6ab5fSopenharmony_ci panda::PandArg<bool> bcMinVersion("bc-min-version", false, "Print ark bytecode minimum supported version"); 4233af6ab5fSopenharmony_ci // todo(huyunhui): change default api verion to 0 after refactoring 4243af6ab5fSopenharmony_ci // The latest api version in isa.yaml is 15 4253af6ab5fSopenharmony_ci panda::PandArg<int> targetApiVersion("target-api-version", 15, 4263af6ab5fSopenharmony_ci "Specify the targeting api version for es2abc to generated the corresponding version of bytecode"); 4273af6ab5fSopenharmony_ci panda::PandArg<bool> targetBcVersion("target-bc-version", false, "Print the corresponding ark bytecode version"\ 4283af6ab5fSopenharmony_ci "for target api version. If both target-bc-version and bc-version are enabled, only target-bc-version"\ 4293af6ab5fSopenharmony_ci "will take effects"); 4303af6ab5fSopenharmony_ci panda::PandArg<std::string> targetApiSubVersion("target-api-sub-version", 4313af6ab5fSopenharmony_ci std::string {util::Helpers::DEFAULT_SUB_API_VERSION}, 4323af6ab5fSopenharmony_ci "Specify the targeting api sub version for es2abc to generated the corresponding version of bytecode"); 4333af6ab5fSopenharmony_ci panda::PandArg<bool> enableAnnotations("enable-annotations", false, "Permits es2abc to compile annotations"); 4343af6ab5fSopenharmony_ci 4353af6ab5fSopenharmony_ci // compile entries and pkg context info 4363af6ab5fSopenharmony_ci panda::PandArg<std::string> compileContextInfoPath("compile-context-info", "", "The path to compile context"\ 4373af6ab5fSopenharmony_ci "info file"); 4383af6ab5fSopenharmony_ci panda::PandArg<bool> opDumpDepsInfo("dump-deps-info", false, "Dump all dependency files and records "\ 4393af6ab5fSopenharmony_ci "including source files and bytecode files"); 4403af6ab5fSopenharmony_ci panda::PandArg<bool> opRemoveRedundantFile("remove-redundant-file", false, "Remove redundant info"\ 4413af6ab5fSopenharmony_ci " from abc file and remove redundant source file, which is effective when the compile-context-info switch"\ 4423af6ab5fSopenharmony_ci " is turned on and there is abc input"); 4433af6ab5fSopenharmony_ci panda::PandArg<bool> opDumpString("dump-string", false, "Dump program strings"); 4443af6ab5fSopenharmony_ci 4453af6ab5fSopenharmony_ci // aop transform 4463af6ab5fSopenharmony_ci panda::PandArg<std::string> transformLib("transform-lib", "", "aop transform lib file path"); 4473af6ab5fSopenharmony_ci 4483af6ab5fSopenharmony_ci // tail arguments 4493af6ab5fSopenharmony_ci panda::PandArg<std::string> inputFile("input", "", "input file"); 4503af6ab5fSopenharmony_ci 4513af6ab5fSopenharmony_ci argparser_->Add(&opHelp); 4523af6ab5fSopenharmony_ci argparser_->Add(&opModule); 4533af6ab5fSopenharmony_ci argparser_->Add(&opCommonjs); 4543af6ab5fSopenharmony_ci argparser_->Add(&opDumpAst); 4553af6ab5fSopenharmony_ci argparser_->Add(&opDumpTransformedAst); 4563af6ab5fSopenharmony_ci argparser_->Add(&opCheckTransformedAstStructure); 4573af6ab5fSopenharmony_ci argparser_->Add(&opRecordDebugSource); 4583af6ab5fSopenharmony_ci argparser_->Add(&opParseOnly); 4593af6ab5fSopenharmony_ci argparser_->Add(&opEnableTypeCheck); 4603af6ab5fSopenharmony_ci argparser_->Add(&opEnableAbcInput); 4613af6ab5fSopenharmony_ci argparser_->Add(&opDumpAsmProgram); 4623af6ab5fSopenharmony_ci argparser_->Add(&opDumpNormalizedAsmProgram); 4633af6ab5fSopenharmony_ci argparser_->Add(&opDumpAssembly); 4643af6ab5fSopenharmony_ci argparser_->Add(&opDebugInfo); 4653af6ab5fSopenharmony_ci argparser_->Add(&opDumpDebugInfo); 4663af6ab5fSopenharmony_ci argparser_->Add(&debuggerEvaluateExpression); 4673af6ab5fSopenharmony_ci argparser_->Add(&base64Input); 4683af6ab5fSopenharmony_ci argparser_->Add(&base64Output); 4693af6ab5fSopenharmony_ci 4703af6ab5fSopenharmony_ci argparser_->Add(&opOptLevel); 4713af6ab5fSopenharmony_ci argparser_->Add(&opFunctionThreadCount); 4723af6ab5fSopenharmony_ci argparser_->Add(&opFileThreadCount); 4733af6ab5fSopenharmony_ci argparser_->Add(&opAbcClassThreadCount); 4743af6ab5fSopenharmony_ci argparser_->Add(&opSizeStat); 4753af6ab5fSopenharmony_ci argparser_->Add(&opSizePctStat); 4763af6ab5fSopenharmony_ci argparser_->Add(&opDumpLiteralBuffer); 4773af6ab5fSopenharmony_ci 4783af6ab5fSopenharmony_ci argparser_->Add(&inputExtension); 4793af6ab5fSopenharmony_ci argparser_->Add(&outputFile); 4803af6ab5fSopenharmony_ci argparser_->Add(&sourceFile); 4813af6ab5fSopenharmony_ci argparser_->Add(&recordName); 4823af6ab5fSopenharmony_ci argparser_->Add(&outputProto); 4833af6ab5fSopenharmony_ci argparser_->Add(&opCacheFile); 4843af6ab5fSopenharmony_ci argparser_->Add(&opNpmModuleEntryList); 4853af6ab5fSopenharmony_ci argparser_->Add(&opMergeAbc); 4863af6ab5fSopenharmony_ci argparser_->Add(&opPerfLevel); 4873af6ab5fSopenharmony_ci argparser_->Add(&opPerfFile); 4883af6ab5fSopenharmony_ci argparser_->Add(&opuseDefineSemantic); 4893af6ab5fSopenharmony_ci argparser_->Add(&moduleRecordFieldName); 4903af6ab5fSopenharmony_ci argparser_->Add(&opBranchElimination); 4913af6ab5fSopenharmony_ci argparser_->Add(&opOptTryCatchFunc); 4923af6ab5fSopenharmony_ci 4933af6ab5fSopenharmony_ci argparser_->Add(&opDumpSymbolTable); 4943af6ab5fSopenharmony_ci argparser_->Add(&opInputSymbolTable); 4953af6ab5fSopenharmony_ci argparser_->Add(&opGeneratePatch); 4963af6ab5fSopenharmony_ci argparser_->Add(&opHotReload); 4973af6ab5fSopenharmony_ci argparser_->Add(&opColdReload); 4983af6ab5fSopenharmony_ci argparser_->Add(&opColdFix); 4993af6ab5fSopenharmony_ci 5003af6ab5fSopenharmony_ci argparser_->Add(&bcVersion); 5013af6ab5fSopenharmony_ci argparser_->Add(&bcMinVersion); 5023af6ab5fSopenharmony_ci argparser_->Add(&targetApiVersion); 5033af6ab5fSopenharmony_ci argparser_->Add(&targetBcVersion); 5043af6ab5fSopenharmony_ci argparser_->Add(&targetApiSubVersion); 5053af6ab5fSopenharmony_ci argparser_->Add(&enableAnnotations); 5063af6ab5fSopenharmony_ci 5073af6ab5fSopenharmony_ci argparser_->Add(&compileContextInfoPath); 5083af6ab5fSopenharmony_ci argparser_->Add(&opDumpDepsInfo); 5093af6ab5fSopenharmony_ci argparser_->Add(&opRemoveRedundantFile); 5103af6ab5fSopenharmony_ci argparser_->Add(&opDumpString); 5113af6ab5fSopenharmony_ci 5123af6ab5fSopenharmony_ci argparser_->Add(&transformLib); 5133af6ab5fSopenharmony_ci 5143af6ab5fSopenharmony_ci argparser_->PushBackTail(&inputFile); 5153af6ab5fSopenharmony_ci argparser_->EnableTail(); 5163af6ab5fSopenharmony_ci argparser_->EnableRemainder(); 5173af6ab5fSopenharmony_ci 5183af6ab5fSopenharmony_ci bool parseStatus = argparser_->Parse(argc, argv); 5193af6ab5fSopenharmony_ci 5203af6ab5fSopenharmony_ci compilerOptions_.targetApiVersion = targetApiVersion.GetValue(); 5213af6ab5fSopenharmony_ci compilerOptions_.targetApiSubVersion = targetApiSubVersion.GetValue(); 5223af6ab5fSopenharmony_ci if (parseStatus && targetBcVersion.GetValue()) { 5233af6ab5fSopenharmony_ci compilerOptions_.targetBcVersion = targetBcVersion.GetValue(); 5243af6ab5fSopenharmony_ci return true; 5253af6ab5fSopenharmony_ci } 5263af6ab5fSopenharmony_ci 5273af6ab5fSopenharmony_ci if (parseStatus && (bcVersion.GetValue() || bcMinVersion.GetValue())) { 5283af6ab5fSopenharmony_ci compilerOptions_.bcVersion = bcVersion.GetValue(); 5293af6ab5fSopenharmony_ci compilerOptions_.bcMinVersion = bcMinVersion.GetValue(); 5303af6ab5fSopenharmony_ci return true; 5313af6ab5fSopenharmony_ci } 5323af6ab5fSopenharmony_ci 5333af6ab5fSopenharmony_ci if (!parseStatus || opHelp.GetValue() || (inputFile.GetValue().empty() && base64Input.GetValue().empty())) { 5343af6ab5fSopenharmony_ci std::stringstream ss; 5353af6ab5fSopenharmony_ci 5363af6ab5fSopenharmony_ci ss << argparser_->GetErrorString() << std::endl; 5373af6ab5fSopenharmony_ci ss << "Usage: " 5383af6ab5fSopenharmony_ci << "es2panda" 5393af6ab5fSopenharmony_ci << " [OPTIONS] [input file] -- [arguments]" << std::endl; 5403af6ab5fSopenharmony_ci ss << std::endl; 5413af6ab5fSopenharmony_ci ss << "optional arguments:" << std::endl; 5423af6ab5fSopenharmony_ci ss << argparser_->GetHelpString() << std::endl; 5433af6ab5fSopenharmony_ci 5443af6ab5fSopenharmony_ci errorMsg_ = ss.str(); 5453af6ab5fSopenharmony_ci return false; 5463af6ab5fSopenharmony_ci } 5473af6ab5fSopenharmony_ci 5483af6ab5fSopenharmony_ci bool inputIsEmpty = inputFile.GetValue().empty(); 5493af6ab5fSopenharmony_ci bool base64InputIsEmpty = base64Input.GetValue().empty(); 5503af6ab5fSopenharmony_ci bool outputIsEmpty = outputFile.GetValue().empty(); 5513af6ab5fSopenharmony_ci 5523af6ab5fSopenharmony_ci if (!inputIsEmpty && !base64InputIsEmpty) { 5533af6ab5fSopenharmony_ci errorMsg_ = "--input and --base64Input can not be used simultaneously"; 5543af6ab5fSopenharmony_ci return false; 5553af6ab5fSopenharmony_ci } 5563af6ab5fSopenharmony_ci 5573af6ab5fSopenharmony_ci if (!outputIsEmpty && base64Output.GetValue()) { 5583af6ab5fSopenharmony_ci errorMsg_ = "--output and --base64Output can not be used simultaneously"; 5593af6ab5fSopenharmony_ci return false; 5603af6ab5fSopenharmony_ci } 5613af6ab5fSopenharmony_ci 5623af6ab5fSopenharmony_ci if (opModule.GetValue() && opCommonjs.GetValue()) { 5633af6ab5fSopenharmony_ci errorMsg_ = "[--module] and [--commonjs] can not be used simultaneously"; 5643af6ab5fSopenharmony_ci return false; 5653af6ab5fSopenharmony_ci } 5663af6ab5fSopenharmony_ci 5673af6ab5fSopenharmony_ci if (opModule.GetValue()) { 5683af6ab5fSopenharmony_ci scriptKind_ = es2panda::parser::ScriptKind::MODULE; 5693af6ab5fSopenharmony_ci } else if (opCommonjs.GetValue()) { 5703af6ab5fSopenharmony_ci scriptKind_ = es2panda::parser::ScriptKind::COMMONJS; 5713af6ab5fSopenharmony_ci } else { 5723af6ab5fSopenharmony_ci scriptKind_ = es2panda::parser::ScriptKind::SCRIPT; 5733af6ab5fSopenharmony_ci } 5743af6ab5fSopenharmony_ci 5753af6ab5fSopenharmony_ci std::string extension = inputExtension.GetValue(); 5763af6ab5fSopenharmony_ci if (!extension.empty()) { 5773af6ab5fSopenharmony_ci if (VALID_EXTENSIONS.find(extension) == VALID_EXTENSIONS.end()) { 5783af6ab5fSopenharmony_ci errorMsg_ = "Invalid extension (available options: js, ts, as, abc)"; 5793af6ab5fSopenharmony_ci return false; 5803af6ab5fSopenharmony_ci } 5813af6ab5fSopenharmony_ci } 5823af6ab5fSopenharmony_ci 5833af6ab5fSopenharmony_ci bool isInputFileList = false; 5843af6ab5fSopenharmony_ci if (!inputIsEmpty) { 5853af6ab5fSopenharmony_ci std::string rawInput = inputFile.GetValue(); 5863af6ab5fSopenharmony_ci isInputFileList = rawInput[0] == PROCESS_AS_LIST_MARK; 5873af6ab5fSopenharmony_ci std::string input = isInputFileList ? rawInput.substr(1) : rawInput; 5883af6ab5fSopenharmony_ci sourceFile_ = input; 5893af6ab5fSopenharmony_ci } 5903af6ab5fSopenharmony_ci 5913af6ab5fSopenharmony_ci if (base64Output.GetValue()) { 5923af6ab5fSopenharmony_ci compilerOutput_ = ""; 5933af6ab5fSopenharmony_ci } else if (!outputIsEmpty) { 5943af6ab5fSopenharmony_ci compilerOutput_ = outputFile.GetValue(); 5953af6ab5fSopenharmony_ci } else if (outputIsEmpty && !inputIsEmpty) { 5963af6ab5fSopenharmony_ci compilerOutput_ = RemoveExtension(util::Helpers::BaseName(sourceFile_)).append(".abc"); 5973af6ab5fSopenharmony_ci } 5983af6ab5fSopenharmony_ci 5993af6ab5fSopenharmony_ci if (opMergeAbc.GetValue()) { 6003af6ab5fSopenharmony_ci recordName_ = recordName.GetValue(); 6013af6ab5fSopenharmony_ci if (recordName_.empty()) { 6023af6ab5fSopenharmony_ci recordName_ = compilerOutput_.empty() ? "Base64Output" : 6033af6ab5fSopenharmony_ci RemoveExtension(util::Helpers::BaseName(compilerOutput_)); 6043af6ab5fSopenharmony_ci } 6053af6ab5fSopenharmony_ci compilerOptions_.mergeAbc = opMergeAbc.GetValue(); 6063af6ab5fSopenharmony_ci } 6073af6ab5fSopenharmony_ci 6083af6ab5fSopenharmony_ci if (opuseDefineSemantic.GetValue()) { 6093af6ab5fSopenharmony_ci compilerOptions_.useDefineSemantic = opuseDefineSemantic.GetValue(); 6103af6ab5fSopenharmony_ci } 6113af6ab5fSopenharmony_ci 6123af6ab5fSopenharmony_ci if (!inputIsEmpty) { 6133af6ab5fSopenharmony_ci // common mode 6143af6ab5fSopenharmony_ci auto inputAbs = panda::os::file::File::GetAbsolutePath(sourceFile_); 6153af6ab5fSopenharmony_ci if (!inputAbs) { 6163af6ab5fSopenharmony_ci std::cerr << "Failed to find file '" << sourceFile_ << "' during input file resolution" << std::endl 6173af6ab5fSopenharmony_ci << "Please check if the file name is correct, the file exists at the specified path, " 6183af6ab5fSopenharmony_ci << "and your project has the necessary permissions to access it." << std::endl; 6193af6ab5fSopenharmony_ci return false; 6203af6ab5fSopenharmony_ci } 6213af6ab5fSopenharmony_ci 6223af6ab5fSopenharmony_ci auto fpath = inputAbs.Value(); 6233af6ab5fSopenharmony_ci if (isInputFileList) { 6243af6ab5fSopenharmony_ci CollectInputFilesFromFileList(fpath, extension); 6253af6ab5fSopenharmony_ci } else if (panda::os::file::File::IsDirectory(fpath)) { 6263af6ab5fSopenharmony_ci CollectInputFilesFromFileDirectory(fpath, extension); 6273af6ab5fSopenharmony_ci } else { 6283af6ab5fSopenharmony_ci es2panda::SourceFile src(sourceFile_, recordName_, scriptKind_, GetScriptExtension(sourceFile_, extension)); 6293af6ab5fSopenharmony_ci src.isSourceMode = !IsAbcFile(sourceFile_, extension); 6303af6ab5fSopenharmony_ci sourceFiles_.push_back(src); 6313af6ab5fSopenharmony_ci } 6323af6ab5fSopenharmony_ci } else if (!base64InputIsEmpty) { 6333af6ab5fSopenharmony_ci // input content is base64 string 6343af6ab5fSopenharmony_ci base64Input_ = ExtractContentFromBase64Input(base64Input.GetValue()); 6353af6ab5fSopenharmony_ci if (base64Input_.empty()) { 6363af6ab5fSopenharmony_ci errorMsg_ = "The input string is not a valid base64 data"; 6373af6ab5fSopenharmony_ci return false; 6383af6ab5fSopenharmony_ci } 6393af6ab5fSopenharmony_ci 6403af6ab5fSopenharmony_ci es2panda::SourceFile src("", recordName_, es2panda::parser::ScriptKind::SCRIPT, 6413af6ab5fSopenharmony_ci GetScriptExtensionFromStr(extension)); 6423af6ab5fSopenharmony_ci src.source = base64Input_; 6433af6ab5fSopenharmony_ci sourceFiles_.push_back(src); 6443af6ab5fSopenharmony_ci } 6453af6ab5fSopenharmony_ci 6463af6ab5fSopenharmony_ci if (!outputProto.GetValue().empty()) { 6473af6ab5fSopenharmony_ci compilerProtoOutput_ = outputProto.GetValue(); 6483af6ab5fSopenharmony_ci } 6493af6ab5fSopenharmony_ci 6503af6ab5fSopenharmony_ci optLevel_ = opOptLevel.GetValue(); 6513af6ab5fSopenharmony_ci functionThreadCount_ = opFunctionThreadCount.GetValue(); 6523af6ab5fSopenharmony_ci fileThreadCount_ = opFileThreadCount.GetValue(); 6533af6ab5fSopenharmony_ci abcClassThreadCount_ = opAbcClassThreadCount.GetValue(); 6543af6ab5fSopenharmony_ci npmModuleEntryList_ = opNpmModuleEntryList.GetValue(); 6553af6ab5fSopenharmony_ci 6563af6ab5fSopenharmony_ci if (!opCacheFile.GetValue().empty()) { 6573af6ab5fSopenharmony_ci ParseCacheFileOption(opCacheFile.GetValue()); 6583af6ab5fSopenharmony_ci } 6593af6ab5fSopenharmony_ci 6603af6ab5fSopenharmony_ci if (opParseOnly.GetValue()) { 6613af6ab5fSopenharmony_ci options_ |= OptionFlags::PARSE_ONLY; 6623af6ab5fSopenharmony_ci } 6633af6ab5fSopenharmony_ci 6643af6ab5fSopenharmony_ci if (opSizeStat.GetValue()) { 6653af6ab5fSopenharmony_ci options_ |= OptionFlags::SIZE_STAT; 6663af6ab5fSopenharmony_ci } 6673af6ab5fSopenharmony_ci 6683af6ab5fSopenharmony_ci if (opSizePctStat.GetValue()) { 6693af6ab5fSopenharmony_ci options_ |= OptionFlags::SIZE_PCT_STAT; 6703af6ab5fSopenharmony_ci } 6713af6ab5fSopenharmony_ci 6723af6ab5fSopenharmony_ci perfFile_ = ""; 6733af6ab5fSopenharmony_ci perfLevel_ = opPerfLevel.GetValue(); 6743af6ab5fSopenharmony_ci if (opPerfFile.WasSet() && (perfLevel_ == 0)) { 6753af6ab5fSopenharmony_ci perfFile_ = opPerfFile.GetValue().empty() ? opPerfFile.GetDefaultValue() : opPerfFile.GetValue(); 6763af6ab5fSopenharmony_ci } 6773af6ab5fSopenharmony_ci panda::Timer::InitializeTimer(perfFile_); 6783af6ab5fSopenharmony_ci 6793af6ab5fSopenharmony_ci compilerOptions_.recordDebugSource = opRecordDebugSource.GetValue(); 6803af6ab5fSopenharmony_ci compilerOptions_.enableAbcInput = opEnableAbcInput.GetValue(); 6813af6ab5fSopenharmony_ci compilerOptions_.dumpAsmProgram = opDumpAsmProgram.GetValue(); 6823af6ab5fSopenharmony_ci compilerOptions_.dumpNormalizedAsmProgram = opDumpNormalizedAsmProgram.GetValue(); 6833af6ab5fSopenharmony_ci compilerOptions_.dumpAsm = opDumpAssembly.GetValue(); 6843af6ab5fSopenharmony_ci compilerOptions_.dumpAst = opDumpAst.GetValue(); 6853af6ab5fSopenharmony_ci compilerOptions_.dumpTransformedAst = opDumpTransformedAst.GetValue(); 6863af6ab5fSopenharmony_ci compilerOptions_.checkTransformedAstStructure = opCheckTransformedAstStructure.GetValue(); 6873af6ab5fSopenharmony_ci compilerOptions_.dumpDebugInfo = opDumpDebugInfo.GetValue(); 6883af6ab5fSopenharmony_ci compilerOptions_.isDebug = opDebugInfo.GetValue(); 6893af6ab5fSopenharmony_ci compilerOptions_.parseOnly = opParseOnly.GetValue(); 6903af6ab5fSopenharmony_ci compilerOptions_.enableTypeCheck = opEnableTypeCheck.GetValue(); 6913af6ab5fSopenharmony_ci compilerOptions_.dumpLiteralBuffer = opDumpLiteralBuffer.GetValue(); 6923af6ab5fSopenharmony_ci compilerOptions_.isDebuggerEvaluateExpressionMode = debuggerEvaluateExpression.GetValue(); 6933af6ab5fSopenharmony_ci 6943af6ab5fSopenharmony_ci compilerOptions_.functionThreadCount = functionThreadCount_; 6953af6ab5fSopenharmony_ci compilerOptions_.fileThreadCount = fileThreadCount_; 6963af6ab5fSopenharmony_ci compilerOptions_.abcClassThreadCount = abcClassThreadCount_; 6973af6ab5fSopenharmony_ci compilerOptions_.output = compilerOutput_; 6983af6ab5fSopenharmony_ci compilerOptions_.debugInfoSourceFile = sourceFile.GetValue(); 6993af6ab5fSopenharmony_ci compilerOptions_.optLevel = (compilerOptions_.isDebug || !base64Input.GetValue().empty() || 7003af6ab5fSopenharmony_ci base64Output.GetValue()) ? 0 : opOptLevel.GetValue(); 7013af6ab5fSopenharmony_ci compilerOptions_.sourceFiles = sourceFiles_; 7023af6ab5fSopenharmony_ci compilerOptions_.mergeAbc = opMergeAbc.GetValue(); 7033af6ab5fSopenharmony_ci compilerOptions_.compileContextInfoPath = compileContextInfoPath.GetValue(); 7043af6ab5fSopenharmony_ci if (!compileContextInfoPath.GetValue().empty()) { 7053af6ab5fSopenharmony_ci ParseCompileContextInfo(compileContextInfoPath.GetValue()); 7063af6ab5fSopenharmony_ci } 7073af6ab5fSopenharmony_ci compilerOptions_.dumpDepsInfo = opDumpDepsInfo.GetValue(); 7083af6ab5fSopenharmony_ci compilerOptions_.updatePkgVersionForAbcInput = compilerOptions_.enableAbcInput && 7093af6ab5fSopenharmony_ci (!compilerOptions_.compileContextInfo.pkgContextInfo.empty() || 7103af6ab5fSopenharmony_ci !compilerOptions_.compileContextInfo.updateVersionInfo.empty()); 7113af6ab5fSopenharmony_ci compilerOptions_.removeRedundantFile = opRemoveRedundantFile.GetValue(); 7123af6ab5fSopenharmony_ci compilerOptions_.dumpString = opDumpString.GetValue(); 7133af6ab5fSopenharmony_ci compilerOptions_.moduleRecordFieldName = moduleRecordFieldName.GetValue(); 7143af6ab5fSopenharmony_ci 7153af6ab5fSopenharmony_ci compilerOptions_.patchFixOptions.dumpSymbolTable = opDumpSymbolTable.GetValue(); 7163af6ab5fSopenharmony_ci compilerOptions_.patchFixOptions.symbolTable = opInputSymbolTable.GetValue(); 7173af6ab5fSopenharmony_ci 7183af6ab5fSopenharmony_ci bool generatePatch = opGeneratePatch.GetValue(); 7193af6ab5fSopenharmony_ci bool hotReload = opHotReload.GetValue(); 7203af6ab5fSopenharmony_ci bool coldReload = opColdReload.GetValue(); 7213af6ab5fSopenharmony_ci bool coldFix = opColdFix.GetValue(); 7223af6ab5fSopenharmony_ci if (generatePatch && hotReload) { 7233af6ab5fSopenharmony_ci errorMsg_ = "--generate-patch and --hot-reload can not be used simultaneously"; 7243af6ab5fSopenharmony_ci return false; 7253af6ab5fSopenharmony_ci } 7263af6ab5fSopenharmony_ci if (coldFix && !generatePatch) { 7273af6ab5fSopenharmony_ci errorMsg_ = "--cold-fix can not be used without --generate-patch"; 7283af6ab5fSopenharmony_ci return false; 7293af6ab5fSopenharmony_ci } 7303af6ab5fSopenharmony_ci compilerOptions_.patchFixOptions.generatePatch = generatePatch; 7313af6ab5fSopenharmony_ci compilerOptions_.patchFixOptions.hotReload = hotReload; 7323af6ab5fSopenharmony_ci compilerOptions_.patchFixOptions.coldReload = coldReload; 7333af6ab5fSopenharmony_ci compilerOptions_.patchFixOptions.coldFix = coldFix; 7343af6ab5fSopenharmony_ci 7353af6ab5fSopenharmony_ci compilerOptions_.enableAnnotations = enableAnnotations.GetValue(); 7363af6ab5fSopenharmony_ci 7373af6ab5fSopenharmony_ci bool transformLibIsEmpty = transformLib.GetValue().empty(); 7383af6ab5fSopenharmony_ci if (!transformLibIsEmpty) { 7393af6ab5fSopenharmony_ci auto libName = transformLib.GetValue(); 7403af6ab5fSopenharmony_ci // check file exist or not 7413af6ab5fSopenharmony_ci auto transformLibAbs = panda::os::file::File::GetAbsolutePath(libName); 7423af6ab5fSopenharmony_ci if (!transformLibAbs) { 7433af6ab5fSopenharmony_ci std::cerr << "Failed to find file '" << libName << "' during transformLib file resolution" << std::endl 7443af6ab5fSopenharmony_ci << "Please check if the file name is correct, the file exists at the specified path, " 7453af6ab5fSopenharmony_ci << "and your project has the necessary permissions to access it." << std::endl; 7463af6ab5fSopenharmony_ci return false; 7473af6ab5fSopenharmony_ci } 7483af6ab5fSopenharmony_ci compilerOptions_.transformLib = transformLibAbs.Value(); 7493af6ab5fSopenharmony_ci } 7503af6ab5fSopenharmony_ci 7513af6ab5fSopenharmony_ci compilerOptions_.branchElimination = opBranchElimination.GetValue(); 7523af6ab5fSopenharmony_ci compilerOptions_.requireGlobalOptimization = compilerOptions_.optLevel > 0 && 7533af6ab5fSopenharmony_ci compilerOptions_.branchElimination && 7543af6ab5fSopenharmony_ci compilerOptions_.mergeAbc; 7553af6ab5fSopenharmony_ci panda::compiler::options.SetCompilerBranchElimination(compilerOptions_.branchElimination); 7563af6ab5fSopenharmony_ci panda::bytecodeopt::options.SetSkipMethodsWithEh(!opOptTryCatchFunc.GetValue()); 7573af6ab5fSopenharmony_ci 7583af6ab5fSopenharmony_ci return true; 7593af6ab5fSopenharmony_ci} 7603af6ab5fSopenharmony_ci 7613af6ab5fSopenharmony_cistd::string Options::ExtractContentFromBase64Input(const std::string &inputBase64String) 7623af6ab5fSopenharmony_ci{ 7633af6ab5fSopenharmony_ci std::string inputContent = util::Base64Decode(inputBase64String); 7643af6ab5fSopenharmony_ci if (inputContent == "") { 7653af6ab5fSopenharmony_ci return ""; 7663af6ab5fSopenharmony_ci } 7673af6ab5fSopenharmony_ci bool validBase64Input = util::Base64Encode(inputContent) == inputBase64String; 7683af6ab5fSopenharmony_ci if (!validBase64Input) { 7693af6ab5fSopenharmony_ci return ""; 7703af6ab5fSopenharmony_ci } 7713af6ab5fSopenharmony_ci return inputContent; 7723af6ab5fSopenharmony_ci} 7733af6ab5fSopenharmony_ci} // namespace panda::es2panda::aot 774