diff --git a/arkoala-arkts/libarkts/.gitignore b/arkoala-arkts/libarkts/.gitignore index a54cdb4b371e117cc69c209347c065dbaa404be3..d37d63bfd0ca9c4d474a0a923b34459b7db19ae7 100644 --- a/arkoala-arkts/libarkts/.gitignore +++ b/arkoala-arkts/libarkts/.gitignore @@ -3,3 +3,6 @@ build* native/build-* native/*.ini lib +!test/es2panda/* +!test/golden/* +!compatible/src/* diff --git a/arkoala-arkts/libarkts/arktsconfig.json b/arkoala-arkts/libarkts/arktsconfig.json index 8152e95b04850448ff47147c42f25fa72916a88e..356d756bc48383f2f7ab0c929806a1f0ef2e67bb 100644 --- a/arkoala-arkts/libarkts/arktsconfig.json +++ b/arkoala-arkts/libarkts/arktsconfig.json @@ -1,12 +1,12 @@ { "compilerOptions": { - "baseUrl": "node_modules/@panda/sdk", + "baseUrl": "../../../arkts/arkcompiler/runtime_core/static_core", "paths": { "std": [ - "./ets/stdlib/std" + "plugins/ets/stdlib/std" ], "escompat": [ - "./ets/stdlib/escompat" + "plugins/ets/stdlib/escompat" ] }, "plugins": [ @@ -15,4 +15,4 @@ } ] } -} \ No newline at end of file +} diff --git a/arkoala-arkts/libarkts/compatible/src/AbstractVisitor.ts b/arkoala-arkts/libarkts/compatible/src/AbstractVisitor.ts new file mode 100644 index 0000000000000000000000000000000000000000..be5bae472faa5567f2b087b306ef4fb204617cda --- /dev/null +++ b/arkoala-arkts/libarkts/compatible/src/AbstractVisitor.ts @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2022-2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import * as api from "api" + +export abstract class AbstractVisitor { + constructor( + // public ctx: api.TransformationContext + ) {} + + indentation = 0 + + withIndentation(exec: () => T) { + this.indentation++ + const result = exec() + this.indentation-- + return result + } + + abstract visitor(node: api.Node): api.Node + + visitEachChild(node: T): T { + return this.withIndentation(() => + api.visitEachChild( + node, + it => this.visitor(it), + // this.ctx + ) + ) + } +} + diff --git a/arkoala-arkts/libarkts/compatible/src/builder-lambda-transformer.ts b/arkoala-arkts/libarkts/compatible/src/builder-lambda-transformer.ts new file mode 100644 index 0000000000000000000000000000000000000000..9816d1b27353ada73420cc1738f7dfcda5e9497d --- /dev/null +++ b/arkoala-arkts/libarkts/compatible/src/builder-lambda-transformer.ts @@ -0,0 +1,128 @@ +/* + * Copyright (c) 2022-2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import * as api from "api" +import { AbstractVisitor } from "./AbstractVisitor"; + +export class BuilderLambdaTransformer extends AbstractVisitor { + constructor( + // public tracer: Tracer, + // public sourceFile: api.SourceFile, + // public functionTable: FunctionTable, + // ctx: api.TransformationContext + ) { + // super(ctx) + super() + } + + private static readonly builderLambdaPrefix = "_BuilderLambdaCall_" + private static readonly builderLambdaInstanceName = "instance" + + private isBuilderLambdaCall(node: api.CallExpression): boolean { + if (!api.isIdentifier(node.expression)) { + return false + } + return node.expression.text.startsWith(BuilderLambdaTransformer.builderLambdaPrefix) + } + + visitor(beforeChildren: api.Node): api.Node { + const node = this.visitEachChild(beforeChildren) + + if (!api.isCallExpression(node)) { + return node + } + + if (true + && api.isPropertyAccessExpression(node.parent) + && api.isIdentifier(node.parent.name) + && api.isCallExpression(node.parent.parent) + ) { + return node + } + + let instanceCalls = [] + let node1 = node + while (true + && api.isPropertyAccessExpression(node1.expression) + && api.isIdentifier(node1.expression.name) + && api.isCallExpression(node1.expression.expression) + ) { + instanceCalls.push( + api.createCallExpression( + node1.expression.name, + undefined, + node1.arguments + ) + ) + node1 = node1.expression.expression + } + + if (!this.isBuilderLambdaCall(node1)) { + return node + } + + instanceCalls = instanceCalls.reverse() + let instanceLambdaBodyStatement: api.Identifier | api.CallExpression = api.createIdentifier(BuilderLambdaTransformer.builderLambdaInstanceName) + instanceCalls.forEach(function (call: api.CallExpression) { + instanceLambdaBodyStatement = api.createCallExpression( + api.createPropertyAccessExpression( + instanceLambdaBodyStatement, + call.expression as api.Identifier + ), + undefined, + call.arguments + ) + }) + const instanceLambdaBody = api.createBlock([ + api.createExpressionStatement( + instanceLambdaBodyStatement + ) + ]) + const instanceLambdaParams = [ + api.createParameterDeclaration( + undefined, + undefined, + api.createIdentifier( + BuilderLambdaTransformer.builderLambdaInstanceName, + api.createKeywordTypeNode(api.SyntaxKind.AnyKeyword) + ) + ) + ] + const lambdaArg = api.createArrowFunction( + undefined, + undefined, + instanceLambdaParams, + undefined, + undefined, + instanceLambdaBody + ) + + let funcName = (node1.expression as api.Identifier).text + funcName = funcName.slice(BuilderLambdaTransformer.builderLambdaPrefix.length) + + // maybe update ? + const result = api.createCallExpression( + // maybe update? + api.createIdentifier(funcName), + undefined, + [ + lambdaArg, + ...node1.arguments + ] + ) + + return result + } +} diff --git a/arkoala-arkts/libarkts/compatible/src/example-transformer.ts b/arkoala-arkts/libarkts/compatible/src/example-transformer.ts index a933bffa0fccac3acf224491d5fe26e0e278e7a8..11aaa6bdd00b0747ca820e209ca7ed81e9093e3b 100644 --- a/arkoala-arkts/libarkts/compatible/src/example-transformer.ts +++ b/arkoala-arkts/libarkts/compatible/src/example-transformer.ts @@ -1,5 +1,6 @@ import * as api from "api" import { PrintVisitor } from "./print-visitor" +import { BuilderLambdaTransformer } from "./builder-lambda-transformer" export interface TransformerOptions { trace?: boolean, @@ -8,8 +9,7 @@ export interface TransformerOptions { export default function exampleTransformer(program: api.Program, userPluginOptions: TransformerOptions) { return (ctx: api.TransformationContext) => { return (node: api.SourceFile) => { - console.log(new PrintVisitor().astToString(node)) - return node + return new BuilderLambdaTransformer().visitor(node) } } } diff --git a/arkoala-arkts/libarkts/input/main.sts b/arkoala-arkts/libarkts/input/main.sts new file mode 100644 index 0000000000000000000000000000000000000000..2fa90fb45d27a9e16b26dab1977d54feae941bb6 --- /dev/null +++ b/arkoala-arkts/libarkts/input/main.sts @@ -0,0 +1 @@ +Foo("label") diff --git a/arkoala-arkts/libarkts/input/main.ts b/arkoala-arkts/libarkts/input/main.ts deleted file mode 100644 index e9c6decc7ff6a423d61ee57605118664f8d77e14..0000000000000000000000000000000000000000 --- a/arkoala-arkts/libarkts/input/main.ts +++ /dev/null @@ -1,6 +0,0 @@ -class A { - private foo() {} - goo() {} - - a: number = 1 -} diff --git a/arkoala-arkts/libarkts/native/meson.build b/arkoala-arkts/libarkts/native/meson.build index 4be47c81ce5afa3d1bce842ad3e0eaf1ab0acac2..67ba731539b1eebfc71a10a4578d955e92f246a1 100644 --- a/arkoala-arkts/libarkts/native/meson.build +++ b/arkoala-arkts/libarkts/native/meson.build @@ -3,18 +3,13 @@ project('Es2panda interop', 'cpp', default_options: ['cpp_std=c++17', 'buildtype=debug'], ) -is_dummy = get_option('dummy') source_dir = meson.current_source_dir() interop_src = '../../../interop/src/cpp' es2panda_header = '../../../incremental/tools/panda/node_modules/@panda/sdk/ohos_arm64/include/tools/es2panda/public' es2panda_gen = '../../../incremental/tools/panda/node_modules/@panda/sdk/ohos_arm64/include/tools/es2panda/' is_msvc = meson.get_compiler('cpp').get_id() == 'msvc' -if is_dummy - implementation = './src/dummy_lib.cc' -else - implementation = './src/es2panda_lib.cc' -endif +implementation = './src/es2panda_lib.cc' os = target_machine.system() diff --git a/arkoala-arkts/libarkts/native/meson_options.txt b/arkoala-arkts/libarkts/native/meson_options.txt index 51966ed59cb036ff8d96159c7751c0f16a71331c..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 100644 --- a/arkoala-arkts/libarkts/native/meson_options.txt +++ b/arkoala-arkts/libarkts/native/meson_options.txt @@ -1,2 +0,0 @@ -option('dummy', type : 'boolean', value : 'false', - description : 'implementation') diff --git a/arkoala-arkts/libarkts/native/src/dummy_lib.cc b/arkoala-arkts/libarkts/native/src/dummy_lib.cc deleted file mode 100644 index f778c2a022c3cf923a91b7cc4fe743da1f3a4e00..0000000000000000000000000000000000000000 --- a/arkoala-arkts/libarkts/native/src/dummy_lib.cc +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Copyright (c) 2022-2023 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#include -#include -#include "es2panda_lib.h" -#include "common-interop.h" -#include "node.h" - -using std::string; - -KNativePointer impl_CreateConfig(KInt argc, KStringArray argv) { - return nullptr; -} -KOALA_INTEROP_2(CreateConfig, KNativePointer, KInt, KStringArray) - -KNativePointer impl_CreateContextFromString(KNativePointer config, KStringPtr sourcePtr, KStringPtr filenamePtr) { - return nullptr; -} -KOALA_INTEROP_3(CreateContextFromString, KNativePointer, KNativePointer, KStringPtr, KStringPtr) - -KNativePointer impl_ProceedToState(KNativePointer context, KInt state) { - return nullptr; -} -KOALA_INTEROP_2(ProceedToState, KNativePointer, KNativePointer, KInt) - -KNativePointer impl_ContextProgram(KNativePointer context) { - return nullptr; -} -KOALA_INTEROP_1(ContextProgram, KNativePointer, KNativePointer) - -KNativePointer impl_ProgramAst(KNativePointer program) { - return new SourceFile({ - new FunctionDeclaration( - new Identifier("main"), - new Block({ - new ExpressionStatement( - new CallExpression( - new PropertyAccessExpression( - new Identifier("console"), - new Identifier("log") - ), - { - new StringLiteral("hello") - } - ) - ) - }) - ) - }); -} -KOALA_INTEROP_1(ProgramAst, KNativePointer, KNativePointer) - -KNativePointer impl_SourceFileGetChildren(KNativePointer sourceFilePtr) { - auto sourceFile = reinterpret_cast(sourceFilePtr); - return &sourceFile->children; -} -KOALA_INTEROP_1(SourceFileGetChildren, KNativePointer, KNativePointer) - -KNativePointer impl_BlockStatementStatements(KNativePointer blockPtr) { - auto sourceFile = reinterpret_cast(blockPtr); - return &sourceFile->statements; -} -KOALA_INTEROP_1(BlockStatementStatements, KNativePointer, KNativePointer) - -KNativePointer impl_FunctionDeclarationGetIdentifier(KNativePointer functionDeclarationPtr) { - auto functionDeclaration = reinterpret_cast(functionDeclarationPtr); - return functionDeclaration->identifier; -} -KOALA_INTEROP_1(FunctionDeclarationGetIdentifier, KNativePointer, KNativePointer); - -KNativePointer impl_FunctionDeclarationGetBlock(KNativePointer functionDeclarationPtr) { - auto functionDeclaration = reinterpret_cast(functionDeclarationPtr); - return functionDeclaration->block; -} -KOALA_INTEROP_1(FunctionDeclarationGetBlock, KNativePointer, KNativePointer); - -KNativePointer impl_ExpressionStatementGetCallExpression(KNativePointer expressionStatementPtr) { - auto expressionStatement = reinterpret_cast(expressionStatementPtr); - return expressionStatement->call; -} -KOALA_INTEROP_1(ExpressionStatementGetCallExpression, KNativePointer, KNativePointer); - -KNativePointer impl_CallExpressionGetPropertyAccessExpression(KNativePointer callExpressionPtr) { - auto call = reinterpret_cast(callExpressionPtr); - return call->propertyAccessExpression; -} -KOALA_INTEROP_1(CallExpressionGetPropertyAccessExpression, KNativePointer, KNativePointer); - -KNativePointer impl_CallExpressionGetArguments(KNativePointer callExpressionPtr) { - auto call = reinterpret_cast(callExpressionPtr); - return &call->arguments; -} -KOALA_INTEROP_1(CallExpressionGetArguments, KNativePointer, KNativePointer); - -KNativePointer impl_PropertyAccessExpressionGetExpression(KNativePointer propertyAccessExpressionPtr) { - auto propertyAccessExpression = reinterpret_cast(propertyAccessExpressionPtr); - return propertyAccessExpression->expression; -} -KOALA_INTEROP_1(PropertyAccessExpressionGetExpression, KNativePointer, KNativePointer); - -KNativePointer impl_PropertyAccessExpressionGetName(KNativePointer propertyAccessExpressionPtr) { - auto propertyAccessExpression = reinterpret_cast(propertyAccessExpressionPtr); - return propertyAccessExpression->name; -} -KOALA_INTEROP_1(PropertyAccessExpressionGetName, KNativePointer, KNativePointer); - -KInt impl_GetKind(KNativePointer nodePtr) { - auto node = reinterpret_cast(nodePtr); - return node->kind(); -} -KOALA_INTEROP_1(GetKind, KInt, KNativePointer) - -KNativePointer impl_IdentifierName(KNativePointer contextPtr, KNativePointer identifierPtr) { - auto identifier = reinterpret_cast(identifierPtr); - return new string(identifier->name); -} -KOALA_INTEROP_2(IdentifierName, KNativePointer, KNativePointer, KNativePointer) - -KNativePointer impl_StringLiteralString(KNativePointer contextPtr, KNativePointer stringLiteralPtr) { - auto stringLiteral = reinterpret_cast(stringLiteralPtr); - return new string(stringLiteral->text); -} -KOALA_INTEROP_2(StringLiteralString, KNativePointer, KNativePointer, KNativePointer) diff --git a/arkoala-arkts/libarkts/native/src/es2panda_lib.cc b/arkoala-arkts/libarkts/native/src/es2panda_lib.cc index 9d7d8defd5cfdbf0d7a7d7fc89bf69493191b522..b5b4194c4513774f9cf6ff86a22bfbff1c1397c9 100644 --- a/arkoala-arkts/libarkts/native/src/es2panda_lib.cc +++ b/arkoala-arkts/libarkts/native/src/es2panda_lib.cc @@ -58,7 +58,7 @@ es2panda_Impl *GetImpl() { return impl; } -es2panda_ContextState intToState(int state) { +es2panda_ContextState intToState(KInt state) { return es2panda_ContextState(state); } @@ -67,7 +67,6 @@ string getString(KStringPtr ptr) { } char* getStringCopy(KStringPtr ptr) { - // TODO: fix memory leak here return strdup(ptr.c_str()); } @@ -75,20 +74,19 @@ inline KUInt unpackUInt(const KByte* bytes) { return (bytes[0] | (bytes[1] << 8) | (bytes[2] << 16) | (bytes[3] << 24)); } -KNativePointer impl_CreateConfig(KInt argc, KStringArray argv) { - std::vector res(argc); - size_t offset = sizeof(KUInt); - const char** args = new const char*[argc]; - for (KInt i = 0; i < argc; ++i) { - auto s = argv + offset; - auto* str = reinterpret_cast(&s[sizeof(KUInt)]); - res[i] = std::string(str, unpackUInt(s)); - offset += res[i].size() + sizeof(KUInt); - args[i] = res[i].c_str(); +KNativePointer impl_CreateConfig(KInt argc, KStringArray argvPtr) { + const std::size_t HEADER_LEN = 4; + + const char** argv = new const char*[argc]; + std::size_t position = HEADER_LEN; + std::size_t str_len; + for (std::size_t i = 0; i < argc; ++i) { + str_len = unpackUInt(argvPtr + position); + position += HEADER_LEN; + argv[i] = strdup(std::string(reinterpret_cast(argvPtr + position), str_len).c_str()); + position += str_len; } - auto result = GetImpl()->CreateConfig(argc, args); - delete [] args; - return result; + return GetImpl()->CreateConfig(argc, argv); } KOALA_INTEROP_2(CreateConfig, KNativePointer, KInt, KStringArray) @@ -144,11 +142,11 @@ KNativePointer impl_CreateIdentifier2(KNativePointer contextPtr, KStringPtr name } KOALA_INTEROP_3(CreateIdentifier2, KNativePointer, KNativePointer, KStringPtr, KNativePointer) -KNativePointer impl_CreateETSPrimitiveType0(KNativePointer contextPtr, KInt type) { +KNativePointer impl_CreateETSPrimitiveType(KNativePointer contextPtr, KInt type) { auto context = reinterpret_cast(contextPtr); - return GetImpl()->CreateETSPrimitiveType0(context, static_cast(type)); + return GetImpl()->CreateETSPrimitiveType(context, static_cast(type)); } -KOALA_INTEROP_2(CreateETSPrimitiveType0, KNativePointer, KNativePointer, KInt) +KOALA_INTEROP_2(CreateETSPrimitiveType, KNativePointer, KNativePointer, KInt) KNativePointer impl_CreateStringLiteral(KNativePointer contextPtr, KStringPtr stringPtr) { auto context = reinterpret_cast(contextPtr); @@ -182,6 +180,10 @@ enum AstNodeKind { FunctionDeclaration = 6, ClassProperty = 7, TSTypeParameterDeclaration = 8, + ETSFunctionType = 9, + CallExpression = 10, + ExpressionStatement = 11, + MemberExpression = 12, }; KInt impl_GetKind(KNativePointer nodePtr) { @@ -208,9 +210,21 @@ KInt impl_GetKind(KNativePointer nodePtr) { if (GetImpl()->IsClassProperty(node)) { return AstNodeKind::ClassProperty; } - if (GetImpl()->IsTSTypeParameterDeclaration) { + if (GetImpl()->IsTSTypeParameterDeclaration(node)) { return AstNodeKind::TSTypeParameterDeclaration; } + if (GetImpl()->IsETSFunctionType(node)) { + return AstNodeKind::ETSFunctionType; + } + if (GetImpl()->IsCallExpression(node)) { + return AstNodeKind::CallExpression; + } + if (GetImpl()->IsExpressionStatement(node)) { + return AstNodeKind::ExpressionStatement; + } + if (GetImpl()->IsMemberExpression(node)) { + return AstNodeKind::MemberExpression; + } return -1; } @@ -277,83 +291,413 @@ KNativePointer impl_ScriptFunctionId(KNativePointer contextPtr, KNativePointer n } KOALA_INTEROP_2(ScriptFunctionId, KNativePointer, KNativePointer, KNativePointer) -// TODO: support body and return type -KNativePointer impl_CreateFunctionDeclaration(KNativePointer contextPtr, KStringPtr namePtr, KNativePointerArray paramsPtr, KInt paramsLen) { +KNativePointer impl_CreateFunctionDeclaration(KNativePointer contextPtr, KNativePointer funcPtr, KBoolean isAnonK) { auto context = reinterpret_cast(contextPtr); - auto name = getStringCopy(namePtr); - auto parameters = reinterpret_cast(paramsPtr); - - es2panda_AstNode* firstStatement = nullptr; - es2panda_AstNode* firstParam = nullptr; - auto function_body = GetImpl()->CreateBlockStatement0(context, &firstStatement, 0); + auto func = reinterpret_cast(funcPtr); + auto isAnon = static_cast(isAnonK); - auto return_type = nullptr; - - auto function_signature = GetImpl()->CreateFunctionSignature0(context, nullptr, parameters, paramsLen, return_type); - - auto script_function = GetImpl()->CreateScriptFunction0(context, function_body, function_signature, SCRIPT_FUNCTION_FLAGS_NONE, MODIFIER_FLAGS_NONE, false); - - GetImpl()->AstNodeSetParent(context, function_body, script_function); - - es2panda_AstNode* ident = GetImpl()->CreateIdentifier1(context, name); - GetImpl()->ScriptFunctionSetIdent(context, script_function, ident); - - return GetImpl()->CreateFunctionDeclaration0(context, script_function, false); + return GetImpl()->CreateFunctionDeclaration(context, func, isAnon); } -KOALA_INTEROP_4(CreateFunctionDeclaration, KNativePointer, KNativePointer, KStringPtr, KNativePointerArray, KInt) +KOALA_INTEROP_3(CreateFunctionDeclaration, KNativePointer, KNativePointer, KNativePointer, KBoolean) -// TODO: support body and return type KNativePointer impl_UpdateFunctionDeclaration( KNativePointer contextPtr, KNativePointer nodePtr, - KStringPtr namePtr, - KNativePointerArray paramsPtr, - KInt paramsLen + KNativePointer funcPtr, + KBoolean isAnonK ) { auto context = reinterpret_cast(contextPtr); - auto name = getStringCopy(namePtr); - auto func_decl_node = reinterpret_cast(nodePtr); - auto script_func_node = GetImpl()->FunctionDeclarationFunction(context, func_decl_node); - auto parameters = reinterpret_cast(paramsPtr); - auto old_signature = GetImpl()->ScriptFunctionIrSignature(context, script_func_node); - auto new_signature = GetImpl()->CreateFunctionSignature0( - context, - GetImpl()->FunctionSignatureTypeParams(context, old_signature), - parameters, - paramsLen, - GetImpl()->FunctionSignatureReturnType(context, old_signature) - ); - GetImpl()->ScriptFunctionUpdateIrSignature(context, script_func_node, new_signature); - - es2panda_AstNode* ident = GetImpl()->CreateIdentifier1(context, name); - GetImpl()->ScriptFunctionSetIdent(context, script_func_node, ident); - return func_decl_node; -} -KOALA_INTEROP_5(UpdateFunctionDeclaration, KNativePointer, KNativePointer, KNativePointer, KStringPtr, KNativePointerArray, KInt) + auto node = reinterpret_cast(nodePtr); + auto func = reinterpret_cast(funcPtr); + auto isAnon = static_cast(isAnonK); + + return GetImpl()->UpdateFunctionDeclaration(context, node, func, isAnon); +} +KOALA_INTEROP_4(UpdateFunctionDeclaration, KNativePointer, KNativePointer, KNativePointer, KNativePointer, KBoolean) // TODO: add param initializer KNativePointer impl_CreateETSParameterExpression(KNativePointer contextPtr, KNativePointer identifierPtr) { auto context = reinterpret_cast(contextPtr); auto identifier = reinterpret_cast(identifierPtr); - return GetImpl()->CreateETSParameterExpression0(context, identifier, nullptr); + return GetImpl()->CreateETSParameterExpression(context, identifier, nullptr); } KOALA_INTEROP_2(CreateETSParameterExpression, KNativePointer, KNativePointer, KNativePointer) -KNativePointer impl_CreateETSTypeReference0(KNativePointer contextPtr, KNativePointer partPtr) { +KNativePointer impl_CreateETSTypeReference(KNativePointer contextPtr, KNativePointer partPtr) { auto context = reinterpret_cast(contextPtr); auto part = reinterpret_cast(partPtr); - return GetImpl()->CreateETSTypeReference0(context, part); + return GetImpl()->CreateETSTypeReference(context, part); } -KOALA_INTEROP_2(CreateETSTypeReference0, KNativePointer, KNativePointer, KNativePointer) +KOALA_INTEROP_2(CreateETSTypeReference, KNativePointer, KNativePointer, KNativePointer) -KNativePointer impl_CreateETSTypeReferencePart0(KNativePointer contextPtr, KNativePointer namePtr, KNativePointer typeParamsPtr, KNativePointer prevPtr) { +KNativePointer impl_CreateETSTypeReferencePart(KNativePointer contextPtr, KNativePointer namePtr, KNativePointer typeParamsPtr, KNativePointer prevPtr) { auto context = reinterpret_cast(contextPtr); auto name = reinterpret_cast(namePtr); auto typeParams = reinterpret_cast(typeParamsPtr); auto prev = reinterpret_cast(prevPtr); - return GetImpl()->CreateETSTypeReferencePart0(context, name, typeParams, prev); + return GetImpl()->CreateETSTypeReferencePart(context, name, typeParams, prev); +} +KOALA_INTEROP_4(CreateETSTypeReferencePart, KNativePointer, KNativePointer, KNativePointer, KNativePointer, KNativePointer) + +KNativePointer impl_UpdateBlockStatement(KNativePointer contextPtr, KNativePointer originalPtr, KNativePointerArray statementListPtr, KInt statementListLen) { + auto context = reinterpret_cast(contextPtr); + auto statementList = reinterpret_cast(statementListPtr); + auto original = reinterpret_cast(originalPtr); + + // tmp solution while waiting fix for UpdateBlockStatement + GetImpl()->BlockStatementSetStatements(context, original, statementList, static_cast(statementListLen)); + return original; +} +KOALA_INTEROP_4(UpdateBlockStatement, KNativePointer, KNativePointer, KNativePointer, KNativePointerArray, KInt) + +KNativePointer impl_CreateReturnStatement1(KNativePointer contextPtr, KNativePointer argumentPtr) { + auto context = reinterpret_cast(contextPtr); + auto argument = reinterpret_cast(argumentPtr); + + return GetImpl()->CreateReturnStatement1(context, argument); +} +KOALA_INTEROP_2(CreateReturnStatement1, KNativePointer, KNativePointer, KNativePointer) + +KNativePointer impl_ReturnStatementArgument(KNativePointer contextPtr, KNativePointer nodePtr) { + auto context = reinterpret_cast(contextPtr); + auto node = reinterpret_cast(nodePtr); + + return GetImpl()->ReturnStatementArgument(context, node); +} +KOALA_INTEROP_2(ReturnStatementArgument, KNativePointer, KNativePointer, KNativePointer) + +KNativePointer impl_CreateIfStatement(KNativePointer contextPtr, KNativePointer testPtr, KNativePointer consequentPtr, KNativePointer alternatePtr) { + auto context = reinterpret_cast(contextPtr); + auto test = reinterpret_cast(testPtr); + auto consequent = reinterpret_cast(consequentPtr); + auto alternate = reinterpret_cast(alternatePtr); + + return GetImpl()->CreateIfStatement(context, test, consequent, alternate); +} +KOALA_INTEROP_4(CreateIfStatement, KNativePointer, KNativePointer, KNativePointer, KNativePointer, KNativePointer) + +KNativePointer impl_CreateMemberExpression( + KNativePointer contextPtr, + KNativePointer objectPtr, + KNativePointer propertyPtr, + KInt kindT, + KBoolean computedT, + KBoolean optionalT +) { + auto context = reinterpret_cast(contextPtr); + auto object = reinterpret_cast(objectPtr); + auto property = reinterpret_cast(propertyPtr); + auto computed = static_cast(computedT); + auto optional = static_cast(optionalT); + auto kind = static_cast(kindT); + + return GetImpl()->CreateMemberExpression(context, object, property, kind, computed, optional); +} +KOALA_INTEROP_6(CreateMemberExpression, KNativePointer, KNativePointer, KNativePointer, KNativePointer, KInt, KBoolean, KBoolean) + +KNativePointer impl_UpdateMemberExpression( + KNativePointer contextPtr, + KNativePointer nodePtr, + KNativePointer objectPtr, + KNativePointer propertyPtr, + KInt kindT, + KBoolean computedT, + KBoolean optionalT +) { + auto context = reinterpret_cast(contextPtr); + auto node = reinterpret_cast(nodePtr); + auto object = reinterpret_cast(objectPtr); + auto property = reinterpret_cast(propertyPtr); + auto computed = static_cast(computedT); + auto optional = static_cast(optionalT); + auto kind = static_cast(kindT); + + return GetImpl()->UpdateMemberExpression(context, node, object, property, kind, computed, optional); +} +KOALA_INTEROP_7(UpdateMemberExpression, KNativePointer, KNativePointer, KNativePointer, KNativePointer, KNativePointer, KInt, KBoolean, KBoolean) + +KNativePointer impl_MemberExpressionObject( + KNativePointer contextPtr, + KNativePointer nodePtr +) { + auto context = reinterpret_cast(contextPtr); + auto node = reinterpret_cast(nodePtr); + + return GetImpl()->MemberExpressionObject(context, node); +} +KOALA_INTEROP_2(MemberExpressionObject, KNativePointer, KNativePointer, KNativePointer) + +KNativePointer impl_MemberExpressionProperty( + KNativePointer contextPtr, + KNativePointer nodePtr +) { + auto context = reinterpret_cast(contextPtr); + auto node = reinterpret_cast(nodePtr); + + return GetImpl()->MemberExpressionProperty(context, node); +} +KOALA_INTEROP_2(MemberExpressionProperty, KNativePointer, KNativePointer, KNativePointer) + +KNativePointer impl_CreateCallExpression( + KNativePointer contextPtr, + KNativePointer calleePtr, + KNativePointerArray argumentsPtr, + KInt argumentsLen, + KNativePointer typeParamsPtr, + KBoolean optionalT, + KBoolean trailingCommaT +) { + auto context = reinterpret_cast(contextPtr); + auto callee = reinterpret_cast(calleePtr); + auto arguments = reinterpret_cast(argumentsPtr); + auto typeParams = reinterpret_cast(typeParamsPtr); + auto optional = static_cast(optionalT); + auto trailingComma = static_cast(trailingCommaT); + + return GetImpl()->CreateCallExpression(context, callee, arguments, argumentsLen, typeParams, optional, trailingComma); +} +KOALA_INTEROP_7(CreateCallExpression, KNativePointer, KNativePointer, KNativePointer, KNativePointerArray, KInt, KNativePointer, KBoolean, KBoolean) + +KNativePointer impl_UpdateCallExpression( + KNativePointer contextPtr, + KNativePointer nodePtr, + KNativePointer calleePtr, + KNativePointerArray argumentsPtr, + KInt argumentsLen, + KNativePointer typeParamsPtr, + KBoolean optionalT, + KBoolean trailingCommaT +) { + auto node = reinterpret_cast(nodePtr); + auto context = reinterpret_cast(contextPtr); + auto callee = reinterpret_cast(calleePtr); + auto arguments = reinterpret_cast(argumentsPtr); + auto typeParams = reinterpret_cast(typeParamsPtr); + auto optional = static_cast(optionalT); + auto trailingComma = static_cast(trailingCommaT); + + return GetImpl()->UpdateCallExpression(context, node, callee, arguments, argumentsLen, typeParams, optional, trailingComma); +} +KOALA_INTEROP_8(UpdateCallExpression, KNativePointer, KNativePointer, KNativePointer, KNativePointer, KNativePointerArray, KInt, KNativePointer, KBoolean, KBoolean) + +KNativePointer impl_CreateExpressionStatement(KNativePointer contextPtr, KNativePointer exprPtr) { + auto context = reinterpret_cast(contextPtr); + auto expr = reinterpret_cast(exprPtr); + + return GetImpl()->CreateExpressionStatement(context, expr); +} +KOALA_INTEROP_2(CreateExpressionStatement, KNativePointer, KNativePointer, KNativePointer) + +KNativePointer impl_UpdateExpressionStatement(KNativePointer contextPtr, KNativePointer nodePtr, KNativePointer exprPtr) { + auto context = reinterpret_cast(contextPtr); + auto node = reinterpret_cast(nodePtr); + auto expr = reinterpret_cast(exprPtr); + + return GetImpl()->UpdateExpressionStatement(context, node, expr); +} +KOALA_INTEROP_3(UpdateExpressionStatement, KNativePointer, KNativePointer, KNativePointer, KNativePointer) + +KNativePointer impl_ScriptFunctionBody(KNativePointer contextPtr, KNativePointer nodePtr) { + auto context = reinterpret_cast(contextPtr); + auto node = reinterpret_cast(nodePtr); + + return GetImpl()->ScriptFunctionBody(context, node); +} +KOALA_INTEROP_2(ScriptFunctionBody, KNativePointer, KNativePointer, KNativePointer) + +KNativePointer impl_CreateBinaryExpression(KNativePointer contextPtr, KNativePointer leftPtr, KNativePointer rightPtr, KInt tokenKind) { + auto context = reinterpret_cast(contextPtr); + auto left = reinterpret_cast(leftPtr); + auto right = reinterpret_cast(rightPtr); + + return GetImpl()->CreateBinaryExpression(context, left, right, Es2pandaTokenType(tokenKind)); +} +KOALA_INTEROP_4(CreateBinaryExpression, KNativePointer, KNativePointer, KNativePointer, KNativePointer, KInt) + +KNativePointer impl_CreateFunctionSignature( + KNativePointer contextPtr, + KNativePointer typeParamsPtr, + KNativePointerArray paramsPtr, + KInt paramsLen, + KNativePointer returnTypeAnnotationPtr +) { + auto context = reinterpret_cast(contextPtr); + auto typeParams = reinterpret_cast(typeParamsPtr); + auto params = reinterpret_cast(paramsPtr); + auto returnTypeAnnotation = reinterpret_cast(returnTypeAnnotationPtr); + + return GetImpl()->CreateFunctionSignature(context, typeParams, params, paramsLen, returnTypeAnnotation); +} +KOALA_INTEROP_5(CreateFunctionSignature, KNativePointer, KNativePointer, KNativePointer, KNativePointerArray, KInt, KNativePointer) + +KNativePointer impl_CreateScriptFunction( + KNativePointer contextPtr, + KNativePointer databodyPtr, + KNativePointer datasignaturePtr, + KInt datafuncFlags, + KInt dataFlags, + KBoolean datadeclare +) { + auto context = reinterpret_cast(contextPtr); + auto databody = reinterpret_cast(databodyPtr); + auto datasignature = reinterpret_cast(datasignaturePtr); + + return GetImpl()->CreateScriptFunction(context, databody, datasignature, datafuncFlags, dataFlags, datadeclare); +} +KOALA_INTEROP_6(CreateScriptFunction, KNativePointer, KNativePointer, KNativePointer, KNativePointer, KInt, KInt, KBoolean) + +KNativePointer impl_UpdateScriptFunction( + KNativePointer contextPtr, + KNativePointer nodePtr, + KNativePointer databodyPtr, + KNativePointer datasignaturePtr, + KInt datafuncFlags, + KInt dataFlags, + KBoolean datadeclare +) { + auto context = reinterpret_cast(contextPtr); + auto node = reinterpret_cast(nodePtr); + auto databody = reinterpret_cast(databodyPtr); + auto datasignature = reinterpret_cast(datasignaturePtr); + + return GetImpl()->UpdateScriptFunction(context, node, databody, datasignature, datafuncFlags, dataFlags, datadeclare); +} +KOALA_INTEROP_7(UpdateScriptFunction, KNativePointer, KNativePointer, KNativePointer, KNativePointer, KNativePointer, KInt, KInt, KBoolean) + +KNativePointer impl_CreateBlockStatement( + KNativePointer contextPtr, + KNativePointerArray statementListPtr, + KInt statementListLen +) { + auto context = reinterpret_cast(contextPtr); + auto statementList = reinterpret_cast(statementListPtr); + + return GetImpl()->CreateBlockStatement(context, statementList, statementListLen); +} +KOALA_INTEROP_3(CreateBlockStatement, KNativePointer, KNativePointer, KNativePointerArray, KInt) + +KNativePointer impl_AstNodeSetParent( + KNativePointer contextPtr, + KNativePointer astPtr, + KNativePointer parentPtr +) { + auto context = reinterpret_cast(contextPtr); + auto ast = reinterpret_cast(astPtr); + auto parent = reinterpret_cast(parentPtr); + + GetImpl()->AstNodeSetParent(context, ast, parent); + return ast; +} +KOALA_INTEROP_3(AstNodeSetParent, KNativePointer, KNativePointer, KNativePointer, KNativePointer) + +KNativePointer impl_ScriptFunctionSetIdent( + KNativePointer contextPtr, + KNativePointer astPtr, + KNativePointer idPtr +) { + auto context = reinterpret_cast(contextPtr); + auto ast = reinterpret_cast(astPtr); + auto id = reinterpret_cast(idPtr); + + GetImpl()->ScriptFunctionSetIdent(context, ast, id); + return ast; +} +KOALA_INTEROP_3(ScriptFunctionSetIdent, KNativePointer, KNativePointer, KNativePointer, KNativePointer) + +KNativePointer impl_ScriptFunctionIrSignature(KNativePointer contextPtr, KNativePointer nodePtr) { + auto context = reinterpret_cast(contextPtr); + auto node = reinterpret_cast(nodePtr); + + return GetImpl()->ScriptFunctionIrSignature(context, node); +} +KOALA_INTEROP_2(ScriptFunctionIrSignature, KNativePointer, KNativePointer, KNativePointer) + +KNativePointer impl_FunctionSignatureTypeParams(KNativePointer contextPtr, KNativePointer nodePtr) { + auto context = reinterpret_cast(contextPtr); + auto node = reinterpret_cast(nodePtr); + + return GetImpl()->FunctionSignatureTypeParams(context, node); +} +KOALA_INTEROP_2(FunctionSignatureTypeParams, KNativePointer, KNativePointer, KNativePointer) + +KNativePointer impl_FunctionSignatureReturnType(KNativePointer contextPtr, KNativePointer nodePtr) { + auto context = reinterpret_cast(contextPtr); + auto node = reinterpret_cast(nodePtr); + + return GetImpl()->FunctionSignatureReturnType(context, node); +} +KOALA_INTEROP_2(FunctionSignatureReturnType, KNativePointer, KNativePointer, KNativePointer) + +KNativePointer impl_UpdateIdentifier1(KNativePointer contextPtr, KNativePointer nodePtr, KStringPtr namePtr) { + auto context = reinterpret_cast(contextPtr); + auto node = reinterpret_cast(nodePtr); + + return GetImpl()->UpdateIdentifier1(context, node, getStringCopy(namePtr)); +} +KOALA_INTEROP_3(UpdateIdentifier1, KNativePointer, KNativePointer, KNativePointer, KStringPtr) + +KNativePointer impl_ScriptFunctionUpdateIrSignature(KNativePointer contextPtr, KNativePointer nodePtr, KNativePointer signaturePtr) { + auto context = reinterpret_cast(contextPtr); + auto node = reinterpret_cast(nodePtr); + auto signature = reinterpret_cast(signaturePtr); + + return GetImpl()->ScriptFunctionUpdateIrSignature(context, node, signature); +} +KOALA_INTEROP_3(ScriptFunctionUpdateIrSignature, KNativePointer, KNativePointer, KNativePointer, KNativePointer) + +KNativePointer impl_CreateArrowFunctionExpression(KNativePointer contextPtr, KNativePointer funcPtr) { + auto context = reinterpret_cast(contextPtr); + auto node = reinterpret_cast(funcPtr); + + return GetImpl()->CreateArrowFunctionExpression(context, node); +} +KOALA_INTEROP_2(CreateArrowFunctionExpression, KNativePointer, KNativePointer, KNativePointer) + +KNativePointer impl_ExpressionStatementGetExpression(KNativePointer contextPtr, KNativePointer nodePtr) { + auto context = reinterpret_cast(contextPtr); + auto node = reinterpret_cast(nodePtr); + + return GetImpl()->ExpressionStatementGetExpression(context, node); +} +KOALA_INTEROP_2(ExpressionStatementGetExpression, KNativePointer, KNativePointer, KNativePointer) + +KNativePointer impl_CallExpressionArguments(KNativePointer contextPtr, KNativePointer nodePtr, KNativePointer returnLen) { + auto context = reinterpret_cast(contextPtr); + auto node = reinterpret_cast(nodePtr); + std::size_t params_len = 0; + auto params = GetImpl()->CallExpressionArguments(context, node, ¶ms_len); + return new std::vector(params, params + params_len); +} +KOALA_INTEROP_3(CallExpressionArguments, KNativePointer, KNativePointer, KNativePointer, KNativePointer) + +KNativePointer impl_CallExpressionCallee(KNativePointer contextPtr, KNativePointer nodePtr) { + auto context = reinterpret_cast(contextPtr); + auto node = reinterpret_cast(nodePtr); + return GetImpl()->CallExpressionCallee(context, node); +} +KOALA_INTEROP_2(CallExpressionCallee, KNativePointer, KNativePointer, KNativePointer) + +KNativePointer impl_AstNodeParent(KNativePointer contextPtr, KNativePointer nodePtr) { + auto context = reinterpret_cast(contextPtr); + auto node = reinterpret_cast(nodePtr); + return GetImpl()->AstNodeParent(context, node); +} +KOALA_INTEROP_2(AstNodeParent, KNativePointer, KNativePointer, KNativePointer) + +KNativePointer impl_BlockStatementSetStatements( + KNativePointer contextPtr, + KNativePointer nodePtr, + KNativePointerArray statementsPtr, + KInt statementsLen +) { + auto context = reinterpret_cast(contextPtr); + auto node = reinterpret_cast(nodePtr); + auto statements = reinterpret_cast(statementsPtr); + + GetImpl()->BlockStatementSetStatements(context, node, statements, statementsLen); + return node; } -KOALA_INTEROP_4(CreateETSTypeReferencePart0, KNativePointer, KNativePointer, KNativePointer, KNativePointer, KNativePointer) +KOALA_INTEROP_4(BlockStatementSetStatements, KNativePointer, KNativePointer, KNativePointer, KNativePointerArray, KInt) diff --git a/arkoala-arkts/libarkts/native/src/playground.cc b/arkoala-arkts/libarkts/native/src/playground.cc index c811085df7500e4b34890bdf3f1746c128d394a9..20c58ed8537c78e8b18e5f0a8540f97b77bc3ca8 100644 --- a/arkoala-arkts/libarkts/native/src/playground.cc +++ b/arkoala-arkts/libarkts/native/src/playground.cc @@ -26,14 +26,78 @@ es2panda_Impl *GetImpl() { static char* source = ""; int main() { - size_t argc = 4; - const char* argv[] = { "_", "--arktsconfig", "../arktsconfig.json", "../input/main.ts" }; - auto config = GetImpl()->CreateConfig(argc, argv); - auto context = GetImpl()->CreateContextFromString(config, source, "../input/main.ts"); + const char* args[] = { + // command with which the program is invoked (ignored) + "", + "--arktsconfig", + // path to config + "../arktsconfig.json", + // path to source + "../input/main.sts" + }; - GetImpl()->ProceedToState(context, ES2PANDA_STATE_PARSED); - auto program = GetImpl()->ContextProgram(context); - auto peer = GetImpl()->ProgramAst(program); + auto config = GetImpl()->CreateConfig(4, args); + auto context = GetImpl()->CreateContextFromString(config, source, args[3]); // playground + + GetImpl()->ProceedToState(context, ES2PANDA_STATE_PARSED); + if(GetImpl()->ContextState(context) == ES2PANDA_STATE_ERROR) + { + std::cout << "PROCEED TO PARSE ERROR" << std::endl; + std::cout << GetImpl()->ContextErrorMessage << std::endl; + } + else { + std::cout << "PROCEED TO PARSE SUCCESS" << std::endl; + } + + GetImpl()->ProceedToState(context, ES2PANDA_STATE_SCOPE_INITED); + if(GetImpl()->ContextState(context) == ES2PANDA_STATE_ERROR) + { + std::cout << "PROCEED TO SCOPE INITED ERROR" << std::endl; + std::cout << GetImpl()->ContextErrorMessage(context) << std::endl; + } + else { + std::cout << "PROCEED TO SCOPE INITED SUCCESS" << std::endl; + } + + GetImpl()->ProceedToState(context, ES2PANDA_STATE_CHECKED); + if(GetImpl()->ContextState(context) == ES2PANDA_STATE_ERROR) + { + std::cout << "PROCEED TO CHECKED ERROR" << std::endl; + std::cout << GetImpl()->ContextErrorMessage(context) << std::endl; + } + else { + std::cout << "PROCEED TO CHECKED SUCCESS" << std::endl; + } + + GetImpl()->ProceedToState(context, ES2PANDA_STATE_LOWERED); + if(GetImpl()->ContextState(context) == ES2PANDA_STATE_ERROR) + { + std::cout << "PROCEED TO LOWERED ERROR" << std::endl; + std::cout << GetImpl()->ContextErrorMessage(context) << std::endl; + } + else { + std::cout << "PROCEED TO LOWERED SUCCESS" << std::endl; + } + + GetImpl()->ProceedToState(context, ES2PANDA_STATE_ASM_GENERATED); + if(GetImpl()->ContextState(context) == ES2PANDA_STATE_ERROR) + { + std::cout << "PROCEED TO ASM ERROR" << std::endl; + std::cout << GetImpl()->ContextErrorMessage(context) << std::endl; + } + else { + std::cout << "PROCEED TO ASM SUCCESS" << std::endl; + } + + GetImpl()->ProceedToState(context, ES2PANDA_STATE_BIN_GENERATED); + if(GetImpl()->ContextState(context) == ES2PANDA_STATE_ERROR) + { + std::cout << "PROCEED TO BIN ERROR" << std::endl; + std::cout << GetImpl()->ContextErrorMessage(context) << std::endl; + } + else { + std::cout << "PROCEED TO BIN SUCCESS" << std::endl; + } } diff --git a/arkoala-arkts/libarkts/package.json b/arkoala-arkts/libarkts/package.json index efd37bb0c9d82a9005a9103b756b57c686445285..021a88adac1068188e17ea01515285d7d9bf84b6 100644 --- a/arkoala-arkts/libarkts/package.json +++ b/arkoala-arkts/libarkts/package.json @@ -18,20 +18,16 @@ }, "scripts": { "clean": "rimraf build node_modules && npm run clean:native && npm run clean:compatible", - "clean:native": "rimraf native/build_dummy native/build_es2panda", + "clean:native": "rimraf native/build_es2panda", "clean:compatible": "rimraf compatible/build compatible/build_typescript compatible/build_arkts", "compile:koala:interop": "cd ../../interop && npm run compile", - "compile:native:dummy": "cd native && meson setup -D dummy=true build_dummy && cd build_dummy && meson compile", - "compile:dummy": "npm run compile:koala:interop && npm run compile:native:dummy", - "test:dummy": "npm run compile:dummy && backend=dummy TS_NODE_PROJECT=./test/tsconfig.json npx mocha -r tsconfig-paths/register --config .mocha-dummy.json", - "compile:native": "cd native && meson setup -D dummy=false build_es2panda && cd build_es2panda && meson compile", + "compile:native": "cd native && meson setup build_es2panda && cd build_es2panda && meson compile", "compile": "npm run compile:koala:interop && npm run compile:native", "test": "npm run compile && backend=es2panda TS_NODE_PROJECT=./test/tsconfig.json mocha -r tsconfig-paths/register --config .mocha.json", "compatible": "cd compatible && npx webpack --config arkts.webpack.config.js", "webpack": "npm run compile && npm run compatible && npx webpack --config es2panda.webpack.config.js", "run:dev": "npm run run && backend=es2panda node build/api/es2panda.js", - "test:all": "npm run test:dummy && npm run test", - "run": "npm run webpack && node build/api/es2panda.js --file ./input/main.ts --arktsconfig ./arktsconfig.json", + "run": "npm run webpack && node build/api/es2panda.js --file ./input/main.sts --arktsconfig ./arktsconfig.json", "run:typescript": "npm run compatible && cd input && memo-tsc -p ./tsconfig.json", "run:debug": "npm run compile:native && cd native && ./build_es2panda/playground_exec" } diff --git a/arkoala-arkts/libarkts/src/NativeModule.ts b/arkoala-arkts/libarkts/src/NativeModule.ts index 861d93b33789bd3a57ab45aea91384c07b00b0dc..3ea74728c7dc6ef7062b18b320caae20bfc54754 100644 --- a/arkoala-arkts/libarkts/src/NativeModule.ts +++ b/arkoala-arkts/libarkts/src/NativeModule.ts @@ -34,9 +34,9 @@ export interface NativeModule { _BlockGetStatements(node: KNativePointer): KNativePointer _FunctionDeclarationGetIdentifier(node: KNativePointer): KNativePointer _FunctionDeclarationGetBlock(node: KNativePointer): KNativePointer - _ExpressionStatementGetCallExpression(node: KNativePointer): KNativePointer - _CallExpressionGetPropertyAccessExpression(node: KNativePointer): KNativePointer - _CallExpressionGetArguments(node: KNativePointer): KNativePointer + _ExpressionStatementGetExpression(context: KNativePointer, node: KNativePointer): KNativePointer + _CallExpressionArguments(context: KNativePointer, node: KNativePointer, returnLen: KNativePointer): KNativePointer + _CallExpressionCallee(context: KNativePointer, node: KNativePointer): KNativePointer _IdentifierGetText(node: KNativePointer): KNativePointer _PropertyAccessExpressionGetExpression(node: KNativePointer): KNativePointer _PropertyAccessExpressionGetName(node: KNativePointer): KNativePointer @@ -45,14 +45,44 @@ export interface NativeModule { _ScriptFunctionSignature(context: KNativePointer, node: KNativePointer): KNativePointer _ScriptFunctionParams(context: KNativePointer, node: KNativePointer): KNativePointer _ScriptFunctionId(context: KNativePointer, node: KNativePointer): KNativePointer + _ScriptFunctionBody(context: KNativePointer, node: KNativePointer): KNativePointer + _UpdateBlockStatement(context: KNativePointer, original: KNativePointer, statementList: BigUint64Array, statementListLen: KInt): KNativePointer _CreateIdentifier1(context: KNativePointer, name: string): KNativePointer _CreateIdentifier2(context: KNativePointer, name: string, type_annotation: KNativePointer): KNativePointer - _CreateFunctionDeclaration(context: KNativePointer, name: string, parameters: BigUint64Array, paramsLen: KInt): KNativePointer - _UpdateFunctionDeclaration(context: KNativePointer, node: KNativePointer, name: string, parameters: BigUint64Array, paramsLen: KInt): KNativePointer + _CreateFunctionDeclaration(context: KNativePointer, func: KNativePointer, isAnon: KBoolean): KNativePointer + _UpdateFunctionDeclaration(context: KNativePointer, node: KNativePointer, func: KNativePointer, isAnon: KBoolean): KNativePointer + _CreateReturnStatement1(context: KNativePointer, argument: KNativePointer): KNativePointer + _ReturnStatementArgument(context: KNativePointer, node: KNativePointer): KNativePointer + _CreateIfStatement(context: KNativePointer, test: KNativePointer, consequent: KNativePointer, alternate: KNativePointer): KNativePointer + _CreateBinaryExpression(context: KNativePointer, left: KNativePointer, right: KNativePointer, operatorType: KInt): KNativePointer + + _CreateFunctionSignature(context: KNativePointer, typeParams: KNativePointer, params: BigUint64Array, paramsLen: KInt, returnTypeAnnotation: KNativePointer): KNativePointer + _CreateScriptFunction(context: KNativePointer, databody: KNativePointer, datasignature: KNativePointer, datafuncFlags: KInt, dataflags: KInt, datadeclare: KBoolean): KNativePointer + _UpdateScriptFunction(context: KNativePointer, original: KNativePointer, databody: KNativePointer, datasignature: KNativePointer, datafuncFlags: KInt, dataflags: KInt, datadeclare: KBoolean): KNativePointer + _CreateBlockStatement(context: KNativePointer, statementList: BigUint64Array, statementListLen: KInt): KNativePointer + _AstNodeParent(context: KNativePointer, ast: KNativePointer): KNativePointer + _AstNodeSetParent(context: KNativePointer, ast: KNativePointer, parent: KNativePointer): KNativePointer + _ScriptFunctionSetIdent(context: KNativePointer, ast: KNativePointer, id: KNativePointer): KNativePointer + _ScriptFunctionIrSignature(context: KNativePointer, ast: KNativePointer): KNativePointer + _ScriptFunctionUpdateIrSignature(context: KNativePointer, ast: KNativePointer, signature: KNativePointer): KNativePointer + _FunctionSignatureTypeParams(context: KNativePointer, ast: KNativePointer): KNativePointer + _FunctionSignatureReturnType(context: KNativePointer, ast: KNativePointer): KNativePointer + _UpdateIdentifier1(context: KNativePointer, ast: KNativePointer, name: string): KNativePointer + + _CreateMemberExpression(context: KNativePointer, object: KNativePointer, property: KNativePointer, kind: KInt, computed: KBoolean, optional: KBoolean): KNativePointer + _UpdateMemberExpression(context: KNativePointer, node: KNativePointer, object: KNativePointer, property: KNativePointer, kind: KInt, computed: KBoolean, optional: KBoolean): KNativePointer + _MemberExpressionObject(context: KNativePointer, node: KNativePointer): KNativePointer + _MemberExpressionProperty(context: KNativePointer, node: KNativePointer): KNativePointer + _CreateCallExpression(context: KNativePointer, callee: KNativePointer, args: BigUint64Array, argsLen: KInt, typeParams: KNativePointer, optional: KBoolean, trailingComma: KBoolean): KNativePointer + _UpdateCallExpression(node: KNativePointer, context: KNativePointer, callee: KNativePointer, args: BigUint64Array, argsLen: KInt, typeParams: KNativePointer, optional: KBoolean, trailingComma: KBoolean): KNativePointer + _CreateArrowFunctionExpression(context: KNativePointer, node: KNativePointer): KNativePointer + + _CreateExpressionStatement(context: KNativePointer, expr: KNativePointer): KNativePointer + _UpdateExpressionStatement(context: KNativePointer, node: KNativePointer, expr: KNativePointer): KNativePointer _CreateETSParameterExpression(context: KNativePointer, identifier: KNativePointer): KNativePointer - _CreateETSPrimitiveType0(context: KNativePointer, type: KInt): KNativePointer - _CreateETSTypeReference0(context: KNativePointer, part: KNativePointer): KNativePointer - _CreateETSTypeReferencePart0(context: KNativePointer, name: KNativePointer, typeParams: KNativePointer, prev: KNativePointer): KNativePointer + _CreateETSPrimitiveType(context: KNativePointer, type: KInt): KNativePointer + _CreateETSTypeReference(context: KNativePointer, part: KNativePointer): KNativePointer + _CreateETSTypeReferencePart(context: KNativePointer, name: KNativePointer, typeParams: KNativePointer, prev: KNativePointer): KNativePointer _IsIdentifier(node: KNativePointer): KBoolean _IdentifierName(context: KNativePointer, node: KNativePointer): KNativePointer @@ -62,6 +92,7 @@ export interface NativeModule { _GetKind(node: KNativePointer): KInt _BlockStatementStatements(context: KNativePointer, node: KNativePointer): KNativePointer + _BlockStatementSetStatements(context: KNativePointer, node: KNativePointer, statements: BigUint64Array, statementsLen: KInt): void _ClassDeclarationDefinition(context: KNativePointer, node: KNativePointer): KNativePointer _ClassDefinitionBody(context: KNativePointer, node: KNativePointer): KNativePointer diff --git a/arkoala-arkts/libarkts/src/arkts/factory/nodeImpls.ts b/arkoala-arkts/libarkts/src/arkts/factory/nodeImpls.ts index 2b5eccbb35bbe40c891a555035d80ba3b9489f4b..c8605a57480396b74aa35bab5cbaa6ccd130c7b4 100644 --- a/arkoala-arkts/libarkts/src/arkts/factory/nodeImpls.ts +++ b/arkoala-arkts/libarkts/src/arkts/factory/nodeImpls.ts @@ -14,21 +14,25 @@ */ import * as api from "../index" -import { Access, fromPtrArray, KNativePointer, withPtrArray, withString, withStringArray, withStringResult } from "@koalaui/interop" +import { Access, fromPtrArray, KInt, KNativePointer, withPtrArray, withString, withStringArray, withStringResult } from "@koalaui/interop" import { nativeModule } from "../../NativeModule" import "../../node/Platform" import { NativePtrDecoder } from "../../node/Platform" import { throwError } from "../util" +const NULLPTR = BigInt(0) +const NULLPTR_ARRAY = new BigUint64Array([NULLPTR]) + export enum ContextState { ES2PANDA_STATE_NEW = 0, ES2PANDA_STATE_PARSED = 1, - ES2PANDA_STATE_CHECKED = 2, - ES2PANDA_STATE_LOWERED = 3, - ES2PANDA_STATE_ASM_GENERATED = 4, - ES2PANDA_STATE_BIN_GENERATED = 5, + ES2PANDA_STATE_SCOPE_INITED = 2, + ES2PANDA_STATE_CHECKED = 3, + ES2PANDA_STATE_LOWERED = 4, + ES2PANDA_STATE_ASM_GENERATED = 5, + ES2PANDA_STATE_BIN_GENERATED = 6, - ES2PANDA_STATE_ERROR = 6, + ES2PANDA_STATE_ERROR = 7, } export class Global { @@ -67,19 +71,101 @@ export class Global { } } +type Visitor = (node: api.Node) => api.Node + +function nodeVisitor(node: T | undefined, visitor: Visitor): T | undefined { + if (node === undefined) { + return undefined + } + return visitor(node) as T +} + +function nodesVisitor(nodes: api.NodeArray | undefined, visitor: Visitor): T[] | undefined { + if (nodes === undefined) { + return undefined + } + return nodes.map((node: T) => (visitor(node) as T)) +} + +type VisitEachChildFunction = (node: T, visitor: Visitor) => T + +// TODO: add more nodes +type HasChildren = + api.SourceFile | api.FunctionDeclaration | api.ExpressionStatement | api.CallExpression | api.PropertyAccessExpression + +type VisitEachChildTable = { [TNode in HasChildren as TNode["kind"]]: VisitEachChildFunction } + +// TODO: add more nodes +const visitEachChildTable: VisitEachChildTable = { + [api.SyntaxKind.SourceFile]: function (node: api.SourceFile, visitor: Visitor) { + return api.updateSourceFile( + node, + nodesVisitor(node.statements, visitor)! + ) + }, + [api.SyntaxKind.FunctionDeclaration]: function (node: api.FunctionDeclaration, visitor: Visitor) { + return api.updateFunctionDeclaration( + node, + undefined, + undefined, + nodeVisitor(node.name, visitor)!, + undefined, + nodesVisitor(node.parameters, visitor)!, + undefined, + nodeVisitor(node.body, visitor), + ) + }, + [api.SyntaxKind.ExpressionStatement]: function (node: api.ExpressionStatement, visitor: Visitor) { + return api.updateExpressionStatement( + node, + nodeVisitor(node.expression, visitor)! + ) + }, + [api.SyntaxKind.CallExpression]: function (node: api.CallExpression, visitor: Visitor) { + return api.updateCallExpression( + node, + nodeVisitor(node.expression, visitor)!, + undefined, + nodesVisitor(node.arguments, visitor) + ) + }, + [api.SyntaxKind.PropertyAccessExpression]: function (node: api.PropertyAccessExpression, visitor: Visitor) { + return api.updatePropertyAccessExpression( + node, + nodeVisitor(node.expression, visitor)!, + nodeVisitor(node.name, visitor) as api.Identifier + ) + }, +} + +function nodeHasChildren(node: api.Node): node is HasChildren { + return node.kind in visitEachChildTable +} + +export function visitEachChild( + node: T, + visitor: Visitor, + // context: api.TransformationContext +): T { + const fn = (visitEachChildTable as Record | undefined>)[node.kind]; + if (nodeHasChildren(node) && fn === undefined) { + throwError('Unsopported node kind: ' + node.kind) + } + return fn === undefined ? node : fn(node, visitor); +} + const DECODER = new NativePtrDecoder() export function createConfig(input: string[]): KNativePointer { - const tail = input.slice(1) - return withStringArray(tail, (stringArray: string[]) => { - return nativeModule._CreateConfig(tail.length, stringArray) + return withStringArray(input, (stringArray: string[]) => { + return nativeModule._CreateConfig(input.length, stringArray) }) } export function createContextFromString(config: KNativePointer, source: string, filename: string): KNativePointer { - return withString(source, (srcPtr: string) => { + return withString(source, (sourcePtr: string) => { return withString(filename, (filenamePtr: string) => { - return nativeModule._CreateContextFromString(config, srcPtr, filenamePtr) + return nativeModule._CreateContextFromString(config, sourcePtr, filenamePtr) }) }) } @@ -117,6 +203,11 @@ abstract class NodeImpl implements api.Node { this.peer = peer } + get parent(): api.Node { + return makeView(nativeModule._AstNodeParent(Global.context, this.peer)) + } + + // TODO: implement getSourceFile(): api.SourceFile { throw new Error("Method not implemented.") } getChildCount(sourceFile?: api.SourceFile | undefined): number { throw new Error("Method not implemented.") } getChildAt(index: number, sourceFile?: api.SourceFile | undefined): api.Node { throw new Error("Method not implemented.") } @@ -135,7 +226,6 @@ abstract class NodeImpl implements api.Node { // TODO: support minimal interface get flags(): api.NodeFlags { return todo() } - get parent(): api.Node { return todo() } get pos(): number { return todo() } get end(): number { return todo() } abstract kind: api.SyntaxKind @@ -155,7 +245,7 @@ class FunctionDeclarationImpl extends NodeImpl implements api.FunctionDeclaratio } get body() { - return makeView(nativeModule._FunctionDeclarationGetBlock(this.peer)) as api.Block + return makeView(nativeModule._ScriptFunctionBody(Global.context, this._scriptFunction)) as api.Block } get parameters(): api.NodeArray { @@ -253,7 +343,7 @@ class ExpressionStatementImpl extends NodeImpl implements api.ExpressionStatemen } get expression(): api.Expression { - return makeView(nativeModule._ExpressionStatementGetCallExpression(this.peer)) as api.Expression + return makeView(nativeModule._ExpressionStatementGetExpression(Global.context, this.peer)) as api.Expression } // TODO: support minimal interface @@ -266,14 +356,18 @@ class CallExpressionImpl extends NodeImpl implements api.CallExpression { super(peer) } + private _expression?: api.LeftHandSideExpression get expression(): api.LeftHandSideExpression { - return makeView(nativeModule._CallExpressionGetPropertyAccessExpression(this.peer)) as api.PropertyAccessExpression + if (this._expression === undefined) { + this._expression = makeView(nativeModule._CallExpressionCallee(Global.context, this.peer)) as api.LeftHandSideExpression + } + return this._expression } private _arguments?: api.NodeArray get arguments(): api.NodeArray { if (this._arguments === undefined) { - const argumentsPtr = nativeModule._CallExpressionGetArguments(this.peer) + const argumentsPtr = nativeModule._CallExpressionArguments(Global.context, this.peer, NULLPTR) this._arguments = unpack(argumentsPtr) as api.NodeArray } return this._arguments @@ -293,12 +387,20 @@ class PropertyAccessExpressionImpl extends NodeImpl implements api.PropertyAcces super(peer) } + private _name?: api.Identifier get name() { - return makeView(nativeModule._PropertyAccessExpressionGetName(this.peer)) as api.Identifier + if (this._name === undefined) { + this._name = makeView(nativeModule._MemberExpressionProperty(Global.context, this.peer)) as api.Identifier + } + return this._name } - get expression() { - return makeView(nativeModule._PropertyAccessExpressionGetExpression(this.peer)) as api.Identifier + private _expression?: api.LeftHandSideExpression + get expression(): api.LeftHandSideExpression { + if (this._expression === undefined) { + this._expression = makeView(nativeModule._MemberExpressionObject(Global.context, this.peer)) as api.LeftHandSideExpression + } + return this._expression } // TODO: support minimal interface @@ -422,15 +524,120 @@ class TypeReferenceNodeImpl extends NodeImpl implements api.TypeReferenceNode { typeName: any } +class FunctionTypeNodeImpl extends NodeImpl implements api.FunctionTypeNode { + constructor(peer: KNativePointer) { + super(peer) + } + + // TODO: support minimal interface + get parent(): api.SignatureDeclaration { return todo() } + get parameters(): api.NodeArray { return todo() } + type: any + _typeNodeBrand: any + _declarationBrand: any + kind: api.SyntaxKind.FunctionType = api.SyntaxKind.FunctionType; +} + +class ReturnStatementImpl extends NodeImpl implements api.ReturnStatement { + constructor(peer: KNativePointer) { + super(peer) + } + + private _expression?: api.Expression; + get expression(): api.Expression | undefined { + if (this._expression === undefined) { + this._expression = makeView(nativeModule._ReturnStatementArgument(Global.context, this.peer)) as api.Expression + } + return this._expression + } + + // TODO: support minimal interface + _statementBrand: any + kind: api.SyntaxKind.ReturnStatement = api.SyntaxKind.ReturnStatement; +} + +class IfStatementImpl extends NodeImpl implements api.IfStatement { + constructor(peer: KNativePointer) { + super(peer) + } + + // TODO: support minimal interface + thenStatement: any + expression: any + _statementBrand: any + kind: api.SyntaxKind.IfStatement = api.SyntaxKind.IfStatement; +} + +class BinaryExpressionImpl extends NodeImpl implements api.BinaryExpression { + constructor(peer: KNativePointer) { + super(peer) + } + + // TODO: support minimal interface + left: any + right: any + operatorToken: any + _expressionBrand: any + _declarationBrand: any + kind: api.SyntaxKind.BinaryExpression = api.SyntaxKind.BinaryExpression; +} + +// should be Token +class BinaryOperatorTokenImpl extends NodeImpl implements api.BinaryOperatorToken { + constructor(token: api.TokenSyntaxKind) { + super(NULLPTR) + this._token = BinaryOperatorTokenImpl.tokenKinds.get(token) + } + + private static readonly tokenKinds = new Map([ + [api.SyntaxKind.PlusToken, 26], + ]) + + + private _token: KInt + get token(): KInt { + return this._token + } + + // TODO: support minimal interface + decorators: any + modifiers: any + kind: any +} + +class ArrowFunctionExpressionImpl extends NodeImpl implements api.ArrowFunction { + constructor(peer: KNativePointer) { + super(peer) + } + + // private _body?: api.Block + // private _parameters?: api.NodeArray + + body: any + get name(): never { + return this.name + } + parameters: any + + // TODO: support minimal interface + equalsGreaterThanToken: any + _expressionBrand: any + _functionLikeDeclarationBrand: any + _declarationBrand: any + kind: any +} + class UnsupportedNode extends NodeImpl implements api.Node { constructor(peer: KNativePointer) { super(peer) } - kind: api.SyntaxKind = -1 + kind: api.SyntaxKind = 0 } enum es2pandaKind { + UnsupportedNode = 0, + Identifier = 1, StringLiteral = 2, Block = 3, @@ -439,8 +646,10 @@ enum es2pandaKind { FunctionDeclaration = 6, PropertyDeclaration = 7, Parameter = 8, - - UnsupportedNode = -1, + ETSFunctionType = 9, + CallExpression = 10, + ExpressionStatement = 11, + MemberExpression = 12, } const kinds = new Map([ @@ -452,6 +661,10 @@ const kinds = new Map([ [es2pandaKind.FunctionDeclaration, api.SyntaxKind.FunctionDeclaration], [es2pandaKind.PropertyDeclaration, api.SyntaxKind.PropertyDeclaration], [es2pandaKind.Parameter, api.SyntaxKind.Parameter], + [es2pandaKind.ETSFunctionType, api.SyntaxKind.FunctionType], + [es2pandaKind.CallExpression, api.SyntaxKind.CallExpression], + [es2pandaKind.ExpressionStatement, api.SyntaxKind.ExpressionStatement], + [es2pandaKind.MemberExpression, api.SyntaxKind.PropertyAccessExpression], ]) export function makeView(peer: KNativePointer): api.Node { @@ -474,13 +687,17 @@ export function makeView(peer: KNativePointer): api.Node { if (kind == api.SyntaxKind.FunctionDeclaration) return new FunctionDeclarationImpl(peer) if (kind == api.SyntaxKind.PropertyDeclaration) return new PropertyDeclarationImpl(peer) if (kind == api.SyntaxKind.Parameter) return new ParameterDeclarationImpl(peer) + if (kind == api.SyntaxKind.FunctionType) return new FunctionTypeNodeImpl(peer) + if (kind == api.SyntaxKind.CallExpression) return new CallExpressionImpl(peer) + if (kind == api.SyntaxKind.ExpressionStatement) return new ExpressionStatementImpl(peer) + if (kind == api.SyntaxKind.PropertyAccessExpression) return new PropertyAccessExpressionImpl(peer) throw new Error(`Unknown node kind: ${kind}`) } -export function createIdentifier(name: string, type_annotation?: api.Node): api.Identifier { +export function createIdentifier(name: string, typeAnnotation?: api.Node): api.Identifier { const peer = withString(name, (name: string) => { - return type_annotation ? nativeModule._CreateIdentifier2(Global.context, name, getPeer(type_annotation)) : nativeModule._CreateIdentifier1(Global.context, name) + return typeAnnotation ? nativeModule._CreateIdentifier2(Global.context, name, getPeer(typeAnnotation)) : nativeModule._CreateIdentifier1(Global.context, name) }) return new IdentifierImpl(peer) @@ -494,32 +711,130 @@ export function createStringLiteral(s: string): api.StringLiteral { return new StringLiteralImpl(peer) } -export function createFunctionDeclaration(name: string, parameter_nodes: api.ParameterDeclaration[]): api.FunctionDeclaration { - const parameters = new BigUint64Array(parameter_nodes.map(node => BigInt(getPeer(node)))) - - const peer = withString(name, (name: string) => { - return withPtrArray(parameters, Access.READWRITE, (parameters: BigUint64Array) => { - return nativeModule._CreateFunctionDeclaration(Global.context, name, parameters, parameters.length) +// createFunctionDeclaration(modifiers: readonly ModifierLike[] | undefined, asteriskToken: AsteriskToken | undefined, name: string | Identifier | undefined, typeParameters: readonly TypeParameterDeclaration[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode | undefined, body: Block | undefined): FunctionDeclaration; +export function createFunctionDeclaration( + modifiers: undefined, + asteriskToken: undefined, + name: api.Identifier, + typeParameters: undefined, + parameters: readonly api.ParameterDeclaration[], + type: undefined, + body: api.Block | undefined +): api.FunctionDeclaration { + const params = new BigUint64Array(parameters.map(node => BigInt(getPeer(node)))) + + const peer = withString(name.text, (_name: string) => { + return withPtrArray(params, Access.READWRITE, (_params: BigUint64Array) => { + const _paramsLen = params.length + const _context = Global.context + const _body = body ? getPeer(body) : NULLPTR + + const _signature = nativeModule._CreateFunctionSignature( + _context, + NULLPTR, + _params, + _paramsLen, + NULLPTR + ) + + const _scriptFunc = nativeModule._CreateScriptFunction( + _context, + _body, + _signature, + // TODO: fix flag params + 0, + 0, + false + ) + if (_body !== NULLPTR) { + nativeModule._AstNodeSetParent(_context, _body, _scriptFunc) + } + + const _ident = nativeModule._CreateIdentifier1(_context, _name) + nativeModule._ScriptFunctionSetIdent(_context, _scriptFunc, _ident) + + return nativeModule._CreateFunctionDeclaration( + _context, + _scriptFunc, + false + ) }) }) return new FunctionDeclarationImpl(peer) } -export function updateFunctionDeclaration(func: api.FunctionDeclaration, name: api.Identifier, parameter_nodes: api.ParameterDeclaration[]): api.FunctionDeclaration { - const parameters = new BigUint64Array(parameter_nodes.map(node => BigInt(getPeer(node)))) +export function updateFunctionDeclaration( + node: api.FunctionDeclaration, + modifiers: undefined, + asteriskToken: undefined, + name: api.Identifier, + typeParameters: undefined, + parameters: readonly api.ParameterDeclaration[], + type: undefined, + body: api.Block | undefined +): api.FunctionDeclaration { + const params = new BigUint64Array(parameters.map(node => BigInt(getPeer(node)))) const peer = withString(name.text, (name: string) => { - return withPtrArray(parameters, Access.READWRITE, (parameters: BigUint64Array) => { - return nativeModule._UpdateFunctionDeclaration(Global.context, getPeer(func), name, parameters, parameters.length) + return withPtrArray(params, Access.READWRITE, (parameters: BigUint64Array) => { + const _paramsLen = parameters.length + const _context = Global.context + const _name = name + const _funcDecl = getPeer(node) + const _oldScriptFunc = nativeModule._FunctionDeclarationFunction(_context, _funcDecl) + const _params = parameters + const _body = body ? getPeer(body) : NULLPTR + + const _oldSignature = nativeModule._ScriptFunctionIrSignature(_context, _oldScriptFunc) + const _newSignature = nativeModule._CreateFunctionSignature( + _context, + nativeModule._FunctionSignatureTypeParams(_context, _oldSignature), + _params, + _paramsLen, + nativeModule._FunctionSignatureReturnType(_context, _oldSignature) + ) + + const _ident = nativeModule._UpdateIdentifier1(_context, nativeModule._ScriptFunctionId(_context, _oldScriptFunc), _name) + + // // TODO: use this flags + // auto script_func_flags = GetImpl()->ScriptFunctionFlagsConst(context, script_func_node); + + const _newScriptFunc = nativeModule._UpdateScriptFunction( + _context, + _oldScriptFunc, + _body, + _newSignature, + // TODO: fix flag params + 0, + 0, + false + ) + + nativeModule._ScriptFunctionSetIdent(_context, _newScriptFunc, _ident) + + return nativeModule._UpdateFunctionDeclaration( + _context, + _funcDecl, + _newScriptFunc, + false + ) }) }) return new FunctionDeclarationImpl(peer) } -export function createParameterDeclaration(identifier: api.Identifier): api.ParameterDeclaration { - const peer = nativeModule._CreateETSParameterExpression(Global.context, getPeer(identifier)) +// tsc: createParameterDeclaration(modifiers: readonly ModifierLike[] | undefined, dotDotDotToken: DotDotDotToken | undefined, name: string | BindingName, questionToken?: QuestionToken, type?: TypeNode, initializer?: Expression): ParameterDeclaration; +export function createParameterDeclaration( + modifiers: undefined, + dotDotDotToken: undefined, + name: api.Identifier, + questionToken?: undefined, + type?: undefined, + initializer?: undefined +): api.ParameterDeclaration { + const peer = nativeModule._CreateETSParameterExpression(Global.context, getPeer(name)) return new ParameterDeclarationImpl(peer) } @@ -555,28 +870,204 @@ export enum Es2pandaPrimitiveType { }; export function createETSPrimitiveType(type: Es2pandaPrimitiveType) { - const peer = nativeModule._CreateETSPrimitiveType0(Global.context, type) + const peer = nativeModule._CreateETSPrimitiveType(Global.context, type) return new ETSPrimitiveTypeImpl(peer) } -const keywords = new Map([ - [api.SyntaxKind.NumberKeyword, "number"], - [api.SyntaxKind.StringKeyword, "string"], -]) - export function createTypeReferenceNode(identifier: api.Identifier): api.TypeReferenceNode { - const type_ref_part = nativeModule._CreateETSTypeReferencePart0(Global.context, getPeer(identifier), BigInt(0), BigInt(0)) - const peer = nativeModule._CreateETSTypeReference0(Global.context, type_ref_part) + const type_ref_part = nativeModule._CreateETSTypeReferencePart(Global.context, getPeer(identifier), NULLPTR, NULLPTR) + const peer = nativeModule._CreateETSTypeReference(Global.context, type_ref_part) return new TypeReferenceNodeImpl(peer) } export function createKeywordTypeNode(TKind: api.KeywordTypeSyntaxKind): api.KeywordTypeNode { + const keywords = new Map([ + [api.SyntaxKind.NumberKeyword, "number"], + [api.SyntaxKind.StringKeyword, "string"], + [api.SyntaxKind.AnyKeyword, "any"], + ]) + const keyword: string = keywords.get(TKind) ?? throwError('unsupported keyword') const identifier = withString(keyword, (name: string) => { return nativeModule._CreateIdentifier1(Global.context, name) }) - const type_ref_part = nativeModule._CreateETSTypeReferencePart0(Global.context, identifier, BigInt(0), BigInt(0)) - const peer = nativeModule._CreateETSTypeReference0(Global.context, type_ref_part) + const type_ref_part = nativeModule._CreateETSTypeReferencePart(Global.context, identifier, NULLPTR, NULLPTR) + const peer = nativeModule._CreateETSTypeReference(Global.context, type_ref_part) return new KeywordTypeNodeImpl(peer) } + +export function createBlock(statements: api.Statement[], multiline?: boolean): api.Block { + const statementList = new BigUint64Array(statements.map(node => BigInt(getPeer(node)))) + + const peer = withPtrArray(statementList, Access.READWRITE, (statementList: BigUint64Array) => { + return nativeModule._CreateBlockStatement(Global.context, statementList, statementList.length) + }) + + return new BlockImpl(peer) +} + +export function updateBlock(node: api.Block, statements: api.Statement[], multiline?: boolean): api.Block { + const statementList = new BigUint64Array(statements.map(node => BigInt(getPeer(node)))) + + const peer = withPtrArray(statementList, Access.READWRITE, (statementList: BigUint64Array) => { + return nativeModule._UpdateBlockStatement(Global.context, getPeer(node), statementList, statementList.length) + }) + + return new BlockImpl(peer) +} + +export function createExpressionStatement(expression: api.Expression): api.ExpressionStatement { + const peer = nativeModule._CreateExpressionStatement(Global.context, getPeer(expression)) + + return new ExpressionStatementImpl(peer) +} + +export function updateExpressionStatement(node: api.ExpressionStatement, expression: api.Expression): api.ExpressionStatement { + const peer = nativeModule._UpdateExpressionStatement(Global.context, getPeer(node), getPeer(expression)) + + return new ExpressionStatementImpl(peer) +} + +export function createReturnStatement(expression: api.Expression): api.ReturnStatement { + const peer = nativeModule._CreateReturnStatement1(Global.context, getPeer(expression)) + + return new ReturnStatementImpl(peer) +} + +// tsc: createPropertyAccessExpression(expression: Expression, name: string | MemberName): PropertyAccessExpression; +export function createPropertyAccessExpression(expression: api.Expression, name: api.Identifier): api.PropertyAccessExpression { + const peer = nativeModule._CreateMemberExpression(Global.context, getPeer(expression), getPeer(name), 2, false, false) + + return new PropertyAccessExpressionImpl(peer) +} + +export function updatePropertyAccessExpression(node: api.PropertyAccessExpression, expression: api.Expression, name: api.Identifier): api.PropertyAccessExpression { + const peer = nativeModule._UpdateMemberExpression(Global.context, getPeer(node), getPeer(expression), getPeer(name), 2, false, false) + + return new PropertyAccessExpressionImpl(peer) +} + +// tsc: createCallExpression(expression: Expression, typeArguments: readonly TypeNode[] | undefined, argumentsArray: readonly Expression[] | undefined): CallExpression; +export function createCallExpression( + expression: api.Expression, + typeArguments?: undefined, + argumentsArray?: readonly api.Expression[] | undefined +): api.CallExpression { + const args = argumentsArray ? new BigUint64Array(argumentsArray.map(node => BigInt(getPeer(node)))) : new BigUint64Array([]) + + const peer = withPtrArray(args, Access.READWRITE, (args: BigUint64Array) => { + return nativeModule._CreateCallExpression( + Global.context, + getPeer(expression), + args, + args.length, + NULLPTR, + false, + false + ) + }) + + return new CallExpressionImpl(peer) +} + +// tsc: updateCallExpression(node: CallExpression, expression: Expression, typeArguments: readonly TypeNode[] | undefined, argumentsArray: readonly Expression[]): CallExpression; +export function updateCallExpression( + node: api.CallExpression, + expression: api.Expression, + typeArguments?: undefined, + argumentsArray?: readonly api.Expression[] | undefined +): api.CallExpression { + const args = argumentsArray ? new BigUint64Array(argumentsArray.map(node => BigInt(getPeer(node)))) : new BigUint64Array([]) + + const peer = withPtrArray(args, Access.READWRITE, (args: BigUint64Array) => { + return nativeModule._UpdateCallExpression( + Global.context, + getPeer(node), + getPeer(expression), + args, + args.length, + NULLPTR, + false, + false + ) + }) + + return new CallExpressionImpl(peer) +} + +// tsc: createIfStatement(expression: Expression, thenStatement: Statement, elseStatement?: Statement): IfStatement; +export function createIfStatement(expression: api.Expression, thenStatement: api.Statement, elseStatement?: undefined): api.IfStatement { + const peer = nativeModule._CreateIfStatement(Global.context, getPeer(expression), getPeer(thenStatement), NULLPTR) + + return new IfStatementImpl(peer) +} + +// returns only BinaryOperatorToken temporary +// tsc: createToken(token: SyntaxKind._): _; +export function createToken(token: api.TokenSyntaxKind): api.BinaryOperatorToken { + return new BinaryOperatorTokenImpl(token) +} + +// tsc: createBinaryExpression(left: Expression, operator: BinaryOperator | BinaryOperatorToken, right: Expression): BinaryExpression; +export function createBinaryExpression(left: api.Expression, operator: api.BinaryOperatorToken, right: api.Expression): api.BinaryExpression { + const peer = nativeModule._CreateBinaryExpression(Global.context, getPeer(left), getPeer(right), (operator as BinaryOperatorTokenImpl).token) + + return new BinaryExpressionImpl(peer) +} + +// tsc: createArrowFunction(modifiers: readonly Modifier[] | undefined, typeParameters: readonly TypeParameterDeclaration[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode | undefined, equalsGreaterThanToken: EqualsGreaterThanToken | undefined, body: ConciseBody): ArrowFunction; +export function createArrowFunction( + modifiers: undefined, + typeParameters: undefined, + parameters: api.ParameterDeclaration[], + type: undefined, + equalsGreaterThanToken: undefined, + body: api.Block +) { + const params = new BigUint64Array(parameters.map(node => BigInt(getPeer(node)))) + + const peer = withPtrArray(params, Access.READWRITE, (_params: BigUint64Array) => { + const _context = Global.context + const _body = getPeer(body) + const _paramsLen = params.length + + const _signature = nativeModule._CreateFunctionSignature( + _context, + NULLPTR, + _params, + _paramsLen, + NULLPTR + ) + + const _scriptFunc = nativeModule._CreateScriptFunction( + _context, + _body, + _signature, + // TODO: fix flag params + 0, + 0, + false + ) + if (_body !== NULLPTR) { + nativeModule._AstNodeSetParent(_context, _body, _scriptFunc) + } + + return nativeModule._CreateArrowFunctionExpression( + _context, + _scriptFunc + ) + }) + + return new ArrowFunctionExpressionImpl(peer) +} + +export function updateSourceFile(node: api.SourceFile, statements: api.Statement[]): api.SourceFile { + const statementList = new BigUint64Array(statements.map(node => BigInt(getPeer(node)))) + + withPtrArray(statementList, Access.READWRITE, (statementList: BigUint64Array) => { + nativeModule._BlockStatementSetStatements(Global.context, getPeer(node), statementList, statementList.length) + }) + + return node +} diff --git a/arkoala-arkts/libarkts/src/arkts/index.ts b/arkoala-arkts/libarkts/src/arkts/index.ts index 965ffbde0654e9d6bf1db3effeb984c301b24032..9459b99884b145c799b554c67bf912a268b46f68 100644 --- a/arkoala-arkts/libarkts/src/arkts/index.ts +++ b/arkoala-arkts/libarkts/src/arkts/index.ts @@ -75,5 +75,12 @@ export { KeywordTypeNode, KeywordTypeSyntaxKind, TypeReferenceNode, + FunctionTypeNode, + ReturnStatement, + IfStatement, + BinaryOperatorToken, + TokenSyntaxKind, + BinaryExpression, + ArrowFunction, } from "typescript" export * from "./factory/nodeImpls" diff --git a/arkoala-arkts/libarkts/src/es2panda.ts b/arkoala-arkts/libarkts/src/es2panda.ts index 79da6181d505b660a41c2579271daf07780b0250..71eb7dc62ca93d51b6aba74abc59176c568c3391 100644 --- a/arkoala-arkts/libarkts/src/es2panda.ts +++ b/arkoala-arkts/libarkts/src/es2panda.ts @@ -24,20 +24,21 @@ function parseCommandLineArgs() { function es2panda(configPath: string, filePath: string, transform: (ast: arkts.Node) => arkts.Node) { const source = fs.readFileSync(filePath).toString() - const cfg = arkts.createConfig([ + arkts.Global.config = arkts.createConfig([ + '_', '--arktsconfig', configPath, filePath ]) - const ctx = arkts.createContextFromString(cfg, source, filePath) - arkts.proceedToState(ctx, arkts.ContextState.ES2PANDA_STATE_PARSED) - const program = arkts.contextProgram(ctx) + arkts.Global.context = arkts.createContextFromString(arkts.Global.config, source, filePath) + arkts.proceedToState(arkts.ContextState.ES2PANDA_STATE_PARSED) + const program = arkts.contextProgram() const peer = arkts.programAst(program) - const ast = arkts.makeView(ctx, peer) + const ast = arkts.makeView(peer) transform(ast) - arkts.proceedToState(ctx, arkts.ContextState.ES2PANDA_STATE_BIN_GENERATED) + arkts.proceedToState(arkts.ContextState.ES2PANDA_STATE_BIN_GENERATED) } function plugins(configPath: string): Promise<((ast: arkts.Node) => arkts.Node)[]> { @@ -49,12 +50,13 @@ function plugins(configPath: string): Promise<((ast: arkts.Node) => arkts.Node)[ // TODO: read and pass plugin options const options = {} - function webpackUnoptimizableImport(path: string) { - return import(/* webpackIgnore: true */ path) + function webpackUnoptimizableImport(path: string): { default: any } { + return require(/* webpackIgnore: true */ path) } // TODO: plugin path relative to arktsconfig const module = webpackUnoptimizableImport('../../' + pluginPath) - return module.then((plugin) => plugin.default.default(options)()) + console.log(module.default) + return module.default(options)() })) } diff --git a/arkoala-arkts/libarkts/test/es2panda/builder-lambda-rewrite.test.ts b/arkoala-arkts/libarkts/test/es2panda/builder-lambda-rewrite.test.ts new file mode 100644 index 0000000000000000000000000000000000000000..7e4e0eeddbecf7feeda0b022b777665d7570948c --- /dev/null +++ b/arkoala-arkts/libarkts/test/es2panda/builder-lambda-rewrite.test.ts @@ -0,0 +1,153 @@ +import * as util from "../test-util" +import * as api from "../../src/arkts" +import { BuilderLambdaTransformer } from "../../compatible/src/builder-lambda-transformer" + +suite(util.getSuiteTitle(__filename), () => { + test("adding-lambda-param-to-signature", function() { + // _Foo((instance: any) => { + // // empty + // }, "label"); + + const sample_in = + ` + Foo("label") + ` + + util.getDefaultSetup(sample_in) + + const newName = "_Foo" + const paramName = "instance" + + const node = (api.makeView(util.getStatement(0)) as api.ExpressionStatement).expression as api.CallExpression + + const instanceLambdaBody = api.createBlock([]) + const lambdaParams = [ + api.createParameterDeclaration( + undefined, + undefined, + api.createIdentifier(paramName, api.createKeywordTypeNode(api.SyntaxKind.AnyKeyword)) + ) + ] + + const lambda = api.createArrowFunction( + undefined, + undefined, + lambdaParams, + undefined, + undefined, + instanceLambdaBody + ) + + const result = api.updateCallExpression( + node, + api.createIdentifier(newName), + undefined, + [ + lambda, + ...node.arguments + ] + ) + + util.assertEqualsGolden(api.dumpJsonNode(result), this) + + api.proceedToState(api.ContextState.ES2PANDA_STATE_CHECKED) + }) + + test("adding-body-to-lambda-param", function() { + // _Foo((instance: any) => { + // instance.bar().qux(); + // }, "label1", "label2"); + + const sample_in = + ` + Foo(instance.bar().qux(), "label1", "label2") + ` + + util.getDefaultSetup(sample_in) + + const newName = "_Foo" + const paramName = "instance" + + const node = (api.makeView(util.getStatement(0)) as api.ExpressionStatement).expression as api.CallExpression + + const instanceLambdaBody = api.createBlock([ + api.createExpressionStatement( + node.arguments[0] + ) + ]) + const lambdaParams = [ + api.createParameterDeclaration( + undefined, + undefined, + api.createIdentifier(paramName, api.createKeywordTypeNode(api.SyntaxKind.AnyKeyword)) + ) + ] + + const lambda = api.createArrowFunction( + undefined, + undefined, + lambdaParams, + undefined, + undefined, + instanceLambdaBody + ) + + const result = api.updateCallExpression( + node, + api.createIdentifier(newName), + undefined, + [ + lambda, + ...node.arguments.slice(1) + ] + ) + + util.assertEqualsGolden(api.dumpJsonNode(result), this) + + api.proceedToState(api.ContextState.ES2PANDA_STATE_CHECKED) + }) + + test("builder-lambda-transformer-sample-1", function() { + // foo((instance: any) => { + // instance; + // }, "label"); + + const sample_in = + ` + _BuilderLambdaCall_foo("label") + ` + + util.getDefaultSetup(sample_in) + + const sourceFile = api.makeView(util.AstProvider.provideAst()) + const builderLambdaTransformer = new BuilderLambdaTransformer() + + const transformed = builderLambdaTransformer.visitor(sourceFile) + + util.assertEqualsGolden(api.dumpJsonNode(transformed), this) + + api.proceedToState(api.ContextState.ES2PANDA_STATE_CHECKED) + }) + + test("builder-lambda-transformer-sample-2", function() { + // Foo((instance: any) => { + // instance.bar().qux(); + // }, "label1", "label2"); + + const sample_in = + ` + _BuilderLambdaCall_foo("label1", "label2").bar().qux() + ` + + util.getDefaultSetup(sample_in) + + const sourceFile = api.makeView(util.AstProvider.provideAst()) + const builderLambdaTransformer = new BuilderLambdaTransformer() + + const transformed = builderLambdaTransformer.visitor(sourceFile) + + util.assertEqualsGolden(api.dumpJsonNode(transformed), this) + + api.proceedToState(api.ContextState.ES2PANDA_STATE_CHECKED) + }) +}) diff --git a/arkoala-arkts/libarkts/test/es2panda/create-function-declaration.test.ts b/arkoala-arkts/libarkts/test/es2panda/create-function-declaration.test.ts index 5fe15c199c0bc3ed76574335269792e251762b34..1cfccb0ba51e6c4569126cbc7fd8558846d73a13 100644 --- a/arkoala-arkts/libarkts/test/es2panda/create-function-declaration.test.ts +++ b/arkoala-arkts/libarkts/test/es2panda/create-function-declaration.test.ts @@ -9,7 +9,18 @@ suite(util.getSuiteTitle(__filename), () => { util.getDefaultSetup('') - const funcDecl = api.createFunctionDeclaration("test_func", []) + const funcDecl = api.createFunctionDeclaration( + undefined, + undefined, + api.createIdentifier("test_func"), + undefined, + [], + undefined, + api.createBlock( + [], + true + ) + ) util.assertEqualsGolden(api.dumpJsonNode(funcDecl), this) }) @@ -22,9 +33,28 @@ suite(util.getSuiteTitle(__filename), () => { util.getDefaultSetup('') const typeAnnotation = api.createKeywordTypeNode(api.SyntaxKind.NumberKeyword) - const funcParams = [api.createParameterDeclaration(api.createIdentifier("x", typeAnnotation))] - const funcDeclaration = api.createFunctionDeclaration("test_func", funcParams) + const funcParams = [ + api.createParameterDeclaration( + undefined, + undefined, + api.createIdentifier("x", typeAnnotation) + ) + ] + const funcDecl = api.createFunctionDeclaration( + undefined, + undefined, + api.createIdentifier("test_func"), + undefined, + funcParams, + undefined, + api.createBlock( + [], + true + ) + ) - util.assertEqualsGolden(api.dumpJsonNode(funcDeclaration), this) + util.assertEqualsGolden(api.dumpJsonNode(funcDecl), this) + + api.proceedToState(api.ContextState.ES2PANDA_STATE_CHECKED) }) }) diff --git a/arkoala-arkts/libarkts/test/es2panda/create-node.test.ts b/arkoala-arkts/libarkts/test/es2panda/create-node.test.ts index 3eee20cd001c010d0fc038c5bc8d65e9056ed6f2..c40d9131c2cfa70fb38373b7bf5f461dacd54f40 100644 --- a/arkoala-arkts/libarkts/test/es2panda/create-node.test.ts +++ b/arkoala-arkts/libarkts/test/es2panda/create-node.test.ts @@ -11,5 +11,7 @@ suite(util.getSuiteTitle(__filename), () => { util.assert.equal(node.text, strStringLiteral) util.assert.isTrue(api.isStringLiteral(node)) util.assertEqualsGolden(api.dumpJsonNode(node), this) + + api.proceedToState(api.ContextState.ES2PANDA_STATE_CHECKED) }) }) diff --git a/arkoala-arkts/libarkts/test/es2panda/lambda-param-memoization.test.ts b/arkoala-arkts/libarkts/test/es2panda/lambda-param-memoization.test.ts new file mode 100644 index 0000000000000000000000000000000000000000..68bc7669ec23acd8f2c634187b2336059d591618 --- /dev/null +++ b/arkoala-arkts/libarkts/test/es2panda/lambda-param-memoization.test.ts @@ -0,0 +1,31 @@ +import * as util from "../test-util" +import * as api from "../../src/arkts" + + + +suite(util.getSuiteTitle(__filename), () => { + test("memo-function-with-lambda-memo-param", function() { + const sample_in = + ` + function foo( + content: () => void + ) { + content() + } + ` + + const sample_out = + ` + function foo( + content: (__memo_context: __memo_context_type, __memo_id: __memo_id_type) => void + ) { + if (__memo_scope.unchanged) + return __memo_scope.cached + content(__memo_context, __memo_id + "key_id_main.ts") + return __memo_scope.recache() + } + ` + + util.assert(false) + }) +}) diff --git a/arkoala-arkts/libarkts/test/es2panda/update-function-declaration.test.ts b/arkoala-arkts/libarkts/test/es2panda/update-function-declaration.test.ts index 7c7bf9fc0798acb6d32ce30812a44b012231fc67..8961b9c4c94c127d31f1211dda3fa97d1fefebeb 100644 --- a/arkoala-arkts/libarkts/test/es2panda/update-function-declaration.test.ts +++ b/arkoala-arkts/libarkts/test/es2panda/update-function-declaration.test.ts @@ -2,7 +2,12 @@ import * as util from "../test-util" import * as api from "../../src/arkts" suite(util.getSuiteTitle(__filename), () => { + // adding y: string to signature test("update-name-and-add-param-to-function", function() { + // function new_test_func(x: number, y: string) { + // // empty + // } + const sample_in = ` function test_func(x: number) { @@ -10,25 +15,35 @@ suite(util.getSuiteTitle(__filename), () => { } ` - // adding y: string to signature - - // function new_test_func(x: number, y: string) { - // // empty - // } - util.getDefaultSetup(sample_in) let testFunc = api.makeView(util.getStatement(0)) as api.FunctionDeclaration const oldParams = testFunc.parameters const newParamTypeAnnotation = api.createKeywordTypeNode(api.SyntaxKind.StringKeyword) - const newParam = api.createParameterDeclaration(api.createIdentifier("y", newParamTypeAnnotation)) + const newParam = api.createParameterDeclaration(undefined, undefined, api.createIdentifier("y", newParamTypeAnnotation)) const newParams = [...oldParams, newParam] - api.updateFunctionDeclaration(testFunc, api.createIdentifier("new_test_func"), newParams) + testFunc = api.updateFunctionDeclaration( + testFunc, + undefined, + undefined, + api.createIdentifier("new_test_func"), + undefined, + newParams, + undefined, + testFunc.body + ) util.assertEqualsGolden(api.dumpJsonNode(testFunc), this) + + api.proceedToState(api.ContextState.ES2PANDA_STATE_CHECKED) }) + // adding memo params to signature test("add-params-to-memo-function", function() { + // function foo(__memo_context: __memo_context_type, __memo_id: __memo_id_type, x: number) { + // // empty + // } + const sample_in = ` function foo(x: number) { @@ -36,23 +51,287 @@ suite(util.getSuiteTitle(__filename), () => { } ` - // adding memo params to signature + util.getDefaultSetup(sample_in) - // function foo(__memo_context: __memo_context_type, __memo_id: __memo_id_type, x: number) { - // // empty + let testFunc = api.makeView(util.getStatement(0)) as api.FunctionDeclaration + + testFunc = util.addMemoParamsToFunctionDeclaration(testFunc) + + util.assertEqualsGolden(api.dumpJsonNode(testFunc), this) + + api.proceedToState(api.ContextState.ES2PANDA_STATE_CHECKED) + }) + + // adding identifier x + test("add-identifier-to-function-body", function() { + // function foo() { + // x + // } + + const sample_in = + ` + function foo() { + // empty + } + ` + + util.getDefaultSetup(sample_in) + + let testFunc = api.makeView(util.getStatement(0)) as api.FunctionDeclaration + + let body_statements = [ + ...testFunc.body!.statements, + api.createExpressionStatement(api.createIdentifier("x")) + ] + + testFunc = api.updateFunctionDeclaration( + testFunc, + undefined, + undefined, + testFunc.name!, + undefined, + testFunc.parameters!, + undefined, + api.updateBlock( + testFunc.body!, + body_statements + ) + ) + + util.assertEqualsGolden(api.dumpJsonNode(testFunc), this) + + api.proceedToState(api.ContextState.ES2PANDA_STATE_CHECKED) + }) + + // adding __memo_scope.recache + test("add-property-access-expression-to-function-body", function() { + // function foo() { + // __memo_scope.recache // } + const sample_in = + ` + function foo() { + // empty + } + ` + util.getDefaultSetup(sample_in) let testFunc = api.makeView(util.getStatement(0)) as api.FunctionDeclaration - const oldParams = testFunc.parameters - const memoContextAnnotation = api.createTypeReferenceNode(api.createIdentifier("__memo_context_type")) - const memoContextParam = api.createParameterDeclaration(api.createIdentifier("__memo_context", memoContextAnnotation)) - const memoIdAnnotation = api.createTypeReferenceNode(api.createIdentifier("__memo_id_type")) - const memoIdParam = api.createParameterDeclaration(api.createIdentifier("__memo_id", memoIdAnnotation)) - const newParams = [memoContextParam, memoIdParam, ...oldParams] - api.updateFunctionDeclaration(testFunc, testFunc.name!, newParams) + + let body_statements = [ + ...testFunc.body!.statements, + api.createExpressionStatement( + api.createPropertyAccessExpression( + api.createIdentifier("__memo_scope"), + api.createIdentifier("recache") + ) + ) + ] + + testFunc = api.updateFunctionDeclaration( + testFunc, + undefined, + undefined, + testFunc.name!, + undefined, + [...testFunc.parameters], + undefined, + api.updateBlock( + testFunc.body!, + body_statements + ) + ) util.assertEqualsGolden(api.dumpJsonNode(testFunc), this) + + api.proceedToState(api.ContextState.ES2PANDA_STATE_CHECKED) + }) + + // body memo rewrite (adding return statement) + test("add-return-statement-to-function-body", function() { + // function foo() { + // // if (__memo_scope.unchanged) + // // return __memo_scope.cached + // // content(__memo_context, __memo_id + "key_id_main.ts") + // return __memo_scope.recache() + // } + + const sample_in = + ` + function foo() { + // empty + } + ` + + util.getDefaultSetup(sample_in) + + let testFunc = api.makeView(util.getStatement(0)) as api.FunctionDeclaration + + let body_statements = [ + ...testFunc.body!.statements, + api.createReturnStatement( + api.createCallExpression( + api.createPropertyAccessExpression( + api.createIdentifier("__memo_scope"), + api.createIdentifier("recache") + ) + ) + ) + ] + + testFunc = api.updateFunctionDeclaration( + testFunc, + undefined, + undefined, + testFunc.name!, + undefined, + [...testFunc.parameters], + undefined, + api.updateBlock( + testFunc.body!, + body_statements + ) + ) + + util.assertEqualsGolden(api.dumpJsonNode(testFunc), this) + + api.proceedToState(api.ContextState.ES2PANDA_STATE_CHECKED) + }) + + // body memo rewrite (adding if statement) + test("add-if-statement-to-function-body", function() { + // function foo() { + // if (__memo_scope.unchanged) + // return __memo_scope.cached + // // content(__memo_context, __memo_id + "key_id_main.ts") + // // return __memo_scope.recache() + // } + + const sample_in = + ` + function foo() { + // empty + } + ` + + util.getDefaultSetup(sample_in) + + let testFunc = api.makeView(util.getStatement(0)) as api.FunctionDeclaration + + let body_statements = [ + api.createIfStatement( + api.createPropertyAccessExpression( + api.createIdentifier("__memo_scope"), + api.createIdentifier("unchanged") + ), + api.createReturnStatement( + api.createPropertyAccessExpression( + api.createIdentifier("__memo_scope"), + api.createIdentifier("cached") + ) + ), + undefined + ), + ...testFunc.body!.statements + ] + + testFunc = api.updateFunctionDeclaration( + testFunc, + undefined, + undefined, + testFunc.name!, + undefined, + [...testFunc.parameters], + undefined, + api.updateBlock( + testFunc.body!, + body_statements + ) + ) + + util.assertEqualsGolden(api.dumpJsonNode(testFunc), this) + + api.proceedToState(api.ContextState.ES2PANDA_STATE_CHECKED) + }) + + // body memo rewrite + test("function-declaration-memo-rewrite", function() { + // function foo(__memo_context: __memo_context_type, __memo_id: __memo_id_type) { + // if (__memo_scope.unchanged) + // return __memo_scope.cached + // content(__memo_context, __memo_id + "key_id_main.ts") + // return __memo_scope.recache() + // } + + const sample_in = + ` + function foo() { + // empty + } + ` + + util.getDefaultSetup(sample_in) + + let testFunc = api.makeView(util.getStatement(0)) as api.FunctionDeclaration + + let body_statements = [ + api.createIfStatement( + api.createPropertyAccessExpression( + api.createIdentifier("__memo_scope"), + api.createIdentifier("unchanged") + ), + api.createReturnStatement( + api.createPropertyAccessExpression( + api.createIdentifier("__memo_scope"), + api.createIdentifier("cached") + ) + ), + undefined + ), + api.createExpressionStatement( + api.createCallExpression( + api.createIdentifier("content"), + undefined, + [ + api.createIdentifier("__memo_context"), + api.createBinaryExpression( + api.createIdentifier("__memo_id"), + api.createToken(api.SyntaxKind.PlusToken), + api.createStringLiteral("key_id_main.ts") + ) + ] + )), + api.createReturnStatement( + api.createCallExpression( + api.createPropertyAccessExpression( + api.createIdentifier("__memo_scope"), + api.createIdentifier("recache") + ) + ) + ), + ...testFunc.body!.statements + ] + + testFunc = util.addMemoParamsToFunctionDeclaration(testFunc) + + testFunc = api.updateFunctionDeclaration( + testFunc, + undefined, + undefined, + testFunc.name!, + undefined, + testFunc.parameters, + undefined, + api.updateBlock( + testFunc.body!, + body_statements + ) + ) + + util.assertEqualsGolden(api.dumpJsonNode(testFunc), this) + + api.proceedToState(api.ContextState.ES2PANDA_STATE_CHECKED) }) }) diff --git a/arkoala-arkts/libarkts/test/golden/builder-lambda-rewrite_adding-body-to-lambda-param.test.ts_dump b/arkoala-arkts/libarkts/test/golden/builder-lambda-rewrite_adding-body-to-lambda-param.test.ts_dump new file mode 100644 index 0000000000000000000000000000000000000000..19e83d1e6a7a20eaa22ab29a9bb87fb48949b298 --- /dev/null +++ b/arkoala-arkts/libarkts/test/golden/builder-lambda-rewrite_adding-body-to-lambda-param.test.ts_dump @@ -0,0 +1,93 @@ +{ + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "_Foo", + "decorators": [] + }, + "arguments": [ + { + "type": "ArrowFunctionExpression", + "function": { + "type": "ScriptFunction", + "id": null, + "generator": false, + "async": false, + "expression": false, + "params": [ + { + "type": "ETSParameterExpression", + "name": { + "type": "Identifier", + "name": "instance", + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "any", + "decorators": [] + } + } + }, + "decorators": [] + } + } + ], + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "MemberExpression", + "object": { + "type": "CallExpression", + "callee": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "instance", + "decorators": [] + }, + "property": { + "type": "Identifier", + "name": "bar", + "decorators": [] + }, + "computed": false, + "optional": false + }, + "arguments": [], + "optional": false + }, + "property": { + "type": "Identifier", + "name": "qux", + "decorators": [] + }, + "computed": false, + "optional": false + }, + "arguments": [], + "optional": false + } + } + ] + } + } + }, + { + "type": "StringLiteral", + "value": "label1" + }, + { + "type": "StringLiteral", + "value": "label2" + } + ], + "optional": false +} \ No newline at end of file diff --git a/arkoala-arkts/libarkts/test/golden/builder-lambda-rewrite_adding-lambda-param-to-signature.test.ts_dump b/arkoala-arkts/libarkts/test/golden/builder-lambda-rewrite_adding-lambda-param-to-signature.test.ts_dump new file mode 100644 index 0000000000000000000000000000000000000000..2676777ed3e402694af215e85caf52a5ef4d7790 --- /dev/null +++ b/arkoala-arkts/libarkts/test/golden/builder-lambda-rewrite_adding-lambda-param-to-signature.test.ts_dump @@ -0,0 +1,50 @@ +{ + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "_Foo", + "decorators": [] + }, + "arguments": [ + { + "type": "ArrowFunctionExpression", + "function": { + "type": "ScriptFunction", + "id": null, + "generator": false, + "async": false, + "expression": false, + "params": [ + { + "type": "ETSParameterExpression", + "name": { + "type": "Identifier", + "name": "instance", + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "any", + "decorators": [] + } + } + }, + "decorators": [] + } + } + ], + "body": { + "type": "BlockStatement", + "statements": [] + } + } + }, + { + "type": "StringLiteral", + "value": "label" + } + ], + "optional": false +} \ No newline at end of file diff --git a/arkoala-arkts/libarkts/test/golden/builder-lambda-rewrite_builder-lambda-transformer-sample-1.test.ts_dump b/arkoala-arkts/libarkts/test/golden/builder-lambda-rewrite_builder-lambda-transformer-sample-1.test.ts_dump new file mode 100644 index 0000000000000000000000000000000000000000..74c555ff85c4f550f15738aacceba12fabafb5f9 --- /dev/null +++ b/arkoala-arkts/libarkts/test/golden/builder-lambda-rewrite_builder-lambda-transformer-sample-1.test.ts_dump @@ -0,0 +1,67 @@ +{ + "type": "Program", + "statements": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "foo", + "decorators": [] + }, + "arguments": [ + { + "type": "ArrowFunctionExpression", + "function": { + "type": "ScriptFunction", + "id": null, + "generator": false, + "async": false, + "expression": false, + "params": [ + { + "type": "ETSParameterExpression", + "name": { + "type": "Identifier", + "name": "instance", + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "any", + "decorators": [] + } + } + }, + "decorators": [] + } + } + ], + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "Identifier", + "name": "instance", + "decorators": [] + } + } + ] + } + } + }, + { + "type": "StringLiteral", + "value": "label" + } + ], + "optional": false + } + } + ] +} \ No newline at end of file diff --git a/arkoala-arkts/libarkts/test/golden/builder-lambda-rewrite_builder-lambda-transformer-sample-2.test.ts_dump b/arkoala-arkts/libarkts/test/golden/builder-lambda-rewrite_builder-lambda-transformer-sample-2.test.ts_dump new file mode 100644 index 0000000000000000000000000000000000000000..f38314f65afdb4954358cec82c8b29c4f593d3ac --- /dev/null +++ b/arkoala-arkts/libarkts/test/golden/builder-lambda-rewrite_builder-lambda-transformer-sample-2.test.ts_dump @@ -0,0 +1,101 @@ +{ + "type": "Program", + "statements": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "foo", + "decorators": [] + }, + "arguments": [ + { + "type": "ArrowFunctionExpression", + "function": { + "type": "ScriptFunction", + "id": null, + "generator": false, + "async": false, + "expression": false, + "params": [ + { + "type": "ETSParameterExpression", + "name": { + "type": "Identifier", + "name": "instance", + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "any", + "decorators": [] + } + } + }, + "decorators": [] + } + } + ], + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "MemberExpression", + "object": { + "type": "CallExpression", + "callee": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "instance", + "decorators": [] + }, + "property": { + "type": "Identifier", + "name": "bar", + "decorators": [] + }, + "computed": false, + "optional": false + }, + "arguments": [], + "optional": false + }, + "property": { + "type": "Identifier", + "name": "qux", + "decorators": [] + }, + "computed": false, + "optional": false + }, + "arguments": [], + "optional": false + } + } + ] + } + } + }, + { + "type": "StringLiteral", + "value": "label1" + }, + { + "type": "StringLiteral", + "value": "label2" + } + ], + "optional": false + } + } + ] +} \ No newline at end of file diff --git a/arkoala-arkts/libarkts/test/golden/update-function-declaration_add-identifier-to-function-body.test.ts_dump b/arkoala-arkts/libarkts/test/golden/update-function-declaration_add-identifier-to-function-body.test.ts_dump new file mode 100644 index 0000000000000000000000000000000000000000..44d4b6777b0133567102c1c3620f148d5e683d7b --- /dev/null +++ b/arkoala-arkts/libarkts/test/golden/update-function-declaration_add-identifier-to-function-body.test.ts_dump @@ -0,0 +1,28 @@ +{ + "type": "FunctionDeclaration", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "foo", + "decorators": [] + }, + "generator": false, + "async": false, + "expression": false, + "params": [], + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "Identifier", + "name": "x", + "decorators": [] + } + } + ] + } + } +} \ No newline at end of file diff --git a/arkoala-arkts/libarkts/test/golden/update-function-declaration_add-if-statement-to-function-body.test.ts_dump b/arkoala-arkts/libarkts/test/golden/update-function-declaration_add-if-statement-to-function-body.test.ts_dump new file mode 100644 index 0000000000000000000000000000000000000000..1a1578cdf8d927eba45c089b5b9ba970231acb0b --- /dev/null +++ b/arkoala-arkts/libarkts/test/golden/update-function-declaration_add-if-statement-to-function-body.test.ts_dump @@ -0,0 +1,57 @@ +{ + "type": "FunctionDeclaration", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "foo", + "decorators": [] + }, + "generator": false, + "async": false, + "expression": false, + "params": [], + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "IfStatement", + "test": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "__memo_scope", + "decorators": [] + }, + "property": { + "type": "Identifier", + "name": "unchanged", + "decorators": [] + }, + "computed": false, + "optional": false + }, + "consequent": { + "type": "ReturnStatement", + "argument": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "__memo_scope", + "decorators": [] + }, + "property": { + "type": "Identifier", + "name": "cached", + "decorators": [] + }, + "computed": false, + "optional": false + } + }, + "alternate": null + } + ] + } + } +} \ No newline at end of file diff --git a/arkoala-arkts/libarkts/test/golden/update-function-declaration_add-property-access-expression-to-function-body.test.ts_dump b/arkoala-arkts/libarkts/test/golden/update-function-declaration_add-property-access-expression-to-function-body.test.ts_dump new file mode 100644 index 0000000000000000000000000000000000000000..f7d17b74f6f2b56eeda22d9313d49352894e754c --- /dev/null +++ b/arkoala-arkts/libarkts/test/golden/update-function-declaration_add-property-access-expression-to-function-body.test.ts_dump @@ -0,0 +1,38 @@ +{ + "type": "FunctionDeclaration", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "foo", + "decorators": [] + }, + "generator": false, + "async": false, + "expression": false, + "params": [], + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "__memo_scope", + "decorators": [] + }, + "property": { + "type": "Identifier", + "name": "recache", + "decorators": [] + }, + "computed": false, + "optional": false + } + } + ] + } + } +} \ No newline at end of file diff --git a/arkoala-arkts/libarkts/test/golden/update-function-declaration_add-return-statement-to-function-body.test.ts_dump b/arkoala-arkts/libarkts/test/golden/update-function-declaration_add-return-statement-to-function-body.test.ts_dump new file mode 100644 index 0000000000000000000000000000000000000000..7b5560cff7918252569ada462128daec835e8169 --- /dev/null +++ b/arkoala-arkts/libarkts/test/golden/update-function-declaration_add-return-statement-to-function-body.test.ts_dump @@ -0,0 +1,43 @@ +{ + "type": "FunctionDeclaration", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "foo", + "decorators": [] + }, + "generator": false, + "async": false, + "expression": false, + "params": [], + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "ReturnStatement", + "argument": { + "type": "CallExpression", + "callee": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "__memo_scope", + "decorators": [] + }, + "property": { + "type": "Identifier", + "name": "recache", + "decorators": [] + }, + "computed": false, + "optional": false + }, + "arguments": [], + "optional": false + } + } + ] + } + } +} \ No newline at end of file diff --git a/arkoala-arkts/libarkts/test/golden/update-function-declaration_function-declaration-memo-rewrite.test.ts_dump b/arkoala-arkts/libarkts/test/golden/update-function-declaration_function-declaration-memo-rewrite.test.ts_dump new file mode 100644 index 0000000000000000000000000000000000000000..aa97fb990b4249a13ba0bef13960856d82f74714 --- /dev/null +++ b/arkoala-arkts/libarkts/test/golden/update-function-declaration_function-declaration-memo-rewrite.test.ts_dump @@ -0,0 +1,151 @@ +{ + "type": "FunctionDeclaration", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "foo", + "decorators": [] + }, + "generator": false, + "async": false, + "expression": false, + "params": [ + { + "type": "ETSParameterExpression", + "name": { + "type": "Identifier", + "name": "__memo_context", + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "__memo_context_type", + "decorators": [] + } + } + }, + "decorators": [] + } + }, + { + "type": "ETSParameterExpression", + "name": { + "type": "Identifier", + "name": "__memo_id", + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "__memo_id_type", + "decorators": [] + } + } + }, + "decorators": [] + } + } + ], + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "IfStatement", + "test": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "__memo_scope", + "decorators": [] + }, + "property": { + "type": "Identifier", + "name": "unchanged", + "decorators": [] + }, + "computed": false, + "optional": false + }, + "consequent": { + "type": "ReturnStatement", + "argument": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "__memo_scope", + "decorators": [] + }, + "property": { + "type": "Identifier", + "name": "cached", + "decorators": [] + }, + "computed": false, + "optional": false + } + }, + "alternate": null + }, + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "content", + "decorators": [] + }, + "arguments": [ + { + "type": "Identifier", + "name": "__memo_context", + "decorators": [] + }, + { + "type": "BinaryExpression", + "operator": "+", + "left": { + "type": "Identifier", + "name": "__memo_id", + "decorators": [] + }, + "right": { + "type": "StringLiteral", + "value": "key_id_main.ts" + } + } + ], + "optional": false + } + }, + { + "type": "ReturnStatement", + "argument": { + "type": "CallExpression", + "callee": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "__memo_scope", + "decorators": [] + }, + "property": { + "type": "Identifier", + "name": "recache", + "decorators": [] + }, + "computed": false, + "optional": false + }, + "arguments": [], + "optional": false + } + } + ] + } + } +} \ No newline at end of file diff --git a/arkoala-arkts/libarkts/test/test-util.ts b/arkoala-arkts/libarkts/test/test-util.ts index 4193af150c5c76dacefa5dafb51daa67ad79b84e..8a185a8ed2825770d4c43641bfccfe260615df6f 100644 --- a/arkoala-arkts/libarkts/test/test-util.ts +++ b/arkoala-arkts/libarkts/test/test-util.ts @@ -21,25 +21,22 @@ import { nativeModule } from "../src/NativeModule" import { NativePtrDecoder } from "../src/node/Platform" import { assert } from "chai" -function getDefaultConfigFileName(): string { - return "./input/main.ts" -} - -function getDefaultConfig() { - const arktsconfig = "./arktsconfig.json" - return ["--arktsconfig", arktsconfig, getDefaultConfigFileName()] +class DefaultConfig { + static readonly configFile = "./arktsconfig.json" + static readonly sourceFile = "./input/main.sts" + static readonly config = ["", "--arktsconfig", this.configFile, this.sourceFile] } export function getDefaultSetup(source: string): void { if (!api.Global.isInitializedConfig()) { - api.Global.config = api.createConfig(getDefaultConfig()) + api.Global.config = api.createConfig(DefaultConfig.config) } - api.Global.context = api.createContextFromString(api.Global.config, source, getDefaultConfigFileName()) + api.Global.context = api.createContextFromString(api.Global.config, source, DefaultConfig.sourceFile) + api.proceedToState(api.ContextState.ES2PANDA_STATE_PARSED) } export class AstProvider { public static provideAst(): KNativePointer { - api.proceedToState(api.ContextState.ES2PANDA_STATE_PARSED) const program = api.contextProgram() const peer = api.programAst(program) return peer @@ -68,5 +65,28 @@ export function assertEqualsGolden(text: string, testCtx: Mocha.Context) { assert.equal(text, loadGoldenDump(testCtx.test!.parent!.title, testCtx.test!.title)) } +export function dumpFirst() { + return api.dumpJson(getStatement(0)) +} + +export function addMemoParamsToFunctionDeclaration(func: api.FunctionDeclaration): api.FunctionDeclaration { + const oldParams = func.parameters + const memoContextAnnotation = api.createTypeReferenceNode(api.createIdentifier("__memo_context_type")) + const memoContextParam = api.createParameterDeclaration(undefined, undefined, api.createIdentifier("__memo_context", memoContextAnnotation)) + const memoIdAnnotation = api.createTypeReferenceNode(api.createIdentifier("__memo_id_type")) + const memoIdParam = api.createParameterDeclaration(undefined, undefined, api.createIdentifier("__memo_id", memoIdAnnotation)) + const newParams = [memoContextParam, memoIdParam, ...oldParams] + return api.updateFunctionDeclaration( + func, + undefined, + undefined, + func.name!, + undefined, + newParams, + undefined, + func.body + ) +} + export { nativeModule } from "../src/NativeModule" export { assert } from "chai"