• 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 "compiler/core/ASTVerifier.h"
19 #include "compiler/core/compilerContext.h"
20 #include "compiler/lowering/ets/objectIndexAccess.h"
21 #include "lexer/token/sourceLocation.h"
22 #include "compiler/lowering/checkerPhase.h"
23 #include "compiler/lowering/plugin_phase.h"
24 #include "compiler/lowering/scopesInit/scopesInitPhase.h"
25 #include "compiler/lowering/ets/expandBrackets.h"
26 #include "compiler/lowering/ets/generateDeclarations.h"
27 #include "compiler/lowering/ets/lambdaLowering.h"
28 #include "compiler/lowering/ets/interfacePropertyDeclarations.h"
29 #include "compiler/lowering/ets/opAssignment.h"
30 #include "compiler/lowering/ets/tupleLowering.h"
31 #include "compiler/lowering/ets/unionLowering.h"
32 #include "compiler/lowering/ets/structLowering.h"
33 #include "public/es2panda_lib.h"
34 #include "compiler/lowering/ets/promiseVoid.h"
35 #include "utils/json_builder.h"
36 
37 namespace panda::es2panda::compiler {
38 
39 static CheckerPhase g_checkerPhase;
40 
GetTrivialPhaseList()41 std::vector<Phase *> GetTrivialPhaseList()
42 {
43     return std::vector<Phase *> {
44         &g_checkerPhase,
45     };
46 }
47 
48 static InterfacePropertyDeclarationsPhase g_interfacePropDeclPhase;
49 static GenerateTsDeclarationsPhase g_generateTsDeclarationsPhase;
50 static LambdaConstructionPhase g_lambdaConstructionPhase;
51 static OpAssignmentLowering g_opAssignmentLowering;
52 static ObjectIndexLowering g_objectIndexLowering;
53 static TupleLowering g_tupleLowering;  // Can be only applied after checking phase, and OP_ASSIGNMENT_LOWERING phase
54 static UnionLowering g_unionLowering;
55 static ExpandBracketsPhase g_expandBracketsPhase;
56 static PromiseVoidInferencePhase g_promiseVoidInferencePhase;
57 static StructLowering g_structLowering;
58 static PluginPhase g_pluginsAfterParse {"plugins-after-parse", ES2PANDA_STATE_PARSED, &util::Plugin::AfterParse};
59 static PluginPhase g_pluginsAfterCheck {"plugins-after-check", ES2PANDA_STATE_CHECKED, &util::Plugin::AfterCheck};
60 static PluginPhase g_pluginsAfterLowerings {"plugins-after-lowering", ES2PANDA_STATE_LOWERED,
61                                             &util::Plugin::AfterLowerings};
62 // NOLINTBEGIN(fuchsia-statically-constructed-objects)
63 static InitScopesPhaseETS g_initScopesPhaseEts;
64 static InitScopesPhaseAS g_initScopesPhaseAs;
65 static InitScopesPhaseTs g_initScopesPhaseTs;
66 static InitScopesPhaseJs g_initScopesPhaseJs;
67 // NOLINTEND(fuchsia-statically-constructed-objects)
68 
GetETSPhaseList()69 std::vector<Phase *> GetETSPhaseList()
70 {
71     return {
72         &g_pluginsAfterParse,    &g_initScopesPhaseEts,      &g_promiseVoidInferencePhase,
73         &g_structLowering,       &g_lambdaConstructionPhase, &g_interfacePropDeclPhase,
74         &g_checkerPhase,         &g_pluginsAfterCheck,       &g_generateTsDeclarationsPhase,
75         &g_opAssignmentLowering, &g_objectIndexLowering,     &g_tupleLowering,
76         &g_unionLowering,        &g_expandBracketsPhase,     &g_pluginsAfterLowerings,
77     };
78 }
79 
GetASPhaseList()80 std::vector<Phase *> GetASPhaseList()
81 {
82     return {
83         &g_initScopesPhaseAs,
84         &g_checkerPhase,
85     };
86 }
87 
GetTSPhaseList()88 std::vector<Phase *> GetTSPhaseList()
89 {
90     return {
91         &g_initScopesPhaseTs,
92         &g_checkerPhase,
93     };
94 }
95 
GetJSPhaseList()96 std::vector<Phase *> GetJSPhaseList()
97 {
98     return {
99         &g_initScopesPhaseJs,
100         &g_checkerPhase,
101     };
102 }
103 
GetPhaseList(ScriptExtension ext)104 std::vector<Phase *> GetPhaseList(ScriptExtension ext)
105 {
106     switch (ext) {
107         case ScriptExtension::ETS:
108             return GetETSPhaseList();
109         case ScriptExtension::AS:
110             return GetASPhaseList();
111         case ScriptExtension::TS:
112             return GetTSPhaseList();
113         case ScriptExtension::JS:
114             return GetJSPhaseList();
115         default:
116             UNREACHABLE();
117     }
118 }
119 
Apply(public_lib::Context * ctx,parser::Program * program)120 bool Phase::Apply(public_lib::Context *ctx, parser::Program *program)
121 {
122     const auto *options = ctx->compilerContext->Options();
123     const auto name = std::string {Name()};
124     if (options->skipPhases.count(name) > 0) {
125         return true;
126     }
127 
128     CheckOptionsBeforePhase(options, program, name);
129 
130 #ifndef NDEBUG
131     if (!Precondition(ctx, program)) {
132         ctx->checker->ThrowTypeError({"Precondition check failed for ", util::StringView {Name()}},
133                                      lexer::SourcePosition {});
134     }
135 #endif
136 
137     if (!Perform(ctx, program)) {
138         return false;
139     }
140 
141     CheckOptionsAfterPhase(options, program, name);
142 
143 #ifndef NDEBUG
144     if (!Postcondition(ctx, program)) {
145         ctx->checker->ThrowTypeError({"Postcondition check failed for ", util::StringView {Name()}},
146                                      lexer::SourcePosition {});
147     }
148 #endif
149 
150     return true;
151 }
152 
CheckOptionsBeforePhase(const CompilerOptions * options,const parser::Program * program,const std::string & name) const153 void Phase::CheckOptionsBeforePhase(const CompilerOptions *options, const parser::Program *program,
154                                     const std::string &name) const
155 {
156     if (options->dumpAfterPhases.count(name) > 0) {
157         std::cout << "After phase " << name << ":" << std::endl;
158         std::cout << program->Dump() << std::endl;
159     }
160 
161     if (options->dumpEtsSrcAfterPhases.count(name) > 0) {
162         std::cout << "After phase " << name << " ets source"
163                   << ":" << std::endl;
164         std::cout << program->Ast()->DumpEtsSrc() << std::endl;
165     }
166 }
167 
CheckOptionsAfterPhase(const CompilerOptions * options,const parser::Program * program,const std::string & name) const168 void Phase::CheckOptionsAfterPhase(const CompilerOptions *options, const parser::Program *program,
169                                    const std::string &name) const
170 {
171     if (options->dumpAfterPhases.count(name) > 0) {
172         std::cout << "After phase " << name << ":" << std::endl;
173         std::cout << program->Dump() << std::endl;
174     }
175 
176     if (options->dumpEtsSrcAfterPhases.count(name) > 0) {
177         std::cout << "After phase " << name << " ets source"
178                   << ":" << std::endl;
179         std::cout << program->Ast()->DumpEtsSrc() << std::endl;
180     }
181 }
182 
183 }  // namespace panda::es2panda::compiler
184