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
56 namespace ark::es2panda::compiler {
57
58 static CheckerPhase g_checkerPhase;
59 static ResolveIdentifiers g_resolveIdentifiers {};
60 static AmbientLowering g_ambientLowering;
61 static BigIntLowering g_bigintLowering;
62 static StringConstructorLowering g_stringConstructorLowering;
63 static ConstStringToCharLowering g_constStringToCharLowering;
64 static InterfacePropertyDeclarationsPhase g_interfacePropDeclPhase;
65 static EnumLoweringPhase g_enumLoweringPhase;
66 static EnumPostCheckLoweringPhase g_enumPostCheckLoweringPhase;
67 static SpreadConstructionPhase g_spreadConstructionPhase;
68 static ExpressionLambdaConstructionPhase g_expressionLambdaConstructionPhase;
69 static OpAssignmentLowering g_opAssignmentLowering;
70 static BoxingForLocals g_boxingForLocals;
71 static CapturedVariables g_capturedVariables {};
72 static LambdaConversionPhase g_lambdaConversionPhase;
73 static ObjectIndexLowering g_objectIndexLowering;
74 static ObjectIteratorLowering g_objectIteratorLowering;
75 static ObjectLiteralLowering g_objectLiteralLowering;
76 static InterfaceObjectLiteralLowering g_interfaceObjectLiteralLowering;
77 static TupleLowering g_tupleLowering; // Can be only applied after checking phase, and OP_ASSIGNMENT_LOWERING phase
78 static UnionLowering g_unionLowering;
79 static OptionalLowering g_optionalLowering;
80 static ExpandBracketsPhase g_expandBracketsPhase;
81 static PromiseVoidInferencePhase g_promiseVoidInferencePhase;
82 static RecordLowering g_recordLowering;
83 static StructLowering g_structLowering;
84 static DefaultParameterLowering g_defaultParameterLowering;
85 static TopLevelStatements g_topLevelStatements;
86 static LocalClassConstructionPhase g_localClassLowering;
87 static StringComparisonLowering g_stringComparisonLowering;
88 static PartialExportClassGen g_partialExportClassGen;
89 static PackageImplicitImport g_packageImplicitImport;
90 static GenericBridgesPhase g_genericBridgesLowering;
91 static PluginPhase g_pluginsAfterParse {"plugins-after-parse", ES2PANDA_STATE_PARSED, &util::Plugin::AfterParse};
92 static PluginPhase g_pluginsAfterCheck {"plugins-after-check", ES2PANDA_STATE_CHECKED, &util::Plugin::AfterCheck};
93 static PluginPhase g_pluginsAfterLowerings {"plugins-after-lowering", ES2PANDA_STATE_LOWERED,
94 &util::Plugin::AfterLowerings};
95 // NOLINTBEGIN(fuchsia-statically-constructed-objects)
96 static InitScopesPhaseETS g_initScopesPhaseEts;
97 static InitScopesPhaseAS g_initScopesPhaseAs;
98 static InitScopesPhaseTs g_initScopesPhaseTs;
99 static InitScopesPhaseJs g_initScopesPhaseJs;
100 // NOLINTEND(fuchsia-statically-constructed-objects)
101
102 static void CheckOptionsBeforePhase(const CompilerOptions &options, const parser::Program *program,
103 const std::string &name);
104 static void CheckOptionsAfterPhase(const CompilerOptions &options, const parser::Program *program,
105 const std::string &name);
106
GetETSPhaseList()107 std::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
GetASPhaseList()152 std::vector<Phase *> GetASPhaseList()
153 {
154 return {
155 &g_initScopesPhaseAs,
156 &g_checkerPhase,
157 };
158 }
159
GetTSPhaseList()160 std::vector<Phase *> GetTSPhaseList()
161 {
162 return {
163 &g_initScopesPhaseTs,
164 &g_checkerPhase,
165 };
166 }
167
GetJSPhaseList()168 std::vector<Phase *> GetJSPhaseList()
169 {
170 return {
171 &g_initScopesPhaseJs,
172 &g_checkerPhase,
173 };
174 }
175
GetPhaseList(ScriptExtension ext)176 std::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
Apply(public_lib::Context *ctx, parser::Program *program)192 bool 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
CheckOptionsBeforePhase(const CompilerOptions &options, const parser::Program *program, const std::string &name)227 static 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
CheckOptionsAfterPhase(const CompilerOptions &options, const parser::Program *program, const std::string &name)242 static 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