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