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/lambdaLowering.h"
30 #include "compiler/lowering/ets/spreadLowering.h"
31 #include "compiler/lowering/ets/interfacePropertyDeclarations.h"
32 #include "compiler/lowering/ets/objectIndexAccess.h"
33 #include "compiler/lowering/ets/objectIterator.h"
34 #include "compiler/lowering/ets/localClassLowering.h"
35 #include "compiler/lowering/ets/opAssignment.h"
36 #include "compiler/lowering/ets/objectLiteralLowering.h"
37 #include "compiler/lowering/ets/interfaceObjectLiteralLowering.h"
38 #include "compiler/lowering/ets/optionalLowering.h"
39 #include "compiler/lowering/ets/partialExportClassGen.h"
40 #include "compiler/lowering/ets/promiseVoid.h"
41 #include "compiler/lowering/ets/stringComparison.h"
42 #include "compiler/lowering/ets/structLowering.h"
43 #include "compiler/lowering/ets/tupleLowering.h"
44 #include "compiler/lowering/ets/bigintLowering.h"
45 #include "compiler/lowering/ets/unionLowering.h"
46 #include "compiler/lowering/ets/stringConstructorLowering.h"
47 #include "compiler/lowering/ets/enumLowering.h"
48 #include "compiler/lowering/ets/enumPostCheckLowering.h"
49 #include "compiler/lowering/plugin_phase.h"
50 #include "compiler/lowering/scopesInit/scopesInitPhase.h"
51 #include "public/es2panda_lib.h"
52
53 namespace ark::es2panda::compiler {
54
55 static CheckerPhase g_checkerPhase;
56 static ResolveIdentifiers g_resolveIdentifiers {};
57 static AmbientLowering g_ambientLowering;
58 static BigIntLowering g_bigintLowering;
59 static StringConstructorLowering g_stringConstructorLowering;
60 static ConstStringToCharLowering g_constStringToCharLowering;
61 static InterfacePropertyDeclarationsPhase g_interfacePropDeclPhase;
62 static EnumLoweringPhase g_enumLoweringPhase;
63 static EnumPostCheckLoweringPhase g_enumPostCheckLoweringPhase;
64 static SpreadConstructionPhase g_spreadConstructionPhase;
65 static ExpressionLambdaConstructionPhase g_expressionLambdaConstructionPhase;
66 static OpAssignmentLowering g_opAssignmentLowering;
67 static BoxingForLocals g_boxingForLocals;
68 static LambdaConversionPhase g_lambdaConversionPhase;
69 static ObjectIndexLowering g_objectIndexLowering;
70 static ObjectIteratorLowering g_objectIteratorLowering;
71 static ObjectLiteralLowering g_objectLiteralLowering;
72 static InterfaceObjectLiteralLowering g_interfaceObjectLiteralLowering;
73 static TupleLowering g_tupleLowering; // Can be only applied after checking phase, and OP_ASSIGNMENT_LOWERING phase
74 static UnionLowering g_unionLowering;
75 static OptionalLowering g_optionalLowering;
76 static ExpandBracketsPhase g_expandBracketsPhase;
77 static PromiseVoidInferencePhase g_promiseVoidInferencePhase;
78 static RecordLowering g_recordLowering;
79 static StructLowering g_structLowering;
80 static DefaultParameterLowering g_defaultParameterLowering;
81 static TopLevelStatements g_topLevelStatements;
82 static LocalClassConstructionPhase g_localClassLowering;
83 static StringComparisonLowering g_stringComparisonLowering;
84 static PartialExportClassGen g_partialExportClassGen;
85 static PluginPhase g_pluginsAfterParse {"plugins-after-parse", ES2PANDA_STATE_PARSED, &util::Plugin::AfterParse};
86 static PluginPhase g_pluginsAfterCheck {"plugins-after-check", ES2PANDA_STATE_CHECKED, &util::Plugin::AfterCheck};
87 static PluginPhase g_pluginsAfterLowerings {"plugins-after-lowering", ES2PANDA_STATE_LOWERED,
88 &util::Plugin::AfterLowerings};
89 // NOLINTBEGIN(fuchsia-statically-constructed-objects)
90 static InitScopesPhaseETS g_initScopesPhaseEts;
91 static InitScopesPhaseAS g_initScopesPhaseAs;
92 static InitScopesPhaseTs g_initScopesPhaseTs;
93 static InitScopesPhaseJs g_initScopesPhaseJs;
94 // NOLINTEND(fuchsia-statically-constructed-objects)
95
96 static void CheckOptionsBeforePhase(const CompilerOptions &options, const parser::Program *program,
97 const std::string &name);
98 static void CheckOptionsAfterPhase(const CompilerOptions &options, const parser::Program *program,
99 const std::string &name);
100
GetETSPhaseList()101 std::vector<Phase *> GetETSPhaseList()
102 {
103 // clang-format off
104 return {
105 &g_pluginsAfterParse,
106 &g_topLevelStatements,
107 &g_defaultParameterLowering,
108 &g_ambientLowering,
109 &g_initScopesPhaseEts,
110 &g_optionalLowering,
111 &g_promiseVoidInferencePhase,
112 &g_structLowering,
113 &g_expressionLambdaConstructionPhase,
114 &g_interfacePropDeclPhase,
115 &g_enumLoweringPhase,
116 &g_resolveIdentifiers,
117 &g_checkerPhase,
118 &g_enumPostCheckLoweringPhase,
119 &g_spreadConstructionPhase,
120 &g_pluginsAfterCheck,
121 &g_bigintLowering,
122 &g_opAssignmentLowering,
123 &g_constStringToCharLowering,
124 &g_boxingForLocals,
125 &g_lambdaConversionPhase,
126 &g_recordLowering,
127 &g_objectIndexLowering,
128 &g_objectIteratorLowering,
129 &g_tupleLowering,
130 &g_unionLowering,
131 &g_expandBracketsPhase,
132 &g_localClassLowering,
133 &g_interfaceObjectLiteralLowering,
134 &g_objectLiteralLowering,
135 &g_stringConstructorLowering,
136 &g_stringComparisonLowering,
137 &g_partialExportClassGen,
138 &g_pluginsAfterLowerings,
139 };
140 // clang-format on
141 }
142
GetASPhaseList()143 std::vector<Phase *> GetASPhaseList()
144 {
145 return {
146 &g_initScopesPhaseAs,
147 &g_checkerPhase,
148 };
149 }
150
GetTSPhaseList()151 std::vector<Phase *> GetTSPhaseList()
152 {
153 return {
154 &g_initScopesPhaseTs,
155 &g_checkerPhase,
156 };
157 }
158
GetJSPhaseList()159 std::vector<Phase *> GetJSPhaseList()
160 {
161 return {
162 &g_initScopesPhaseJs,
163 &g_checkerPhase,
164 };
165 }
166
GetPhaseList(ScriptExtension ext)167 std::vector<Phase *> GetPhaseList(ScriptExtension ext)
168 {
169 switch (ext) {
170 case ScriptExtension::ETS:
171 return GetETSPhaseList();
172 case ScriptExtension::AS:
173 return GetASPhaseList();
174 case ScriptExtension::TS:
175 return GetTSPhaseList();
176 case ScriptExtension::JS:
177 return GetJSPhaseList();
178 default:
179 UNREACHABLE();
180 }
181 }
182
Apply(public_lib::Context * ctx,parser::Program * program)183 bool Phase::Apply(public_lib::Context *ctx, parser::Program *program)
184 {
185 const auto &options = ctx->config->options->CompilerOptions();
186 const auto name = std::string {Name()};
187 if (options.skipPhases.count(name) > 0) {
188 return true;
189 }
190
191 CheckOptionsBeforePhase(options, program, name);
192
193 #ifndef NDEBUG
194 if (!Precondition(ctx, program)) {
195 ctx->checker->ThrowTypeError({"Precondition check failed for ", util::StringView {Name()}},
196 lexer::SourcePosition {});
197 }
198 #endif
199
200 if (!Perform(ctx, program)) {
201 return false;
202 }
203
204 CheckOptionsAfterPhase(options, program, name);
205
206 #ifndef NDEBUG
207 if (!Postcondition(ctx, program)) {
208 ctx->checker->ThrowTypeError({"Postcondition check failed for ", util::StringView {Name()}},
209 lexer::SourcePosition {});
210 }
211 #endif
212
213 return true;
214 }
215
CheckOptionsBeforePhase(const CompilerOptions & options,const parser::Program * program,const std::string & name)216 static void CheckOptionsBeforePhase(const CompilerOptions &options, const parser::Program *program,
217 const std::string &name)
218 {
219 if (options.dumpBeforePhases.count(name) > 0) {
220 std::cout << "Before phase " << name << ":" << std::endl;
221 std::cout << program->Dump() << std::endl;
222 }
223
224 if (options.dumpEtsSrcBeforePhases.count(name) > 0) {
225 std::cout << "Before phase " << name << " ets source"
226 << ":" << std::endl;
227 std::cout << program->Ast()->DumpEtsSrc() << std::endl;
228 }
229 }
230
CheckOptionsAfterPhase(const CompilerOptions & options,const parser::Program * program,const std::string & name)231 static void CheckOptionsAfterPhase(const CompilerOptions &options, const parser::Program *program,
232 const std::string &name)
233 {
234 if (options.dumpAfterPhases.count(name) > 0) {
235 std::cout << "After phase " << name << ":" << std::endl;
236 std::cout << program->Dump() << std::endl;
237 }
238
239 if (options.dumpEtsSrcAfterPhases.count(name) > 0) {
240 std::cout << "After phase " << name << " ets source"
241 << ":" << std::endl;
242 std::cout << program->Ast()->DumpEtsSrc() << std::endl;
243 }
244 }
245
246 } // namespace ark::es2panda::compiler
247