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