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, ®Spiller, 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 ¶ms = 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 ¶ms = 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 ¶ms = 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 ¶ms = 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