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