diff --git a/arkoala-arkts/libarkts/native/src/es2panda_lib.cc b/arkoala-arkts/libarkts/native/src/es2panda_lib.cc index f05b77d8720df44de32b6b012ab3f2b468ce7510..5ddb63afedfb17a1634e4bb6a47ee2d0d04b0615 100644 --- a/arkoala-arkts/libarkts/native/src/es2panda_lib.cc +++ b/arkoala-arkts/libarkts/native/src/es2panda_lib.cc @@ -137,7 +137,8 @@ KOALA_INTEROP_2(IdentifierName, KNativePointer, KNativePointer, KNativePointer) KNativePointer impl_CreateIdentifier(KNativePointer contextPtr, KStringPtr namePtr) { auto context = reinterpret_cast(contextPtr); - return GetImpl()->CreateIdentifier1(context, getStringCopy(namePtr)); + return GetImpl()->CreateIdentifier2(context, getStringCopy(namePtr), GetImpl()->CreateETSPrimitiveType0(context, PRIMITIVE_TYPE_INT)); + // return GetImpl()->CreateIdentifier1(context, getStringCopy(namePtr)); } KOALA_INTEROP_2(CreateIdentifier, KNativePointer, KNativePointer, KStringPtr) @@ -154,12 +155,12 @@ KNativePointer impl_StringLiteralString(KNativePointer contextPtr, KNativePointe } KOALA_INTEROP_2(StringLiteralString, KNativePointer, KNativePointer, KNativePointer) -KNativePointer impl_AstNodeDumpJson(KNativePointer contextPtr, KNativePointer nodePtr) { +KNativePointer impl_AstNodeDumpJsonConst(KNativePointer contextPtr, KNativePointer nodePtr) { auto context = reinterpret_cast(contextPtr); auto node = reinterpret_cast(nodePtr); - return new string(GetImpl()->AstNodeDumpJSON(context, node)); + return new string(GetImpl()->AstNodeDumpJSONConst(context, node)); } -KOALA_INTEROP_2(AstNodeDumpJson, KNativePointer, KNativePointer, KNativePointer) +KOALA_INTEROP_2(AstNodeDumpJsonConst, KNativePointer, KNativePointer, KNativePointer) /* TODO: AstNodeKind should be provided by es2panda @@ -206,7 +207,7 @@ KOALA_INTEROP_1(GetKind, KInt, KNativePointer) KBoolean impl_IsProgram(KNativePointer contextPtr, KNativePointer nodePtr) { auto context = reinterpret_cast(contextPtr); auto node = reinterpret_cast(nodePtr); - return GetImpl()->AstNodeIsProgram(context, node); + return GetImpl()->AstNodeIsProgramConst(context, node); } KOALA_INTEROP_2(IsProgram, KBoolean, KNativePointer, KNativePointer) @@ -240,3 +241,38 @@ KNativePointer impl_ClassDefinitionBody(KNativePointer contextPtr, KNativePointe return new std::vector(body, body + n); } KOALA_INTEROP_2(ClassDefinitionBody, KNativePointer, KNativePointer, KNativePointer) + +KNativePointer impl_CreateFunctionDeclaration(KNativePointer contextPtr, KStringPtr stringPtr, KNativePointerArray paramsPtr, KInt paramsLen) { + auto context = reinterpret_cast(contextPtr); + auto name = getStringCopy(stringPtr); + auto parameters = reinterpret_cast(paramsPtr); + + es2panda_AstNode* firstStatement = nullptr; + es2panda_AstNode* firstParam = nullptr; + auto function_body = GetImpl()->CreateBlockStatement0(context, &firstStatement, 0); + + // auto return_type = GetImpl()->CreateETSPrimitiveType0(context, PRIMITIVE_TYPE_VOID); + 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); +} +KOALA_INTEROP_4(CreateFunctionDeclaration, KNativePointer, KNativePointer, KStringPtr, KNativePointerArray, KInt) + +// TODO: add param initializer +KNativePointer impl_CreateETSParameterExpression(KNativePointer contextPtr, KNativePointer identifierPtr) { + auto context = reinterpret_cast(contextPtr); + auto identifier = reinterpret_cast(identifierPtr); + + auto result = GetImpl()->CreateETSParameterExpression0(context, identifier, nullptr); + return result; +} +KOALA_INTEROP_2(CreateETSParameterExpression, KNativePointer, KNativePointer, KNativePointer) diff --git a/arkoala-arkts/libarkts/native/src/for_debug.cc b/arkoala-arkts/libarkts/native/src/for_debug.cc index c0c1444cb24a747cb9827433eb25ac56f588fec1..c811085df7500e4b34890bdf3f1746c128d394a9 100644 --- a/arkoala-arkts/libarkts/native/src/for_debug.cc +++ b/arkoala-arkts/libarkts/native/src/for_debug.cc @@ -23,6 +23,17 @@ es2panda_Impl *GetImpl() { return impl; } +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"); + + GetImpl()->ProceedToState(context, ES2PANDA_STATE_PARSED); + auto program = GetImpl()->ContextProgram(context); + auto peer = GetImpl()->ProgramAst(program); + // playground } diff --git a/arkoala-arkts/libarkts/src/NativeModule.ts b/arkoala-arkts/libarkts/src/NativeModule.ts index 5071092ed41a4745ea35d203b81d8662f9423c7f..f2584edb284e83d12a611f9380399ae765012c0e 100644 --- a/arkoala-arkts/libarkts/src/NativeModule.ts +++ b/arkoala-arkts/libarkts/src/NativeModule.ts @@ -13,8 +13,7 @@ * limitations under the License. */ -import { KBoolean, KInt, pointer } from "@koalaui/interop" -export { pointer } from "@koalaui/interop" +import { KBoolean, KInt, KNativePointer, pointer } from "@koalaui/interop" import * as path from "path" export interface NativeModule { @@ -43,6 +42,8 @@ export interface NativeModule { _PropertyAccessExpressionGetName(node: pointer): pointer _CreateIdentifier(context: pointer, name: string): pointer + _CreateFunctionDeclaration(context: pointer, name: string, parameters: BigUint64Array, paramsLen: KInt): pointer + _CreateETSParameterExpression(context: pointer, identifier: pointer): pointer _IsIdentifier(node: pointer): KBoolean _IdentifierName(context: pointer, node: pointer): pointer @@ -56,7 +57,7 @@ export interface NativeModule { _ClassDefinitionBody(context: pointer, node: pointer): pointer _IsProgram(context: pointer, node: pointer): KBoolean - _AstNodeDumpJson(context: pointer, node: pointer): pointer + _AstNodeDumpJsonConst(context: pointer, node: pointer): pointer } const backend = process.env.backend ?? 'es2panda' diff --git a/arkoala-arkts/libarkts/src/arkts/factory/nodeImpls.ts b/arkoala-arkts/libarkts/src/arkts/factory/nodeImpls.ts index e37a0ef8bbb39356276eb3e48ad50319399e4559..3c9270492907b9e3a041701e24c8f2b83a5b2100 100644 --- a/arkoala-arkts/libarkts/src/arkts/factory/nodeImpls.ts +++ b/arkoala-arkts/libarkts/src/arkts/factory/nodeImpls.ts @@ -15,7 +15,7 @@ import * as api from "../index" -import { fromPtrArray, pointer as NativePtr, withString, withStringArray, withStringResult } from "@koalaui/interop" +import { Access, fromPtrArray, KNativePointer, KPointer, pointer as NativePtr, withPtrArray, withString, withStringArray, withStringResult } from "@koalaui/interop" import { nativeModule } from "../../NativeModule" import "../../node/Platform" import { NativePtrDecoder } from "../../node/Platform" @@ -78,11 +78,15 @@ function unpack(context: NativePtr, arrayPtr: NativePtr): ReadonlyArray | undefined + + get name(): api.BindingName { + return todo() + } + + questionToken?: api.QuestionToken | undefined + exclamationToken?: api.ExclamationToken | undefined + + get parameters(): api.NodeArray { + return todo() + } + + type?: api.TypeNode | undefined + _classElementBrand: any + + constructor(context: NativePtr, peer: NativePtr) { + super(context, peer) + } + + _declarationBrand: any + kind: api.SyntaxKind.Parameter = api.SyntaxKind.Parameter; + initializer?: api.Expression; +} + class UnsupportedNode extends NodeImpl implements api.Node { kind: api.SyntaxKind = -1 @@ -521,7 +555,8 @@ enum es2pandaKind { MethodDeclaration = 4, ClassDeclaration = 5, FunctionDeclaration = 6, - ClassProperty = 7, + PropertyDeclaration = 7, + Parameter = 8, UnsupportedNode = -1, } @@ -533,7 +568,8 @@ const kinds = new Map([ [es2pandaKind.MethodDeclaration, api.SyntaxKind.MethodDeclaration], [es2pandaKind.ClassDeclaration, api.SyntaxKind.ClassDeclaration], [es2pandaKind.FunctionDeclaration, api.SyntaxKind.FunctionDeclaration], - [es2pandaKind.ClassProperty, api.SyntaxKind.PropertyDeclaration], + [es2pandaKind.PropertyDeclaration, api.SyntaxKind.PropertyDeclaration], + [es2pandaKind.Parameter, api.SyntaxKind.Parameter], ]) export function makeView(context: NativePtr, peer: NativePtr): api.Node { @@ -554,6 +590,7 @@ export function makeView(context: NativePtr, peer: NativePtr): api.Node { if (kind == api.SyntaxKind.ClassDeclaration) return new ClassDeclarationImpl(context, peer) if (kind == api.SyntaxKind.FunctionDeclaration) return new FunctionDeclarationImpl(context, peer) if (kind == api.SyntaxKind.PropertyDeclaration) return new PropertyDeclarationImpl(context, peer) + if (kind == api.SyntaxKind.Parameter) return new ParameterDeclarationImpl(context, peer) throw new Error(`Unknown node kind ${kind}`) } @@ -574,6 +611,39 @@ export function createStringLiteral(context: NativePtr, s: string): api.StringLi return new StringLiteralImpl(context, peer) } +export function createFunctionDeclaration(context: NativePtr, name: string, parameter_nodes: api.ParameterDeclaration[]): api.FunctionDeclaration { + // is it ok then NativePtr = bigint | number is number? + const parameters: BigUint64Array = 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(context, name, parameters, parameters.length) + }) + }) + + return new FunctionDeclarationImpl(context, peer) +} + +export function createParameterDeclaration(context: NativePtr, identifier: api.Identifier): api.ParameterDeclaration { + const peer = nativeModule._CreateETSParameterExpression(context, getPeer(identifier)!) + + return new ParameterDeclarationImpl(context, peer) +} + export function dumpJson(context: NativePtr, peer: NativePtr): string | undefined { - return withStringResult(nativeModule._AstNodeDumpJson(context, peer)) + return withStringResult(nativeModule._AstNodeDumpJsonConst(context, peer)) +} + +export function dumpJsonNode(node: api.Node): string | undefined { + if (node instanceof NodeImpl) { + return dumpJson(node.context, node.peer) + } + return undefined +} + +export function getPeer(node: api.Node): NativePtr | undefined { + if (node instanceof NodeImpl) { + return node.peer + } + return undefined } diff --git a/arkoala-arkts/libarkts/src/arkts/index.ts b/arkoala-arkts/libarkts/src/arkts/index.ts index ce097dabfbc5ab24be7d9ac5babc8c371b33818c..5d61659f6670898b266742db4aff6c3b67796934 100644 --- a/arkoala-arkts/libarkts/src/arkts/index.ts +++ b/arkoala-arkts/libarkts/src/arkts/index.ts @@ -69,5 +69,8 @@ export { Program, TransformationContext, PropertyDeclaration, + TypeParameter, + BindingName, + SignatureDeclaration, } from "typescript" export * from "./factory/nodeImpls" diff --git a/arkoala-arkts/libarkts/test/es2panda/create-function-declaration.test.ts b/arkoala-arkts/libarkts/test/es2panda/create-function-declaration.test.ts new file mode 100644 index 0000000000000000000000000000000000000000..7bd6c2486c9abc69f54657309e50326bc8ac642e --- /dev/null +++ b/arkoala-arkts/libarkts/test/es2panda/create-function-declaration.test.ts @@ -0,0 +1,49 @@ +import * as api from "../../src/arkts" +import { assert } from "chai" +import { AstProvider, ContextProvider } from "../common" +import { nativeModule } from "src/NativeModule" +import { NativePtrDecoder } from "../../src/node/Platform" + +suite("create function declaration tests", () => { + test("empty function", () => { + const sample = + ` + function test_func() { + // empty + } + ` + const context = ContextProvider.provideContext(sample) + const peer = AstProvider.provideAst(context) + + const decoder = new NativePtrDecoder() + const program_statements = decoder.decode(nativeModule._BlockStatementStatements(context, peer)) + const expected_output = api.dumpJson(context, program_statements[0]) + + const funcDecl = api.createFunctionDeclaration(context, "test_func", []) + const output = api.dumpJsonNode(funcDecl) + + assert.equal(output!.trim(), expected_output!.trim()) + }) + + test("empty function with param", () => { + const sample = + ` + function test_func(x: int) { + // empty + } + ` + const context = ContextProvider.provideContext(sample) + const peer = AstProvider.provideAst(context) + + const decoder = new NativePtrDecoder() + const program_statements = decoder.decode(nativeModule._BlockStatementStatements(context, peer)) + const expected_output = api.dumpJson(context, program_statements[0]) + + const funcParams = [api.createParameterDeclaration(context, api.createIdentifier(context, "x"))] + + const funcDecl = api.createFunctionDeclaration(context, "test_func", funcParams) + const output = api.dumpJsonNode(funcDecl) + + assert.equal(output!.trim(), expected_output!.trim()) + }) +}) diff --git a/arkoala-arkts/libarkts/test/es2panda/create-node.test.ts b/arkoala-arkts/libarkts/test/es2panda/create-node.test.ts index ffa99bbd47c9365df26e81071403ea93f182a93a..5a174bbc1f99ff5694d5b67b424a317a0914c905 100644 --- a/arkoala-arkts/libarkts/test/es2panda/create-node.test.ts +++ b/arkoala-arkts/libarkts/test/es2panda/create-node.test.ts @@ -2,7 +2,7 @@ import { assert } from "chai" import * as api from "../../src/arkts" import { ContextProvider } from "../common"; -suite("basic test", () => { +suite("create node test", () => { test("create & isNode", () => { const context = ContextProvider.provideContext('')