• 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 "es2panda_lib.h"
17 #include <memory>
18 
19 #include "varbinder/varbinder.h"
20 #include "varbinder/scope.h"
21 #include "varbinder/variable.h"
22 #include "public/public.h"
23 #include "generated/signatures.h"
24 #include "es2panda.h"
25 #include "assembler/assembly-program.h"
26 #include "varbinder/ETSBinder.h"
27 #include "checker/ETSAnalyzer.h"
28 #include "checker/ETSchecker.h"
29 #include "compiler/core/compileQueue.h"
30 #include "compiler/core/ETSCompiler.h"
31 #include "compiler/core/ETSemitter.h"
32 #include "compiler/core/ETSGen.h"
33 #include "compiler/core/regSpiller.h"
34 #include "compiler/lowering/phase.h"
35 #include "compiler/lowering/checkerPhase.h"
36 #include "compiler/lowering/scopesInit/scopesInitPhase.h"
37 #include "ir/astNode.h"
38 #include "ir/expressions/arrowFunctionExpression.h"
39 #include "ir/ts/tsAsExpression.h"
40 #include "ir/expressions/assignmentExpression.h"
41 #include "ir/expressions/binaryExpression.h"
42 #include "ir/statements/blockStatement.h"
43 #include "ir/expressions/callExpression.h"
44 #include "ir/expressions/chainExpression.h"
45 #include "ir/statements/classDeclaration.h"
46 #include "ir/base/classDefinition.h"
47 #include "ir/base/classElement.h"
48 #include "ir/ts/tsClassImplements.h"
49 #include "ir/base/classProperty.h"
50 #include "ir/base/scriptFunctionSignature.h"
51 #include "ir/statements/expressionStatement.h"
52 #include "ir/statements/functionDeclaration.h"
53 #include "ir/expressions/functionExpression.h"
54 #include "ir/ets/etsFunctionType.h"
55 #include "ir/expressions/identifier.h"
56 #include "ir/statements/ifStatement.h"
57 #include "ir/module/importDeclaration.h"
58 #include "ir/expressions/importExpression.h"
59 #include "ir/module/importSpecifier.h"
60 #include "ir/base/methodDefinition.h"
61 #include "ir/ets/etsNewClassInstanceExpression.h"
62 #include "ir/ets/etsNewArrayInstanceExpression.h"
63 #include "ir/ets/etsNewMultiDimArrayInstanceExpression.h"
64 #include "ir/expressions/thisExpression.h"
65 #include "ir/ts/tsTypeParameter.h"
66 #include "ir/ts/tsTypeParameterDeclaration.h"
67 #include "ir/ts/tsTypeParameterInstantiation.h"
68 #include "ir/statements/variableDeclaration.h"
69 #include "ir/statements/variableDeclarator.h"
70 #include "parser/ETSparser.h"
71 #include "parser/context/parserContext.h"
72 #include "parser/program/program.h"
73 #include "util/generateBin.h"
74 #include "util/language.h"
75 #include "util/options.h"
76 
77 namespace ark::es2panda::public_lib {
78 
79 struct TokenTypeToStr {
80     lexer::TokenType token;
81     char const *str;
82 };
83 
StrToToken(TokenTypeToStr const * table,char const * str)84 static lexer::TokenType StrToToken(TokenTypeToStr const *table, char const *str)
85 {
86     // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
87     for (auto *tp = table; tp->str != nullptr; tp++) {
88         if (strcmp(str, tp->str) == 0) {
89             return tp->token;
90         }
91     }
92     UNREACHABLE();
93 }
94 
TokenToStr(TokenTypeToStr const * table,lexer::TokenType token)95 static char const *TokenToStr(TokenTypeToStr const *table, lexer::TokenType token)
96 {
97     // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
98     for (auto *tp = table; tp->str != nullptr; tp++) {
99         if (tp->token == token) {
100             return tp->str;
101         }
102     }
103     UNREACHABLE();
104 }
105 
StringViewToCString(ArenaAllocator * allocator,util::StringView const sv)106 static char const *StringViewToCString(ArenaAllocator *allocator, util::StringView const sv)
107 {
108     // NOLINTBEGIN(cppcoreguidelines-pro-bounds-pointer-arithmetic, readability-simplify-subscript-expr)
109     std::string_view utf8 = sv.Utf8();
110     if (utf8.data()[utf8.size()] == '\0') {
111         // Avoid superfluous allocation.
112         return utf8.data();
113     }
114     char *res = reinterpret_cast<char *>(allocator->Alloc(utf8.size() + 1));
115     [[maybe_unused]] auto err = memmove_s(res, utf8.size() + 1, utf8.cbegin(), utf8.size());
116     ASSERT(err == EOK);
117     res[utf8.size()] = '\0';
118     return res;
119     // NOLINTEND(cppcoreguidelines-pro-bounds-pointer-arithmetic, readability-simplify-subscript-expr)
120 }
121 
ArenaStrdup(ArenaAllocator * allocator,char const * src)122 static char const *ArenaStrdup(ArenaAllocator *allocator, char const *src)
123 {
124     size_t len = strlen(src);
125     char *res = reinterpret_cast<char *>(allocator->Alloc(len + 1));
126     [[maybe_unused]] auto err = memmove_s(res, len + 1, src, len);
127     ASSERT(err == EOK);
128 
129     // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
130     res[len] = '\0';
131     return res;
132 }
133 
E2pToIrAccessFlags(es2panda_ModifierFlags e2pFlags)134 static ir::ModifierFlags E2pToIrAccessFlags(es2panda_ModifierFlags e2pFlags)
135 {
136     ir::ModifierFlags irFlags {ir::ModifierFlags::NONE};
137     irFlags |= (e2pFlags & ES2PANDA_MODIFIER_PUBLIC) != 0 ? ir::ModifierFlags::PUBLIC : ir::ModifierFlags::NONE;
138     irFlags |= (e2pFlags & ES2PANDA_MODIFIER_PROTECTED) != 0 ? ir::ModifierFlags::PROTECTED : ir::ModifierFlags::NONE;
139     irFlags |= (e2pFlags & ES2PANDA_MODIFIER_PRIVATE) != 0 ? ir::ModifierFlags::PRIVATE : ir::ModifierFlags::NONE;
140     irFlags |= (e2pFlags & ES2PANDA_MODIFIER_INTERNAL) != 0 ? ir::ModifierFlags::INTERNAL : ir::ModifierFlags::NONE;
141 
142     return irFlags;
143 }
144 
E2pToIrMethodFlags(es2panda_ModifierFlags e2pFlags)145 static ir::ModifierFlags E2pToIrMethodFlags(es2panda_ModifierFlags e2pFlags)
146 {
147     ir::ModifierFlags irFlags {ir::ModifierFlags::NONE};
148     irFlags |= (e2pFlags & ES2PANDA_MODIFIER_STATIC) != 0 ? ir::ModifierFlags::STATIC : ir::ModifierFlags::NONE;
149     irFlags |= (e2pFlags & ES2PANDA_MODIFIER_ABSTRACT) != 0 ? ir::ModifierFlags::ABSTRACT : ir::ModifierFlags::NONE;
150     irFlags |= (e2pFlags & ES2PANDA_MODIFIER_FINAL) != 0 ? ir::ModifierFlags::FINAL : ir::ModifierFlags::NONE;
151     irFlags |= (e2pFlags & ES2PANDA_MODIFIER_NATIVE) != 0 ? ir::ModifierFlags::NATIVE : ir::ModifierFlags::NONE;
152     irFlags |= (e2pFlags & ES2PANDA_MODIFIER_OVERRIDE) != 0 ? ir::ModifierFlags::OVERRIDE : ir::ModifierFlags::NONE;
153 
154     return irFlags;
155 }
156 
E2pToIrModifierFlags(es2panda_ModifierFlags e2pFlags)157 static ir::ModifierFlags E2pToIrModifierFlags(es2panda_ModifierFlags e2pFlags)
158 {
159     ir::ModifierFlags irFlags {ir::ModifierFlags::NONE};
160     irFlags |= E2pToIrAccessFlags(e2pFlags);
161     irFlags |= E2pToIrMethodFlags(e2pFlags);
162     irFlags |= (e2pFlags & ES2PANDA_MODIFIER_ASYNC) != 0 ? ir::ModifierFlags::ASYNC : ir::ModifierFlags::NONE;
163     irFlags |= (e2pFlags & ES2PANDA_MODIFIER_DECLARE) != 0 ? ir::ModifierFlags::DECLARE : ir::ModifierFlags::NONE;
164     irFlags |= (e2pFlags & ES2PANDA_MODIFIER_READONLY) != 0 ? ir::ModifierFlags::READONLY : ir::ModifierFlags::NONE;
165     irFlags |= (e2pFlags & ES2PANDA_MODIFIER_OPTIONAL) != 0 ? ir::ModifierFlags::OPTIONAL : ir::ModifierFlags::NONE;
166     irFlags |= (e2pFlags & ES2PANDA_MODIFIER_DEFINITE) != 0 ? ir::ModifierFlags::DEFINITE : ir::ModifierFlags::NONE;
167     irFlags |= (e2pFlags & ES2PANDA_MODIFIER_CONST) != 0 ? ir::ModifierFlags::CONST : ir::ModifierFlags::NONE;
168     irFlags |=
169         (e2pFlags & ES2PANDA_MODIFIER_CONSTRUCTOR) != 0 ? ir::ModifierFlags::CONSTRUCTOR : ir::ModifierFlags::NONE;
170     irFlags |=
171         (e2pFlags & ES2PANDA_MODIFIER_SYNCHRONIZED) != 0 ? ir::ModifierFlags::SYNCHRONIZED : ir::ModifierFlags::NONE;
172     irFlags |= (e2pFlags & ES2PANDA_MODIFIER_FUNCTIONAL) != 0 ? ir::ModifierFlags::FUNCTIONAL : ir::ModifierFlags::NONE;
173     irFlags |= (e2pFlags & ES2PANDA_MODIFIER_IN) != 0 ? ir::ModifierFlags::IN : ir::ModifierFlags::NONE;
174     irFlags |= (e2pFlags & ES2PANDA_MODIFIER_OUT) != 0 ? ir::ModifierFlags::OUT : ir::ModifierFlags::NONE;
175     irFlags |= (e2pFlags & ES2PANDA_MODIFIER_EXPORT) != 0 ? ir::ModifierFlags::EXPORT : ir::ModifierFlags::NONE;
176     irFlags |= (e2pFlags & ES2PANDA_MODIFIER_SETTER) != 0 ? ir::ModifierFlags::SETTER : ir::ModifierFlags::NONE;
177     irFlags |= (e2pFlags & ES2PANDA_MODIFIER_DEFAULT_EXPORT) != 0 ? ir::ModifierFlags::DEFAULT_EXPORT
178                                                                   : ir::ModifierFlags::NONE;
179 
180     return irFlags;
181 }
182 
IrToE2pAccessFlags(es2panda_ModifierFlags e2pFlags,ir::ModifierFlags irFlags)183 static es2panda_ModifierFlags IrToE2pAccessFlags(es2panda_ModifierFlags e2pFlags, ir::ModifierFlags irFlags)
184 {
185     e2pFlags = static_cast<es2panda_ModifierFlags>(
186         (irFlags & ir::ModifierFlags::PUBLIC) != 0 ? e2pFlags | ES2PANDA_MODIFIER_PUBLIC : e2pFlags);
187     e2pFlags = static_cast<es2panda_ModifierFlags>(
188         (irFlags & ir::ModifierFlags::PROTECTED) != 0 ? e2pFlags | ES2PANDA_MODIFIER_PROTECTED : e2pFlags);
189     e2pFlags = static_cast<es2panda_ModifierFlags>(
190         (irFlags & ir::ModifierFlags::PRIVATE) != 0 ? e2pFlags | ES2PANDA_MODIFIER_PRIVATE : e2pFlags);
191     e2pFlags = static_cast<es2panda_ModifierFlags>(
192         (irFlags & ir::ModifierFlags::INTERNAL) != 0 ? e2pFlags | ES2PANDA_MODIFIER_INTERNAL : e2pFlags);
193 
194     return e2pFlags;
195 }
196 
IrToE2pMethodFlags(es2panda_ModifierFlags e2pFlags,ir::ModifierFlags irFlags)197 static es2panda_ModifierFlags IrToE2pMethodFlags(es2panda_ModifierFlags e2pFlags, ir::ModifierFlags irFlags)
198 {
199     e2pFlags = static_cast<es2panda_ModifierFlags>(
200         (irFlags & ir::ModifierFlags::STATIC) != 0 ? e2pFlags | ES2PANDA_MODIFIER_STATIC : e2pFlags);
201     e2pFlags = static_cast<es2panda_ModifierFlags>(
202         (irFlags & ir::ModifierFlags::ABSTRACT) != 0 ? e2pFlags | ES2PANDA_MODIFIER_ABSTRACT : e2pFlags);
203     e2pFlags = static_cast<es2panda_ModifierFlags>(
204         (irFlags & ir::ModifierFlags::FINAL) != 0 ? e2pFlags | ES2PANDA_MODIFIER_FINAL : e2pFlags);
205     e2pFlags = static_cast<es2panda_ModifierFlags>(
206         (irFlags & ir::ModifierFlags::NATIVE) != 0 ? e2pFlags | ES2PANDA_MODIFIER_NATIVE : e2pFlags);
207     e2pFlags = static_cast<es2panda_ModifierFlags>(
208         (irFlags & ir::ModifierFlags::OVERRIDE) != 0 ? e2pFlags | ES2PANDA_MODIFIER_OVERRIDE : e2pFlags);
209 
210     return e2pFlags;
211 }
212 
IrToE2pModifierFlags(ir::ModifierFlags irFlags)213 static es2panda_ModifierFlags IrToE2pModifierFlags(ir::ModifierFlags irFlags)
214 {
215     es2panda_ModifierFlags e2pFlags {ES2PANDA_MODIFIER_NONE};
216     e2pFlags = IrToE2pAccessFlags(e2pFlags, irFlags);
217     e2pFlags = IrToE2pMethodFlags(e2pFlags, irFlags);
218     e2pFlags = static_cast<es2panda_ModifierFlags>(
219         (irFlags & ir::ModifierFlags::ASYNC) != 0 ? e2pFlags | ES2PANDA_MODIFIER_ASYNC : e2pFlags);
220     e2pFlags = static_cast<es2panda_ModifierFlags>(
221         (irFlags & ir::ModifierFlags::DECLARE) != 0 ? e2pFlags | ES2PANDA_MODIFIER_DECLARE : e2pFlags);
222     e2pFlags = static_cast<es2panda_ModifierFlags>(
223         (irFlags & ir::ModifierFlags::READONLY) != 0 ? e2pFlags | ES2PANDA_MODIFIER_READONLY : e2pFlags);
224     e2pFlags = static_cast<es2panda_ModifierFlags>(
225         (irFlags & ir::ModifierFlags::OPTIONAL) != 0 ? e2pFlags | ES2PANDA_MODIFIER_OPTIONAL : e2pFlags);
226     e2pFlags = static_cast<es2panda_ModifierFlags>(
227         (irFlags & ir::ModifierFlags::DEFINITE) != 0 ? e2pFlags | ES2PANDA_MODIFIER_DEFINITE : e2pFlags);
228     e2pFlags = static_cast<es2panda_ModifierFlags>(
229         (irFlags & ir::ModifierFlags::CONST) != 0 ? e2pFlags | ES2PANDA_MODIFIER_CONST : e2pFlags);
230     e2pFlags = static_cast<es2panda_ModifierFlags>(
231         (irFlags & ir::ModifierFlags::CONSTRUCTOR) != 0 ? e2pFlags | ES2PANDA_MODIFIER_CONSTRUCTOR : e2pFlags);
232     e2pFlags = static_cast<es2panda_ModifierFlags>(
233         (irFlags & ir::ModifierFlags::SYNCHRONIZED) != 0 ? e2pFlags | ES2PANDA_MODIFIER_SYNCHRONIZED : e2pFlags);
234     e2pFlags = static_cast<es2panda_ModifierFlags>(
235         (irFlags & ir::ModifierFlags::FUNCTIONAL) != 0 ? e2pFlags | ES2PANDA_MODIFIER_FUNCTIONAL : e2pFlags);
236     e2pFlags = static_cast<es2panda_ModifierFlags>(
237         (irFlags & ir::ModifierFlags::IN) != 0 ? e2pFlags | ES2PANDA_MODIFIER_IN : e2pFlags);
238     e2pFlags = static_cast<es2panda_ModifierFlags>(
239         (irFlags & ir::ModifierFlags::OUT) != 0 ? e2pFlags | ES2PANDA_MODIFIER_OUT : e2pFlags);
240     e2pFlags = static_cast<es2panda_ModifierFlags>(
241         (irFlags & ir::ModifierFlags::EXPORT) != 0 ? e2pFlags | ES2PANDA_MODIFIER_EXPORT : e2pFlags);
242     e2pFlags = static_cast<es2panda_ModifierFlags>(
243         (irFlags & ir::ModifierFlags::SETTER) != 0 ? e2pFlags | ES2PANDA_MODIFIER_SETTER : e2pFlags);
244     e2pFlags = static_cast<es2panda_ModifierFlags>(
245         (irFlags & ir::ModifierFlags::DEFAULT_EXPORT) != 0 ? e2pFlags | ES2PANDA_MODIFIER_DEFAULT_EXPORT : e2pFlags);
246 
247     return e2pFlags;
248 }
249 
E2pToIrTypeScriptFunctionFlags(es2panda_ScriptFunctionFlags e2pFlags)250 static ir::ScriptFunctionFlags E2pToIrTypeScriptFunctionFlags(es2panda_ScriptFunctionFlags e2pFlags)
251 {
252     ir::ScriptFunctionFlags irFlags {ir::ScriptFunctionFlags::NONE};
253     irFlags |= (e2pFlags & ES2PANDA_SCRIPT_FUNCTION_GENERATOR) != 0 ? ir::ScriptFunctionFlags::GENERATOR
254                                                                     : ir::ScriptFunctionFlags::NONE;
255     irFlags |= (e2pFlags & ES2PANDA_SCRIPT_FUNCTION_ARROW) != 0 ? ir::ScriptFunctionFlags::ARROW
256                                                                 : ir::ScriptFunctionFlags::NONE;
257     irFlags |= (e2pFlags & ES2PANDA_SCRIPT_FUNCTION_CONSTRUCTOR) != 0 ? ir::ScriptFunctionFlags::CONSTRUCTOR
258                                                                       : ir::ScriptFunctionFlags::NONE;
259     irFlags |= (e2pFlags & ES2PANDA_SCRIPT_FUNCTION_METHOD) != 0 ? ir::ScriptFunctionFlags::METHOD
260                                                                  : ir::ScriptFunctionFlags::NONE;
261     irFlags |= (e2pFlags & ES2PANDA_SCRIPT_FUNCTION_STATIC_BLOCK) != 0 ? ir::ScriptFunctionFlags::STATIC_BLOCK
262                                                                        : ir::ScriptFunctionFlags::NONE;
263     irFlags |= (e2pFlags & ES2PANDA_SCRIPT_FUNCTION_PROXY) != 0 ? ir::ScriptFunctionFlags::PROXY
264                                                                 : ir::ScriptFunctionFlags::NONE;
265     irFlags |= (e2pFlags & ES2PANDA_SCRIPT_FUNCTION_GETTER) != 0 ? ir::ScriptFunctionFlags::GETTER
266                                                                  : ir::ScriptFunctionFlags::NONE;
267     irFlags |= (e2pFlags & ES2PANDA_SCRIPT_FUNCTION_SETTER) != 0 ? ir::ScriptFunctionFlags::SETTER
268                                                                  : ir::ScriptFunctionFlags::NONE;
269     irFlags |= (e2pFlags & ES2PANDA_SCRIPT_FUNCTION_INSTANCE_EXTENSION_METHOD) != 0
270                    ? ir::ScriptFunctionFlags::INSTANCE_EXTENSION_METHOD
271                    : ir::ScriptFunctionFlags::NONE;
272 
273     return irFlags;
274 }
275 
E2pToIrScriptFunctionFlags(es2panda_ScriptFunctionFlags e2pFlags)276 static ir::ScriptFunctionFlags E2pToIrScriptFunctionFlags(es2panda_ScriptFunctionFlags e2pFlags)
277 {
278     ir::ScriptFunctionFlags irFlags {ir::ScriptFunctionFlags::NONE};
279     irFlags |= E2pToIrTypeScriptFunctionFlags(e2pFlags);
280     irFlags |= (e2pFlags & ES2PANDA_SCRIPT_FUNCTION_ASYNC) != 0 ? ir::ScriptFunctionFlags::ASYNC
281                                                                 : ir::ScriptFunctionFlags::NONE;
282     irFlags |= (e2pFlags & ES2PANDA_SCRIPT_FUNCTION_EXPRESSION) != 0 ? ir::ScriptFunctionFlags::EXPRESSION
283                                                                      : ir::ScriptFunctionFlags::NONE;
284     irFlags |= (e2pFlags & ES2PANDA_SCRIPT_FUNCTION_OVERLOAD) != 0 ? ir::ScriptFunctionFlags::OVERLOAD
285                                                                    : ir::ScriptFunctionFlags::NONE;
286     irFlags |= (e2pFlags & ES2PANDA_SCRIPT_FUNCTION_HIDDEN) != 0 ? ir::ScriptFunctionFlags::HIDDEN
287                                                                  : ir::ScriptFunctionFlags::NONE;
288     irFlags |= (e2pFlags & ES2PANDA_SCRIPT_FUNCTION_IMPLICIT_SUPER_CALL_NEEDED) != 0
289                    ? ir::ScriptFunctionFlags::IMPLICIT_SUPER_CALL_NEEDED
290                    : ir::ScriptFunctionFlags::NONE;
291     irFlags |=
292         (e2pFlags & ES2PANDA_SCRIPT_FUNCTION_ENUM) != 0 ? ir::ScriptFunctionFlags::ENUM : ir::ScriptFunctionFlags::NONE;
293     irFlags |= (e2pFlags & ES2PANDA_SCRIPT_FUNCTION_EXTERNAL) != 0 ? ir::ScriptFunctionFlags::EXTERNAL
294                                                                    : ir::ScriptFunctionFlags::NONE;
295     irFlags |= (e2pFlags & ES2PANDA_SCRIPT_FUNCTION_THROWS) != 0 ? ir::ScriptFunctionFlags::THROWS
296                                                                  : ir::ScriptFunctionFlags::NONE;
297     irFlags |= (e2pFlags & ES2PANDA_SCRIPT_FUNCTION_RETHROWS) != 0 ? ir::ScriptFunctionFlags::RETHROWS
298                                                                    : ir::ScriptFunctionFlags::NONE;
299     irFlags |= (e2pFlags & ES2PANDA_SCRIPT_FUNCTION_ENTRY_POINT) != 0 ? ir::ScriptFunctionFlags::ENTRY_POINT
300                                                                       : ir::ScriptFunctionFlags::NONE;
301     irFlags |= (e2pFlags & ES2PANDA_SCRIPT_FUNCTION_HAS_RETURN) != 0 ? ir::ScriptFunctionFlags::HAS_RETURN
302                                                                      : ir::ScriptFunctionFlags::NONE;
303 
304     return irFlags;
305 }
306 
IrToE2pTypeScriptFunctionFlags(es2panda_ScriptFunctionFlags e2pFlags,ir::ScriptFunctionFlags irFlags)307 static es2panda_ScriptFunctionFlags IrToE2pTypeScriptFunctionFlags(es2panda_ScriptFunctionFlags e2pFlags,
308                                                                    ir::ScriptFunctionFlags irFlags)
309 {
310     e2pFlags = static_cast<es2panda_ScriptFunctionFlags>(
311         (irFlags & ir::ScriptFunctionFlags::GENERATOR) != 0 ? e2pFlags | ES2PANDA_SCRIPT_FUNCTION_GENERATOR : e2pFlags);
312     e2pFlags = static_cast<es2panda_ScriptFunctionFlags>(
313         (irFlags & ir::ScriptFunctionFlags::ARROW) != 0 ? e2pFlags | ES2PANDA_SCRIPT_FUNCTION_ARROW : e2pFlags);
314     e2pFlags = static_cast<es2panda_ScriptFunctionFlags>((irFlags & ir::ScriptFunctionFlags::CONSTRUCTOR) != 0
315                                                              ? e2pFlags | ES2PANDA_SCRIPT_FUNCTION_CONSTRUCTOR
316                                                              : e2pFlags);
317     e2pFlags = static_cast<es2panda_ScriptFunctionFlags>(
318         (irFlags & ir::ScriptFunctionFlags::METHOD) != 0 ? e2pFlags | ES2PANDA_SCRIPT_FUNCTION_METHOD : e2pFlags);
319     e2pFlags = static_cast<es2panda_ScriptFunctionFlags>((irFlags & ir::ScriptFunctionFlags::STATIC_BLOCK) != 0
320                                                              ? e2pFlags | ES2PANDA_SCRIPT_FUNCTION_STATIC_BLOCK
321                                                              : e2pFlags);
322     e2pFlags = static_cast<es2panda_ScriptFunctionFlags>(
323         (irFlags & ir::ScriptFunctionFlags::PROXY) != 0 ? e2pFlags | ES2PANDA_SCRIPT_FUNCTION_PROXY : e2pFlags);
324     e2pFlags = static_cast<es2panda_ScriptFunctionFlags>(
325         (irFlags & ir::ScriptFunctionFlags::GETTER) != 0 ? e2pFlags | ES2PANDA_SCRIPT_FUNCTION_GETTER : e2pFlags);
326     e2pFlags = static_cast<es2panda_ScriptFunctionFlags>(
327         (irFlags & ir::ScriptFunctionFlags::SETTER) != 0 ? e2pFlags | ES2PANDA_SCRIPT_FUNCTION_SETTER : e2pFlags);
328     e2pFlags =
329         static_cast<es2panda_ScriptFunctionFlags>((irFlags & ir::ScriptFunctionFlags::INSTANCE_EXTENSION_METHOD) != 0
330                                                       ? e2pFlags | ES2PANDA_SCRIPT_FUNCTION_INSTANCE_EXTENSION_METHOD
331                                                       : e2pFlags);
332 
333     return e2pFlags;
334 }
335 
IrToE2pScriptFunctionFlags(ir::ScriptFunctionFlags irFlags)336 static es2panda_ScriptFunctionFlags IrToE2pScriptFunctionFlags(ir::ScriptFunctionFlags irFlags)
337 {
338     es2panda_ScriptFunctionFlags e2pFlags {ES2PANDA_SCRIPT_FUNCTION_NONE};
339     e2pFlags = IrToE2pTypeScriptFunctionFlags(e2pFlags, irFlags);
340     e2pFlags = static_cast<es2panda_ScriptFunctionFlags>(
341         (irFlags & ir::ScriptFunctionFlags::ASYNC) != 0 ? e2pFlags | ES2PANDA_SCRIPT_FUNCTION_ASYNC : e2pFlags);
342     e2pFlags = static_cast<es2panda_ScriptFunctionFlags>((irFlags & ir::ScriptFunctionFlags::EXPRESSION) != 0
343                                                              ? e2pFlags | ES2PANDA_SCRIPT_FUNCTION_EXPRESSION
344                                                              : e2pFlags);
345     e2pFlags = static_cast<es2panda_ScriptFunctionFlags>(
346         (irFlags & ir::ScriptFunctionFlags::OVERLOAD) != 0 ? e2pFlags | ES2PANDA_SCRIPT_FUNCTION_OVERLOAD : e2pFlags);
347     e2pFlags = static_cast<es2panda_ScriptFunctionFlags>(
348         (irFlags & ir::ScriptFunctionFlags::HIDDEN) != 0 ? e2pFlags | ES2PANDA_SCRIPT_FUNCTION_HIDDEN : e2pFlags);
349     e2pFlags =
350         static_cast<es2panda_ScriptFunctionFlags>((irFlags & ir::ScriptFunctionFlags::IMPLICIT_SUPER_CALL_NEEDED) != 0
351                                                       ? e2pFlags | ES2PANDA_SCRIPT_FUNCTION_IMPLICIT_SUPER_CALL_NEEDED
352                                                       : e2pFlags);
353     e2pFlags = static_cast<es2panda_ScriptFunctionFlags>(
354         (irFlags & ir::ScriptFunctionFlags::ENUM) != 0 ? e2pFlags | ES2PANDA_SCRIPT_FUNCTION_ENUM : e2pFlags);
355     e2pFlags = static_cast<es2panda_ScriptFunctionFlags>(
356         (irFlags & ir::ScriptFunctionFlags::EXTERNAL) != 0 ? e2pFlags | ES2PANDA_SCRIPT_FUNCTION_EXTERNAL : e2pFlags);
357     e2pFlags = static_cast<es2panda_ScriptFunctionFlags>(
358         (irFlags & ir::ScriptFunctionFlags::THROWS) != 0 ? e2pFlags | ES2PANDA_SCRIPT_FUNCTION_THROWS : e2pFlags);
359     e2pFlags = static_cast<es2panda_ScriptFunctionFlags>(
360         (irFlags & ir::ScriptFunctionFlags::RETHROWS) != 0 ? e2pFlags | ES2PANDA_SCRIPT_FUNCTION_RETHROWS : e2pFlags);
361     e2pFlags = static_cast<es2panda_ScriptFunctionFlags>((irFlags & ir::ScriptFunctionFlags::ENTRY_POINT) != 0
362                                                              ? e2pFlags | ES2PANDA_SCRIPT_FUNCTION_ENTRY_POINT
363                                                              : e2pFlags);
364     e2pFlags = static_cast<es2panda_ScriptFunctionFlags>((irFlags & ir::ScriptFunctionFlags::HAS_RETURN) != 0
365                                                              ? e2pFlags | ES2PANDA_SCRIPT_FUNCTION_HAS_RETURN
366                                                              : e2pFlags);
367 
368     return e2pFlags;
369 }
370 
CreateConfig(int args,char const ** argv)371 extern "C" es2panda_Config *CreateConfig(int args, char const **argv)
372 {
373     constexpr auto COMPILER_SIZE = 256_MB;
374 
375     mem::MemConfig::Initialize(0, 0, COMPILER_SIZE, 0, 0, 0);
376     PoolManager::Initialize(PoolType::MMAP);
377 
378     auto *options = new util::Options();
379     if (!options->Parse(args, argv)) {
380         // NOTE: gogabr. report option errors properly.
381         std::cerr << options->ErrorMsg() << std::endl;
382         return nullptr;
383     }
384     Logger::ComponentMask mask {};
385     mask.set(Logger::Component::ES2PANDA);
386     Logger::InitializeStdLogging(Logger::LevelFromString(options->LogLevel()), mask);
387 
388     auto *res = new ConfigImpl;
389     res->options = options;
390     return reinterpret_cast<es2panda_Config *>(res);
391 }
392 
DestroyConfig(es2panda_Config * config)393 extern "C" void DestroyConfig(es2panda_Config *config)
394 {
395     PoolManager::Finalize();
396     mem::MemConfig::Finalize();
397 
398     auto *cfg = reinterpret_cast<ConfigImpl *>(config);
399     if (cfg == nullptr) {
400         return;
401     }
402 
403     delete cfg->options;
404     delete cfg;
405 }
406 
CompileJob(public_lib::Context * context,varbinder::FunctionScope * scope,compiler::ProgramElement * programElement)407 static void CompileJob(public_lib::Context *context, varbinder::FunctionScope *scope,
408                        compiler::ProgramElement *programElement)
409 {
410     compiler::StaticRegSpiller regSpiller;
411     ArenaAllocator allocator {SpaceType::SPACE_TYPE_COMPILER, nullptr, true};
412     compiler::ETSCompiler astCompiler {};
413     compiler::ETSGen cg {&allocator, &regSpiller, context, std::make_tuple(scope, programElement, &astCompiler)};
414     compiler::ETSFunctionEmitter funcEmitter {&cg, programElement};
415     funcEmitter.Generate();
416 }
417 
CreateContext(es2panda_Config * config,std::string const && source,std::string const && fileName)418 static es2panda_Context *CreateContext(es2panda_Config *config, std::string const &&source,
419                                        std::string const &&fileName)
420 {
421     auto *cfg = reinterpret_cast<ConfigImpl *>(config);
422     auto *res = new Context;
423     res->input = source;
424     res->sourceFileName = fileName;
425     res->config = cfg;
426 
427     try {
428         res->sourceFile = new SourceFile(res->sourceFileName, res->input, cfg->options->ParseModule());
429         res->allocator = new ArenaAllocator(SpaceType::SPACE_TYPE_COMPILER, nullptr, true);
430         res->queue = new compiler::CompileQueue(cfg->options->ThreadCount());
431 
432         auto *varbinder = res->allocator->New<varbinder::ETSBinder>(res->allocator);
433         res->parserProgram = new parser::Program(res->allocator, varbinder);
434         res->parserProgram->MarkEntry();
435         res->parser =
436             new parser::ETSParser(res->parserProgram, cfg->options->CompilerOptions(), parser::ParserStatus::NO_OPTS);
437         res->checker = new checker::ETSChecker();
438         res->checker->ErrorLogger()->SetOstream(nullptr);
439         res->analyzer = new checker::ETSAnalyzer(res->checker);
440         res->checker->SetAnalyzer(res->analyzer);
441 
442         varbinder->SetProgram(res->parserProgram);
443 
444         varbinder->SetContext(res);
445         res->codeGenCb = CompileJob;
446         res->phases = compiler::GetPhaseList(ScriptExtension::ETS);
447         res->currentPhase = 0;
448         res->emitter = new compiler::ETSEmitter(res);
449         res->program = nullptr;
450         res->state = ES2PANDA_STATE_NEW;
451     } catch (Error &e) {
452         std::stringstream ss;
453         ss << e.TypeString() << ": " << e.Message() << "[" << e.File() << ":" << e.Line() << "," << e.Col() << "]";
454         res->errorMessage = ss.str();
455         res->state = ES2PANDA_STATE_ERROR;
456     }
457     return reinterpret_cast<es2panda_Context *>(res);
458 }
459 
CreateContextFromFile(es2panda_Config * config,char const * sourceFileName)460 extern "C" es2panda_Context *CreateContextFromFile(es2panda_Config *config, char const *sourceFileName)
461 {
462     std::ifstream inputStream;
463     inputStream.open(sourceFileName);
464     if (inputStream.fail()) {
465         auto *res = new Context;
466         res->errorMessage = "Failed to open file: ";
467         res->errorMessage.append(sourceFileName);
468         return reinterpret_cast<es2panda_Context *>(res);
469     }
470     std::stringstream ss;
471     ss << inputStream.rdbuf();
472     if (inputStream.fail()) {
473         auto *res = new Context;
474         res->errorMessage = "Failed to read file: ";
475         res->errorMessage.append(sourceFileName);
476         return reinterpret_cast<es2panda_Context *>(res);
477     }
478     return CreateContext(config, ss.str(), sourceFileName);
479 }
480 
CreateContextFromString(es2panda_Config * config,char const * source,char const * fileName)481 extern "C" es2panda_Context *CreateContextFromString(es2panda_Config *config, char const *source, char const *fileName)
482 {
483     // NOTE: gogabr. avoid copying source.
484     return CreateContext(config, source, fileName);
485 }
486 
Parse(Context * ctx)487 static Context *Parse(Context *ctx)
488 {
489     if (ctx->state != ES2PANDA_STATE_NEW) {
490         ctx->state = ES2PANDA_STATE_ERROR;
491         ctx->errorMessage = "Bad state at entry to Parse, needed NEW";
492         return ctx;
493     }
494     try {
495         ctx->parser->ParseScript(*ctx->sourceFile, ctx->config->options->CompilerOptions().compilationMode ==
496                                                        CompilationMode::GEN_STD_LIB);
497         ctx->state = ES2PANDA_STATE_PARSED;
498     } catch (Error &e) {
499         std::stringstream ss;
500         ss << e.TypeString() << ": " << e.Message() << "[" << e.File() << ":" << e.Line() << "," << e.Col() << "]";
501         ctx->errorMessage = ss.str();
502         ctx->state = ES2PANDA_STATE_ERROR;
503     }
504 
505     return ctx;
506 }
507 
InitScopes(Context * ctx)508 static Context *InitScopes(Context *ctx)
509 {
510     // NOTE: Remove duplicated code in all phases
511     if (ctx->state < ES2PANDA_STATE_PARSED) {
512         ctx = Parse(ctx);
513     }
514     if (ctx->state == ES2PANDA_STATE_ERROR) {
515         return ctx;
516     }
517 
518     ASSERT(ctx->state == ES2PANDA_STATE_PARSED);
519 
520     try {
521         compiler::InitScopesPhaseETS scopesInit;
522         scopesInit.Perform(ctx, ctx->parserProgram);
523         do {
524             if (ctx->currentPhase >= ctx->phases.size()) {
525                 break;
526             }
527             ctx->phases[ctx->currentPhase]->Apply(ctx, ctx->parserProgram);
528         } while (ctx->phases[ctx->currentPhase++]->Name() != compiler::ScopesInitPhase::NAME);
529         ctx->state = ES2PANDA_STATE_SCOPE_INITED;
530     } catch (Error &e) {
531         std::stringstream ss;
532         ss << e.TypeString() << ": " << e.Message() << "[" << e.File() << ":" << e.Line() << "," << e.Col() << "]";
533         ctx->errorMessage = ss.str();
534         ctx->state = ES2PANDA_STATE_ERROR;
535     }
536     return ctx;
537 }
538 
Check(Context * ctx)539 static Context *Check(Context *ctx)
540 {
541     if (ctx->state < ES2PANDA_STATE_PARSED) {
542         ctx = Parse(ctx);
543     }
544 
545     if (ctx->state == ES2PANDA_STATE_ERROR) {
546         return ctx;
547     }
548 
549     ASSERT(ctx->state >= ES2PANDA_STATE_PARSED && ctx->state < ES2PANDA_STATE_CHECKED);
550 
551     auto handleError = [ctx](Error const &e) {
552         std::stringstream ss;
553         ss << e.TypeString() << ": " << e.Message() << "[" << e.File() << ":" << e.Line() << "," << e.Col() << "]";
554         ctx->errorMessage = ss.str();
555         ctx->state = ES2PANDA_STATE_ERROR;
556     };
557 
558     try {
559         do {
560             if (ctx->currentPhase >= ctx->phases.size()) {
561                 break;
562             }
563 
564             ctx->phases[ctx->currentPhase]->Apply(ctx, ctx->parserProgram);
565         } while (ctx->phases[ctx->currentPhase++]->Name() != compiler::CheckerPhase::NAME);
566         if (ctx->checker->ErrorLogger()->IsAnyError()) {
567             handleError(ctx->checker->ErrorLogger()->Log()[0]);
568         } else {
569             ctx->state = ES2PANDA_STATE_CHECKED;
570         }
571     } catch (Error &e) {
572         handleError(e);
573     }
574     return ctx;
575 }
576 
Lower(Context * ctx)577 static Context *Lower(Context *ctx)
578 {
579     if (ctx->state < ES2PANDA_STATE_CHECKED) {
580         ctx = Check(ctx);
581     }
582 
583     if (ctx->state == ES2PANDA_STATE_ERROR) {
584         return ctx;
585     }
586 
587     ASSERT(ctx->state == ES2PANDA_STATE_CHECKED);
588 
589     try {
590         while (ctx->currentPhase < ctx->phases.size()) {
591             ctx->phases[ctx->currentPhase++]->Apply(ctx, ctx->parserProgram);
592         }
593 
594         ctx->state = ES2PANDA_STATE_LOWERED;
595     } catch (Error &e) {
596         std::stringstream ss;
597         ss << e.TypeString() << ": " << e.Message() << "[" << e.File() << ":" << e.Line() << "," << e.Col() << "]";
598         ctx->errorMessage = ss.str();
599         ctx->state = ES2PANDA_STATE_ERROR;
600     }
601 
602     return ctx;
603 }
604 
GenerateAsm(Context * ctx)605 static Context *GenerateAsm(Context *ctx)
606 {
607     if (ctx->state < ES2PANDA_STATE_LOWERED) {
608         ctx = Lower(ctx);
609     }
610 
611     if (ctx->state == ES2PANDA_STATE_ERROR) {
612         return ctx;
613     }
614 
615     ASSERT(ctx->state == ES2PANDA_STATE_LOWERED);
616 
617     auto *emitter = ctx->emitter;
618     try {
619         emitter->GenAnnotation();
620 
621         // Handle context literals.
622         uint32_t index = 0;
623         for (const auto &buff : ctx->contextLiterals) {
624             emitter->AddLiteralBuffer(buff, index++);
625         }
626 
627         emitter->LiteralBufferIndex() += ctx->contextLiterals.size();
628 
629         /* Main thread can also be used instead of idling */
630         ctx->queue->Schedule(ctx);
631         ctx->queue->Consume();
632         ctx->queue->Wait(
633             [emitter](compiler::CompileJob *job) { emitter->AddProgramElement(job->GetProgramElement()); });
634         ASSERT(ctx->program == nullptr);
635         ctx->program =
636             emitter->Finalize(ctx->config->options->CompilerOptions().dumpDebugInfo, compiler::Signatures::ETS_GLOBAL);
637 
638         ctx->state = ES2PANDA_STATE_ASM_GENERATED;
639     } catch (Error &e) {
640         std::stringstream ss;
641         ss << e.TypeString() << ": " << e.Message() << "[" << e.File() << ":" << e.Line() << "," << e.Col() << "]";
642         ctx->errorMessage = ss.str();
643         ctx->state = ES2PANDA_STATE_ERROR;
644     }
645     return ctx;
646 }
647 
GenerateBin(Context * ctx)648 Context *GenerateBin(Context *ctx)
649 {
650     if (ctx->state < ES2PANDA_STATE_ASM_GENERATED) {
651         ctx = GenerateAsm(ctx);
652     }
653 
654     if (ctx->state == ES2PANDA_STATE_ERROR) {
655         return ctx;
656     }
657 
658     ASSERT(ctx->state == ES2PANDA_STATE_ASM_GENERATED);
659 
660     try {
661         ASSERT(ctx->program != nullptr);
662         util::GenerateProgram(ctx->program, ctx->config->options,
663                               [ctx](const std::string &str) { ctx->errorMessage = str; });
664 
665         ctx->state = ES2PANDA_STATE_BIN_GENERATED;
666     } catch (Error &e) {
667         std::stringstream ss;
668         ss << e.TypeString() << ": " << e.Message() << "[" << e.File() << ":" << e.Line() << "," << e.Col() << "]";
669         ctx->errorMessage = ss.str();
670         ctx->state = ES2PANDA_STATE_ERROR;
671     }
672     return ctx;
673 }
674 
ProceedToState(es2panda_Context * context,es2panda_ContextState state)675 extern "C" es2panda_Context *ProceedToState(es2panda_Context *context, es2panda_ContextState state)
676 {
677     auto *ctx = reinterpret_cast<Context *>(context);
678     switch (state) {
679         case ES2PANDA_STATE_NEW:
680             break;
681         case ES2PANDA_STATE_PARSED:
682             ctx = Parse(ctx);
683             break;
684         case ES2PANDA_STATE_SCOPE_INITED:
685             ctx = InitScopes(ctx);
686             break;
687         case ES2PANDA_STATE_CHECKED:
688             ctx = Check(ctx);
689             break;
690         case ES2PANDA_STATE_LOWERED:
691             ctx = Lower(ctx);
692             break;
693         case ES2PANDA_STATE_ASM_GENERATED:
694             ctx = GenerateAsm(ctx);
695             break;
696         case ES2PANDA_STATE_BIN_GENERATED:
697             ctx = GenerateBin(ctx);
698             break;
699         default:
700             ctx->errorMessage = "It does not make sense to request stage";
701             ctx->state = ES2PANDA_STATE_ERROR;
702             break;
703     }
704     return reinterpret_cast<es2panda_Context *>(ctx);
705 }
706 
DestroyContext(es2panda_Context * context)707 extern "C" void DestroyContext(es2panda_Context *context)
708 {
709     auto *ctx = reinterpret_cast<Context *>(context);
710     delete ctx->program;
711     delete ctx->emitter;
712     delete ctx->analyzer;
713     delete ctx->checker;
714     delete ctx->parser;
715     delete ctx->parserProgram;
716     delete ctx->queue;
717     delete ctx->allocator;
718     delete ctx->sourceFile;
719     delete ctx;
720 }
721 
ContextState(es2panda_Context * context)722 extern "C" es2panda_ContextState ContextState(es2panda_Context *context)
723 {
724     auto *s = reinterpret_cast<Context *>(context);
725     return s->state;
726 }
727 
ContextErrorMessage(es2panda_Context * context)728 extern "C" char const *ContextErrorMessage(es2panda_Context *context)
729 {
730     auto *s = reinterpret_cast<Context *>(context);
731     return s->errorMessage.c_str();
732 }
733 
ContextProgram(es2panda_Context * context)734 extern "C" es2panda_Program *ContextProgram(es2panda_Context *context)
735 {
736     auto *ctx = reinterpret_cast<Context *>(context);
737     return reinterpret_cast<es2panda_Program *>(ctx->parserProgram);
738 }
739 
ProgramAst(es2panda_Program * program)740 extern "C" es2panda_AstNode *ProgramAst(es2panda_Program *program)
741 {
742     auto *pgm = reinterpret_cast<parser::Program *>(program);
743     return reinterpret_cast<es2panda_AstNode *>(pgm->Ast());
744 }
745 
746 using ExternalSourceEntry = std::pair<char const *, ArenaVector<parser::Program *> *>;
747 
ProgramExternalSources(es2panda_Program * program,size_t * lenP)748 extern "C" es2panda_ExternalSource **ProgramExternalSources(es2panda_Program *program, size_t *lenP)
749 {
750     auto *pgm = reinterpret_cast<parser::Program *>(program);
751     auto *allocator = pgm->VarBinder()->Allocator();
752     auto *vec = allocator->New<ArenaVector<ExternalSourceEntry *>>(allocator->Adapter());
753 
754     for (auto &[e_name, e_programs] : pgm->ExternalSources()) {
755         vec->push_back(allocator->New<ExternalSourceEntry>(StringViewToCString(allocator, e_name), &e_programs));
756     }
757 
758     *lenP = vec->size();
759     return reinterpret_cast<es2panda_ExternalSource **>(vec->data());
760 }
761 
ExternalSourceName(es2panda_ExternalSource * eSource)762 extern "C" char const *ExternalSourceName(es2panda_ExternalSource *eSource)
763 {
764     auto *entry = reinterpret_cast<ExternalSourceEntry *>(eSource);
765     return entry->first;
766 }
767 
ExternalSourcePrograms(es2panda_ExternalSource * eSource,size_t * lenP)768 extern "C" es2panda_Program **ExternalSourcePrograms(es2panda_ExternalSource *eSource, size_t *lenP)
769 {
770     auto *entry = reinterpret_cast<ExternalSourceEntry *>(eSource);
771     *lenP = entry->second->size();
772     return reinterpret_cast<es2panda_Program **>(entry->second->data());
773 }
774 
AstNodeType(es2panda_AstNode * ast)775 extern "C" es2panda_Type *AstNodeType(es2panda_AstNode *ast)
776 {
777     auto *node = reinterpret_cast<ir::AstNode *>(ast);
778     // Need to work with other TypeAstNodes
779     if (node->IsExpression()) {
780         return reinterpret_cast<es2panda_Type *>(node->AsExpression()->TsType());
781     }
782     return nullptr;
783 }
784 
AstNodeDecorators(es2panda_AstNode * ast,size_t * sizeP)785 extern "C" es2panda_AstNode *const *AstNodeDecorators(es2panda_AstNode *ast, size_t *sizeP)
786 {
787     auto *node = reinterpret_cast<ir::AstNode *>(ast);
788     if (node->CanHaveDecorator(false)) {
789         auto *decorators = node->DecoratorsPtr();
790         *sizeP = decorators->size();
791         return reinterpret_cast<es2panda_AstNode *const *>(decorators->data());
792     }
793     *sizeP = 0;
794     return nullptr;
795 }
796 
AstNodeModifierFlags(es2panda_AstNode * ast)797 extern "C" es2panda_ModifierFlags AstNodeModifierFlags(es2panda_AstNode *ast)
798 {
799     auto *node = reinterpret_cast<ir::AstNode *>(ast);
800     return IrToE2pModifierFlags(node->Modifiers());
801 }
802 
AstNodeSetDecorators(es2panda_Context * context,es2panda_AstNode * ast,es2panda_AstNode ** decorators,size_t nDecorators)803 extern "C" void AstNodeSetDecorators(es2panda_Context *context, es2panda_AstNode *ast, es2panda_AstNode **decorators,
804                                      size_t nDecorators)
805 {
806     auto *ctx = reinterpret_cast<Context *>(context);
807     auto *allocator = ctx->allocator;
808     auto *node = reinterpret_cast<ir::AstNode *>(ast);
809 
810     ArenaVector<ir::Decorator *> decoratorsVector {allocator->Adapter()};
811     for (size_t i = 0; i < nDecorators; i++) {
812         // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
813         decoratorsVector.push_back(reinterpret_cast<ir::AstNode *>(decorators[i])->AsDecorator());
814     }
815     node->AddDecorators(std::move(decoratorsVector));
816 }
817 
AstNodeSetType(es2panda_AstNode * ast,es2panda_Type * type)818 extern "C" void AstNodeSetType(es2panda_AstNode *ast, es2panda_Type *type)
819 {
820     auto *node = reinterpret_cast<ir::AstNode *>(ast);
821     auto *tp = reinterpret_cast<checker::Type *>(type);
822     // Need to work with other TypedAstNodes
823     if (node->IsExpression()) {
824         node->AsExpression()->SetTsType(tp);
825     } else {
826         UNREACHABLE();
827     }
828 }
829 
AstNodeForEach(es2panda_AstNode * ast,void (* func)(es2panda_AstNode *,void *),void * arg)830 extern "C" void AstNodeForEach(es2panda_AstNode *ast, void (*func)(es2panda_AstNode *, void *), void *arg)
831 {
832     auto *node = reinterpret_cast<ir::AstNode *>(ast);
833     func(ast, arg);
834     node->IterateRecursively([=](ir::AstNode *child) { func(reinterpret_cast<es2panda_AstNode *>(child), arg); });
835 }
836 
837 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
838 #define IS(public_name, e2p_name)                          \
839     extern "C" bool Is##public_name(es2panda_AstNode *ast) \
840     {                                                      \
841         auto *node = reinterpret_cast<ir::AstNode *>(ast); \
842         return node->Is##e2p_name();                       \
843     }
844 
IS(ArrowFunctionExpression,ArrowFunctionExpression)845 IS(ArrowFunctionExpression, ArrowFunctionExpression)
846 IS(AsExpression, TSAsExpression)
847 IS(AssignmentExpression, AssignmentExpression)
848 IS(BinaryExpression, BinaryExpression)
849 IS(BlockStatement, BlockStatement)
850 IS(CallExpression, CallExpression)
851 IS(ChainExpression, ChainExpression)
852 IS(ClassDeclaration, ClassDeclaration)
853 IS(ClassDefinition, ClassDefinition)
854 IS(ClassImplementsClause, TSClassImplements)
855 IS(ClassProperty, ClassProperty)
856 IS(ExpressionStatement, ExpressionStatement)
857 IS(FunctionDeclaration, FunctionDeclaration)
858 IS(FunctionExpression, FunctionExpression)
859 IS(FunctionTypeNode, TSFunctionType)
860 IS(Identifier, Identifier)
861 IS(IfStatement, IfStatement)
862 IS(ImportDeclaration, ImportDeclaration)
863 IS(ImportExpression, ImportExpression)
864 IS(ImportSpecifier, ImportSpecifier)
865 IS(MemberExpression, MemberExpression)
866 IS(MethodDefinition, MethodDefinition)
867 IS(NewClassInstanceExpression, ETSNewClassInstanceExpression)
868 IS(NewArrayInstanceExpression, ETSNewArrayInstanceExpression)
869 IS(NewMultiDimArrayInstanceExpression, ETSNewMultiDimArrayInstanceExpression)
870 IS(NonNullExpression, TSNonNullExpression)
871 IS(NumberLiteral, NumberLiteral)
872 IS(ObjectExpression, ObjectExpression)
873 IS(ParameterDeclaration, ETSParameterExpression)
874 IS(PrimitiveTypeNode, ETSPrimitiveType)
875 IS(ReturnStatement, ReturnStatement)
876 IS(ScriptFunction, ScriptFunction)
877 IS(StringLiteral, StringLiteral)
878 IS(ThisExpression, ThisExpression)
879 IS(TypeParameter, TSTypeParameter)
880 IS(TypeParameterDeclaration, TSTypeParameterDeclaration)
881 IS(TypeParameterInstantiation, TSTypeParameterInstantiation)
882 IS(TypeReferenceNode, ETSTypeReference)
883 IS(TypeReferencePart, ETSTypeReferencePart)
884 IS(UnionTypeNode, TSUnionType)
885 IS(VariableDeclaration, VariableDeclaration)
886 IS(VariableDeclarator, VariableDeclarator)
887 
888 #undef IS
889 
890 extern "C" es2panda_AstNode *CreateArrowFunctionExpression(es2panda_Context *context, es2panda_AstNode *scriptFunction)
891 {
892     auto *ctx = reinterpret_cast<Context *>(context);
893     auto *func = reinterpret_cast<ir::AstNode *>(scriptFunction)->AsScriptFunction();
894     auto *allocator = ctx->allocator;
895 
896     return reinterpret_cast<es2panda_AstNode *>(allocator->New<ir::ArrowFunctionExpression>(func));
897 }
898 
ArrowFunctionExpressionScriptFunction(es2panda_AstNode * ast)899 extern "C" es2panda_AstNode *ArrowFunctionExpressionScriptFunction(es2panda_AstNode *ast)
900 {
901     auto *node = reinterpret_cast<ir::AstNode *>(ast)->AsArrowFunctionExpression();
902     return reinterpret_cast<es2panda_AstNode *>(node->Function());
903 }
904 
CreateAsExpression(es2panda_Context * context,es2panda_AstNode * expr,es2panda_AstNode * typeAnnotation,bool isConst)905 extern "C" es2panda_AstNode *CreateAsExpression(es2panda_Context *context, es2panda_AstNode *expr,
906                                                 es2panda_AstNode *typeAnnotation, bool isConst)
907 {
908     auto *ctx = reinterpret_cast<Context *>(context);
909     auto *leftExpr = reinterpret_cast<ir::AstNode *>(expr)->AsExpression();
910     auto *tp = reinterpret_cast<ir::AstNode *>(typeAnnotation)->AsExpression()->AsTypeNode();
911     auto *allocator = ctx->allocator;
912 
913     return reinterpret_cast<es2panda_AstNode *>(allocator->New<ir::TSAsExpression>(leftExpr, tp, isConst));
914 }
915 
AsExpressionExpr(es2panda_AstNode * ast)916 extern "C" es2panda_AstNode *AsExpressionExpr(es2panda_AstNode *ast)
917 {
918     auto *node = reinterpret_cast<ir::AstNode *>(ast)->AsTSAsExpression();
919     return reinterpret_cast<es2panda_AstNode *>(node->Expr());
920 }
921 
AsExpressionTypeAnnotation(es2panda_AstNode * ast)922 extern "C" es2panda_AstNode *AsExpressionTypeAnnotation(es2panda_AstNode *ast)
923 {
924     auto *node = reinterpret_cast<ir::AstNode *>(ast)->AsTSAsExpression();
925     return reinterpret_cast<es2panda_AstNode *>(node->Type());
926 }
927 
AsExpressionIsConst(es2panda_AstNode * ast)928 extern "C" bool AsExpressionIsConst(es2panda_AstNode *ast)
929 {
930     auto *node = reinterpret_cast<ir::AstNode *>(ast)->AsTSAsExpression();
931     return node->IsConst();
932 }
933 
AsExpressionSetExpr(es2panda_AstNode * ast,es2panda_AstNode * expr)934 extern "C" void AsExpressionSetExpr(es2panda_AstNode *ast, es2panda_AstNode *expr)
935 {
936     auto *node = reinterpret_cast<ir::AstNode *>(ast)->AsTSAsExpression();
937     auto *newExpr = reinterpret_cast<ir::AstNode *>(expr)->AsExpression();
938     node->SetExpr(newExpr);
939 }
940 
AsExpressionSetTypeAnnotation(es2panda_AstNode * ast,es2panda_AstNode * typeAnnotation)941 extern "C" void AsExpressionSetTypeAnnotation(es2panda_AstNode *ast, es2panda_AstNode *typeAnnotation)
942 {
943     auto *node = reinterpret_cast<ir::AstNode *>(ast)->AsTSAsExpression();
944     auto *tp = reinterpret_cast<ir::AstNode *>(typeAnnotation)->AsExpression()->AsTypeNode();
945     node->SetTsTypeAnnotation(tp);
946 }
947 
948 static constexpr std::array<TokenTypeToStr, 18U> ASSIGNMENT_TOKEN_TYPES {
949     {{lexer::TokenType::PUNCTUATOR_SUBSTITUTION, "="},
950      {lexer::TokenType::PUNCTUATOR_UNSIGNED_RIGHT_SHIFT_EQUAL, ">>>="},
951      {lexer::TokenType::PUNCTUATOR_RIGHT_SHIFT_EQUAL, ">>="},
952      {lexer::TokenType::PUNCTUATOR_LEFT_SHIFT_EQUAL, "<<="},
953      {lexer::TokenType::PUNCTUATOR_PLUS_EQUAL, "+="},
954      {lexer::TokenType::PUNCTUATOR_MINUS_EQUAL, "-="},
955      {lexer::TokenType::PUNCTUATOR_MULTIPLY_EQUAL, "*="},
956      {lexer::TokenType::PUNCTUATOR_DIVIDE_EQUAL, "/="},
957      {lexer::TokenType::PUNCTUATOR_MOD_EQUAL, "%="},
958      {lexer::TokenType::PUNCTUATOR_BITWISE_AND_EQUAL, "&="},
959      {lexer::TokenType::PUNCTUATOR_BITWISE_OR_EQUAL, "|="},
960      {lexer::TokenType::PUNCTUATOR_BITWISE_XOR_EQUAL, "^="},
961      {lexer::TokenType::PUNCTUATOR_LOGICAL_AND_EQUAL, "&&="},
962      {lexer::TokenType::PUNCTUATOR_LOGICAL_OR_EQUAL, "||="},
963      {lexer::TokenType::PUNCTUATOR_LOGICAL_NULLISH_EQUAL, "\?\?="},
964      {lexer::TokenType::PUNCTUATOR_EXPONENTIATION_EQUAL, "**="},
965      {lexer::TokenType::EOS, nullptr}}};
966 
CreateAssignmentExpression(es2panda_Context * context,es2panda_AstNode * left,es2panda_AstNode * right,char const * operatorType)967 extern "C" es2panda_AstNode *CreateAssignmentExpression(es2panda_Context *context, es2panda_AstNode *left,
968                                                         es2panda_AstNode *right, char const *operatorType)
969 {
970     auto *ctx = reinterpret_cast<Context *>(context);
971     auto *allocator = ctx->allocator;
972     auto *leftNode = reinterpret_cast<ir::AstNode *>(left)->AsExpression();
973     auto *rightNode = reinterpret_cast<ir::AstNode *>(right)->AsExpression();
974     lexer::TokenType tok = StrToToken(ASSIGNMENT_TOKEN_TYPES.data(), operatorType);
975     return reinterpret_cast<es2panda_AstNode *>(allocator->New<ir::AssignmentExpression>(leftNode, rightNode, tok));
976 }
977 
AssignmentExpressionLeft(es2panda_AstNode * ast)978 extern "C" es2panda_AstNode *AssignmentExpressionLeft(es2panda_AstNode *ast)
979 {
980     auto *node = reinterpret_cast<ir::AstNode *>(ast)->AsAssignmentExpression();
981     return reinterpret_cast<es2panda_AstNode *>(node->Left());
982 }
983 
AssignmentExpressionRight(es2panda_AstNode * ast)984 extern "C" es2panda_AstNode *AssignmentExpressionRight(es2panda_AstNode *ast)
985 {
986     auto *node = reinterpret_cast<ir::AstNode *>(ast)->AsAssignmentExpression();
987     return reinterpret_cast<es2panda_AstNode *>(node->Right());
988 }
989 
AssignmentExpressionOperatorType(es2panda_AstNode * ast)990 extern "C" char const *AssignmentExpressionOperatorType(es2panda_AstNode *ast)
991 {
992     auto *node = reinterpret_cast<ir::AstNode *>(ast)->AsAssignmentExpression();
993     return TokenToStr(ASSIGNMENT_TOKEN_TYPES.data(), node->OperatorType());
994 }
995 
AssignmentExpressionSetOperatorType(es2panda_AstNode * ast,char const * operatorType)996 extern "C" void AssignmentExpressionSetOperatorType(es2panda_AstNode *ast, char const *operatorType)
997 {
998     auto *node = reinterpret_cast<ir::AstNode *>(ast)->AsAssignmentExpression();
999     auto tok = StrToToken(ASSIGNMENT_TOKEN_TYPES.data(), operatorType);
1000     node->SetOperatorType(tok);
1001 }
1002 
1003 static constexpr std::array<TokenTypeToStr, 26U> BINARY_OP_TOKEN_TYPES {
1004     {{lexer::TokenType::PUNCTUATOR_UNSIGNED_RIGHT_SHIFT, ">>>"},
1005      {lexer::TokenType::PUNCTUATOR_RIGHT_SHIFT, ">>"},
1006      {lexer::TokenType::PUNCTUATOR_LEFT_SHIFT, "<<"},
1007      {lexer::TokenType::PUNCTUATOR_PLUS, "+"},
1008      {lexer::TokenType::PUNCTUATOR_MINUS, "-"},
1009      {lexer::TokenType::PUNCTUATOR_MULTIPLY, "*"},
1010      {lexer::TokenType::PUNCTUATOR_DIVIDE, "/"},
1011      {lexer::TokenType::PUNCTUATOR_MOD, "%"},
1012      {lexer::TokenType::PUNCTUATOR_BITWISE_AND, "&"},
1013      {lexer::TokenType::PUNCTUATOR_BITWISE_OR, "|"},
1014      {lexer::TokenType::PUNCTUATOR_BITWISE_XOR, "^"},
1015      {lexer::TokenType::PUNCTUATOR_LOGICAL_AND, "&&"},
1016      {lexer::TokenType::PUNCTUATOR_LOGICAL_OR, "||"},
1017      {lexer::TokenType::PUNCTUATOR_NULLISH_COALESCING, "??"},
1018      {lexer::TokenType::PUNCTUATOR_EXPONENTIATION, "**"},
1019      {lexer::TokenType::PUNCTUATOR_EQUAL, "=="},
1020      {lexer::TokenType::PUNCTUATOR_NOT_EQUAL, "/="},
1021      {lexer::TokenType::PUNCTUATOR_STRICT_EQUAL, "==="},
1022      {lexer::TokenType::PUNCTUATOR_NOT_STRICT_EQUAL, "/=="},
1023      {lexer::TokenType::PUNCTUATOR_LESS_THAN, "<"},
1024      {lexer::TokenType::PUNCTUATOR_LESS_THAN_EQUAL, "<="},
1025      {lexer::TokenType::PUNCTUATOR_GREATER_THAN, ">"},
1026      {lexer::TokenType::PUNCTUATOR_GREATER_THAN_EQUAL, ">="},
1027      {lexer::TokenType::KEYW_IN, "in"},
1028      {lexer::TokenType::KEYW_INSTANCEOF, "instanceof"},
1029      {lexer::TokenType::EOS, nullptr}}};
1030 
CreateBinaryExpression(es2panda_Context * context,es2panda_AstNode * left,es2panda_AstNode * right,char const * operatorType)1031 extern "C" es2panda_AstNode *CreateBinaryExpression(es2panda_Context *context, es2panda_AstNode *left,
1032                                                     es2panda_AstNode *right, char const *operatorType)
1033 {
1034     auto *ctx = reinterpret_cast<Context *>(context);
1035     auto *allocator = ctx->allocator;
1036     auto *leftExpr = reinterpret_cast<ir::AstNode *>(left)->AsExpression();
1037     auto *rightExpr = reinterpret_cast<ir::AstNode *>(right)->AsExpression();
1038     auto tok = StrToToken(BINARY_OP_TOKEN_TYPES.data(), operatorType);
1039 
1040     return reinterpret_cast<es2panda_AstNode *>(allocator->New<ir::BinaryExpression>(leftExpr, rightExpr, tok));
1041 }
1042 
BinaryExpressionLeft(es2panda_AstNode * ast)1043 extern "C" es2panda_AstNode *BinaryExpressionLeft(es2panda_AstNode *ast)
1044 {
1045     auto *node = reinterpret_cast<ir::AstNode *>(ast)->AsBinaryExpression();
1046     return reinterpret_cast<es2panda_AstNode *>(node->Left());
1047 }
1048 
BinaryExpressionRight(es2panda_AstNode * ast)1049 extern "C" es2panda_AstNode *BinaryExpressionRight(es2panda_AstNode *ast)
1050 {
1051     auto *node = reinterpret_cast<ir::AstNode *>(ast)->AsBinaryExpression();
1052     return reinterpret_cast<es2panda_AstNode *>(node->Right());
1053 }
1054 
BinaryExpressionOperator(es2panda_AstNode * ast)1055 extern "C" char const *BinaryExpressionOperator(es2panda_AstNode *ast)
1056 {
1057     auto *node = reinterpret_cast<ir::AstNode *>(ast)->AsBinaryExpression();
1058     return TokenToStr(BINARY_OP_TOKEN_TYPES.data(), node->OperatorType());
1059 }
1060 
BinaryExpressionSetOperator(es2panda_AstNode * ast,char const * operatorType)1061 extern "C" void BinaryExpressionSetOperator(es2panda_AstNode *ast, char const *operatorType)
1062 {
1063     auto *node = reinterpret_cast<ir::AstNode *>(ast)->AsBinaryExpression();
1064     auto op = StrToToken(BINARY_OP_TOKEN_TYPES.data(), operatorType);
1065     node->SetOperator(op);
1066 }
1067 
CreateBlockStatement(es2panda_Context * context)1068 extern "C" es2panda_AstNode *CreateBlockStatement(es2panda_Context *context)
1069 {
1070     auto *ctx = reinterpret_cast<Context *>(context);
1071     auto *allocator = ctx->allocator;
1072 
1073     ArenaVector<ir::Statement *> stmts {allocator->Adapter()};
1074     auto block = allocator->New<ir::BlockStatement>(allocator, std::move(stmts));
1075     return reinterpret_cast<es2panda_AstNode *>(block);
1076 }
1077 
BlockStatementStatements(es2panda_AstNode * ast,size_t * sizeP)1078 extern "C" es2panda_AstNode **BlockStatementStatements(es2panda_AstNode *ast, size_t *sizeP)
1079 {
1080     auto *node = reinterpret_cast<ir::AstNode *>(ast)->AsBlockStatement();
1081     *sizeP = node->Statements().size();
1082     return reinterpret_cast<es2panda_AstNode **>(node->Statements().data());
1083 }
1084 
BlockStatementAddStatement(es2panda_AstNode * ast,es2panda_AstNode * statement)1085 extern "C" void BlockStatementAddStatement(es2panda_AstNode *ast, es2panda_AstNode *statement)
1086 {
1087     auto *node = reinterpret_cast<ir::AstNode *>(ast)->AsBlockStatement();
1088     auto *stmt = reinterpret_cast<ir::AstNode *>(statement)->AsBlockStatement();
1089     node->Statements().push_back(stmt);
1090     stmt->SetParent(node);
1091 }
1092 
CreateCallExpression(es2panda_Context * context,es2panda_AstNode * callee,es2panda_AstNode * typeArguments,es2panda_AstNode ** arguments,size_t nArguments,bool isOptional)1093 extern "C" es2panda_AstNode *CreateCallExpression(es2panda_Context *context, es2panda_AstNode *callee,
1094                                                   es2panda_AstNode *typeArguments, es2panda_AstNode **arguments,
1095                                                   size_t nArguments, bool isOptional)
1096 {
1097     auto *ctx = reinterpret_cast<Context *>(context);
1098     auto *allocator = ctx->allocator;
1099     auto *calleeNode = reinterpret_cast<ir::AstNode *>(callee)->AsExpression();
1100 
1101     ir::TSTypeParameterInstantiation *typeArgs = nullptr;
1102     if (typeArguments != nullptr) {
1103         typeArgs = reinterpret_cast<ir::AstNode *>(typeArguments)->AsTSTypeParameterInstantiation();
1104     }
1105 
1106     ArenaVector<ir::Expression *> args {allocator->Adapter()};
1107     for (size_t i = 0; i < nArguments; i++) {
1108         // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
1109         args.push_back(reinterpret_cast<ir::AstNode *>(arguments[i])->AsExpression());
1110     }
1111     return reinterpret_cast<es2panda_AstNode *>(
1112         allocator->New<ir::CallExpression>(calleeNode, std::move(args), typeArgs, isOptional));
1113 }
1114 
CallExpressionCallee(es2panda_AstNode * ast)1115 extern "C" es2panda_AstNode const *CallExpressionCallee(es2panda_AstNode *ast)
1116 {
1117     auto *node = reinterpret_cast<ir::AstNode *>(ast)->AsCallExpression();
1118     return reinterpret_cast<es2panda_AstNode const *>(node->Callee());
1119 }
1120 
CallExpressionTypeArguments(es2panda_AstNode * ast)1121 extern "C" es2panda_AstNode const *CallExpressionTypeArguments(es2panda_AstNode *ast)
1122 {
1123     auto *node = reinterpret_cast<ir::AstNode *>(ast)->AsCallExpression();
1124     return reinterpret_cast<es2panda_AstNode const *>(node->TypeParams());
1125 }
1126 
CallExpressionArguments(es2panda_AstNode * ast,size_t * sizeP)1127 extern "C" es2panda_AstNode **CallExpressionArguments(es2panda_AstNode *ast, size_t *sizeP)
1128 {
1129     auto *node = reinterpret_cast<ir::AstNode *>(ast)->AsCallExpression();
1130     *sizeP = node->Arguments().size();
1131     return reinterpret_cast<es2panda_AstNode **>(node->Arguments().data());
1132 }
1133 
CallExpressionIsOptional(es2panda_AstNode * ast)1134 extern "C" bool CallExpressionIsOptional(es2panda_AstNode *ast)
1135 {
1136     auto *node = reinterpret_cast<ir::AstNode *>(ast)->AsCallExpression();
1137     return node->IsOptional();
1138 }
1139 
CallExpressionSetTypeArguments(es2panda_AstNode * ast,es2panda_AstNode * typeArguments)1140 extern "C" void CallExpressionSetTypeArguments(es2panda_AstNode *ast, es2panda_AstNode *typeArguments)
1141 {
1142     auto *node = reinterpret_cast<ir::AstNode *>(ast)->AsCallExpression();
1143     auto *typeArgs = reinterpret_cast<ir::AstNode *>(typeArguments)->AsTSTypeParameterInstantiation();
1144     node->SetTypeParams(typeArgs);
1145 }
1146 
CreateChainExpression(es2panda_Context * context,es2panda_AstNode * child)1147 extern "C" es2panda_AstNode *CreateChainExpression(es2panda_Context *context, es2panda_AstNode *child)
1148 {
1149     auto *ctx = reinterpret_cast<Context *>(context);
1150     auto *allocator = ctx->allocator;
1151     auto *childExpr = reinterpret_cast<ir::AstNode *>(child)->AsExpression();
1152 
1153     return reinterpret_cast<es2panda_AstNode *>(allocator->New<ir::ChainExpression>(childExpr));
1154 }
1155 
ChainExpressionChild(es2panda_AstNode * ast)1156 extern "C" es2panda_AstNode const *ChainExpressionChild(es2panda_AstNode *ast)
1157 {
1158     auto *node = reinterpret_cast<ir::AstNode *>(ast)->AsChainExpression();
1159     return reinterpret_cast<es2panda_AstNode const *>(node->GetExpression());
1160 }
1161 
CreateClassDeclaration(es2panda_Context * context,es2panda_AstNode * definition)1162 extern "C" es2panda_AstNode *CreateClassDeclaration(es2panda_Context *context, es2panda_AstNode *definition)
1163 {
1164     auto *ctx = reinterpret_cast<Context *>(context);
1165     auto *allocator = ctx->allocator;
1166     auto *dfn = reinterpret_cast<ir::AstNode *>(definition)->AsClassDefinition();
1167 
1168     return reinterpret_cast<es2panda_AstNode *>(allocator->New<ir::ClassDeclaration>(dfn, allocator));
1169 }
1170 
ClassDeclarationDefinition(es2panda_AstNode * ast)1171 extern "C" es2panda_AstNode *ClassDeclarationDefinition(es2panda_AstNode *ast)
1172 {
1173     auto *node = reinterpret_cast<ir::AstNode *>(ast)->AsClassDeclaration();
1174     return reinterpret_cast<es2panda_AstNode *>(node->Definition());
1175 }
1176 
CreateClassDefinition(es2panda_Context * context,es2panda_AstNode * identifier,es2panda_ModifierFlags flags)1177 extern "C" es2panda_AstNode *CreateClassDefinition(es2panda_Context *context, es2panda_AstNode *identifier,
1178                                                    es2panda_ModifierFlags flags)
1179 {
1180     auto *ctx = reinterpret_cast<Context *>(context);
1181     auto *allocator = ctx->allocator;
1182     auto *id = reinterpret_cast<ir::AstNode *>(identifier)->AsIdentifier();
1183 
1184     auto classDef =
1185         allocator->New<ir::ClassDefinition>(allocator, id, ir::ClassDefinitionModifiers::NONE,
1186                                             E2pToIrModifierFlags(flags), Language::FromString("sts").value());
1187     return reinterpret_cast<es2panda_AstNode *>(classDef);
1188 }
1189 
ClassDefinitionIdentifier(es2panda_AstNode * ast)1190 extern "C" es2panda_AstNode *ClassDefinitionIdentifier(es2panda_AstNode *ast)
1191 {
1192     auto *node = reinterpret_cast<ir::AstNode *>(ast)->AsClassDefinition();
1193     return reinterpret_cast<es2panda_AstNode *>(node->Ident());
1194 }
1195 
ClassDefinitionTypeParameters(es2panda_AstNode * ast)1196 extern "C" es2panda_AstNode *ClassDefinitionTypeParameters(es2panda_AstNode *ast)
1197 {
1198     auto *node = reinterpret_cast<ir::AstNode *>(ast)->AsClassDefinition();
1199     return reinterpret_cast<es2panda_AstNode *>(node->TypeParams());
1200 }
1201 
ClassDefinitionSuperClass(es2panda_AstNode * ast)1202 extern "C" es2panda_AstNode *ClassDefinitionSuperClass(es2panda_AstNode *ast)
1203 {
1204     auto *node = reinterpret_cast<ir::AstNode *>(ast)->AsClassDefinition();
1205     return reinterpret_cast<es2panda_AstNode *>(node->Super());
1206 }
1207 
ClassDefinitionImplements(es2panda_AstNode * ast,size_t * sizeP)1208 extern "C" es2panda_AstNode **ClassDefinitionImplements(es2panda_AstNode *ast, size_t *sizeP)
1209 {
1210     auto *node = reinterpret_cast<ir::AstNode *>(ast)->AsClassDefinition();
1211     auto &implVec = node->Implements();
1212     *sizeP = implVec.size();
1213     return reinterpret_cast<es2panda_AstNode **>(implVec.data());
1214 }
1215 
ClassDefinitionConstructor(es2panda_AstNode * ast)1216 extern "C" es2panda_AstNode *ClassDefinitionConstructor(es2panda_AstNode *ast)
1217 {
1218     auto *node = reinterpret_cast<ir::AstNode *>(ast)->AsClassDefinition();
1219     return reinterpret_cast<es2panda_AstNode *>(node->Ctor());
1220 }
1221 
ClassDefinitionBody(es2panda_AstNode * ast,size_t * sizeP)1222 extern "C" es2panda_AstNode **ClassDefinitionBody(es2panda_AstNode *ast, size_t *sizeP)
1223 {
1224     auto *node = reinterpret_cast<ir::AstNode *>(ast)->AsClassDefinition();
1225     auto &bodyVec = node->Body();
1226     *sizeP = bodyVec.size();
1227     return reinterpret_cast<es2panda_AstNode **>(bodyVec.data());
1228 }
1229 
ClassDefinitionSetIdentifier(es2panda_AstNode * ast,es2panda_AstNode * identifier)1230 extern "C" void ClassDefinitionSetIdentifier(es2panda_AstNode *ast, es2panda_AstNode *identifier)
1231 {
1232     auto *node = reinterpret_cast<ir::AstNode *>(ast)->AsClassDefinition();
1233     auto *id = reinterpret_cast<ir::AstNode *>(identifier)->AsIdentifier();
1234     node->SetIdent(id);
1235 }
1236 
ClassDefinitionSetTypeParameters(es2panda_AstNode * ast,es2panda_AstNode * typeParams)1237 extern "C" void ClassDefinitionSetTypeParameters(es2panda_AstNode *ast, es2panda_AstNode *typeParams)
1238 {
1239     auto *node = reinterpret_cast<ir::AstNode *>(ast)->AsClassDefinition();
1240     auto *tpd = reinterpret_cast<ir::AstNode *>(typeParams)->AsTSTypeParameterDeclaration();
1241     node->SetTypeParams(tpd);
1242 }
1243 
ClassDefinitionSetSuperClass(es2panda_AstNode * ast,es2panda_AstNode * superClass)1244 extern "C" void ClassDefinitionSetSuperClass(es2panda_AstNode *ast, es2panda_AstNode *superClass)
1245 {
1246     auto *node = reinterpret_cast<ir::AstNode *>(ast)->AsClassDefinition();
1247     auto *super = reinterpret_cast<ir::AstNode *>(superClass)->AsExpression();
1248     node->SetSuper(super);
1249 }
1250 
ClassDefinitionSetImplements(es2panda_AstNode * ast,es2panda_AstNode ** implements,size_t nImplements)1251 extern "C" void ClassDefinitionSetImplements(es2panda_AstNode *ast, es2panda_AstNode **implements, size_t nImplements)
1252 {
1253     auto *node = reinterpret_cast<ir::AstNode *>(ast)->AsClassDefinition();
1254     auto &implVec = node->Implements();
1255     implVec.resize(0);
1256     for (size_t i = 0; i < nImplements; i++) {
1257         // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
1258         implVec.push_back(reinterpret_cast<ir::AstNode *>(implements[i])->AsTSClassImplements());
1259     }
1260 }
1261 
ClassDefinitionAddImplements(es2panda_AstNode * ast,es2panda_AstNode * implements)1262 extern "C" void ClassDefinitionAddImplements(es2panda_AstNode *ast, es2panda_AstNode *implements)
1263 {
1264     auto *node = reinterpret_cast<ir::AstNode *>(ast)->AsClassDefinition();
1265     auto &implVec = node->Implements();
1266     implVec.push_back(reinterpret_cast<ir::AstNode *>(implements)->AsTSClassImplements());
1267 }
1268 
ClassDefinitionSetConstructor(es2panda_AstNode * ast,es2panda_AstNode * constructor)1269 extern "C" void ClassDefinitionSetConstructor(es2panda_AstNode *ast, es2panda_AstNode *constructor)
1270 {
1271     auto *node = reinterpret_cast<ir::AstNode *>(ast)->AsClassDefinition();
1272     auto *ctor = reinterpret_cast<ir::AstNode *>(constructor)->AsMethodDefinition();
1273     node->SetCtor(ctor);
1274 }
1275 
ClassDefinitionSetBody(es2panda_AstNode * ast,es2panda_AstNode ** body,size_t nElems)1276 extern "C" void ClassDefinitionSetBody(es2panda_AstNode *ast, es2panda_AstNode **body, size_t nElems)
1277 {
1278     auto *node = reinterpret_cast<ir::AstNode *>(ast)->AsClassDefinition();
1279     auto &bodyVec = node->Body();
1280     bodyVec.resize(0);
1281     for (size_t i = 0; i < nElems; i++) {
1282         // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
1283         bodyVec.push_back(reinterpret_cast<ir::AstNode *>(body[i]));
1284     }
1285 }
1286 
ClassDefinitionAddToBody(es2panda_AstNode * ast,es2panda_AstNode * bodyElem)1287 extern "C" void ClassDefinitionAddToBody(es2panda_AstNode *ast, es2panda_AstNode *bodyElem)
1288 {
1289     auto *node = reinterpret_cast<ir::AstNode *>(ast)->AsClassDefinition();
1290     auto *elem = reinterpret_cast<ir::AstNode *>(bodyElem);
1291     auto &bodyVec = node->Body();
1292     bodyVec.push_back(reinterpret_cast<ir::AstNode *>(elem));
1293 }
1294 
ClassElementKey(es2panda_AstNode * ast)1295 extern "C" es2panda_AstNode *ClassElementKey(es2panda_AstNode *ast)
1296 {
1297     auto *node = reinterpret_cast<ir::AstNode *>(ast)->AsClassElement();
1298     return reinterpret_cast<es2panda_AstNode *>(node->Key());
1299 }
1300 
ClassElementValue(es2panda_AstNode * ast)1301 extern "C" es2panda_AstNode *ClassElementValue(es2panda_AstNode *ast)
1302 {
1303     auto *node = reinterpret_cast<ir::AstNode *>(ast)->AsClassElement();
1304     return reinterpret_cast<es2panda_AstNode *>(node->Value());
1305 }
1306 
CreateClassImplementsClause(es2panda_Context * context,es2panda_AstNode * expression,es2panda_AstNode * typeArguments)1307 extern "C" es2panda_AstNode *CreateClassImplementsClause(es2panda_Context *context, es2panda_AstNode *expression,
1308                                                          es2panda_AstNode *typeArguments)
1309 {
1310     auto *ctx = reinterpret_cast<Context *>(context);
1311     auto *allocator = ctx->allocator;
1312     auto *expr = reinterpret_cast<ir::AstNode *>(expression)->AsExpression();
1313     auto *targs = typeArguments == nullptr
1314                       ? nullptr
1315                       : reinterpret_cast<ir::AstNode *>(typeArguments)->AsTSTypeParameterInstantiation();
1316 
1317     return reinterpret_cast<es2panda_AstNode *>(allocator->New<ir::TSClassImplements>(expr, targs));
1318 }
1319 
ClassImplementsClauseExpression(es2panda_AstNode * ast)1320 extern "C" es2panda_AstNode *ClassImplementsClauseExpression(es2panda_AstNode *ast)
1321 {
1322     auto *node = reinterpret_cast<ir::AstNode *>(ast)->AsTSClassImplements();
1323     return reinterpret_cast<es2panda_AstNode *>(node->Expr());
1324 }
1325 
ClassImplementsClauseTypeArguments(es2panda_AstNode * ast)1326 extern "C" es2panda_AstNode const *ClassImplementsClauseTypeArguments(es2panda_AstNode *ast)
1327 {
1328     auto *node = reinterpret_cast<ir::AstNode *>(ast)->AsTSClassImplements();
1329     return reinterpret_cast<es2panda_AstNode const *>(node->TypeParameters());
1330 }
1331 
CreateClassProperty(es2panda_Context * context,es2panda_AstNode * key,es2panda_AstNode * value,es2panda_AstNode * typeAnnotation,es2panda_ModifierFlags modifierFlags,bool isComputed)1332 extern "C" es2panda_AstNode *CreateClassProperty(es2panda_Context *context, es2panda_AstNode *key,
1333                                                  es2panda_AstNode *value, es2panda_AstNode *typeAnnotation,
1334                                                  es2panda_ModifierFlags modifierFlags, bool isComputed)
1335 {
1336     auto *ctx = reinterpret_cast<Context *>(context);
1337     auto *allocator = ctx->allocator;
1338     auto *ekey = reinterpret_cast<ir::AstNode *>(key)->AsExpression();
1339     auto *evalue = value == nullptr ? nullptr : reinterpret_cast<ir::AstNode *>(value)->AsExpression();
1340     auto *tpAnn = typeAnnotation == nullptr
1341                       ? nullptr
1342                       : reinterpret_cast<ir::AstNode *>(typeAnnotation)->AsExpression()->AsTypeNode();
1343     auto modifiers = E2pToIrModifierFlags(modifierFlags);
1344 
1345     return reinterpret_cast<es2panda_AstNode *>(
1346         allocator->New<ir::ClassProperty>(ekey, evalue, tpAnn, modifiers, allocator, isComputed));
1347 }
1348 
ClassPropertyTypeAnnotation(es2panda_AstNode * ast)1349 extern "C" es2panda_AstNode *ClassPropertyTypeAnnotation(es2panda_AstNode *ast)
1350 {
1351     auto *node = reinterpret_cast<ir::AstNode *>(ast)->AsClassProperty();
1352     return reinterpret_cast<es2panda_AstNode *>(node->TypeAnnotation());
1353 }
1354 
CreateExpressionStatement(es2panda_Context * context,es2panda_AstNode * expression)1355 extern "C" es2panda_AstNode *CreateExpressionStatement(es2panda_Context *context, es2panda_AstNode *expression)
1356 {
1357     auto *ctx = reinterpret_cast<Context *>(context);
1358     auto *allocator = ctx->allocator;
1359     auto *expr = reinterpret_cast<ir::AstNode *>(expression)->AsExpression();
1360 
1361     return reinterpret_cast<es2panda_AstNode *>(allocator->New<ir::ExpressionStatement>(expr));
1362 }
1363 
ExpressionStatementExpression(es2panda_AstNode * ast)1364 extern "C" es2panda_AstNode *ExpressionStatementExpression(es2panda_AstNode *ast)
1365 {
1366     auto *node = reinterpret_cast<ir::AstNode *>(ast)->AsExpressionStatement();
1367     return reinterpret_cast<es2panda_AstNode *>(node->GetExpression());
1368 }
1369 
CreateFunctionDeclaration(es2panda_Context * context,es2panda_AstNode * function)1370 extern "C" es2panda_AstNode *CreateFunctionDeclaration(es2panda_Context *context, es2panda_AstNode *function)
1371 {
1372     auto *ctx = reinterpret_cast<Context *>(context);
1373     auto *allocator = ctx->allocator;
1374     auto *func = reinterpret_cast<ir::AstNode *>(function)->AsScriptFunction();
1375 
1376     return reinterpret_cast<es2panda_AstNode *>(allocator->New<ir::FunctionDeclaration>(allocator, func));
1377 }
1378 
FunctionDeclarationFunction(es2panda_AstNode * ast)1379 extern "C" es2panda_AstNode *FunctionDeclarationFunction(es2panda_AstNode *ast)
1380 {
1381     auto *node = reinterpret_cast<ir::AstNode *>(ast)->AsFunctionDeclaration();
1382     return reinterpret_cast<es2panda_AstNode *>(node->Function());
1383 }
1384 
CreateFunctionExpression(es2panda_Context * context,es2panda_AstNode * function)1385 extern "C" es2panda_AstNode *CreateFunctionExpression(es2panda_Context *context, es2panda_AstNode *function)
1386 {
1387     auto *ctx = reinterpret_cast<Context *>(context);
1388     auto *allocator = ctx->allocator;
1389     auto *func = reinterpret_cast<ir::AstNode *>(function)->AsScriptFunction();
1390 
1391     return reinterpret_cast<es2panda_AstNode *>(allocator->New<ir::FunctionExpression>(func));
1392 }
1393 
FunctionExpressionFunction(es2panda_AstNode * ast)1394 extern "C" es2panda_AstNode *FunctionExpressionFunction(es2panda_AstNode *ast)
1395 {
1396     auto *node = reinterpret_cast<ir::AstNode *>(ast)->AsFunctionExpression();
1397     return reinterpret_cast<es2panda_AstNode *>(node->Function());
1398 }
1399 
CreateFunctionTypeNode(es2panda_Context * context,es2panda_AstNode * typeParams,es2panda_AstNode ** params,size_t nParams,es2panda_AstNode * returnType,es2panda_ScriptFunctionFlags funcFlags)1400 extern "C" es2panda_AstNode *CreateFunctionTypeNode(es2panda_Context *context, es2panda_AstNode *typeParams,
1401                                                     es2panda_AstNode **params, size_t nParams,
1402                                                     es2panda_AstNode *returnType,
1403                                                     es2panda_ScriptFunctionFlags funcFlags)
1404 {
1405     auto *ctx = reinterpret_cast<Context *>(context);
1406     auto *allocator = ctx->allocator;
1407     auto *tpar =
1408         typeParams == nullptr ? nullptr : reinterpret_cast<ir::AstNode *>(typeParams)->AsTSTypeParameterDeclaration();
1409     auto *tret =
1410         returnType == nullptr ? nullptr : reinterpret_cast<ir::AstNode *>(returnType)->AsExpression()->AsTypeNode();
1411     auto flags = E2pToIrScriptFunctionFlags(funcFlags);
1412 
1413     ArenaVector<ir::Expression *> par {allocator->Adapter()};
1414     for (size_t i = 0; i < nParams; i++) {
1415         // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
1416         par.push_back(reinterpret_cast<ir::AstNode *>(params[i])->AsExpression());
1417     }
1418 
1419     auto signature = ir::FunctionSignature(tpar, std::move(par), tret);
1420     auto func = allocator->New<ir::ETSFunctionType>(std::move(signature), flags);
1421     return reinterpret_cast<es2panda_AstNode *>(func);
1422 }
1423 
FunctionTypeNodeTypeParams(es2panda_AstNode * ast)1424 extern "C" es2panda_AstNode const *FunctionTypeNodeTypeParams(es2panda_AstNode *ast)
1425 {
1426     auto *node = reinterpret_cast<ir::AstNode *>(ast)->AsETSFunctionType();
1427     return reinterpret_cast<es2panda_AstNode const *>(node->TypeParams());
1428 }
1429 
FunctionTypeNodeParams(es2panda_AstNode * ast,size_t * sizeP)1430 extern "C" es2panda_AstNode *const *FunctionTypeNodeParams(es2panda_AstNode *ast, size_t *sizeP)
1431 {
1432     auto *node = reinterpret_cast<ir::AstNode *>(ast)->AsETSFunctionType();
1433     auto &params = node->Params();
1434     *sizeP = params.size();
1435     return reinterpret_cast<es2panda_AstNode *const *>(params.data());
1436 }
1437 
FunctionTypeNodeReturnType(es2panda_AstNode * ast)1438 extern "C" es2panda_AstNode *FunctionTypeNodeReturnType(es2panda_AstNode *ast)
1439 {
1440     auto *node = reinterpret_cast<ir::AstNode *>(ast)->AsETSFunctionType();
1441     return reinterpret_cast<es2panda_AstNode *>(node->ReturnType());
1442 }
1443 
FunctionTypeNodeFlags(es2panda_AstNode * ast)1444 extern "C" es2panda_ScriptFunctionFlags FunctionTypeNodeFlags(es2panda_AstNode *ast)
1445 {
1446     auto *node = reinterpret_cast<ir::AstNode *>(ast)->AsETSFunctionType();
1447     return IrToE2pScriptFunctionFlags(node->Flags());
1448 }
1449 
CreateIdentifier(es2panda_Context * context,char const * name,es2panda_AstNode * typeAnnotations)1450 extern "C" es2panda_AstNode *CreateIdentifier(es2panda_Context *context, char const *name,
1451                                               es2panda_AstNode *typeAnnotations)
1452 {
1453     auto *ctx = reinterpret_cast<Context *>(context);
1454     auto *allocator = ctx->allocator;
1455     auto *nameCopy = ArenaStrdup(ctx->allocator, name);
1456     auto *tpAnn = typeAnnotations == nullptr
1457                       ? nullptr
1458                       : reinterpret_cast<ir::AstNode *>(typeAnnotations)->AsExpression()->AsTypeNode();
1459 
1460     auto *res = allocator->New<ir::Identifier>(util::StringView {nameCopy}, tpAnn, allocator);
1461 
1462     return reinterpret_cast<es2panda_AstNode *>(res);
1463 }
1464 
IdentifierName(es2panda_Context * context,es2panda_AstNode * identifier)1465 extern "C" char const *IdentifierName(es2panda_Context *context, es2panda_AstNode *identifier)
1466 {
1467     auto *ctx = reinterpret_cast<Context *>(context);
1468     auto *id = reinterpret_cast<ir::AstNode *>(identifier);
1469     ASSERT(id->IsIdentifier());
1470 
1471     return StringViewToCString(ctx->allocator, id->AsIdentifier()->Name());
1472 }
1473 
IdentifierTypeAnnotation(es2panda_AstNode * identifier)1474 extern "C" es2panda_AstNode *IdentifierTypeAnnotation(es2panda_AstNode *identifier)
1475 {
1476     auto *id = reinterpret_cast<ir::AstNode *>(identifier)->AsIdentifier();
1477     return reinterpret_cast<es2panda_AstNode *>(id->TypeAnnotation());
1478 }
1479 
IdentifierVariable(es2panda_AstNode * identifier)1480 extern "C" es2panda_Variable *IdentifierVariable(es2panda_AstNode *identifier)
1481 {
1482     auto *id = reinterpret_cast<ir::AstNode *>(identifier)->AsIdentifier();
1483 
1484     return reinterpret_cast<es2panda_Variable *>(id->Variable());
1485 }
1486 
IdentifierSetVariable(es2panda_AstNode * identifier,es2panda_Variable * variable)1487 extern "C" void IdentifierSetVariable(es2panda_AstNode *identifier, es2panda_Variable *variable)
1488 {
1489     auto *id = reinterpret_cast<ir::AstNode *>(identifier)->AsIdentifier();
1490     auto *var = reinterpret_cast<varbinder::Variable *>(variable);
1491 
1492     id->SetVariable(var);
1493 }
1494 
CreateIfStatement(es2panda_Context * context,es2panda_AstNode * test,es2panda_AstNode * consequent,es2panda_AstNode * alternate)1495 extern "C" es2panda_AstNode *CreateIfStatement(es2panda_Context *context, es2panda_AstNode *test,
1496                                                es2panda_AstNode *consequent, es2panda_AstNode *alternate)
1497 {
1498     auto *ctx = reinterpret_cast<Context *>(context);
1499     auto *allocator = ctx->allocator;
1500     auto *t = reinterpret_cast<ir::AstNode *>(test)->AsExpression();
1501     auto *conseq = reinterpret_cast<ir::AstNode *>(consequent)->AsStatement();
1502     auto *alt = reinterpret_cast<ir::AstNode *>(alternate)->AsStatement();
1503 
1504     return reinterpret_cast<es2panda_AstNode *>(allocator->New<ir::IfStatement>(t, conseq, alt));
1505 }
1506 
IfStatementTest(es2panda_AstNode * identifier)1507 extern "C" es2panda_AstNode const *IfStatementTest(es2panda_AstNode *identifier)
1508 {
1509     auto *ifStat = reinterpret_cast<ir::AstNode *>(identifier)->AsIfStatement();
1510 
1511     return reinterpret_cast<es2panda_AstNode const *>(ifStat->Test());
1512 }
1513 
IfStatementConsequent(es2panda_AstNode * identifier)1514 extern "C" es2panda_AstNode const *IfStatementConsequent(es2panda_AstNode *identifier)
1515 {
1516     auto *ifStat = reinterpret_cast<ir::AstNode *>(identifier)->AsIfStatement();
1517 
1518     return reinterpret_cast<es2panda_AstNode const *>(ifStat->Consequent());
1519 }
1520 
IfStatementAlternate(es2panda_AstNode * identifier)1521 extern "C" es2panda_AstNode const *IfStatementAlternate(es2panda_AstNode *identifier)
1522 {
1523     auto *ifStat = reinterpret_cast<ir::AstNode *>(identifier)->AsIfStatement();
1524 
1525     return reinterpret_cast<es2panda_AstNode const *>(ifStat->Alternate());
1526 }
1527 
CreateImportDeclaration(es2panda_Context * context,es2panda_AstNode * source,es2panda_AstNode ** specifiers,size_t nSpecifiers)1528 extern "C" es2panda_AstNode *CreateImportDeclaration(es2panda_Context *context, es2panda_AstNode *source,
1529                                                      es2panda_AstNode **specifiers, size_t nSpecifiers)
1530 {
1531     auto *ctx = reinterpret_cast<Context *>(context);
1532     auto *allocator = ctx->allocator;
1533     auto *src = reinterpret_cast<ir::AstNode *>(source)->AsStringLiteral();
1534 
1535     ArenaVector<ir::AstNode *> specs {allocator->Adapter()};
1536     for (size_t i = 0; i < nSpecifiers; i++) {
1537         // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
1538         specs.push_back(reinterpret_cast<ir::AstNode *>(specifiers[i]));
1539     }
1540 
1541     return reinterpret_cast<es2panda_AstNode *>(allocator->New<ir::ImportDeclaration>(src, std::move(specs)));
1542 }
1543 
ImportDeclarationSource(es2panda_AstNode * ast)1544 extern "C" es2panda_AstNode const *ImportDeclarationSource(es2panda_AstNode *ast)
1545 {
1546     auto *decl = reinterpret_cast<ir::AstNode *>(ast)->AsImportDeclaration();
1547 
1548     return reinterpret_cast<es2panda_AstNode const *>(decl->Source());
1549 }
1550 
ImportDeclarationSpecifiers(es2panda_AstNode * ast,size_t * sizeP)1551 extern "C" es2panda_AstNode *const *ImportDeclarationSpecifiers(es2panda_AstNode *ast, size_t *sizeP)
1552 {
1553     auto *decl = reinterpret_cast<ir::AstNode *>(ast)->AsImportDeclaration();
1554     auto &specs = decl->Specifiers();
1555 
1556     *sizeP = specs.size();
1557 
1558     return reinterpret_cast<es2panda_AstNode *const *>(specs.data());
1559 }
1560 
CreateImportExpression(es2panda_Context * context,es2panda_AstNode * source)1561 extern "C" es2panda_AstNode *CreateImportExpression(es2panda_Context *context, es2panda_AstNode *source)
1562 {
1563     auto *ctx = reinterpret_cast<Context *>(context);
1564     auto *allocator = ctx->allocator;
1565     auto *src = reinterpret_cast<ir::AstNode *>(source)->AsExpression();
1566 
1567     return reinterpret_cast<es2panda_AstNode *>(allocator->New<ir::ImportExpression>(src));
1568 }
1569 
ImportExpressionSource(es2panda_AstNode * ast)1570 extern "C" es2panda_AstNode *ImportExpressionSource(es2panda_AstNode *ast)
1571 {
1572     auto *node = reinterpret_cast<ir::AstNode *>(ast)->AsImportExpression();
1573     return reinterpret_cast<es2panda_AstNode *>(node->Source());
1574 }
1575 
CreateImportSpecifier(es2panda_Context * context,es2panda_AstNode * imported,es2panda_AstNode * local)1576 extern "C" es2panda_AstNode *CreateImportSpecifier(es2panda_Context *context, es2panda_AstNode *imported,
1577                                                    es2panda_AstNode *local)
1578 {
1579     auto *ctx = reinterpret_cast<Context *>(context);
1580     auto *allocator = ctx->allocator;
1581     auto *irImported = reinterpret_cast<ir::AstNode *>(imported)->AsIdentifier();
1582     auto *irLocal = reinterpret_cast<ir::AstNode *>(local)->AsIdentifier();
1583 
1584     return reinterpret_cast<es2panda_AstNode *>(allocator->New<ir::ImportSpecifier>(irImported, irLocal));
1585 }
1586 
ImportSpecifierImported(es2panda_AstNode * ast)1587 extern "C" es2panda_AstNode *ImportSpecifierImported(es2panda_AstNode *ast)
1588 {
1589     auto *node = reinterpret_cast<ir::AstNode *>(ast)->AsImportSpecifier();
1590     return reinterpret_cast<es2panda_AstNode *>(node->Imported());
1591 }
1592 
ImportSpecifierLocal(es2panda_AstNode * ast)1593 extern "C" es2panda_AstNode *ImportSpecifierLocal(es2panda_AstNode *ast)
1594 {
1595     auto *node = reinterpret_cast<ir::AstNode *>(ast)->AsImportSpecifier();
1596     return reinterpret_cast<es2panda_AstNode *>(node->Local());
1597 }
1598 
E2pToIrMemberExpressionKind(es2panda_MemberExpressionKind e2pKind)1599 static ir::MemberExpressionKind E2pToIrMemberExpressionKind(es2panda_MemberExpressionKind e2pKind)
1600 {
1601     ir::MemberExpressionKind irKind = ir::MemberExpressionKind::NONE;
1602     irKind |= (e2pKind & ES2PANDA_MEMBER_EXPRESSION_KIND_ELEMENT_ACCESS) != 0 ? ir::MemberExpressionKind::ELEMENT_ACCESS
1603                                                                               : ir::MemberExpressionKind::NONE;
1604     irKind |= (e2pKind & ES2PANDA_MEMBER_EXPRESSION_KIND_PROPERTY_ACCESS) != 0
1605                   ? ir::MemberExpressionKind::PROPERTY_ACCESS
1606                   : ir::MemberExpressionKind::NONE;
1607     irKind |= (e2pKind & ES2PANDA_MEMBER_EXPRESSION_KIND_GETTER) != 0 ? ir::MemberExpressionKind::GETTER
1608                                                                       : ir::MemberExpressionKind::NONE;
1609     irKind |= (e2pKind & ES2PANDA_MEMBER_EXPRESSION_KIND_SETTER) != 0 ? ir::MemberExpressionKind::SETTER
1610                                                                       : ir::MemberExpressionKind::NONE;
1611 
1612     return irKind;
1613 }
1614 
IrToE2pMemberExpressionKind(ir::MemberExpressionKind irKind)1615 static es2panda_MemberExpressionKind IrToE2pMemberExpressionKind(ir::MemberExpressionKind irKind)
1616 {
1617     es2panda_MemberExpressionKind e2pKind = ES2PANDA_MEMBER_EXPRESSION_KIND_NONE;
1618     e2pKind = static_cast<es2panda_MemberExpressionKind>((irKind & ir::MemberExpressionKind::ELEMENT_ACCESS) != 0
1619                                                              ? e2pKind | ES2PANDA_MEMBER_EXPRESSION_KIND_ELEMENT_ACCESS
1620                                                              : e2pKind);
1621     e2pKind = static_cast<es2panda_MemberExpressionKind>((irKind & ir::MemberExpressionKind::PROPERTY_ACCESS) != 0
1622                                                              ? e2pKind | ES2PANDA_MEMBER_EXPRESSION_KIND_PROPERTY_ACCESS
1623                                                              : e2pKind);
1624     e2pKind = static_cast<es2panda_MemberExpressionKind>(
1625         (irKind & ir::MemberExpressionKind::GETTER) != 0 ? e2pKind | ES2PANDA_MEMBER_EXPRESSION_KIND_GETTER : e2pKind);
1626     e2pKind = static_cast<es2panda_MemberExpressionKind>(
1627         (irKind & ir::MemberExpressionKind::SETTER) != 0 ? e2pKind | ES2PANDA_MEMBER_EXPRESSION_KIND_SETTER : e2pKind);
1628 
1629     return e2pKind;
1630 }
1631 
CreateMemberExpression(es2panda_Context * context,es2panda_AstNode * object,es2panda_AstNode * property,es2panda_MemberExpressionKind kind,bool isComputed,bool isOptional)1632 extern "C" es2panda_AstNode *CreateMemberExpression(es2panda_Context *context, es2panda_AstNode *object,
1633                                                     es2panda_AstNode *property, es2panda_MemberExpressionKind kind,
1634                                                     bool isComputed, bool isOptional)
1635 {
1636     auto *ctx = reinterpret_cast<Context *>(context);
1637     auto *allocator = ctx->allocator;
1638     auto irObject = reinterpret_cast<ir::AstNode *>(object)->AsExpression();
1639     auto irProperty = reinterpret_cast<ir::AstNode *>(property)->AsExpression();
1640     auto irKind = E2pToIrMemberExpressionKind(kind);
1641 
1642     return reinterpret_cast<es2panda_AstNode *>(
1643         allocator->New<ir::MemberExpression>(irObject, irProperty, irKind, isComputed, isOptional));
1644 }
1645 
MemberExpressionObject(es2panda_AstNode * ast)1646 extern "C" es2panda_AstNode *MemberExpressionObject(es2panda_AstNode *ast)
1647 {
1648     auto *node = reinterpret_cast<ir::AstNode *>(ast)->AsMemberExpression();
1649     return reinterpret_cast<es2panda_AstNode *>(node->Object());
1650 }
1651 
MemberExpressionProperty(es2panda_AstNode * ast)1652 extern "C" es2panda_AstNode *MemberExpressionProperty(es2panda_AstNode *ast)
1653 {
1654     auto *node = reinterpret_cast<ir::AstNode *>(ast)->AsMemberExpression();
1655     return reinterpret_cast<es2panda_AstNode *>(node->Property());
1656 }
1657 
MemberExpressionKind(es2panda_AstNode * ast)1658 extern "C" es2panda_MemberExpressionKind MemberExpressionKind(es2panda_AstNode *ast)
1659 {
1660     auto *node = reinterpret_cast<ir::AstNode *>(ast)->AsMemberExpression();
1661     return IrToE2pMemberExpressionKind(node->Kind());
1662 }
1663 
MemberExpressionIsComputed(es2panda_AstNode * ast)1664 extern "C" bool MemberExpressionIsComputed(es2panda_AstNode *ast)
1665 {
1666     auto *node = reinterpret_cast<ir::AstNode *>(ast)->AsMemberExpression();
1667     return node->IsComputed();
1668 }
1669 
MemberExpressionIsOptional(es2panda_AstNode * ast)1670 extern "C" bool MemberExpressionIsOptional(es2panda_AstNode *ast)
1671 {
1672     auto *node = reinterpret_cast<ir::AstNode *>(ast)->AsMemberExpression();
1673     return node->IsOptional();
1674 }
1675 
1676 struct MethodDefinitionKindToStrStruct {
1677     ir::MethodDefinitionKind kind;
1678     char const *str;
1679 };
1680 
1681 static constexpr std::array<MethodDefinitionKindToStrStruct, 5U> METHOD_DEFINITION_KIND_TO_STR {{
1682     {ir::MethodDefinitionKind::CONSTRUCTOR, "constructor"},
1683     {ir::MethodDefinitionKind::METHOD, "method"},
1684     {ir::MethodDefinitionKind::EXTENSION_METHOD, "extension method"},
1685     {ir::MethodDefinitionKind::GET, "get"},
1686     {ir::MethodDefinitionKind::SET, "set"},
1687 }};
1688 
StrToMethodDefinitionKind(char const * str)1689 static ir::MethodDefinitionKind StrToMethodDefinitionKind(char const *str)
1690 {
1691     for (auto &elem : METHOD_DEFINITION_KIND_TO_STR) {
1692         if (strcmp(elem.str, str) == 0) {
1693             return elem.kind;
1694         }
1695     }
1696     return ir::MethodDefinitionKind::NONE;
1697 }
1698 
MethodDefinitionKindToStr(ir::MethodDefinitionKind kind)1699 static char const *MethodDefinitionKindToStr(ir::MethodDefinitionKind kind)
1700 {
1701     for (auto &elem : METHOD_DEFINITION_KIND_TO_STR) {
1702         if (elem.kind == kind) {
1703             return elem.str;
1704         }
1705     }
1706     return "unknown";
1707 }
1708 
CreateMethodDefinition(es2panda_Context * context,char const * kind,es2panda_AstNode * key,es2panda_AstNode * value,es2panda_ModifierFlags modifiers,bool isComputed)1709 extern "C" es2panda_AstNode *CreateMethodDefinition(es2panda_Context *context, char const *kind, es2panda_AstNode *key,
1710                                                     es2panda_AstNode *value, es2panda_ModifierFlags modifiers,
1711                                                     bool isComputed)
1712 {
1713     auto *ctx = reinterpret_cast<Context *>(context);
1714     auto *allocator = ctx->allocator;
1715     auto irKind = StrToMethodDefinitionKind(kind);
1716     auto *irKey = reinterpret_cast<ir::AstNode *>(key)->AsExpression();
1717     auto *irValue = reinterpret_cast<ir::AstNode *>(value)->AsExpression();
1718     auto irFlags = E2pToIrModifierFlags(modifiers);
1719 
1720     return reinterpret_cast<es2panda_AstNode *>(
1721         allocator->New<ir::MethodDefinition>(irKind, irKey, irValue, irFlags, allocator, isComputed));
1722 }
1723 
MethodDefinitionKind(es2panda_AstNode * ast)1724 extern "C" char const *MethodDefinitionKind(es2panda_AstNode *ast)
1725 {
1726     auto *node = reinterpret_cast<ir::AstNode *>(ast)->AsMethodDefinition();
1727     return MethodDefinitionKindToStr(node->Kind());
1728 }
1729 
MethodDefinitionKey(es2panda_AstNode * ast)1730 extern "C" es2panda_AstNode const *MethodDefinitionKey(es2panda_AstNode *ast)
1731 {
1732     auto *node = reinterpret_cast<ir::AstNode *>(ast)->AsMethodDefinition();
1733     return reinterpret_cast<es2panda_AstNode const *>(node->Key());
1734 }
1735 
MethodDefinitionValue(es2panda_AstNode * ast)1736 extern "C" es2panda_AstNode const *MethodDefinitionValue(es2panda_AstNode *ast)
1737 {
1738     auto *node = reinterpret_cast<ir::AstNode *>(ast)->AsMethodDefinition();
1739     return reinterpret_cast<es2panda_AstNode const *>(node->Value());
1740 }
1741 
MethodDefinitionModifiers(es2panda_AstNode * ast)1742 extern "C" es2panda_ModifierFlags MethodDefinitionModifiers(es2panda_AstNode *ast)
1743 {
1744     auto *node = reinterpret_cast<ir::AstNode *>(ast)->AsMethodDefinition();
1745     return IrToE2pModifierFlags(node->Modifiers());
1746 }
1747 
MethodDefinitionIsComputed(es2panda_AstNode * ast)1748 extern "C" bool MethodDefinitionIsComputed(es2panda_AstNode *ast)
1749 {
1750     auto *node = reinterpret_cast<ir::AstNode *>(ast)->AsMethodDefinition();
1751     return node->IsComputed();
1752 }
1753 
MethodDefinitionOverloads(es2panda_AstNode * ast,size_t * sizeP)1754 extern "C" es2panda_AstNode *const *MethodDefinitionOverloads(es2panda_AstNode *ast, size_t *sizeP)
1755 {
1756     auto *node = reinterpret_cast<ir::AstNode *>(ast)->AsMethodDefinition();
1757     auto const &overloads = node->Overloads();
1758     *sizeP = overloads.size();
1759     return reinterpret_cast<es2panda_AstNode *const *>(overloads.data());
1760 }
1761 
MethodDefinitionSetOverloads(es2panda_AstNode * ast,es2panda_AstNode ** overloads,size_t nOverloads)1762 extern "C" void MethodDefinitionSetOverloads(es2panda_AstNode *ast, es2panda_AstNode **overloads, size_t nOverloads)
1763 {
1764     auto *node = reinterpret_cast<ir::AstNode *>(ast)->AsMethodDefinition();
1765     ArenaVector<ir::MethodDefinition *> irOverloads {node->Overloads().get_allocator()};
1766     irOverloads.reserve(nOverloads);
1767     for (size_t i = 0; i < nOverloads; i++) {
1768         // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
1769         irOverloads.push_back(reinterpret_cast<ir::AstNode *>(overloads[i])->AsMethodDefinition());
1770     }
1771     node->SetOverloads(std::move(irOverloads));
1772 }
1773 
MethodDefinitionAddOverload(es2panda_AstNode * ast,es2panda_AstNode * overload)1774 extern "C" void MethodDefinitionAddOverload(es2panda_AstNode *ast, es2panda_AstNode *overload)
1775 {
1776     auto *node = reinterpret_cast<ir::AstNode *>(ast)->AsMethodDefinition();
1777     auto *irOverload = reinterpret_cast<ir::AstNode *>(overload)->AsMethodDefinition();
1778     node->AddOverload(irOverload);
1779 }
1780 
CreateNewClassInstanceExpression(es2panda_Context * context,es2panda_AstNode * typeReference,es2panda_AstNode ** arguments,size_t nArguments,es2panda_AstNode * classDefinition)1781 extern "C" es2panda_AstNode *CreateNewClassInstanceExpression(es2panda_Context *context,
1782                                                               es2panda_AstNode *typeReference,
1783                                                               es2panda_AstNode **arguments, size_t nArguments,
1784                                                               es2panda_AstNode *classDefinition)
1785 {
1786     auto *ctx = reinterpret_cast<Context *>(context);
1787     auto *allocator = ctx->allocator;
1788     auto *irTyperef = reinterpret_cast<ir::AstNode *>(typeReference)->AsExpression();
1789 
1790     ArenaVector<ir::Expression *> args {allocator->Adapter()};
1791     for (size_t i = 0; i < nArguments; i++) {
1792         // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
1793         args.push_back(reinterpret_cast<ir::AstNode *>(arguments[i])->AsExpression());
1794     }
1795 
1796     auto *irClassdef =
1797         classDefinition == nullptr ? nullptr : reinterpret_cast<ir::AstNode *>(classDefinition)->AsClassDefinition();
1798 
1799     return reinterpret_cast<es2panda_AstNode *>(
1800         allocator->New<ir::ETSNewClassInstanceExpression>(irTyperef, std::move(args), irClassdef));
1801 }
1802 
NewClassInstanceExpressionTypeReference(es2panda_AstNode * ast)1803 extern "C" es2panda_AstNode *NewClassInstanceExpressionTypeReference(es2panda_AstNode *ast)
1804 {
1805     auto *node = reinterpret_cast<ir::AstNode *>(ast)->AsETSNewClassInstanceExpression();
1806     return reinterpret_cast<es2panda_AstNode *>(node->GetTypeRef());
1807 }
1808 
NewClassInstanceExpressionArguments(es2panda_AstNode * ast,size_t * sizeP)1809 extern "C" es2panda_AstNode *const *NewClassInstanceExpressionArguments(es2panda_AstNode *ast, size_t *sizeP)
1810 {
1811     auto *node = reinterpret_cast<ir::AstNode *>(ast)->AsETSNewClassInstanceExpression();
1812     auto const &args = node->GetArguments();
1813 
1814     *sizeP = args.size();
1815     return reinterpret_cast<es2panda_AstNode *const *>(args.data());
1816 }
1817 
NewClassInstanceExpressionClassDefinition(es2panda_AstNode * ast)1818 extern "C" es2panda_AstNode *NewClassInstanceExpressionClassDefinition(es2panda_AstNode *ast)
1819 {
1820     auto *node = reinterpret_cast<ir::AstNode *>(ast)->AsETSNewClassInstanceExpression();
1821     return reinterpret_cast<es2panda_AstNode *>(node->ClassDefinition());
1822 }
1823 
CreateNewArrayInstanceExpression(es2panda_Context * context,es2panda_AstNode * typeReference,es2panda_AstNode * dimension)1824 extern "C" es2panda_AstNode *CreateNewArrayInstanceExpression(es2panda_Context *context,
1825                                                               es2panda_AstNode *typeReference,
1826                                                               es2panda_AstNode *dimension)
1827 {
1828     auto *ctx = reinterpret_cast<Context *>(context);
1829     auto *allocator = ctx->allocator;
1830     auto *irTyperef = reinterpret_cast<ir::AstNode *>(typeReference)->AsExpression()->AsTypeNode();
1831     auto *irDim = reinterpret_cast<ir::AstNode *>(dimension)->AsExpression();
1832 
1833     return reinterpret_cast<es2panda_AstNode *>(allocator->New<ir::ETSNewArrayInstanceExpression>(irTyperef, irDim));
1834 }
1835 
NewArrayInstanceExpressionTypeReference(es2panda_AstNode * ast)1836 extern "C" es2panda_AstNode *NewArrayInstanceExpressionTypeReference(es2panda_AstNode *ast)
1837 {
1838     auto *node = reinterpret_cast<ir::AstNode *>(ast)->AsETSNewArrayInstanceExpression();
1839     return reinterpret_cast<es2panda_AstNode *>(node->TypeReference());
1840 }
1841 
NewArrayInstanceExpressionDimension(es2panda_AstNode * ast)1842 extern "C" es2panda_AstNode *NewArrayInstanceExpressionDimension(es2panda_AstNode *ast)
1843 {
1844     auto *node = reinterpret_cast<ir::AstNode *>(ast)->AsETSNewArrayInstanceExpression();
1845     return reinterpret_cast<es2panda_AstNode *>(node->Dimension());
1846 }
1847 
CreateNewMultiDimArrayInstanceExpression(es2panda_Context * context,es2panda_AstNode * typeReference,es2panda_AstNode ** dimensions,size_t nDimensions)1848 extern "C" es2panda_AstNode *CreateNewMultiDimArrayInstanceExpression(es2panda_Context *context,
1849                                                                       es2panda_AstNode *typeReference,
1850                                                                       es2panda_AstNode **dimensions, size_t nDimensions)
1851 {
1852     auto *ctx = reinterpret_cast<Context *>(context);
1853     auto *allocator = ctx->allocator;
1854     auto *irTyperef = reinterpret_cast<ir::AstNode *>(typeReference)->AsExpression()->AsTypeNode();
1855 
1856     ArenaVector<ir::Expression *> irDims {allocator->Adapter()};
1857     for (size_t i = 0; i < nDimensions; i++) {
1858         // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
1859         irDims.push_back(reinterpret_cast<ir::AstNode *>(dimensions[i])->AsExpression());
1860     }
1861 
1862     return reinterpret_cast<es2panda_AstNode *>(
1863         allocator->New<ir::ETSNewMultiDimArrayInstanceExpression>(irTyperef, std::move(irDims)));
1864 }
1865 
NewMultiDimArrayInstanceExpressionTypeReference(es2panda_AstNode * ast)1866 extern "C" es2panda_AstNode *NewMultiDimArrayInstanceExpressionTypeReference(es2panda_AstNode *ast)
1867 {
1868     auto *node = reinterpret_cast<ir::AstNode *>(ast)->AsETSNewMultiDimArrayInstanceExpression();
1869     return reinterpret_cast<es2panda_AstNode *>(node->TypeReference());
1870 }
1871 
NewMultiDimArrayInstanceExpressionDimensions(es2panda_AstNode * ast,size_t * sizeP)1872 extern "C" es2panda_AstNode *const *NewMultiDimArrayInstanceExpressionDimensions(es2panda_AstNode *ast, size_t *sizeP)
1873 {
1874     auto *node = reinterpret_cast<ir::AstNode *>(ast)->AsETSNewMultiDimArrayInstanceExpression();
1875     auto const &dims = node->Dimensions();
1876 
1877     *sizeP = dims.size();
1878     return reinterpret_cast<es2panda_AstNode *const *>(dims.data());
1879 }
1880 
CreateParameterDeclaration(es2panda_Context * context,es2panda_AstNode * identifierOrSpread,es2panda_AstNode * initializer)1881 extern "C" es2panda_AstNode *CreateParameterDeclaration(es2panda_Context *context, es2panda_AstNode *identifierOrSpread,
1882                                                         es2panda_AstNode *initializer)
1883 {
1884     auto *ctx = reinterpret_cast<Context *>(context);
1885     auto *allocator = ctx->allocator;
1886 
1887     auto *irIdentOrSpreadRaw = reinterpret_cast<ir::AstNode *>(identifierOrSpread)->AsExpression();
1888     ir::AnnotatedExpression *irIdentOrSpread;
1889     if (irIdentOrSpreadRaw->IsIdentifier()) {
1890         irIdentOrSpread = irIdentOrSpreadRaw->AsIdentifier();
1891     } else if (irIdentOrSpreadRaw->IsSpreadElement()) {
1892         irIdentOrSpread = irIdentOrSpreadRaw->AsSpreadElement();
1893     } else {
1894         UNREACHABLE();
1895     }
1896 
1897     auto *irInitializer =
1898         initializer == nullptr ? nullptr : reinterpret_cast<ir::AstNode *>(initializer)->AsExpression();
1899 
1900     return reinterpret_cast<es2panda_AstNode *>(
1901         allocator->New<ir::ETSParameterExpression>(irIdentOrSpread, irInitializer));
1902 }
1903 
ParameterDeclarationIdentifierOrSpread(es2panda_AstNode * ast)1904 extern "C" es2panda_AstNode *ParameterDeclarationIdentifierOrSpread(es2panda_AstNode *ast)
1905 {
1906     auto *node = reinterpret_cast<ir::AstNode *>(ast)->AsETSParameterExpression();
1907 
1908     ir::AstNode *res;
1909     if (node->IsRestParameter()) {
1910         res = node->RestParameter();
1911     } else {
1912         res = node->Ident();
1913     }
1914     return reinterpret_cast<es2panda_AstNode *>(res);
1915 }
1916 
ParameterDeclarationInitializer(es2panda_AstNode * ast)1917 extern "C" es2panda_AstNode *ParameterDeclarationInitializer(es2panda_AstNode *ast)
1918 {
1919     auto *node = reinterpret_cast<ir::AstNode *>(ast)->AsETSParameterExpression();
1920     return reinterpret_cast<es2panda_AstNode *>(node->Initializer());
1921 }
1922 
1923 struct PrimitiveTypeToStrStruct {
1924     ir::PrimitiveType type;
1925     char const *str;
1926 };
1927 
1928 static constexpr std::array<PrimitiveTypeToStrStruct, 9U> PRIMITIVE_TYPE_TO_STR {{
1929     {ir::PrimitiveType::BYTE, "byte"},
1930     {ir::PrimitiveType::INT, "int"},
1931     {ir::PrimitiveType::LONG, "long"},
1932     {ir::PrimitiveType::SHORT, "short"},
1933     {ir::PrimitiveType::FLOAT, "float"},
1934     {ir::PrimitiveType::DOUBLE, "double"},
1935     {ir::PrimitiveType::BOOLEAN, "boolean"},
1936     {ir::PrimitiveType::CHAR, "char"},
1937     {ir::PrimitiveType::VOID, "void"},
1938 }};
1939 
StrToPrimitiveType(char const * str)1940 static ir::PrimitiveType StrToPrimitiveType(char const *str)
1941 {
1942     for (auto &elem : PRIMITIVE_TYPE_TO_STR) {
1943         if (strcmp(elem.str, str) == 0) {
1944             return elem.type;
1945         }
1946     }
1947     return ir::PrimitiveType::VOID;
1948 }
1949 
PrimitiveTypeToStr(ir::PrimitiveType type)1950 static char const *PrimitiveTypeToStr(ir::PrimitiveType type)
1951 {
1952     for (auto &elem : PRIMITIVE_TYPE_TO_STR) {
1953         if (elem.type == type) {
1954             return elem.str;
1955         }
1956     }
1957     return "unknown";
1958 }
1959 
CreatePrimitiveTypeNode(es2panda_Context * context,char const * type)1960 extern "C" es2panda_AstNode *CreatePrimitiveTypeNode(es2panda_Context *context, char const *type)
1961 {
1962     auto *ctx = reinterpret_cast<Context *>(context);
1963     auto *allocator = ctx->allocator;
1964     auto tp = StrToPrimitiveType(type);
1965 
1966     return reinterpret_cast<es2panda_AstNode *>(allocator->New<ir::ETSPrimitiveType>(tp));
1967 }
1968 
PrimitiveTypeNodeType(es2panda_AstNode * ast)1969 extern "C" char const *PrimitiveTypeNodeType(es2panda_AstNode *ast)
1970 {
1971     auto *node = reinterpret_cast<ir::AstNode *>(ast)->AsETSPrimitiveType();
1972     return PrimitiveTypeToStr(node->GetPrimitiveType());
1973 }
1974 
CreateReturnStatement(es2panda_Context * context,es2panda_AstNode * argument)1975 extern "C" es2panda_AstNode *CreateReturnStatement(es2panda_Context *context, es2panda_AstNode *argument)
1976 {
1977     auto *ctx = reinterpret_cast<Context *>(context);
1978     auto *allocator = ctx->allocator;
1979     auto *irArg = argument == nullptr ? nullptr : reinterpret_cast<ir::AstNode *>(argument)->AsExpression();
1980 
1981     return reinterpret_cast<es2panda_AstNode *>(allocator->New<ir::ReturnStatement>(irArg));
1982 }
1983 
ReturnStatementArgument(es2panda_AstNode * ast)1984 extern "C" es2panda_AstNode *ReturnStatementArgument(es2panda_AstNode *ast)
1985 {
1986     auto *node = reinterpret_cast<ir::AstNode *>(ast)->AsReturnStatement();
1987     return reinterpret_cast<es2panda_AstNode *>(node->Argument());
1988 }
1989 
ReturnStatementReturnType(es2panda_AstNode * ast)1990 extern "C" es2panda_Type *ReturnStatementReturnType(es2panda_AstNode *ast)
1991 {
1992     auto *node = reinterpret_cast<ir::AstNode *>(ast)->AsReturnStatement();
1993     return reinterpret_cast<es2panda_Type *>(node->ReturnType());
1994 }
1995 
CreateScriptFunction(es2panda_Context * context,es2panda_AstNode * typeParams,es2panda_AstNode ** params,size_t nParams,es2panda_AstNode * returnTypeAnnotation,es2panda_ScriptFunctionFlags functionFlags,es2panda_ModifierFlags modifierFlags,bool isDeclare)1996 extern "C" es2panda_AstNode *CreateScriptFunction(es2panda_Context *context, es2panda_AstNode *typeParams,
1997                                                   es2panda_AstNode **params, size_t nParams,
1998                                                   es2panda_AstNode *returnTypeAnnotation,
1999                                                   es2panda_ScriptFunctionFlags functionFlags,
2000                                                   es2panda_ModifierFlags modifierFlags, bool isDeclare)
2001 {
2002     auto *ctx = reinterpret_cast<Context *>(context);
2003     auto *allocator = ctx->allocator;
2004     auto *irTypeParams =
2005         typeParams == nullptr ? nullptr : reinterpret_cast<ir::AstNode *>(typeParams)->AsTSTypeParameterDeclaration();
2006 
2007     ArenaVector<ir::Expression *> irParams {allocator->Adapter()};
2008     for (size_t i = 0; i < nParams; i++) {
2009         // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
2010         irParams.push_back(reinterpret_cast<ir::AstNode *>(params[i])->AsExpression());
2011     }
2012 
2013     auto irReturnTypeAnnotation =
2014         returnTypeAnnotation == nullptr
2015             ? nullptr
2016             : reinterpret_cast<ir::AstNode *>(returnTypeAnnotation)->AsExpression()->AsTypeNode();
2017 
2018     auto irFunctionFlags = E2pToIrScriptFunctionFlags(functionFlags);
2019     auto irModifierFlags = E2pToIrModifierFlags(modifierFlags);
2020 
2021     ir::FunctionSignature sig(irTypeParams, std::move(irParams), irReturnTypeAnnotation);
2022     auto func = allocator->New<ir::ScriptFunction>(
2023         allocator,
2024         ir::ScriptFunction::ScriptFunctionData {nullptr, std::move(sig), irFunctionFlags, irModifierFlags, isDeclare});
2025     return reinterpret_cast<es2panda_AstNode *>(func);
2026 }
2027 
ScriptFunctionTypeParams(es2panda_AstNode * ast)2028 extern "C" es2panda_AstNode *ScriptFunctionTypeParams(es2panda_AstNode *ast)
2029 {
2030     auto *node = reinterpret_cast<ir::AstNode *>(ast)->AsScriptFunction();
2031     return reinterpret_cast<es2panda_AstNode *>(node->TypeParams());
2032 }
2033 
ScriptFunctionParams(es2panda_AstNode * ast,size_t * sizeP)2034 extern "C" es2panda_AstNode *const *ScriptFunctionParams(es2panda_AstNode *ast, size_t *sizeP)
2035 {
2036     auto *node = reinterpret_cast<ir::AstNode *>(ast)->AsScriptFunction();
2037     auto &params = node->Params();
2038 
2039     *sizeP = params.size();
2040     return reinterpret_cast<es2panda_AstNode *const *>(params.data());
2041 }
2042 
ScriptFunctionReturnTypeAnnotation(es2panda_AstNode * ast)2043 extern "C" es2panda_AstNode *ScriptFunctionReturnTypeAnnotation(es2panda_AstNode *ast)
2044 {
2045     auto *node = reinterpret_cast<ir::AstNode *>(ast)->AsScriptFunction();
2046     return reinterpret_cast<es2panda_AstNode *>(node->ReturnTypeAnnotation());
2047 }
2048 
ScriptFunctionScriptFunctionFlags(es2panda_AstNode * ast)2049 extern "C" es2panda_ScriptFunctionFlags ScriptFunctionScriptFunctionFlags(es2panda_AstNode *ast)
2050 {
2051     auto *node = reinterpret_cast<ir::AstNode *>(ast)->AsScriptFunction();
2052     return IrToE2pScriptFunctionFlags(node->Flags());
2053 }
2054 
ScriptFunctionIsDeclare(es2panda_AstNode * ast)2055 extern "C" bool ScriptFunctionIsDeclare(es2panda_AstNode *ast)
2056 {
2057     auto *node = reinterpret_cast<ir::AstNode *>(ast)->AsScriptFunction();
2058     return node->Declare();
2059 }
2060 
ScriptFunctionIdentifier(es2panda_AstNode * ast)2061 extern "C" es2panda_AstNode *ScriptFunctionIdentifier(es2panda_AstNode *ast)
2062 {
2063     auto *node = reinterpret_cast<ir::AstNode *>(ast)->AsScriptFunction();
2064     return reinterpret_cast<es2panda_AstNode *>(node->Id());
2065 }
2066 
ScriptFunctionBody(es2panda_AstNode * ast)2067 extern "C" es2panda_AstNode *ScriptFunctionBody(es2panda_AstNode *ast)
2068 {
2069     auto *node = reinterpret_cast<ir::AstNode *>(ast)->AsScriptFunction();
2070     return reinterpret_cast<es2panda_AstNode *>(node->Body());
2071 }
2072 
ScriptFunctionSetIdentifier(es2panda_AstNode * ast,es2panda_AstNode * identifier)2073 extern "C" void ScriptFunctionSetIdentifier(es2panda_AstNode *ast, es2panda_AstNode *identifier)
2074 {
2075     auto *node = reinterpret_cast<ir::AstNode *>(ast)->AsScriptFunction();
2076     auto *id = reinterpret_cast<ir::AstNode *>(identifier)->AsIdentifier();
2077 
2078     node->SetIdent(id);
2079 }
2080 
ScriptFunctionSetBody(es2panda_AstNode * ast,es2panda_AstNode * body)2081 extern "C" void ScriptFunctionSetBody(es2panda_AstNode *ast, es2panda_AstNode *body)
2082 {
2083     auto *node = reinterpret_cast<ir::AstNode *>(ast)->AsScriptFunction();
2084     auto *irBody = reinterpret_cast<ir::AstNode *>(body);
2085 
2086     node->SetBody(irBody);
2087 }
2088 
ScriptFunctionSetParams(es2panda_AstNode * ast,es2panda_AstNode ** params,size_t nParams)2089 extern "C" void ScriptFunctionSetParams(es2panda_AstNode *ast, es2panda_AstNode **params, size_t nParams)
2090 {
2091     auto *node = reinterpret_cast<ir::AstNode *>(ast)->AsScriptFunction();
2092     auto &irParams = node->Params();
2093 
2094     irParams.clear();
2095     for (size_t i = 0; i < nParams; i++) {
2096         // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
2097         irParams.push_back(reinterpret_cast<ir::AstNode *>(params[i])->AsExpression());
2098     }
2099 }
2100 
ScripFunctionAddParam(es2panda_AstNode * ast,es2panda_AstNode * param)2101 extern "C" void ScripFunctionAddParam(es2panda_AstNode *ast, es2panda_AstNode *param)
2102 {
2103     auto *node = reinterpret_cast<ir::AstNode *>(ast)->AsScriptFunction();
2104     auto *irParam = reinterpret_cast<ir::AstNode *>(param)->AsExpression();
2105 
2106     node->Params().push_back(irParam);
2107 }
2108 
CreateStringLiteral(es2panda_Context * context,char const * string)2109 extern "C" es2panda_AstNode *CreateStringLiteral(es2panda_Context *context, char const *string)
2110 {
2111     auto *ctx = reinterpret_cast<Context *>(context);
2112     auto *allocator = ctx->allocator;
2113     auto *str = ArenaStrdup(allocator, string);
2114 
2115     return reinterpret_cast<es2panda_AstNode *>(allocator->New<ir::StringLiteral>(str));
2116 }
2117 
StringLiteralString(es2panda_Context * context,es2panda_AstNode * ast)2118 extern "C" char const *StringLiteralString(es2panda_Context *context, es2panda_AstNode *ast)
2119 {
2120     auto *ctx = reinterpret_cast<Context *>(context);
2121     auto *allocator = ctx->allocator;
2122     auto *node = reinterpret_cast<ir::AstNode *>(ast)->AsStringLiteral();
2123     return StringViewToCString(allocator, node->Str());
2124 }
2125 
CreateThisExpression(es2panda_Context * context)2126 extern "C" es2panda_AstNode *CreateThisExpression(es2panda_Context *context)
2127 {
2128     auto *ctx = reinterpret_cast<Context *>(context);
2129     auto *allocator = ctx->allocator;
2130 
2131     return reinterpret_cast<es2panda_AstNode *>(allocator->New<ir::ThisExpression>());
2132 }
2133 
CreateTypeParameter(es2panda_Context * context,es2panda_AstNode * name,es2panda_AstNode * constraint,es2panda_AstNode * defaultType)2134 extern "C" es2panda_AstNode *CreateTypeParameter(es2panda_Context *context, es2panda_AstNode *name,
2135                                                  es2panda_AstNode *constraint, es2panda_AstNode *defaultType)
2136 {
2137     auto *ctx = reinterpret_cast<Context *>(context);
2138     auto *allocator = ctx->allocator;
2139     auto *nm = reinterpret_cast<ir::AstNode *>(name)->AsIdentifier();
2140     auto *constr =
2141         constraint == nullptr ? nullptr : reinterpret_cast<ir::AstNode *>(constraint)->AsExpression()->AsTypeNode();
2142     auto *dflt =
2143         defaultType == nullptr ? nullptr : reinterpret_cast<ir::AstNode *>(defaultType)->AsExpression()->AsTypeNode();
2144 
2145     return reinterpret_cast<es2panda_AstNode *>(allocator->New<ir::TSTypeParameter>(nm, constr, dflt));
2146 }
2147 
TypeParameterName(es2panda_AstNode * ast)2148 extern "C" es2panda_AstNode const *TypeParameterName(es2panda_AstNode *ast)
2149 {
2150     auto *tp = reinterpret_cast<ir::AstNode *>(ast)->AsTSTypeParameter();
2151     return reinterpret_cast<es2panda_AstNode const *>(tp->Name());
2152 }
2153 
TypeParameterConstraint(es2panda_AstNode * ast)2154 extern "C" es2panda_AstNode const *TypeParameterConstraint(es2panda_AstNode *ast)
2155 {
2156     auto *tp = reinterpret_cast<ir::AstNode *>(ast)->AsTSTypeParameter();
2157     return reinterpret_cast<es2panda_AstNode const *>(tp->Constraint());
2158 }
2159 
TypeParameterDefaultType(es2panda_AstNode * ast)2160 extern "C" es2panda_AstNode const *TypeParameterDefaultType(es2panda_AstNode *ast)
2161 {
2162     auto *tp = reinterpret_cast<ir::AstNode *>(ast)->AsTSTypeParameter();
2163     return reinterpret_cast<es2panda_AstNode const *>(tp->DefaultType());
2164 }
2165 
CreateTypeParameterDeclaration(es2panda_Context * context)2166 extern "C" es2panda_AstNode *CreateTypeParameterDeclaration(es2panda_Context *context)
2167 {
2168     auto *ctx = reinterpret_cast<Context *>(context);
2169     auto *allocator = ctx->allocator;
2170 
2171     ArenaVector<ir::TSTypeParameter *> params {allocator->Adapter()};
2172     auto typeParams = allocator->New<ir::TSTypeParameterDeclaration>(std::move(params), 0);
2173     return reinterpret_cast<es2panda_AstNode *>(typeParams);
2174 }
2175 
TypeParameterDeclarationAddTypeParameter(es2panda_AstNode * ast,es2panda_AstNode * typeParameter)2176 extern "C" void TypeParameterDeclarationAddTypeParameter(es2panda_AstNode *ast, es2panda_AstNode *typeParameter)
2177 {
2178     auto *tpd = reinterpret_cast<ir::AstNode *>(ast)->AsTSTypeParameterDeclaration();
2179     auto *param = reinterpret_cast<ir::AstNode *>(typeParameter)->AsTSTypeParameter();
2180 
2181     tpd->AddParam(param);
2182 }
2183 
TypeParameterDeclarationTypeParameters(es2panda_AstNode * ast,size_t * sizeP)2184 extern "C" es2panda_AstNode *const *TypeParameterDeclarationTypeParameters(es2panda_AstNode *ast, size_t *sizeP)
2185 {
2186     auto *tpd = reinterpret_cast<ir::AstNode const *>(ast)->AsTSTypeParameterDeclaration();
2187     auto const &params = tpd->Params();
2188     *sizeP = params.size();
2189     return reinterpret_cast<es2panda_AstNode *const *>(params.data());
2190 }
2191 
CreateTypeParameterInstantiation(es2panda_Context * context,es2panda_AstNode ** typeParameters,size_t nParams)2192 extern "C" es2panda_AstNode *CreateTypeParameterInstantiation(es2panda_Context *context,
2193                                                               es2panda_AstNode **typeParameters, size_t nParams)
2194 {
2195     auto *ctx = reinterpret_cast<Context *>(context);
2196     auto *allocator = ctx->allocator;
2197 
2198     ArenaVector<ir::TypeNode *> params {allocator->Adapter()};
2199     for (size_t i = 0; i < nParams; i++) {
2200         // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
2201         params.push_back(reinterpret_cast<ir::AstNode *>(typeParameters[i])->AsExpression()->AsTypeNode());
2202     }
2203     return reinterpret_cast<es2panda_AstNode *>(allocator->New<ir::TSTypeParameterInstantiation>(std::move(params)));
2204 }
2205 
TypeParameterInstantiationTypeParameters(es2panda_AstNode * ast,size_t * sizeP)2206 extern "C" es2panda_AstNode *const *TypeParameterInstantiationTypeParameters(es2panda_AstNode *ast, size_t *sizeP)
2207 {
2208     auto *tpi = reinterpret_cast<ir::AstNode const *>(ast)->AsTSTypeParameterInstantiation();
2209     auto const &params = tpi->Params();
2210     *sizeP = params.size();
2211     return reinterpret_cast<es2panda_AstNode *const *>(params.data());
2212 }
2213 
CreateTypeReferenceNode(es2panda_Context * context,es2panda_AstNode * part)2214 extern "C" es2panda_AstNode *CreateTypeReferenceNode(es2panda_Context *context, es2panda_AstNode *part)
2215 {
2216     auto *ctx = reinterpret_cast<Context *>(context);
2217     auto *allocator = ctx->allocator;
2218     auto *irPart = reinterpret_cast<ir::AstNode *>(part)->AsETSTypeReferencePart();
2219 
2220     return reinterpret_cast<es2panda_AstNode *>(allocator->New<ir::ETSTypeReference>(irPart));
2221 }
2222 
TypeReferenceNodePart(es2panda_AstNode * ast)2223 extern "C" es2panda_AstNode *TypeReferenceNodePart(es2panda_AstNode *ast)
2224 {
2225     auto *node = reinterpret_cast<ir::AstNode const *>(ast)->AsETSTypeReference();
2226     return reinterpret_cast<es2panda_AstNode *>(node->Part());
2227 }
2228 
CreateTypeReferencePart(es2panda_Context * context,es2panda_AstNode * name,es2panda_AstNode * typeArguments,es2panda_AstNode * previous)2229 extern "C" es2panda_AstNode *CreateTypeReferencePart(es2panda_Context *context, es2panda_AstNode *name,
2230                                                      es2panda_AstNode *typeArguments, es2panda_AstNode *previous)
2231 {
2232     auto *ctx = reinterpret_cast<Context *>(context);
2233     auto *allocator = ctx->allocator;
2234     auto *irName = reinterpret_cast<ir::AstNode *>(name)->AsExpression();
2235     auto *irTypeArgs = typeArguments == nullptr
2236                            ? nullptr
2237                            : reinterpret_cast<ir::AstNode *>(typeArguments)->AsTSTypeParameterInstantiation();
2238     auto *irPrev = previous == nullptr ? nullptr : reinterpret_cast<ir::AstNode *>(previous)->AsETSTypeReferencePart();
2239 
2240     return reinterpret_cast<es2panda_AstNode *>(allocator->New<ir::ETSTypeReferencePart>(irName, irTypeArgs, irPrev));
2241 }
2242 
TypeReferencePartName(es2panda_AstNode * ast)2243 extern "C" es2panda_AstNode *TypeReferencePartName(es2panda_AstNode *ast)
2244 {
2245     auto *node = reinterpret_cast<ir::AstNode *>(ast)->AsETSTypeReferencePart();
2246     return reinterpret_cast<es2panda_AstNode *>(node->Name());
2247 }
2248 
TypeReferencePartTypeArguments(es2panda_AstNode * ast)2249 extern "C" es2panda_AstNode *TypeReferencePartTypeArguments(es2panda_AstNode *ast)
2250 {
2251     auto *node = reinterpret_cast<ir::AstNode *>(ast)->AsETSTypeReferencePart();
2252     return reinterpret_cast<es2panda_AstNode *>(node->TypeParams());
2253 }
2254 
TypeReferencePartPrevious(es2panda_AstNode * ast)2255 extern "C" es2panda_AstNode *TypeReferencePartPrevious(es2panda_AstNode *ast)
2256 {
2257     auto *node = reinterpret_cast<ir::AstNode *>(ast)->AsETSTypeReferencePart();
2258     return reinterpret_cast<es2panda_AstNode *>(node->Previous());
2259 }
2260 
CreateUnionTypeNode(es2panda_Context * context,es2panda_AstNode ** types,size_t nTypes)2261 extern "C" es2panda_AstNode *CreateUnionTypeNode(es2panda_Context *context, es2panda_AstNode **types, size_t nTypes)
2262 {
2263     auto *ctx = reinterpret_cast<Context *>(context);
2264     auto *allocator = ctx->allocator;
2265 
2266     ArenaVector<ir::TypeNode *> irTypes {allocator->Adapter()};
2267     for (size_t i = 0; i < nTypes; i++) {
2268         // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
2269         irTypes.push_back(reinterpret_cast<ir::AstNode *>(types[i])->AsExpression()->AsTypeNode());
2270     }
2271 
2272     return reinterpret_cast<es2panda_AstNode *>(allocator->New<ir::TSUnionType>(std::move(irTypes)));
2273 }
2274 
UnionTypeNodeTypes(es2panda_AstNode * ast,size_t * sizeP)2275 extern "C" es2panda_AstNode *const *UnionTypeNodeTypes(es2panda_AstNode *ast, size_t *sizeP)
2276 {
2277     auto *node = reinterpret_cast<ir::AstNode *>(ast)->AsTSUnionType();
2278     auto &irTypes = node->Types();
2279 
2280     *sizeP = irTypes.size();
2281     return reinterpret_cast<es2panda_AstNode *const *>(irTypes.data());
2282 }
2283 
2284 struct VariableDeclarationKindToStrStruct {
2285     ir::VariableDeclaration::VariableDeclarationKind kind;
2286     char const *str;
2287 };
2288 
2289 static constexpr std::array<VariableDeclarationKindToStrStruct, 3U> VARIABLE_DECLARATION_KIND_TO_STR {{
2290     {ir::VariableDeclaration::VariableDeclarationKind::CONST, "const"},
2291     {ir::VariableDeclaration::VariableDeclarationKind::LET, "let"},
2292     {ir::VariableDeclaration::VariableDeclarationKind::VAR, "var"},
2293 }};
2294 
StrToVariableDeclarationKind(char const * str)2295 static ir::VariableDeclaration::VariableDeclarationKind StrToVariableDeclarationKind(char const *str)
2296 {
2297     for (auto &elem : VARIABLE_DECLARATION_KIND_TO_STR) {
2298         if (strcmp(elem.str, str) == 0) {
2299             return elem.kind;
2300         }
2301     }
2302 
2303     // NOTE(gogabr): handle errors
2304     UNREACHABLE();
2305 }
2306 
VariableDeclarationKindToStr(ir::VariableDeclaration::VariableDeclarationKind kind)2307 static char const *VariableDeclarationKindToStr(ir::VariableDeclaration::VariableDeclarationKind kind)
2308 {
2309     for (auto &elem : VARIABLE_DECLARATION_KIND_TO_STR) {
2310         if (elem.kind == kind) {
2311             return elem.str;
2312         }
2313     }
2314     return "unknown";
2315 }
2316 
CreateVariableDeclaration(es2panda_Context * context,char const * kind,es2panda_AstNode ** declarators,size_t nDeclarators,bool isDeclare)2317 extern "C" es2panda_AstNode *CreateVariableDeclaration(es2panda_Context *context, char const *kind,
2318                                                        es2panda_AstNode **declarators, size_t nDeclarators,
2319                                                        bool isDeclare)
2320 {
2321     auto *ctx = reinterpret_cast<Context *>(context);
2322     auto *allocator = ctx->allocator;
2323     auto irKind = StrToVariableDeclarationKind(kind);
2324 
2325     ArenaVector<ir::VariableDeclarator *> irDeclarators {allocator->Adapter()};
2326     for (size_t i = 0; i < nDeclarators; i++) {
2327         // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
2328         irDeclarators.push_back(reinterpret_cast<ir::AstNode *>(declarators[i])->AsVariableDeclarator());
2329     }
2330 
2331     return reinterpret_cast<es2panda_AstNode *>(
2332         allocator->New<ir::VariableDeclaration>(irKind, allocator, std::move(irDeclarators), isDeclare));
2333 }
2334 
VariableDeclarationKind(es2panda_AstNode * ast)2335 extern "C" char const *VariableDeclarationKind(es2panda_AstNode *ast)
2336 {
2337     auto *node = reinterpret_cast<ir::AstNode *>(ast)->AsVariableDeclaration();
2338     return VariableDeclarationKindToStr(node->Kind());
2339 }
2340 
VariableDeclarationDeclarators(es2panda_AstNode * ast,size_t * sizeP)2341 extern "C" es2panda_AstNode *const *VariableDeclarationDeclarators(es2panda_AstNode *ast, size_t *sizeP)
2342 {
2343     auto *node = reinterpret_cast<ir::AstNode *>(ast)->AsVariableDeclaration();
2344     auto const &declarators = node->Declarators();
2345     *sizeP = declarators.size();
2346     return reinterpret_cast<es2panda_AstNode *const *>(declarators.data());
2347 }
2348 
VariableDeclarationIsDeclare(es2panda_AstNode * ast)2349 extern "C" bool VariableDeclarationIsDeclare(es2panda_AstNode *ast)
2350 {
2351     auto *node = reinterpret_cast<ir::AstNode *>(ast)->AsVariableDeclaration();
2352     return node->Declare();
2353 }
2354 
CreateVariableDeclarator(es2panda_Context * context,es2panda_AstNode * identifier,es2panda_AstNode * initializer)2355 extern "C" es2panda_AstNode *CreateVariableDeclarator(es2panda_Context *context, es2panda_AstNode *identifier,
2356                                                       es2panda_AstNode *initializer)
2357 {
2358     auto *ctx = reinterpret_cast<Context *>(context);
2359     auto *allocator = ctx->allocator;
2360     auto *ident = reinterpret_cast<ir::AstNode *>(identifier)->AsExpression();
2361     auto *init = initializer == nullptr ? nullptr : reinterpret_cast<ir::AstNode *>(initializer)->AsExpression();
2362 
2363     auto varDecl = allocator->New<ir::VariableDeclarator>(ir::VariableDeclaratorFlag::UNKNOWN, ident, init);
2364     return reinterpret_cast<es2panda_AstNode *>(varDecl);
2365 }
2366 
VariableDeclaratorIdentifier(es2panda_AstNode * ast)2367 extern "C" es2panda_AstNode *VariableDeclaratorIdentifier(es2panda_AstNode *ast)
2368 {
2369     auto *node = reinterpret_cast<ir::AstNode *>(ast)->AsVariableDeclarator();
2370     return reinterpret_cast<es2panda_AstNode *>(node->Id());
2371 }
2372 
VariableDeclaratorInitializer(es2panda_AstNode * ast)2373 extern "C" es2panda_AstNode *VariableDeclaratorInitializer(es2panda_AstNode *ast)
2374 {
2375     auto *node = reinterpret_cast<ir::AstNode *>(ast)->AsVariableDeclarator();
2376     return reinterpret_cast<es2panda_AstNode *>(node->Init());
2377 }
2378 
2379 es2panda_Impl g_impl = {
2380     ES2PANDA_LIB_VERSION,
2381 
2382     CreateConfig,
2383     DestroyConfig,
2384 
2385     CreateContextFromFile,
2386     CreateContextFromString,
2387     ProceedToState,
2388     DestroyContext,
2389 
2390     ContextState,
2391     ContextErrorMessage,
2392 
2393     ContextProgram,
2394     ProgramAst,
2395     ProgramExternalSources,
2396     ExternalSourceName,
2397     ExternalSourcePrograms,
2398 
2399     AstNodeType,
2400     AstNodeSetType,
2401 
2402     AstNodeDecorators,
2403     AstNodeSetDecorators,
2404 
2405     AstNodeModifierFlags,
2406 
2407     AstNodeForEach,
2408 
2409     IsArrowFunctionExpression,
2410     CreateArrowFunctionExpression,
2411     ArrowFunctionExpressionScriptFunction,
2412 
2413     IsAsExpression,
2414     CreateAsExpression,
2415     AsExpressionExpr,
2416     AsExpressionTypeAnnotation,
2417     AsExpressionIsConst,
2418     AsExpressionSetExpr,
2419     AsExpressionSetTypeAnnotation,
2420 
2421     IsAssignmentExpression,
2422     CreateAssignmentExpression,
2423     AssignmentExpressionLeft,
2424     AssignmentExpressionRight,
2425     AssignmentExpressionOperatorType,
2426     AssignmentExpressionSetOperatorType,
2427 
2428     IsBinaryExpression,
2429     CreateBinaryExpression,
2430     BinaryExpressionLeft,
2431     BinaryExpressionRight,
2432     BinaryExpressionOperator,
2433     BinaryExpressionSetOperator,
2434 
2435     IsBlockStatement,
2436     CreateBlockStatement,
2437     BlockStatementStatements,
2438     BlockStatementAddStatement,
2439 
2440     IsCallExpression,
2441     CreateCallExpression,
2442     CallExpressionCallee,
2443     CallExpressionTypeArguments,
2444     CallExpressionArguments,
2445     CallExpressionIsOptional,
2446     CallExpressionSetTypeArguments,
2447 
2448     IsChainExpression,
2449     CreateChainExpression,
2450     ChainExpressionChild,
2451 
2452     IsClassDeclaration,
2453     CreateClassDeclaration,
2454     ClassDeclarationDefinition,
2455 
2456     IsClassDefinition,
2457     CreateClassDefinition,
2458     ClassDefinitionIdentifier,
2459     ClassDefinitionTypeParameters,
2460     ClassDefinitionSuperClass,
2461     ClassDefinitionImplements,
2462     ClassDefinitionConstructor,
2463     ClassDefinitionBody,
2464     ClassDefinitionSetIdentifier,
2465     ClassDefinitionSetTypeParameters,
2466     ClassDefinitionSetSuperClass,
2467     ClassDefinitionSetImplements,
2468     ClassDefinitionAddImplements,
2469     ClassDefinitionSetConstructor,
2470     ClassDefinitionSetBody,
2471     ClassDefinitionAddToBody,
2472 
2473     ClassElementKey,
2474     ClassElementValue,
2475 
2476     IsClassImplementsClause,
2477     CreateClassImplementsClause,
2478     ClassImplementsClauseExpression,
2479     ClassImplementsClauseTypeArguments,
2480 
2481     IsClassProperty,
2482     CreateClassProperty,
2483     ClassPropertyTypeAnnotation,
2484 
2485     IsExpressionStatement,
2486     CreateExpressionStatement,
2487     ExpressionStatementExpression,
2488 
2489     IsFunctionDeclaration,
2490     CreateFunctionDeclaration,
2491     FunctionDeclarationFunction,
2492 
2493     IsFunctionExpression,
2494     CreateFunctionExpression,
2495     FunctionExpressionFunction,
2496 
2497     IsFunctionTypeNode,
2498     CreateFunctionTypeNode,
2499     FunctionTypeNodeTypeParams,
2500     FunctionTypeNodeParams,
2501     FunctionTypeNodeReturnType,
2502     FunctionTypeNodeFlags,
2503 
2504     IsIdentifier,
2505     CreateIdentifier,
2506     IdentifierName,
2507     IdentifierTypeAnnotation,
2508     IdentifierVariable,
2509     IdentifierSetVariable,
2510 
2511     IsIfStatement,
2512     CreateIfStatement,
2513     IfStatementTest,
2514     IfStatementConsequent,
2515     IfStatementAlternate,
2516 
2517     IsImportDeclaration,
2518     CreateImportDeclaration,
2519     ImportDeclarationSource,
2520     ImportDeclarationSpecifiers,
2521 
2522     IsImportExpression,
2523     CreateImportExpression,
2524     ImportExpressionSource,
2525 
2526     IsImportSpecifier,
2527     CreateImportSpecifier,
2528     ImportSpecifierImported,
2529     ImportSpecifierLocal,
2530 
2531     IsMemberExpression,
2532     CreateMemberExpression,
2533     MemberExpressionObject,
2534     MemberExpressionProperty,
2535     MemberExpressionKind,
2536     MemberExpressionIsComputed,
2537     MemberExpressionIsOptional,
2538 
2539     IsMethodDefinition,
2540     CreateMethodDefinition,
2541     MethodDefinitionKind,
2542     MethodDefinitionKey,
2543     MethodDefinitionValue,
2544     MethodDefinitionModifiers,
2545     MethodDefinitionIsComputed,
2546     MethodDefinitionOverloads,
2547     MethodDefinitionSetOverloads,
2548     MethodDefinitionAddOverload,
2549 
2550     IsNewClassInstanceExpression,
2551     CreateNewClassInstanceExpression,
2552     NewClassInstanceExpressionTypeReference,
2553     NewClassInstanceExpressionArguments,
2554     NewClassInstanceExpressionClassDefinition,
2555 
2556     IsNewArrayInstanceExpression,
2557     CreateNewArrayInstanceExpression,
2558     NewArrayInstanceExpressionTypeReference,
2559     NewArrayInstanceExpressionDimension,
2560 
2561     IsNewMultiDimArrayInstanceExpression,
2562     CreateNewMultiDimArrayInstanceExpression,
2563     NewMultiDimArrayInstanceExpressionTypeReference,
2564     NewMultiDimArrayInstanceExpressionDimensions,
2565 
2566     IsNonNullExpression,
2567     IsNumberLiteral,
2568     IsObjectExpression,
2569 
2570     IsParameterDeclaration,
2571     CreateParameterDeclaration,
2572     ParameterDeclarationIdentifierOrSpread,
2573     ParameterDeclarationInitializer,
2574 
2575     IsPrimitiveTypeNode,
2576     CreatePrimitiveTypeNode,
2577     PrimitiveTypeNodeType,
2578 
2579     IsReturnStatement,
2580     CreateReturnStatement,
2581     ReturnStatementArgument,
2582     ReturnStatementReturnType,
2583 
2584     IsScriptFunction,
2585     CreateScriptFunction,
2586     ScriptFunctionTypeParams,
2587     ScriptFunctionParams,
2588     ScriptFunctionReturnTypeAnnotation,
2589     ScriptFunctionScriptFunctionFlags,
2590     ScriptFunctionIsDeclare,
2591     ScriptFunctionIdentifier,
2592     ScriptFunctionBody,
2593     ScriptFunctionSetIdentifier,
2594     ScriptFunctionSetBody,
2595     ScriptFunctionSetParams,
2596     ScripFunctionAddParam,
2597 
2598     IsStringLiteral,
2599     CreateStringLiteral,
2600     StringLiteralString,
2601 
2602     IsThisExpression,
2603     CreateThisExpression,
2604 
2605     IsTypeParameter,
2606     CreateTypeParameter,
2607     TypeParameterName,
2608     TypeParameterConstraint,
2609     TypeParameterDefaultType,
2610 
2611     IsTypeParameterDeclaration,
2612     CreateTypeParameterDeclaration,
2613     TypeParameterDeclarationAddTypeParameter,
2614     TypeParameterDeclarationTypeParameters,
2615 
2616     IsTypeParameterInstantiation,
2617     CreateTypeParameterInstantiation,
2618     TypeParameterInstantiationTypeParameters,
2619 
2620     IsTypeReferenceNode,
2621     CreateTypeReferenceNode,
2622     TypeReferenceNodePart,
2623 
2624     IsTypeReferencePart,
2625     CreateTypeReferencePart,
2626     TypeReferencePartName,
2627     TypeReferencePartTypeArguments,
2628     TypeReferencePartPrevious,
2629 
2630     IsUnionTypeNode,
2631     CreateUnionTypeNode,
2632     UnionTypeNodeTypes,
2633 
2634     IsVariableDeclaration,
2635     CreateVariableDeclaration,
2636     VariableDeclarationKind,
2637     VariableDeclarationDeclarators,
2638     VariableDeclarationIsDeclare,
2639 
2640     IsVariableDeclarator,
2641     CreateVariableDeclarator,
2642     VariableDeclaratorIdentifier,
2643     VariableDeclaratorInitializer,
2644 };
2645 
2646 }  // namespace ark::es2panda::public_lib
2647 
es2panda_GetImpl(int version)2648 extern "C" es2panda_Impl const *es2panda_GetImpl(int version)
2649 {
2650     if (version != ES2PANDA_LIB_VERSION) {
2651         return nullptr;
2652     }
2653     return &ark::es2panda::public_lib::g_impl;
2654 }
2655