13af6ab5fSopenharmony_ci/* 23af6ab5fSopenharmony_ci * Copyright (c) 2021-2024 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 "ETSchecker.h" 173af6ab5fSopenharmony_ci 183af6ab5fSopenharmony_ci#include "es2panda.h" 193af6ab5fSopenharmony_ci#include "ir/base/classDefinition.h" 203af6ab5fSopenharmony_ci#include "ir/expression.h" 213af6ab5fSopenharmony_ci#include "ir/expressions/callExpression.h" 223af6ab5fSopenharmony_ci#include "ir/ts/tsInterfaceDeclaration.h" 233af6ab5fSopenharmony_ci#include "ir/statements/blockStatement.h" 243af6ab5fSopenharmony_ci#include "varbinder/ETSBinder.h" 253af6ab5fSopenharmony_ci#include "parser/program/program.h" 263af6ab5fSopenharmony_ci#include "checker/ets/aliveAnalyzer.h" 273af6ab5fSopenharmony_ci#include "checker/ets/assignAnalyzer.h" 283af6ab5fSopenharmony_ci#include "checker/ets/etsWarningAnalyzer.h" 293af6ab5fSopenharmony_ci#include "checker/types/globalTypesHolder.h" 303af6ab5fSopenharmony_ci#include "ir/base/scriptFunction.h" 313af6ab5fSopenharmony_ci#include "util/helpers.h" 323af6ab5fSopenharmony_ci#include "evaluate/scopedDebugInfoPlugin.h" 333af6ab5fSopenharmony_ci 343af6ab5fSopenharmony_cinamespace ark::es2panda::checker { 353af6ab5fSopenharmony_ci 363af6ab5fSopenharmony_cistatic util::StringView InitBuiltin(ETSChecker *checker, std::string_view signature) 373af6ab5fSopenharmony_ci{ 383af6ab5fSopenharmony_ci const auto varMap = checker->VarBinder()->TopScope()->Bindings(); 393af6ab5fSopenharmony_ci const auto iterator = varMap.find(signature); 403af6ab5fSopenharmony_ci ASSERT(iterator != varMap.end()); 413af6ab5fSopenharmony_ci auto *var = iterator->second; 423af6ab5fSopenharmony_ci Type *type {nullptr}; 433af6ab5fSopenharmony_ci if (var->Declaration()->Node()->IsClassDefinition()) { 443af6ab5fSopenharmony_ci type = checker->BuildBasicClassProperties(var->Declaration()->Node()->AsClassDefinition()); 453af6ab5fSopenharmony_ci } else { 463af6ab5fSopenharmony_ci ASSERT(var->Declaration()->Node()->IsTSInterfaceDeclaration()); 473af6ab5fSopenharmony_ci type = checker->BuildBasicInterfaceProperties(var->Declaration()->Node()->AsTSInterfaceDeclaration()); 483af6ab5fSopenharmony_ci } 493af6ab5fSopenharmony_ci checker->GetGlobalTypesHolder()->InitializeBuiltin(iterator->first, type); 503af6ab5fSopenharmony_ci return iterator->first; 513af6ab5fSopenharmony_ci} 523af6ab5fSopenharmony_ci 533af6ab5fSopenharmony_cistatic void SetupFunctionalInterface(ETSObjectType *type) 543af6ab5fSopenharmony_ci{ 553af6ab5fSopenharmony_ci type->AddObjectFlag(ETSObjectFlags::FUNCTIONAL); 563af6ab5fSopenharmony_ci auto *invoke = type->GetOwnProperty<PropertyType::INSTANCE_METHOD>(FUNCTIONAL_INTERFACE_INVOKE_METHOD_NAME); 573af6ab5fSopenharmony_ci auto *invokeType = invoke->TsType()->AsETSFunctionType(); 583af6ab5fSopenharmony_ci ASSERT(invokeType->CallSignatures().size() == 1); 593af6ab5fSopenharmony_ci auto *signature = invokeType->CallSignatures()[0]; 603af6ab5fSopenharmony_ci signature->AddSignatureFlag(SignatureFlags::FUNCTIONAL_INTERFACE_SIGNATURE); 613af6ab5fSopenharmony_ci} 623af6ab5fSopenharmony_ci 633af6ab5fSopenharmony_cistatic void SetupBuiltinMember(varbinder::Variable *var) 643af6ab5fSopenharmony_ci{ 653af6ab5fSopenharmony_ci auto *type = var->TsType(); 663af6ab5fSopenharmony_ci if (type == nullptr || !type->IsETSObjectType()) { 673af6ab5fSopenharmony_ci return; 683af6ab5fSopenharmony_ci } 693af6ab5fSopenharmony_ci} 703af6ab5fSopenharmony_ci 713af6ab5fSopenharmony_ci// NOLINTNEXTLINE(modernize-avoid-c-arrays) 723af6ab5fSopenharmony_cistatic constexpr std::string_view BUILTINS_TO_INIT[] = { 733af6ab5fSopenharmony_ci compiler::Signatures::BUILTIN_BOOLEAN_CLASS, 743af6ab5fSopenharmony_ci compiler::Signatures::BUILTIN_BYTE_CLASS, 753af6ab5fSopenharmony_ci compiler::Signatures::BUILTIN_CHAR_CLASS, 763af6ab5fSopenharmony_ci compiler::Signatures::BUILTIN_SHORT_CLASS, 773af6ab5fSopenharmony_ci compiler::Signatures::BUILTIN_INT_CLASS, 783af6ab5fSopenharmony_ci compiler::Signatures::BUILTIN_LONG_CLASS, 793af6ab5fSopenharmony_ci compiler::Signatures::BUILTIN_FLOAT_CLASS, 803af6ab5fSopenharmony_ci compiler::Signatures::BUILTIN_DOUBLE_CLASS, 813af6ab5fSopenharmony_ci compiler::Signatures::BUILTIN_FUNCTION0_CLASS, 823af6ab5fSopenharmony_ci compiler::Signatures::BUILTIN_FUNCTION1_CLASS, 833af6ab5fSopenharmony_ci compiler::Signatures::BUILTIN_FUNCTION2_CLASS, 843af6ab5fSopenharmony_ci compiler::Signatures::BUILTIN_FUNCTION3_CLASS, 853af6ab5fSopenharmony_ci compiler::Signatures::BUILTIN_FUNCTION4_CLASS, 863af6ab5fSopenharmony_ci compiler::Signatures::BUILTIN_FUNCTION5_CLASS, 873af6ab5fSopenharmony_ci compiler::Signatures::BUILTIN_FUNCTION6_CLASS, 883af6ab5fSopenharmony_ci compiler::Signatures::BUILTIN_FUNCTION7_CLASS, 893af6ab5fSopenharmony_ci compiler::Signatures::BUILTIN_FUNCTION8_CLASS, 903af6ab5fSopenharmony_ci compiler::Signatures::BUILTIN_FUNCTION9_CLASS, 913af6ab5fSopenharmony_ci compiler::Signatures::BUILTIN_FUNCTION10_CLASS, 923af6ab5fSopenharmony_ci compiler::Signatures::BUILTIN_FUNCTION11_CLASS, 933af6ab5fSopenharmony_ci compiler::Signatures::BUILTIN_FUNCTION12_CLASS, 943af6ab5fSopenharmony_ci compiler::Signatures::BUILTIN_FUNCTION13_CLASS, 953af6ab5fSopenharmony_ci compiler::Signatures::BUILTIN_FUNCTION14_CLASS, 963af6ab5fSopenharmony_ci compiler::Signatures::BUILTIN_FUNCTION15_CLASS, 973af6ab5fSopenharmony_ci compiler::Signatures::BUILTIN_FUNCTION16_CLASS, 983af6ab5fSopenharmony_ci compiler::Signatures::BUILTIN_FUNCTIONN_CLASS, 993af6ab5fSopenharmony_ci compiler::Signatures::BUILTIN_THROWING_FUNCTION0_CLASS, 1003af6ab5fSopenharmony_ci compiler::Signatures::BUILTIN_THROWING_FUNCTION1_CLASS, 1013af6ab5fSopenharmony_ci compiler::Signatures::BUILTIN_THROWING_FUNCTION2_CLASS, 1023af6ab5fSopenharmony_ci compiler::Signatures::BUILTIN_THROWING_FUNCTION3_CLASS, 1033af6ab5fSopenharmony_ci compiler::Signatures::BUILTIN_THROWING_FUNCTION4_CLASS, 1043af6ab5fSopenharmony_ci compiler::Signatures::BUILTIN_THROWING_FUNCTION5_CLASS, 1053af6ab5fSopenharmony_ci compiler::Signatures::BUILTIN_THROWING_FUNCTION6_CLASS, 1063af6ab5fSopenharmony_ci compiler::Signatures::BUILTIN_THROWING_FUNCTION7_CLASS, 1073af6ab5fSopenharmony_ci compiler::Signatures::BUILTIN_THROWING_FUNCTION8_CLASS, 1083af6ab5fSopenharmony_ci compiler::Signatures::BUILTIN_THROWING_FUNCTION9_CLASS, 1093af6ab5fSopenharmony_ci compiler::Signatures::BUILTIN_THROWING_FUNCTION10_CLASS, 1103af6ab5fSopenharmony_ci compiler::Signatures::BUILTIN_THROWING_FUNCTION11_CLASS, 1113af6ab5fSopenharmony_ci compiler::Signatures::BUILTIN_THROWING_FUNCTION12_CLASS, 1123af6ab5fSopenharmony_ci compiler::Signatures::BUILTIN_THROWING_FUNCTION13_CLASS, 1133af6ab5fSopenharmony_ci compiler::Signatures::BUILTIN_THROWING_FUNCTION14_CLASS, 1143af6ab5fSopenharmony_ci compiler::Signatures::BUILTIN_THROWING_FUNCTION15_CLASS, 1153af6ab5fSopenharmony_ci compiler::Signatures::BUILTIN_THROWING_FUNCTION16_CLASS, 1163af6ab5fSopenharmony_ci compiler::Signatures::BUILTIN_THROWING_FUNCTIONN_CLASS, 1173af6ab5fSopenharmony_ci compiler::Signatures::BUILTIN_RETHROWING_FUNCTION0_CLASS, 1183af6ab5fSopenharmony_ci compiler::Signatures::BUILTIN_RETHROWING_FUNCTION1_CLASS, 1193af6ab5fSopenharmony_ci compiler::Signatures::BUILTIN_RETHROWING_FUNCTION2_CLASS, 1203af6ab5fSopenharmony_ci compiler::Signatures::BUILTIN_RETHROWING_FUNCTION3_CLASS, 1213af6ab5fSopenharmony_ci compiler::Signatures::BUILTIN_RETHROWING_FUNCTION4_CLASS, 1223af6ab5fSopenharmony_ci compiler::Signatures::BUILTIN_RETHROWING_FUNCTION5_CLASS, 1233af6ab5fSopenharmony_ci compiler::Signatures::BUILTIN_RETHROWING_FUNCTION6_CLASS, 1243af6ab5fSopenharmony_ci compiler::Signatures::BUILTIN_RETHROWING_FUNCTION7_CLASS, 1253af6ab5fSopenharmony_ci compiler::Signatures::BUILTIN_RETHROWING_FUNCTION8_CLASS, 1263af6ab5fSopenharmony_ci compiler::Signatures::BUILTIN_RETHROWING_FUNCTION9_CLASS, 1273af6ab5fSopenharmony_ci compiler::Signatures::BUILTIN_RETHROWING_FUNCTION10_CLASS, 1283af6ab5fSopenharmony_ci compiler::Signatures::BUILTIN_RETHROWING_FUNCTION11_CLASS, 1293af6ab5fSopenharmony_ci compiler::Signatures::BUILTIN_RETHROWING_FUNCTION12_CLASS, 1303af6ab5fSopenharmony_ci compiler::Signatures::BUILTIN_RETHROWING_FUNCTION13_CLASS, 1313af6ab5fSopenharmony_ci compiler::Signatures::BUILTIN_RETHROWING_FUNCTION14_CLASS, 1323af6ab5fSopenharmony_ci compiler::Signatures::BUILTIN_RETHROWING_FUNCTION15_CLASS, 1333af6ab5fSopenharmony_ci compiler::Signatures::BUILTIN_RETHROWING_FUNCTION16_CLASS, 1343af6ab5fSopenharmony_ci compiler::Signatures::BUILTIN_RETHROWING_FUNCTIONN_CLASS, 1353af6ab5fSopenharmony_ci}; 1363af6ab5fSopenharmony_ci 1373af6ab5fSopenharmony_civoid ETSChecker::InitializeBuiltins(varbinder::ETSBinder *varbinder) 1383af6ab5fSopenharmony_ci{ 1393af6ab5fSopenharmony_ci if (HasStatus(CheckerStatus::BUILTINS_INITIALIZED)) { 1403af6ab5fSopenharmony_ci return; 1413af6ab5fSopenharmony_ci } 1423af6ab5fSopenharmony_ci 1433af6ab5fSopenharmony_ci const auto varMap = varbinder->TopScope()->Bindings(); 1443af6ab5fSopenharmony_ci 1453af6ab5fSopenharmony_ci auto const objectName = InitBuiltin(this, compiler::Signatures::BUILTIN_OBJECT_CLASS); 1463af6ab5fSopenharmony_ci 1473af6ab5fSopenharmony_ci for (auto sig : BUILTINS_TO_INIT) { 1483af6ab5fSopenharmony_ci InitBuiltin(this, sig); 1493af6ab5fSopenharmony_ci } 1503af6ab5fSopenharmony_ci 1513af6ab5fSopenharmony_ci for (size_t id = static_cast<size_t>(GlobalTypeId::ETS_THROWING_FUNCTION0_CLASS), nargs = 0; 1523af6ab5fSopenharmony_ci id <= static_cast<size_t>(GlobalTypeId::ETS_THROWING_FUNCTIONN_CLASS); id++, nargs++) { 1533af6ab5fSopenharmony_ci auto *type = GetGlobalTypesHolder() 1543af6ab5fSopenharmony_ci ->GlobalFunctionBuiltinType(nargs, ir::ScriptFunctionFlags::THROWS) 1553af6ab5fSopenharmony_ci ->AsETSObjectType(); 1563af6ab5fSopenharmony_ci SetupFunctionalInterface(type); 1573af6ab5fSopenharmony_ci } 1583af6ab5fSopenharmony_ci 1593af6ab5fSopenharmony_ci for (size_t id = static_cast<size_t>(GlobalTypeId::ETS_RETHROWING_FUNCTION0_CLASS), nargs = 0; 1603af6ab5fSopenharmony_ci id <= static_cast<size_t>(GlobalTypeId::ETS_RETHROWING_FUNCTIONN_CLASS); id++, nargs++) { 1613af6ab5fSopenharmony_ci auto *type = GetGlobalTypesHolder() 1623af6ab5fSopenharmony_ci ->GlobalFunctionBuiltinType(nargs, ir::ScriptFunctionFlags::RETHROWS) 1633af6ab5fSopenharmony_ci ->AsETSObjectType(); 1643af6ab5fSopenharmony_ci SetupFunctionalInterface(type); 1653af6ab5fSopenharmony_ci // note(gergocs): type->Interfaces().front() should be the same as the type in throwing functions 1663af6ab5fSopenharmony_ci // and adding the functional flag to the interface should be deleted 1673af6ab5fSopenharmony_ci type->Interfaces().front()->AddObjectFlag(ETSObjectFlags::FUNCTIONAL); 1683af6ab5fSopenharmony_ci } 1693af6ab5fSopenharmony_ci 1703af6ab5fSopenharmony_ci for (size_t id = static_cast<size_t>(GlobalTypeId::ETS_FUNCTION0_CLASS), nargs = 0; 1713af6ab5fSopenharmony_ci id <= static_cast<size_t>(GlobalTypeId::ETS_FUNCTIONN_CLASS); id++, nargs++) { 1723af6ab5fSopenharmony_ci auto *type = 1733af6ab5fSopenharmony_ci GetGlobalTypesHolder()->GlobalFunctionBuiltinType(nargs, ir::ScriptFunctionFlags::NONE)->AsETSObjectType(); 1743af6ab5fSopenharmony_ci SetupFunctionalInterface(type); 1753af6ab5fSopenharmony_ci // note(gergocs): type->Interfaces().front() should be the same as the type in rethrowing functions 1763af6ab5fSopenharmony_ci // and adding the functional flag to the interface should be deleted 1773af6ab5fSopenharmony_ci type->Interfaces().front()->AddObjectFlag(ETSObjectFlags::FUNCTIONAL); 1783af6ab5fSopenharmony_ci type->Interfaces().front()->Interfaces().front()->AddObjectFlag(ETSObjectFlags::FUNCTIONAL); 1793af6ab5fSopenharmony_ci } 1803af6ab5fSopenharmony_ci 1813af6ab5fSopenharmony_ci for (const auto &[name, var] : varMap) { 1823af6ab5fSopenharmony_ci (void)name; 1833af6ab5fSopenharmony_ci SetupBuiltinMember(var); 1843af6ab5fSopenharmony_ci } 1853af6ab5fSopenharmony_ci 1863af6ab5fSopenharmony_ci for (const auto &[name, var] : varMap) { 1873af6ab5fSopenharmony_ci if (name == objectName) { 1883af6ab5fSopenharmony_ci continue; 1893af6ab5fSopenharmony_ci } 1903af6ab5fSopenharmony_ci 1913af6ab5fSopenharmony_ci if (var->HasFlag(varbinder::VariableFlags::BUILTIN_TYPE)) { 1923af6ab5fSopenharmony_ci if (var->TsType() == nullptr) { 1933af6ab5fSopenharmony_ci InitializeBuiltin(var, name); 1943af6ab5fSopenharmony_ci } else { 1953af6ab5fSopenharmony_ci GetGlobalTypesHolder()->InitializeBuiltin(name, var->TsType()); 1963af6ab5fSopenharmony_ci } 1973af6ab5fSopenharmony_ci } 1983af6ab5fSopenharmony_ci } 1993af6ab5fSopenharmony_ci 2003af6ab5fSopenharmony_ci AddStatus(CheckerStatus::BUILTINS_INITIALIZED); 2013af6ab5fSopenharmony_ci} 2023af6ab5fSopenharmony_ci 2033af6ab5fSopenharmony_civoid ETSChecker::InitializeBuiltin(varbinder::Variable *var, const util::StringView &name) 2043af6ab5fSopenharmony_ci{ 2053af6ab5fSopenharmony_ci Type *type {nullptr}; 2063af6ab5fSopenharmony_ci if (var->Declaration()->Node()->IsClassDefinition()) { 2073af6ab5fSopenharmony_ci type = BuildBasicClassProperties(var->Declaration()->Node()->AsClassDefinition()); 2083af6ab5fSopenharmony_ci } else { 2093af6ab5fSopenharmony_ci ASSERT(var->Declaration()->Node()->IsTSInterfaceDeclaration()); 2103af6ab5fSopenharmony_ci type = BuildBasicInterfaceProperties(var->Declaration()->Node()->AsTSInterfaceDeclaration()); 2113af6ab5fSopenharmony_ci } 2123af6ab5fSopenharmony_ci GetGlobalTypesHolder()->InitializeBuiltin(name, type); 2133af6ab5fSopenharmony_ci} 2143af6ab5fSopenharmony_ci 2153af6ab5fSopenharmony_cibool ETSChecker::StartChecker(varbinder::VarBinder *varbinder, const CompilerOptions &options) 2163af6ab5fSopenharmony_ci{ 2173af6ab5fSopenharmony_ci Initialize(varbinder); 2183af6ab5fSopenharmony_ci 2193af6ab5fSopenharmony_ci if (options.parseOnly) { 2203af6ab5fSopenharmony_ci return false; 2213af6ab5fSopenharmony_ci } 2223af6ab5fSopenharmony_ci 2233af6ab5fSopenharmony_ci auto *etsBinder = varbinder->AsETSBinder(); 2243af6ab5fSopenharmony_ci InitializeBuiltins(etsBinder); 2253af6ab5fSopenharmony_ci 2263af6ab5fSopenharmony_ci for (auto &entry : etsBinder->DynamicImportVars()) { 2273af6ab5fSopenharmony_ci auto &data = entry.second; 2283af6ab5fSopenharmony_ci if (data.import->IsPureDynamic()) { 2293af6ab5fSopenharmony_ci data.variable->SetTsType(GlobalBuiltinDynamicType(data.import->Language())); 2303af6ab5fSopenharmony_ci } 2313af6ab5fSopenharmony_ci } 2323af6ab5fSopenharmony_ci 2333af6ab5fSopenharmony_ci bool isEvalMode = (debugInfoPlugin_ != nullptr); 2343af6ab5fSopenharmony_ci if (UNLIKELY(isEvalMode)) { 2353af6ab5fSopenharmony_ci debugInfoPlugin_->PreCheck(); 2363af6ab5fSopenharmony_ci } 2373af6ab5fSopenharmony_ci 2383af6ab5fSopenharmony_ci CheckProgram(Program(), true); 2393af6ab5fSopenharmony_ci 2403af6ab5fSopenharmony_ci if (UNLIKELY(isEvalMode)) { 2413af6ab5fSopenharmony_ci debugInfoPlugin_->PostCheck(); 2423af6ab5fSopenharmony_ci } 2433af6ab5fSopenharmony_ci 2443af6ab5fSopenharmony_ci BuildDynamicImportClass(); 2453af6ab5fSopenharmony_ci 2463af6ab5fSopenharmony_ci#ifndef NDEBUG 2473af6ab5fSopenharmony_ci for (auto *func : varbinder->Functions()) { 2483af6ab5fSopenharmony_ci ASSERT(!func->Node()->AsScriptFunction()->Scope()->InternalName().Empty()); 2493af6ab5fSopenharmony_ci } 2503af6ab5fSopenharmony_ci#endif 2513af6ab5fSopenharmony_ci 2523af6ab5fSopenharmony_ci if (options.dumpCheckedAst) { 2533af6ab5fSopenharmony_ci std::cout << Program()->Dump() << std::endl; 2543af6ab5fSopenharmony_ci } 2553af6ab5fSopenharmony_ci 2563af6ab5fSopenharmony_ci if (options.etsHasWarnings) { 2573af6ab5fSopenharmony_ci CheckWarnings(Program(), options); 2583af6ab5fSopenharmony_ci } 2593af6ab5fSopenharmony_ci 2603af6ab5fSopenharmony_ci return !ErrorLogger()->IsAnyError(); 2613af6ab5fSopenharmony_ci} 2623af6ab5fSopenharmony_ci 2633af6ab5fSopenharmony_cievaluate::ScopedDebugInfoPlugin *ETSChecker::GetDebugInfoPlugin() 2643af6ab5fSopenharmony_ci{ 2653af6ab5fSopenharmony_ci return debugInfoPlugin_; 2663af6ab5fSopenharmony_ci} 2673af6ab5fSopenharmony_ci 2683af6ab5fSopenharmony_ciconst evaluate::ScopedDebugInfoPlugin *ETSChecker::GetDebugInfoPlugin() const 2693af6ab5fSopenharmony_ci{ 2703af6ab5fSopenharmony_ci return debugInfoPlugin_; 2713af6ab5fSopenharmony_ci} 2723af6ab5fSopenharmony_ci 2733af6ab5fSopenharmony_civoid ETSChecker::SetDebugInfoPlugin(evaluate::ScopedDebugInfoPlugin *debugInfo) 2743af6ab5fSopenharmony_ci{ 2753af6ab5fSopenharmony_ci debugInfoPlugin_ = debugInfo; 2763af6ab5fSopenharmony_ci} 2773af6ab5fSopenharmony_ci 2783af6ab5fSopenharmony_civoid ETSChecker::CheckProgram(parser::Program *program, bool runAnalysis) 2793af6ab5fSopenharmony_ci{ 2803af6ab5fSopenharmony_ci auto *savedProgram = Program(); 2813af6ab5fSopenharmony_ci SetProgram(program); 2823af6ab5fSopenharmony_ci 2833af6ab5fSopenharmony_ci for (auto &[_, extPrograms] : program->ExternalSources()) { 2843af6ab5fSopenharmony_ci (void)_; 2853af6ab5fSopenharmony_ci for (auto *extProg : extPrograms) { 2863af6ab5fSopenharmony_ci checker::SavedCheckerContext savedContext(this, Context().Status(), Context().ContainingClass()); 2873af6ab5fSopenharmony_ci AddStatus(checker::CheckerStatus::IN_EXTERNAL); 2883af6ab5fSopenharmony_ci CheckProgram(extProg, VarBinder()->IsGenStdLib()); 2893af6ab5fSopenharmony_ci } 2903af6ab5fSopenharmony_ci } 2913af6ab5fSopenharmony_ci 2923af6ab5fSopenharmony_ci ASSERT(Program()->Ast()->IsProgram()); 2933af6ab5fSopenharmony_ci Program()->Ast()->Check(this); 2943af6ab5fSopenharmony_ci 2953af6ab5fSopenharmony_ci if (ErrorLogger()->IsAnyError()) { 2963af6ab5fSopenharmony_ci return; 2973af6ab5fSopenharmony_ci } 2983af6ab5fSopenharmony_ci 2993af6ab5fSopenharmony_ci if (runAnalysis) { 3003af6ab5fSopenharmony_ci AliveAnalyzer aliveAnalyzer(Program()->Ast(), this); 3013af6ab5fSopenharmony_ci AssignAnalyzer(this).Analyze(Program()->Ast()); 3023af6ab5fSopenharmony_ci } 3033af6ab5fSopenharmony_ci 3043af6ab5fSopenharmony_ci ASSERT(VarBinder()->AsETSBinder()->GetExternalRecordTable().find(program)->second); 3053af6ab5fSopenharmony_ci 3063af6ab5fSopenharmony_ci SetProgram(savedProgram); 3073af6ab5fSopenharmony_ci} 3083af6ab5fSopenharmony_ci 3093af6ab5fSopenharmony_civoid ETSChecker::CheckWarnings(parser::Program *program, const CompilerOptions &options) 3103af6ab5fSopenharmony_ci{ 3113af6ab5fSopenharmony_ci const auto etsWarningCollection = options.etsWarningCollection; 3123af6ab5fSopenharmony_ci for (const auto warning : etsWarningCollection) { 3133af6ab5fSopenharmony_ci ETSWarningAnalyzer(Program()->Ast(), program, warning, options.etsWerror); 3143af6ab5fSopenharmony_ci } 3153af6ab5fSopenharmony_ci} 3163af6ab5fSopenharmony_ci 3173af6ab5fSopenharmony_ciType *ETSChecker::CheckTypeCached(ir::Expression *expr) 3183af6ab5fSopenharmony_ci{ 3193af6ab5fSopenharmony_ci if (expr->TsType() == nullptr) { 3203af6ab5fSopenharmony_ci expr->SetTsType(expr->Check(this)); 3213af6ab5fSopenharmony_ci } 3223af6ab5fSopenharmony_ci 3233af6ab5fSopenharmony_ci return expr->TsType(); 3243af6ab5fSopenharmony_ci} 3253af6ab5fSopenharmony_ci 3263af6ab5fSopenharmony_citemplate <typename... Args> 3273af6ab5fSopenharmony_ciETSObjectType *ETSChecker::AsETSObjectType(Type *(GlobalTypesHolder::*typeFunctor)(Args...), Args... args) const 3283af6ab5fSopenharmony_ci{ 3293af6ab5fSopenharmony_ci auto *ret = (GetGlobalTypesHolder()->*typeFunctor)(args...); 3303af6ab5fSopenharmony_ci return ret != nullptr ? ret->AsETSObjectType() : nullptr; 3313af6ab5fSopenharmony_ci} 3323af6ab5fSopenharmony_ci 3333af6ab5fSopenharmony_ciType *ETSChecker::GlobalByteType() const 3343af6ab5fSopenharmony_ci{ 3353af6ab5fSopenharmony_ci return GetGlobalTypesHolder()->GlobalByteType(); 3363af6ab5fSopenharmony_ci} 3373af6ab5fSopenharmony_ci 3383af6ab5fSopenharmony_ciType *ETSChecker::GlobalShortType() const 3393af6ab5fSopenharmony_ci{ 3403af6ab5fSopenharmony_ci return GetGlobalTypesHolder()->GlobalShortType(); 3413af6ab5fSopenharmony_ci} 3423af6ab5fSopenharmony_ci 3433af6ab5fSopenharmony_ciType *ETSChecker::GlobalIntType() const 3443af6ab5fSopenharmony_ci{ 3453af6ab5fSopenharmony_ci return GetGlobalTypesHolder()->GlobalIntType(); 3463af6ab5fSopenharmony_ci} 3473af6ab5fSopenharmony_ci 3483af6ab5fSopenharmony_ciType *ETSChecker::GlobalLongType() const 3493af6ab5fSopenharmony_ci{ 3503af6ab5fSopenharmony_ci return GetGlobalTypesHolder()->GlobalLongType(); 3513af6ab5fSopenharmony_ci} 3523af6ab5fSopenharmony_ci 3533af6ab5fSopenharmony_ciType *ETSChecker::GlobalFloatType() const 3543af6ab5fSopenharmony_ci{ 3553af6ab5fSopenharmony_ci return GetGlobalTypesHolder()->GlobalFloatType(); 3563af6ab5fSopenharmony_ci} 3573af6ab5fSopenharmony_ci 3583af6ab5fSopenharmony_ciType *ETSChecker::GlobalDoubleType() const 3593af6ab5fSopenharmony_ci{ 3603af6ab5fSopenharmony_ci return GetGlobalTypesHolder()->GlobalDoubleType(); 3613af6ab5fSopenharmony_ci} 3623af6ab5fSopenharmony_ci 3633af6ab5fSopenharmony_ciType *ETSChecker::GlobalCharType() const 3643af6ab5fSopenharmony_ci{ 3653af6ab5fSopenharmony_ci return GetGlobalTypesHolder()->GlobalCharType(); 3663af6ab5fSopenharmony_ci} 3673af6ab5fSopenharmony_ci 3683af6ab5fSopenharmony_ciType *ETSChecker::GlobalETSBooleanType() const 3693af6ab5fSopenharmony_ci{ 3703af6ab5fSopenharmony_ci return GetGlobalTypesHolder()->GlobalETSBooleanType(); 3713af6ab5fSopenharmony_ci} 3723af6ab5fSopenharmony_ci 3733af6ab5fSopenharmony_ciType *ETSChecker::GlobalVoidType() const 3743af6ab5fSopenharmony_ci{ 3753af6ab5fSopenharmony_ci return GetGlobalTypesHolder()->GlobalETSVoidType(); 3763af6ab5fSopenharmony_ci} 3773af6ab5fSopenharmony_ci 3783af6ab5fSopenharmony_ciType *ETSChecker::GlobalETSNullType() const 3793af6ab5fSopenharmony_ci{ 3803af6ab5fSopenharmony_ci return GetGlobalTypesHolder()->GlobalETSNullType(); 3813af6ab5fSopenharmony_ci} 3823af6ab5fSopenharmony_ci 3833af6ab5fSopenharmony_ciType *ETSChecker::GlobalETSUndefinedType() const 3843af6ab5fSopenharmony_ci{ 3853af6ab5fSopenharmony_ci return GetGlobalTypesHolder()->GlobalETSUndefinedType(); 3863af6ab5fSopenharmony_ci} 3873af6ab5fSopenharmony_ci 3883af6ab5fSopenharmony_ciType *ETSChecker::GlobalETSStringLiteralType() const 3893af6ab5fSopenharmony_ci{ 3903af6ab5fSopenharmony_ci return GetGlobalTypesHolder()->GlobalETSStringLiteralType(); 3913af6ab5fSopenharmony_ci} 3923af6ab5fSopenharmony_ci 3933af6ab5fSopenharmony_ciType *ETSChecker::GlobalETSBigIntType() const 3943af6ab5fSopenharmony_ci{ 3953af6ab5fSopenharmony_ci return GetGlobalTypesHolder()->GlobalETSBigIntBuiltinType(); 3963af6ab5fSopenharmony_ci} 3973af6ab5fSopenharmony_ci 3983af6ab5fSopenharmony_ciType *ETSChecker::GlobalWildcardType() const 3993af6ab5fSopenharmony_ci{ 4003af6ab5fSopenharmony_ci return GetGlobalTypesHolder()->GlobalWildcardType(); 4013af6ab5fSopenharmony_ci} 4023af6ab5fSopenharmony_ci 4033af6ab5fSopenharmony_ciETSObjectType *ETSChecker::GlobalETSObjectType() const 4043af6ab5fSopenharmony_ci{ 4053af6ab5fSopenharmony_ci return AsETSObjectType(&GlobalTypesHolder::GlobalETSObjectType); 4063af6ab5fSopenharmony_ci} 4073af6ab5fSopenharmony_ci 4083af6ab5fSopenharmony_ciETSUnionType *ETSChecker::GlobalETSNullishType() const 4093af6ab5fSopenharmony_ci{ 4103af6ab5fSopenharmony_ci auto *ret = (GetGlobalTypesHolder()->*&GlobalTypesHolder::GlobalETSNullishType)(); 4113af6ab5fSopenharmony_ci return ret != nullptr ? ret->AsETSUnionType() : nullptr; 4123af6ab5fSopenharmony_ci} 4133af6ab5fSopenharmony_ci 4143af6ab5fSopenharmony_ciETSUnionType *ETSChecker::GlobalETSNullishObjectType() const 4153af6ab5fSopenharmony_ci{ 4163af6ab5fSopenharmony_ci auto *ret = (GetGlobalTypesHolder()->*&GlobalTypesHolder::GlobalETSNullishObjectType)(); 4173af6ab5fSopenharmony_ci return ret != nullptr ? ret->AsETSUnionType() : nullptr; 4183af6ab5fSopenharmony_ci} 4193af6ab5fSopenharmony_ci 4203af6ab5fSopenharmony_ciETSObjectType *ETSChecker::GlobalBuiltinETSStringType() const 4213af6ab5fSopenharmony_ci{ 4223af6ab5fSopenharmony_ci return AsETSObjectType(&GlobalTypesHolder::GlobalETSStringBuiltinType); 4233af6ab5fSopenharmony_ci} 4243af6ab5fSopenharmony_ci 4253af6ab5fSopenharmony_ciETSObjectType *ETSChecker::GlobalBuiltinETSBigIntType() const 4263af6ab5fSopenharmony_ci{ 4273af6ab5fSopenharmony_ci return AsETSObjectType(&GlobalTypesHolder::GlobalETSBigIntBuiltinType); 4283af6ab5fSopenharmony_ci} 4293af6ab5fSopenharmony_ci 4303af6ab5fSopenharmony_ciETSObjectType *ETSChecker::GlobalBuiltinTypeType() const 4313af6ab5fSopenharmony_ci{ 4323af6ab5fSopenharmony_ci return AsETSObjectType(&GlobalTypesHolder::GlobalTypeBuiltinType); 4333af6ab5fSopenharmony_ci} 4343af6ab5fSopenharmony_ci 4353af6ab5fSopenharmony_ciETSObjectType *ETSChecker::GlobalBuiltinExceptionType() const 4363af6ab5fSopenharmony_ci{ 4373af6ab5fSopenharmony_ci return AsETSObjectType(&GlobalTypesHolder::GlobalExceptionBuiltinType); 4383af6ab5fSopenharmony_ci} 4393af6ab5fSopenharmony_ci 4403af6ab5fSopenharmony_ciETSObjectType *ETSChecker::GlobalBuiltinErrorType() const 4413af6ab5fSopenharmony_ci{ 4423af6ab5fSopenharmony_ci return AsETSObjectType(&GlobalTypesHolder::GlobalErrorBuiltinType); 4433af6ab5fSopenharmony_ci} 4443af6ab5fSopenharmony_ci 4453af6ab5fSopenharmony_ciETSObjectType *ETSChecker::GlobalStringBuilderBuiltinType() const 4463af6ab5fSopenharmony_ci{ 4473af6ab5fSopenharmony_ci return AsETSObjectType(&GlobalTypesHolder::GlobalStringBuilderBuiltinType); 4483af6ab5fSopenharmony_ci} 4493af6ab5fSopenharmony_ci 4503af6ab5fSopenharmony_ciETSObjectType *ETSChecker::GlobalBuiltinPromiseType() const 4513af6ab5fSopenharmony_ci{ 4523af6ab5fSopenharmony_ci return AsETSObjectType(&GlobalTypesHolder::GlobalPromiseBuiltinType); 4533af6ab5fSopenharmony_ci} 4543af6ab5fSopenharmony_ci 4553af6ab5fSopenharmony_ciETSObjectType *ETSChecker::GlobalBuiltinJSRuntimeType() const 4563af6ab5fSopenharmony_ci{ 4573af6ab5fSopenharmony_ci return AsETSObjectType(&GlobalTypesHolder::GlobalJSRuntimeBuiltinType); 4583af6ab5fSopenharmony_ci} 4593af6ab5fSopenharmony_ci 4603af6ab5fSopenharmony_ciETSObjectType *ETSChecker::GlobalBuiltinJSValueType() const 4613af6ab5fSopenharmony_ci{ 4623af6ab5fSopenharmony_ci return AsETSObjectType(&GlobalTypesHolder::GlobalJSValueBuiltinType); 4633af6ab5fSopenharmony_ci} 4643af6ab5fSopenharmony_ci 4653af6ab5fSopenharmony_ciETSObjectType *ETSChecker::GlobalBuiltinFunctionType(size_t nargs, ir::ScriptFunctionFlags flags) const 4663af6ab5fSopenharmony_ci{ 4673af6ab5fSopenharmony_ci return AsETSObjectType(&GlobalTypesHolder::GlobalFunctionBuiltinType, nargs, flags); 4683af6ab5fSopenharmony_ci} 4693af6ab5fSopenharmony_ci 4703af6ab5fSopenharmony_cisize_t ETSChecker::GlobalBuiltinFunctionTypeVariadicThreshold() const 4713af6ab5fSopenharmony_ci{ 4723af6ab5fSopenharmony_ci return GetGlobalTypesHolder()->VariadicFunctionTypeThreshold(); 4733af6ab5fSopenharmony_ci} 4743af6ab5fSopenharmony_ci 4753af6ab5fSopenharmony_ciETSObjectType *ETSChecker::GlobalBuiltinDynamicType(Language lang) const 4763af6ab5fSopenharmony_ci{ 4773af6ab5fSopenharmony_ci if (lang.GetId() == Language::Id::JS) { 4783af6ab5fSopenharmony_ci return GlobalBuiltinJSValueType(); 4793af6ab5fSopenharmony_ci } 4803af6ab5fSopenharmony_ci return nullptr; 4813af6ab5fSopenharmony_ci} 4823af6ab5fSopenharmony_ci 4833af6ab5fSopenharmony_ciETSObjectType *ETSChecker::GlobalBuiltinBoxType(Type *contents) 4843af6ab5fSopenharmony_ci{ 4853af6ab5fSopenharmony_ci switch (TypeKind(contents)) { 4863af6ab5fSopenharmony_ci case TypeFlag::ETS_BOOLEAN: 4873af6ab5fSopenharmony_ci return AsETSObjectType(&GlobalTypesHolder::GlobalBooleanBoxBuiltinType); 4883af6ab5fSopenharmony_ci case TypeFlag::BYTE: 4893af6ab5fSopenharmony_ci return AsETSObjectType(&GlobalTypesHolder::GlobalByteBoxBuiltinType); 4903af6ab5fSopenharmony_ci case TypeFlag::CHAR: 4913af6ab5fSopenharmony_ci return AsETSObjectType(&GlobalTypesHolder::GlobalCharBoxBuiltinType); 4923af6ab5fSopenharmony_ci case TypeFlag::SHORT: 4933af6ab5fSopenharmony_ci return AsETSObjectType(&GlobalTypesHolder::GlobalShortBoxBuiltinType); 4943af6ab5fSopenharmony_ci case TypeFlag::INT: 4953af6ab5fSopenharmony_ci return AsETSObjectType(&GlobalTypesHolder::GlobalIntBoxBuiltinType); 4963af6ab5fSopenharmony_ci case TypeFlag::LONG: 4973af6ab5fSopenharmony_ci return AsETSObjectType(&GlobalTypesHolder::GlobalLongBoxBuiltinType); 4983af6ab5fSopenharmony_ci case TypeFlag::FLOAT: 4993af6ab5fSopenharmony_ci return AsETSObjectType(&GlobalTypesHolder::GlobalFloatBoxBuiltinType); 5003af6ab5fSopenharmony_ci case TypeFlag::DOUBLE: 5013af6ab5fSopenharmony_ci return AsETSObjectType(&GlobalTypesHolder::GlobalDoubleBoxBuiltinType); 5023af6ab5fSopenharmony_ci default: { 5033af6ab5fSopenharmony_ci auto *base = AsETSObjectType(&GlobalTypesHolder::GlobalBoxBuiltinType); 5043af6ab5fSopenharmony_ci auto *substitution = NewSubstitution(); 5053af6ab5fSopenharmony_ci substitution->emplace(base->TypeArguments()[0]->AsETSTypeParameter(), contents); 5063af6ab5fSopenharmony_ci return base->Substitute(Relation(), substitution); 5073af6ab5fSopenharmony_ci } 5083af6ab5fSopenharmony_ci } 5093af6ab5fSopenharmony_ci} 5103af6ab5fSopenharmony_ci 5113af6ab5fSopenharmony_ciconst checker::WrapperDesc &ETSChecker::PrimitiveWrapper() const 5123af6ab5fSopenharmony_ci{ 5133af6ab5fSopenharmony_ci return primitiveWrappers_.Wrappers(); 5143af6ab5fSopenharmony_ci} 5153af6ab5fSopenharmony_ci 5163af6ab5fSopenharmony_ciGlobalArraySignatureMap &ETSChecker::GlobalArrayTypes() 5173af6ab5fSopenharmony_ci{ 5183af6ab5fSopenharmony_ci return globalArraySignatures_; 5193af6ab5fSopenharmony_ci} 5203af6ab5fSopenharmony_ci 5213af6ab5fSopenharmony_ciconst GlobalArraySignatureMap &ETSChecker::GlobalArrayTypes() const 5223af6ab5fSopenharmony_ci{ 5233af6ab5fSopenharmony_ci return globalArraySignatures_; 5243af6ab5fSopenharmony_ci} 5253af6ab5fSopenharmony_ci 5263af6ab5fSopenharmony_ciType *ETSChecker::GlobalTypeError() const 5273af6ab5fSopenharmony_ci{ 5283af6ab5fSopenharmony_ci return GetGlobalTypesHolder()->GlobalTypeError(); 5293af6ab5fSopenharmony_ci} 5303af6ab5fSopenharmony_ci 5313af6ab5fSopenharmony_civoid ETSChecker::HandleUpdatedCallExpressionNode(ir::CallExpression *callExpr) 5323af6ab5fSopenharmony_ci{ 5333af6ab5fSopenharmony_ci VarBinder()->AsETSBinder()->HandleCustomNodes(callExpr); 5343af6ab5fSopenharmony_ci} 5353af6ab5fSopenharmony_ci 5363af6ab5fSopenharmony_ciType *ETSChecker::SelectGlobalIntegerTypeForNumeric(Type *type) 5373af6ab5fSopenharmony_ci{ 5383af6ab5fSopenharmony_ci switch (ETSType(type)) { 5393af6ab5fSopenharmony_ci case checker::TypeFlag::FLOAT: { 5403af6ab5fSopenharmony_ci return GlobalIntType(); 5413af6ab5fSopenharmony_ci } 5423af6ab5fSopenharmony_ci case checker::TypeFlag::DOUBLE: { 5433af6ab5fSopenharmony_ci return GlobalLongType(); 5443af6ab5fSopenharmony_ci } 5453af6ab5fSopenharmony_ci default: { 5463af6ab5fSopenharmony_ci return type; 5473af6ab5fSopenharmony_ci } 5483af6ab5fSopenharmony_ci } 5493af6ab5fSopenharmony_ci} 5503af6ab5fSopenharmony_ci 5513af6ab5fSopenharmony_ci} // namespace ark::es2panda::checker 552