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 "phase.h"
173af6ab5fSopenharmony_ci#include "checker/checker.h"
183af6ab5fSopenharmony_ci#include "ets/ambientLowering.h"
193af6ab5fSopenharmony_ci#include "lexer/token/sourceLocation.h"
203af6ab5fSopenharmony_ci#include "compiler/lowering/resolveIdentifiers.h"
213af6ab5fSopenharmony_ci#include "compiler/lowering/checkerPhase.h"
223af6ab5fSopenharmony_ci#include "compiler/lowering/ets/constStringToCharLowering.h"
233af6ab5fSopenharmony_ci#include "compiler/lowering/ets/defaultParameterLowering.h"
243af6ab5fSopenharmony_ci#include "compiler/lowering/ets/expandBrackets.h"
253af6ab5fSopenharmony_ci#include "compiler/lowering/ets/recordLowering.h"
263af6ab5fSopenharmony_ci#include "compiler/lowering/ets/topLevelStmts/topLevelStmts.h"
273af6ab5fSopenharmony_ci#include "compiler/lowering/ets/expressionLambdaLowering.h"
283af6ab5fSopenharmony_ci#include "compiler/lowering/ets/boxingForLocals.h"
293af6ab5fSopenharmony_ci#include "compiler/lowering/ets/capturedVariables.h"
303af6ab5fSopenharmony_ci#include "compiler/lowering/ets/lambdaLowering.h"
313af6ab5fSopenharmony_ci#include "compiler/lowering/ets/spreadLowering.h"
323af6ab5fSopenharmony_ci#include "compiler/lowering/ets/interfacePropertyDeclarations.h"
333af6ab5fSopenharmony_ci#include "compiler/lowering/ets/objectIndexAccess.h"
343af6ab5fSopenharmony_ci#include "compiler/lowering/ets/objectIterator.h"
353af6ab5fSopenharmony_ci#include "compiler/lowering/ets/localClassLowering.h"
363af6ab5fSopenharmony_ci#include "compiler/lowering/ets/opAssignment.h"
373af6ab5fSopenharmony_ci#include "compiler/lowering/ets/objectLiteralLowering.h"
383af6ab5fSopenharmony_ci#include "compiler/lowering/ets/interfaceObjectLiteralLowering.h"
393af6ab5fSopenharmony_ci#include "compiler/lowering/ets/optionalLowering.h"
403af6ab5fSopenharmony_ci#include "compiler/lowering/ets/packageImplicitImport.h"
413af6ab5fSopenharmony_ci#include "compiler/lowering/ets/partialExportClassGen.h"
423af6ab5fSopenharmony_ci#include "compiler/lowering/ets/promiseVoid.h"
433af6ab5fSopenharmony_ci#include "compiler/lowering/ets/stringComparison.h"
443af6ab5fSopenharmony_ci#include "compiler/lowering/ets/structLowering.h"
453af6ab5fSopenharmony_ci#include "compiler/lowering/ets/tupleLowering.h"
463af6ab5fSopenharmony_ci#include "compiler/lowering/ets/bigintLowering.h"
473af6ab5fSopenharmony_ci#include "compiler/lowering/ets/unionLowering.h"
483af6ab5fSopenharmony_ci#include "compiler/lowering/ets/stringConstructorLowering.h"
493af6ab5fSopenharmony_ci#include "compiler/lowering/ets/enumLowering.h"
503af6ab5fSopenharmony_ci#include "compiler/lowering/ets/enumPostCheckLowering.h"
513af6ab5fSopenharmony_ci#include "compiler/lowering/ets/genericBridgesLowering.h"
523af6ab5fSopenharmony_ci#include "compiler/lowering/plugin_phase.h"
533af6ab5fSopenharmony_ci#include "compiler/lowering/scopesInit/scopesInitPhase.h"
543af6ab5fSopenharmony_ci#include "public/es2panda_lib.h"
553af6ab5fSopenharmony_ci
563af6ab5fSopenharmony_cinamespace ark::es2panda::compiler {
573af6ab5fSopenharmony_ci
583af6ab5fSopenharmony_cistatic CheckerPhase g_checkerPhase;
593af6ab5fSopenharmony_cistatic ResolveIdentifiers g_resolveIdentifiers {};
603af6ab5fSopenharmony_cistatic AmbientLowering g_ambientLowering;
613af6ab5fSopenharmony_cistatic BigIntLowering g_bigintLowering;
623af6ab5fSopenharmony_cistatic StringConstructorLowering g_stringConstructorLowering;
633af6ab5fSopenharmony_cistatic ConstStringToCharLowering g_constStringToCharLowering;
643af6ab5fSopenharmony_cistatic InterfacePropertyDeclarationsPhase g_interfacePropDeclPhase;
653af6ab5fSopenharmony_cistatic EnumLoweringPhase g_enumLoweringPhase;
663af6ab5fSopenharmony_cistatic EnumPostCheckLoweringPhase g_enumPostCheckLoweringPhase;
673af6ab5fSopenharmony_cistatic SpreadConstructionPhase g_spreadConstructionPhase;
683af6ab5fSopenharmony_cistatic ExpressionLambdaConstructionPhase g_expressionLambdaConstructionPhase;
693af6ab5fSopenharmony_cistatic OpAssignmentLowering g_opAssignmentLowering;
703af6ab5fSopenharmony_cistatic BoxingForLocals g_boxingForLocals;
713af6ab5fSopenharmony_cistatic CapturedVariables g_capturedVariables {};
723af6ab5fSopenharmony_cistatic LambdaConversionPhase g_lambdaConversionPhase;
733af6ab5fSopenharmony_cistatic ObjectIndexLowering g_objectIndexLowering;
743af6ab5fSopenharmony_cistatic ObjectIteratorLowering g_objectIteratorLowering;
753af6ab5fSopenharmony_cistatic ObjectLiteralLowering g_objectLiteralLowering;
763af6ab5fSopenharmony_cistatic InterfaceObjectLiteralLowering g_interfaceObjectLiteralLowering;
773af6ab5fSopenharmony_cistatic TupleLowering g_tupleLowering;  // Can be only applied after checking phase, and OP_ASSIGNMENT_LOWERING phase
783af6ab5fSopenharmony_cistatic UnionLowering g_unionLowering;
793af6ab5fSopenharmony_cistatic OptionalLowering g_optionalLowering;
803af6ab5fSopenharmony_cistatic ExpandBracketsPhase g_expandBracketsPhase;
813af6ab5fSopenharmony_cistatic PromiseVoidInferencePhase g_promiseVoidInferencePhase;
823af6ab5fSopenharmony_cistatic RecordLowering g_recordLowering;
833af6ab5fSopenharmony_cistatic StructLowering g_structLowering;
843af6ab5fSopenharmony_cistatic DefaultParameterLowering g_defaultParameterLowering;
853af6ab5fSopenharmony_cistatic TopLevelStatements g_topLevelStatements;
863af6ab5fSopenharmony_cistatic LocalClassConstructionPhase g_localClassLowering;
873af6ab5fSopenharmony_cistatic StringComparisonLowering g_stringComparisonLowering;
883af6ab5fSopenharmony_cistatic PartialExportClassGen g_partialExportClassGen;
893af6ab5fSopenharmony_cistatic PackageImplicitImport g_packageImplicitImport;
903af6ab5fSopenharmony_cistatic GenericBridgesPhase g_genericBridgesLowering;
913af6ab5fSopenharmony_cistatic PluginPhase g_pluginsAfterParse {"plugins-after-parse", ES2PANDA_STATE_PARSED, &util::Plugin::AfterParse};
923af6ab5fSopenharmony_cistatic PluginPhase g_pluginsAfterCheck {"plugins-after-check", ES2PANDA_STATE_CHECKED, &util::Plugin::AfterCheck};
933af6ab5fSopenharmony_cistatic PluginPhase g_pluginsAfterLowerings {"plugins-after-lowering", ES2PANDA_STATE_LOWERED,
943af6ab5fSopenharmony_ci                                            &util::Plugin::AfterLowerings};
953af6ab5fSopenharmony_ci// NOLINTBEGIN(fuchsia-statically-constructed-objects)
963af6ab5fSopenharmony_cistatic InitScopesPhaseETS g_initScopesPhaseEts;
973af6ab5fSopenharmony_cistatic InitScopesPhaseAS g_initScopesPhaseAs;
983af6ab5fSopenharmony_cistatic InitScopesPhaseTs g_initScopesPhaseTs;
993af6ab5fSopenharmony_cistatic InitScopesPhaseJs g_initScopesPhaseJs;
1003af6ab5fSopenharmony_ci// NOLINTEND(fuchsia-statically-constructed-objects)
1013af6ab5fSopenharmony_ci
1023af6ab5fSopenharmony_cistatic void CheckOptionsBeforePhase(const CompilerOptions &options, const parser::Program *program,
1033af6ab5fSopenharmony_ci                                    const std::string &name);
1043af6ab5fSopenharmony_cistatic void CheckOptionsAfterPhase(const CompilerOptions &options, const parser::Program *program,
1053af6ab5fSopenharmony_ci                                   const std::string &name);
1063af6ab5fSopenharmony_ci
1073af6ab5fSopenharmony_cistd::vector<Phase *> GetETSPhaseList()
1083af6ab5fSopenharmony_ci{
1093af6ab5fSopenharmony_ci    // clang-format off
1103af6ab5fSopenharmony_ci    return {
1113af6ab5fSopenharmony_ci        &g_pluginsAfterParse,
1123af6ab5fSopenharmony_ci        &g_packageImplicitImport,
1133af6ab5fSopenharmony_ci        &g_topLevelStatements,
1143af6ab5fSopenharmony_ci        &g_defaultParameterLowering,
1153af6ab5fSopenharmony_ci        &g_ambientLowering,
1163af6ab5fSopenharmony_ci        &g_initScopesPhaseEts,
1173af6ab5fSopenharmony_ci        &g_optionalLowering,
1183af6ab5fSopenharmony_ci        &g_promiseVoidInferencePhase,
1193af6ab5fSopenharmony_ci        &g_structLowering,
1203af6ab5fSopenharmony_ci        &g_expressionLambdaConstructionPhase,
1213af6ab5fSopenharmony_ci        &g_interfacePropDeclPhase,
1223af6ab5fSopenharmony_ci        &g_enumLoweringPhase,
1233af6ab5fSopenharmony_ci        &g_resolveIdentifiers,
1243af6ab5fSopenharmony_ci        &g_capturedVariables,
1253af6ab5fSopenharmony_ci        &g_checkerPhase,        // please DO NOT change order of these two phases: checkerPhase and pluginsAfterCheck
1263af6ab5fSopenharmony_ci        &g_pluginsAfterCheck,   // pluginsAfterCheck has to go right after checkerPhase, nothing should be between them
1273af6ab5fSopenharmony_ci        &g_enumPostCheckLoweringPhase,
1283af6ab5fSopenharmony_ci        &g_spreadConstructionPhase,
1293af6ab5fSopenharmony_ci        &g_bigintLowering,
1303af6ab5fSopenharmony_ci        &g_opAssignmentLowering,
1313af6ab5fSopenharmony_ci        &g_constStringToCharLowering,
1323af6ab5fSopenharmony_ci        &g_boxingForLocals,
1333af6ab5fSopenharmony_ci        &g_lambdaConversionPhase,
1343af6ab5fSopenharmony_ci        &g_recordLowering,
1353af6ab5fSopenharmony_ci        &g_objectIndexLowering,
1363af6ab5fSopenharmony_ci        &g_objectIteratorLowering,
1373af6ab5fSopenharmony_ci        &g_tupleLowering,
1383af6ab5fSopenharmony_ci        &g_unionLowering,
1393af6ab5fSopenharmony_ci        &g_expandBracketsPhase,
1403af6ab5fSopenharmony_ci        &g_localClassLowering,
1413af6ab5fSopenharmony_ci        &g_interfaceObjectLiteralLowering,
1423af6ab5fSopenharmony_ci        &g_objectLiteralLowering,
1433af6ab5fSopenharmony_ci        &g_stringConstructorLowering,
1443af6ab5fSopenharmony_ci        &g_stringComparisonLowering,
1453af6ab5fSopenharmony_ci        &g_partialExportClassGen,
1463af6ab5fSopenharmony_ci        &g_genericBridgesLowering,
1473af6ab5fSopenharmony_ci        &g_pluginsAfterLowerings,  // pluginsAfterLowerings has to come at the very end, nothing should go after it
1483af6ab5fSopenharmony_ci    };
1493af6ab5fSopenharmony_ci    // clang-format on
1503af6ab5fSopenharmony_ci}
1513af6ab5fSopenharmony_ci
1523af6ab5fSopenharmony_cistd::vector<Phase *> GetASPhaseList()
1533af6ab5fSopenharmony_ci{
1543af6ab5fSopenharmony_ci    return {
1553af6ab5fSopenharmony_ci        &g_initScopesPhaseAs,
1563af6ab5fSopenharmony_ci        &g_checkerPhase,
1573af6ab5fSopenharmony_ci    };
1583af6ab5fSopenharmony_ci}
1593af6ab5fSopenharmony_ci
1603af6ab5fSopenharmony_cistd::vector<Phase *> GetTSPhaseList()
1613af6ab5fSopenharmony_ci{
1623af6ab5fSopenharmony_ci    return {
1633af6ab5fSopenharmony_ci        &g_initScopesPhaseTs,
1643af6ab5fSopenharmony_ci        &g_checkerPhase,
1653af6ab5fSopenharmony_ci    };
1663af6ab5fSopenharmony_ci}
1673af6ab5fSopenharmony_ci
1683af6ab5fSopenharmony_cistd::vector<Phase *> GetJSPhaseList()
1693af6ab5fSopenharmony_ci{
1703af6ab5fSopenharmony_ci    return {
1713af6ab5fSopenharmony_ci        &g_initScopesPhaseJs,
1723af6ab5fSopenharmony_ci        &g_checkerPhase,
1733af6ab5fSopenharmony_ci    };
1743af6ab5fSopenharmony_ci}
1753af6ab5fSopenharmony_ci
1763af6ab5fSopenharmony_cistd::vector<Phase *> GetPhaseList(ScriptExtension ext)
1773af6ab5fSopenharmony_ci{
1783af6ab5fSopenharmony_ci    switch (ext) {
1793af6ab5fSopenharmony_ci        case ScriptExtension::ETS:
1803af6ab5fSopenharmony_ci            return GetETSPhaseList();
1813af6ab5fSopenharmony_ci        case ScriptExtension::AS:
1823af6ab5fSopenharmony_ci            return GetASPhaseList();
1833af6ab5fSopenharmony_ci        case ScriptExtension::TS:
1843af6ab5fSopenharmony_ci            return GetTSPhaseList();
1853af6ab5fSopenharmony_ci        case ScriptExtension::JS:
1863af6ab5fSopenharmony_ci            return GetJSPhaseList();
1873af6ab5fSopenharmony_ci        default:
1883af6ab5fSopenharmony_ci            UNREACHABLE();
1893af6ab5fSopenharmony_ci    }
1903af6ab5fSopenharmony_ci}
1913af6ab5fSopenharmony_ci
1923af6ab5fSopenharmony_cibool Phase::Apply(public_lib::Context *ctx, parser::Program *program)
1933af6ab5fSopenharmony_ci{
1943af6ab5fSopenharmony_ci    const auto &options = ctx->config->options->CompilerOptions();
1953af6ab5fSopenharmony_ci    const auto name = std::string {Name()};
1963af6ab5fSopenharmony_ci    if (options.skipPhases.count(name) > 0) {
1973af6ab5fSopenharmony_ci        return true;
1983af6ab5fSopenharmony_ci    }
1993af6ab5fSopenharmony_ci
2003af6ab5fSopenharmony_ci    CheckOptionsBeforePhase(options, program, name);
2013af6ab5fSopenharmony_ci
2023af6ab5fSopenharmony_ci#ifndef NDEBUG
2033af6ab5fSopenharmony_ci    if (!Precondition(ctx, program)) {
2043af6ab5fSopenharmony_ci        ctx->checker->LogTypeError({"Precondition check failed for ", util::StringView {Name()}},
2053af6ab5fSopenharmony_ci                                   lexer::SourcePosition {});
2063af6ab5fSopenharmony_ci        return false;
2073af6ab5fSopenharmony_ci    }
2083af6ab5fSopenharmony_ci#endif
2093af6ab5fSopenharmony_ci
2103af6ab5fSopenharmony_ci    if (!Perform(ctx, program)) {
2113af6ab5fSopenharmony_ci        return false;
2123af6ab5fSopenharmony_ci    }
2133af6ab5fSopenharmony_ci
2143af6ab5fSopenharmony_ci    CheckOptionsAfterPhase(options, program, name);
2153af6ab5fSopenharmony_ci
2163af6ab5fSopenharmony_ci#ifndef NDEBUG
2173af6ab5fSopenharmony_ci    if (!Postcondition(ctx, program)) {
2183af6ab5fSopenharmony_ci        ctx->checker->LogTypeError({"Postcondition check failed for ", util::StringView {Name()}},
2193af6ab5fSopenharmony_ci                                   lexer::SourcePosition {});
2203af6ab5fSopenharmony_ci        return false;
2213af6ab5fSopenharmony_ci    }
2223af6ab5fSopenharmony_ci#endif
2233af6ab5fSopenharmony_ci
2243af6ab5fSopenharmony_ci    return !ctx->checker->ErrorLogger()->IsAnyError();
2253af6ab5fSopenharmony_ci}
2263af6ab5fSopenharmony_ci
2273af6ab5fSopenharmony_cistatic void CheckOptionsBeforePhase(const CompilerOptions &options, const parser::Program *program,
2283af6ab5fSopenharmony_ci                                    const std::string &name)
2293af6ab5fSopenharmony_ci{
2303af6ab5fSopenharmony_ci    if (options.dumpBeforePhases.count(name) > 0) {
2313af6ab5fSopenharmony_ci        std::cout << "Before phase " << name << ":" << std::endl;
2323af6ab5fSopenharmony_ci        std::cout << program->Dump() << std::endl;
2333af6ab5fSopenharmony_ci    }
2343af6ab5fSopenharmony_ci
2353af6ab5fSopenharmony_ci    if (options.dumpEtsSrcBeforePhases.count(name) > 0) {
2363af6ab5fSopenharmony_ci        std::cout << "Before phase " << name << " ets source"
2373af6ab5fSopenharmony_ci                  << ":" << std::endl;
2383af6ab5fSopenharmony_ci        std::cout << program->Ast()->DumpEtsSrc() << std::endl;
2393af6ab5fSopenharmony_ci    }
2403af6ab5fSopenharmony_ci}
2413af6ab5fSopenharmony_ci
2423af6ab5fSopenharmony_cistatic void CheckOptionsAfterPhase(const CompilerOptions &options, const parser::Program *program,
2433af6ab5fSopenharmony_ci                                   const std::string &name)
2443af6ab5fSopenharmony_ci{
2453af6ab5fSopenharmony_ci    if (options.dumpAfterPhases.count(name) > 0) {
2463af6ab5fSopenharmony_ci        std::cout << "After phase " << name << ":" << std::endl;
2473af6ab5fSopenharmony_ci        std::cout << program->Dump() << std::endl;
2483af6ab5fSopenharmony_ci    }
2493af6ab5fSopenharmony_ci
2503af6ab5fSopenharmony_ci    if (options.dumpEtsSrcAfterPhases.count(name) > 0) {
2513af6ab5fSopenharmony_ci        std::cout << "After phase " << name << " ets source"
2523af6ab5fSopenharmony_ci                  << ":" << std::endl;
2533af6ab5fSopenharmony_ci        std::cout << program->Ast()->DumpEtsSrc() << std::endl;
2543af6ab5fSopenharmony_ci    }
2553af6ab5fSopenharmony_ci}
2563af6ab5fSopenharmony_ci
2573af6ab5fSopenharmony_ci}  // namespace ark::es2panda::compiler
258