• 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/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