1/* 2 * Copyright (c) 2021-2024 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16#include "phase.h" 17#include "checker/checker.h" 18#include "ets/ambientLowering.h" 19#include "lexer/token/sourceLocation.h" 20#include "compiler/lowering/resolveIdentifiers.h" 21#include "compiler/lowering/checkerPhase.h" 22#include "compiler/lowering/ets/constStringToCharLowering.h" 23#include "compiler/lowering/ets/defaultParameterLowering.h" 24#include "compiler/lowering/ets/expandBrackets.h" 25#include "compiler/lowering/ets/recordLowering.h" 26#include "compiler/lowering/ets/topLevelStmts/topLevelStmts.h" 27#include "compiler/lowering/ets/expressionLambdaLowering.h" 28#include "compiler/lowering/ets/boxingForLocals.h" 29#include "compiler/lowering/ets/capturedVariables.h" 30#include "compiler/lowering/ets/lambdaLowering.h" 31#include "compiler/lowering/ets/spreadLowering.h" 32#include "compiler/lowering/ets/interfacePropertyDeclarations.h" 33#include "compiler/lowering/ets/objectIndexAccess.h" 34#include "compiler/lowering/ets/objectIterator.h" 35#include "compiler/lowering/ets/localClassLowering.h" 36#include "compiler/lowering/ets/opAssignment.h" 37#include "compiler/lowering/ets/objectLiteralLowering.h" 38#include "compiler/lowering/ets/interfaceObjectLiteralLowering.h" 39#include "compiler/lowering/ets/optionalLowering.h" 40#include "compiler/lowering/ets/packageImplicitImport.h" 41#include "compiler/lowering/ets/partialExportClassGen.h" 42#include "compiler/lowering/ets/promiseVoid.h" 43#include "compiler/lowering/ets/stringComparison.h" 44#include "compiler/lowering/ets/structLowering.h" 45#include "compiler/lowering/ets/tupleLowering.h" 46#include "compiler/lowering/ets/bigintLowering.h" 47#include "compiler/lowering/ets/unionLowering.h" 48#include "compiler/lowering/ets/stringConstructorLowering.h" 49#include "compiler/lowering/ets/enumLowering.h" 50#include "compiler/lowering/ets/enumPostCheckLowering.h" 51#include "compiler/lowering/ets/genericBridgesLowering.h" 52#include "compiler/lowering/plugin_phase.h" 53#include "compiler/lowering/scopesInit/scopesInitPhase.h" 54#include "public/es2panda_lib.h" 55 56namespace ark::es2panda::compiler { 57 58static CheckerPhase g_checkerPhase; 59static ResolveIdentifiers g_resolveIdentifiers {}; 60static AmbientLowering g_ambientLowering; 61static BigIntLowering g_bigintLowering; 62static StringConstructorLowering g_stringConstructorLowering; 63static ConstStringToCharLowering g_constStringToCharLowering; 64static InterfacePropertyDeclarationsPhase g_interfacePropDeclPhase; 65static EnumLoweringPhase g_enumLoweringPhase; 66static EnumPostCheckLoweringPhase g_enumPostCheckLoweringPhase; 67static SpreadConstructionPhase g_spreadConstructionPhase; 68static ExpressionLambdaConstructionPhase g_expressionLambdaConstructionPhase; 69static OpAssignmentLowering g_opAssignmentLowering; 70static BoxingForLocals g_boxingForLocals; 71static CapturedVariables g_capturedVariables {}; 72static LambdaConversionPhase g_lambdaConversionPhase; 73static ObjectIndexLowering g_objectIndexLowering; 74static ObjectIteratorLowering g_objectIteratorLowering; 75static ObjectLiteralLowering g_objectLiteralLowering; 76static InterfaceObjectLiteralLowering g_interfaceObjectLiteralLowering; 77static TupleLowering g_tupleLowering; // Can be only applied after checking phase, and OP_ASSIGNMENT_LOWERING phase 78static UnionLowering g_unionLowering; 79static OptionalLowering g_optionalLowering; 80static ExpandBracketsPhase g_expandBracketsPhase; 81static PromiseVoidInferencePhase g_promiseVoidInferencePhase; 82static RecordLowering g_recordLowering; 83static StructLowering g_structLowering; 84static DefaultParameterLowering g_defaultParameterLowering; 85static TopLevelStatements g_topLevelStatements; 86static LocalClassConstructionPhase g_localClassLowering; 87static StringComparisonLowering g_stringComparisonLowering; 88static PartialExportClassGen g_partialExportClassGen; 89static PackageImplicitImport g_packageImplicitImport; 90static GenericBridgesPhase g_genericBridgesLowering; 91static PluginPhase g_pluginsAfterParse {"plugins-after-parse", ES2PANDA_STATE_PARSED, &util::Plugin::AfterParse}; 92static PluginPhase g_pluginsAfterCheck {"plugins-after-check", ES2PANDA_STATE_CHECKED, &util::Plugin::AfterCheck}; 93static PluginPhase g_pluginsAfterLowerings {"plugins-after-lowering", ES2PANDA_STATE_LOWERED, 94 &util::Plugin::AfterLowerings}; 95// NOLINTBEGIN(fuchsia-statically-constructed-objects) 96static InitScopesPhaseETS g_initScopesPhaseEts; 97static InitScopesPhaseAS g_initScopesPhaseAs; 98static InitScopesPhaseTs g_initScopesPhaseTs; 99static InitScopesPhaseJs g_initScopesPhaseJs; 100// NOLINTEND(fuchsia-statically-constructed-objects) 101 102static void CheckOptionsBeforePhase(const CompilerOptions &options, const parser::Program *program, 103 const std::string &name); 104static void CheckOptionsAfterPhase(const CompilerOptions &options, const parser::Program *program, 105 const std::string &name); 106 107std::vector<Phase *> GetETSPhaseList() 108{ 109 // clang-format off 110 return { 111 &g_pluginsAfterParse, 112 &g_packageImplicitImport, 113 &g_topLevelStatements, 114 &g_defaultParameterLowering, 115 &g_ambientLowering, 116 &g_initScopesPhaseEts, 117 &g_optionalLowering, 118 &g_promiseVoidInferencePhase, 119 &g_structLowering, 120 &g_expressionLambdaConstructionPhase, 121 &g_interfacePropDeclPhase, 122 &g_enumLoweringPhase, 123 &g_resolveIdentifiers, 124 &g_capturedVariables, 125 &g_checkerPhase, // please DO NOT change order of these two phases: checkerPhase and pluginsAfterCheck 126 &g_pluginsAfterCheck, // pluginsAfterCheck has to go right after checkerPhase, nothing should be between them 127 &g_enumPostCheckLoweringPhase, 128 &g_spreadConstructionPhase, 129 &g_bigintLowering, 130 &g_opAssignmentLowering, 131 &g_constStringToCharLowering, 132 &g_boxingForLocals, 133 &g_lambdaConversionPhase, 134 &g_recordLowering, 135 &g_objectIndexLowering, 136 &g_objectIteratorLowering, 137 &g_tupleLowering, 138 &g_unionLowering, 139 &g_expandBracketsPhase, 140 &g_localClassLowering, 141 &g_interfaceObjectLiteralLowering, 142 &g_objectLiteralLowering, 143 &g_stringConstructorLowering, 144 &g_stringComparisonLowering, 145 &g_partialExportClassGen, 146 &g_genericBridgesLowering, 147 &g_pluginsAfterLowerings, // pluginsAfterLowerings has to come at the very end, nothing should go after it 148 }; 149 // clang-format on 150} 151 152std::vector<Phase *> GetASPhaseList() 153{ 154 return { 155 &g_initScopesPhaseAs, 156 &g_checkerPhase, 157 }; 158} 159 160std::vector<Phase *> GetTSPhaseList() 161{ 162 return { 163 &g_initScopesPhaseTs, 164 &g_checkerPhase, 165 }; 166} 167 168std::vector<Phase *> GetJSPhaseList() 169{ 170 return { 171 &g_initScopesPhaseJs, 172 &g_checkerPhase, 173 }; 174} 175 176std::vector<Phase *> GetPhaseList(ScriptExtension ext) 177{ 178 switch (ext) { 179 case ScriptExtension::ETS: 180 return GetETSPhaseList(); 181 case ScriptExtension::AS: 182 return GetASPhaseList(); 183 case ScriptExtension::TS: 184 return GetTSPhaseList(); 185 case ScriptExtension::JS: 186 return GetJSPhaseList(); 187 default: 188 UNREACHABLE(); 189 } 190} 191 192bool Phase::Apply(public_lib::Context *ctx, parser::Program *program) 193{ 194 const auto &options = ctx->config->options->CompilerOptions(); 195 const auto name = std::string {Name()}; 196 if (options.skipPhases.count(name) > 0) { 197 return true; 198 } 199 200 CheckOptionsBeforePhase(options, program, name); 201 202#ifndef NDEBUG 203 if (!Precondition(ctx, program)) { 204 ctx->checker->LogTypeError({"Precondition check failed for ", util::StringView {Name()}}, 205 lexer::SourcePosition {}); 206 return false; 207 } 208#endif 209 210 if (!Perform(ctx, program)) { 211 return false; 212 } 213 214 CheckOptionsAfterPhase(options, program, name); 215 216#ifndef NDEBUG 217 if (!Postcondition(ctx, program)) { 218 ctx->checker->LogTypeError({"Postcondition check failed for ", util::StringView {Name()}}, 219 lexer::SourcePosition {}); 220 return false; 221 } 222#endif 223 224 return !ctx->checker->ErrorLogger()->IsAnyError(); 225} 226 227static void CheckOptionsBeforePhase(const CompilerOptions &options, const parser::Program *program, 228 const std::string &name) 229{ 230 if (options.dumpBeforePhases.count(name) > 0) { 231 std::cout << "Before phase " << name << ":" << std::endl; 232 std::cout << program->Dump() << std::endl; 233 } 234 235 if (options.dumpEtsSrcBeforePhases.count(name) > 0) { 236 std::cout << "Before phase " << name << " ets source" 237 << ":" << std::endl; 238 std::cout << program->Ast()->DumpEtsSrc() << std::endl; 239 } 240} 241 242static void CheckOptionsAfterPhase(const CompilerOptions &options, const parser::Program *program, 243 const std::string &name) 244{ 245 if (options.dumpAfterPhases.count(name) > 0) { 246 std::cout << "After phase " << name << ":" << std::endl; 247 std::cout << program->Dump() << std::endl; 248 } 249 250 if (options.dumpEtsSrcAfterPhases.count(name) > 0) { 251 std::cout << "After phase " << name << " ets source" 252 << ":" << std::endl; 253 std::cout << program->Ast()->DumpEtsSrc() << std::endl; 254 } 255} 256 257} // namespace ark::es2panda::compiler 258