From 1f148d3e36a1e31545516298fa7271c1e0723d87 Mon Sep 17 00:00:00 2001 From: chernishevvictor Date: Tue, 24 Sep 2024 19:49:00 +0300 Subject: [PATCH 1/6] add create-function-declaration test add update-function-declaration test context brought out + review fix native types refactoring add golden for tests + review fix add test-util and some refactoring adding memo params in function signature and some refactoring add new tests with body changing updateBlock and updateFunctionDeclaration rewrite function declaration body updates context creation bug fixed + added type checking at the end for tests function delcaration full memo rewrite add some native functions moving impl details from lib to api --- .../libarkts/native/src/es2panda_lib.cc | 344 ++++++++++++++---- .../libarkts/native/src/playground.cc | 4 - arkoala-arkts/libarkts/src/NativeModule.ts | 33 +- .../libarkts/src/arkts/factory/nodeImpls.ts | 319 ++++++++++++++-- arkoala-arkts/libarkts/src/arkts/index.ts | 6 + arkoala-arkts/libarkts/src/es2panda.ts | 1 + .../create-function-declaration.test.ts | 30 +- .../test/es2panda/create-node.test.ts | 2 + .../es2panda/lambda-param-memoization.test.ts | 39 ++ .../update-function-declaration.test.ts | 317 +++++++++++++++- ...d-identifier-to-function-body.test.ts_dump | 28 ++ ...if-statement-to-function-body.test.ts_dump | 57 +++ ...s-expression-to-function-body.test.ts_dump | 38 ++ ...rn-statement-to-function-body.test.ts_dump | 43 +++ ...tion-declaration-memo-rewrite.test.ts_dump | 151 ++++++++ arkoala-arkts/libarkts/test/test-util.ts | 27 +- 16 files changed, 1317 insertions(+), 122 deletions(-) create mode 100644 arkoala-arkts/libarkts/test/es2panda/lambda-param-memoization.test.ts create mode 100644 arkoala-arkts/libarkts/test/golden/update-function-declaration_add-identifier-to-function-body.test.ts_dump create mode 100644 arkoala-arkts/libarkts/test/golden/update-function-declaration_add-if-statement-to-function-body.test.ts_dump create mode 100644 arkoala-arkts/libarkts/test/golden/update-function-declaration_add-property-access-expression-to-function-body.test.ts_dump create mode 100644 arkoala-arkts/libarkts/test/golden/update-function-declaration_add-return-statement-to-function-body.test.ts_dump create mode 100644 arkoala-arkts/libarkts/test/golden/update-function-declaration_function-declaration-memo-rewrite.test.ts_dump diff --git a/arkoala-arkts/libarkts/native/src/es2panda_lib.cc b/arkoala-arkts/libarkts/native/src/es2panda_lib.cc index 9d7d8defd..ad3b19799 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,7 @@ enum AstNodeKind { FunctionDeclaration = 6, ClassProperty = 7, TSTypeParameterDeclaration = 8, + ETSFunctionType = 9, }; KInt impl_GetKind(KNativePointer nodePtr) { @@ -208,9 +207,12 @@ 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; + } return -1; } @@ -277,83 +279,285 @@ 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 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); + auto func = reinterpret_cast(funcPtr); + auto isAnon = static_cast(isAnonK); - 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_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_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_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_4(CreateETSTypeReferencePart0, KNativePointer, KNativePointer, KNativePointer, KNativePointer, KNativePointer) +KOALA_INTEROP_3(ScriptFunctionUpdateIrSignature, KNativePointer, KNativePointer, KNativePointer, KNativePointer) diff --git a/arkoala-arkts/libarkts/native/src/playground.cc b/arkoala-arkts/libarkts/native/src/playground.cc index c811085df..170a05bf1 100644 --- a/arkoala-arkts/libarkts/native/src/playground.cc +++ b/arkoala-arkts/libarkts/native/src/playground.cc @@ -31,9 +31,5 @@ int main() { 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 861d93b33..9b075d018 100644 --- a/arkoala-arkts/libarkts/src/NativeModule.ts +++ b/arkoala-arkts/libarkts/src/NativeModule.ts @@ -45,14 +45,37 @@ 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 + _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 + _CreateCallExpression(context: KNativePointer, callee: KNativePointer, args: BigUint64Array, argsLen: KInt, typeParams: KNativePointer, optional: KBoolean, trailingComma: KBoolean): KNativePointer + + _CreateExpressionStatement(context: 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 diff --git a/arkoala-arkts/libarkts/src/arkts/factory/nodeImpls.ts b/arkoala-arkts/libarkts/src/arkts/factory/nodeImpls.ts index 2b5eccbb3..702206754 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 { @@ -70,9 +74,8 @@ export class Global { 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) }) } @@ -155,7 +158,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 { @@ -422,15 +425,98 @@ 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 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 +525,7 @@ enum es2pandaKind { FunctionDeclaration = 6, PropertyDeclaration = 7, Parameter = 8, - - UnsupportedNode = -1, + ETSFunctionType = 9, } const kinds = new Map([ @@ -452,6 +537,7 @@ const kinds = new Map([ [es2pandaKind.FunctionDeclaration, api.SyntaxKind.FunctionDeclaration], [es2pandaKind.PropertyDeclaration, api.SyntaxKind.PropertyDeclaration], [es2pandaKind.Parameter, api.SyntaxKind.Parameter], + [es2pandaKind.ETSFunctionType, api.SyntaxKind.FunctionType], ]) export function makeView(peer: KNativePointer): api.Node { @@ -474,13 +560,14 @@ 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) 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,24 +581,114 @@ 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 + ) }) }) @@ -555,7 +732,7 @@ 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) } @@ -566,8 +743,8 @@ const keywords = new Map([ ]) 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) } @@ -576,7 +753,89 @@ export function createKeywordTypeNode(TKind: api.KeywordTypeSyntaxKind): api.Key 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 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) +} + +// 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: 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) +} diff --git a/arkoala-arkts/libarkts/src/arkts/index.ts b/arkoala-arkts/libarkts/src/arkts/index.ts index 965ffbde0..1fe3a78b5 100644 --- a/arkoala-arkts/libarkts/src/arkts/index.ts +++ b/arkoala-arkts/libarkts/src/arkts/index.ts @@ -75,5 +75,11 @@ export { KeywordTypeNode, KeywordTypeSyntaxKind, TypeReferenceNode, + FunctionTypeNode, + ReturnStatement, + IfStatement, + BinaryOperatorToken, + TokenSyntaxKind, + BinaryExpression, } from "typescript" export * from "./factory/nodeImpls" diff --git a/arkoala-arkts/libarkts/src/es2panda.ts b/arkoala-arkts/libarkts/src/es2panda.ts index 79da6181d..df84093e3 100644 --- a/arkoala-arkts/libarkts/src/es2panda.ts +++ b/arkoala-arkts/libarkts/src/es2panda.ts @@ -25,6 +25,7 @@ function parseCommandLineArgs() { function es2panda(configPath: string, filePath: string, transform: (ast: arkts.Node) => arkts.Node) { const source = fs.readFileSync(filePath).toString() const cfg = arkts.createConfig([ + '_', '--arktsconfig', configPath, filePath 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 5fe15c199..bd42c5964 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) }) @@ -23,8 +34,21 @@ suite(util.getSuiteTitle(__filename), () => { const typeAnnotation = api.createKeywordTypeNode(api.SyntaxKind.NumberKeyword) const funcParams = [api.createParameterDeclaration(api.createIdentifier("x", typeAnnotation))] - const funcDeclaration = api.createFunctionDeclaration("test_func", funcParams) + 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 3eee20cd0..c40d9131c 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 000000000..1bccd2ecb --- /dev/null +++ b/arkoala-arkts/libarkts/test/es2panda/lambda-param-memoization.test.ts @@ -0,0 +1,39 @@ +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.getDefaultSetup(sample_in) + + // console.log(util.dumpFirst()) + + // let testFunc = api.makeView(util.getStatement(0)) as api.FunctionDeclaration + + // util.assertEqualsGolden(api.dumpJsonNode(testFunc), this) + + // api.proceedToState(api.ContextState.ES2PANDA_STATE_CHECKED) + }) +}) 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 7c7bf9fc0..14498f362 100644 --- a/arkoala-arkts/libarkts/test/es2panda/update-function-declaration.test.ts +++ b/arkoala-arkts/libarkts/test/es2panda/update-function-declaration.test.ts @@ -23,9 +23,20 @@ suite(util.getSuiteTitle(__filename), () => { const newParamTypeAnnotation = api.createKeywordTypeNode(api.SyntaxKind.StringKeyword) const newParam = api.createParameterDeclaration(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) }) test("add-params-to-memo-function", function() { @@ -45,14 +56,304 @@ suite(util.getSuiteTitle(__filename), () => { 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) + + testFunc = util.addMemoParamsToFunctionDeclaration(testFunc) + + util.assertEqualsGolden(api.dumpJsonNode(testFunc), this) + + api.proceedToState(api.ContextState.ES2PANDA_STATE_CHECKED) + }) + + test("add-identifier-to-function-body", function() { + const sample_in = + ` + function foo() { + // empty + } + ` + + // adding identifier x + + const sample_out = + ` + function foo() { + x + } + ` + + 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_BIN_GENERATED) + }) + + test("add-property-access-expression-to-function-body", function() { + const sample_in = + ` + function foo() { + // empty + } + ` + + // adding __memo_scope.recache + + // const sample_out = + // ` + // function foo() { + // __memo_scope.recache + // } + // ` + + util.getDefaultSetup(sample_in) + + let testFunc = api.makeView(util.getStatement(0)) as api.FunctionDeclaration + + 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) + }) + + test("add-return-statement-to-function-body", function() { + const sample_in = + ` + function foo() { + // empty + } + ` + + // body memo rewrite (adding return statement) + + // const sample_out = + // ` + // function foo() { + // // if (__memo_scope.unchanged) + // // return __memo_scope.cached + // // content(__memo_context, __memo_id + "key_id_main.ts") + // return __memo_scope.recache() + // } + // ` + + 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) + }) + + test("add-if-statement-to-function-body", function() { + const sample_in = + ` + function foo() { + // empty + } + ` + + // body memo rewrite (adding if statement) + + // const sample_out = + // ` + // function foo() { + // if (__memo_scope.unchanged) + // return __memo_scope.cached + // // content(__memo_context, __memo_id + "key_id_main.ts") + // // return __memo_scope.recache() + // } + // ` + + 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) + }) + + test("function-declaration-memo-rewrite", function() { + const sample_in = + ` + function foo() { + // empty + } + ` + + // body memo rewrite + + // const sample_out = + // ` + // 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() + // } + // ` + + 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/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 000000000..44d4b6777 --- /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 000000000..1a1578cdf --- /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 000000000..f7d17b74f --- /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 000000000..7b5560cff --- /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 000000000..aa97fb990 --- /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 4193af150..95ae66248 100644 --- a/arkoala-arkts/libarkts/test/test-util.ts +++ b/arkoala-arkts/libarkts/test/test-util.ts @@ -27,7 +27,7 @@ function getDefaultConfigFileName(): string { function getDefaultConfig() { const arktsconfig = "./arktsconfig.json" - return ["--arktsconfig", arktsconfig, getDefaultConfigFileName()] + return ["_", "--arktsconfig", arktsconfig, getDefaultConfigFileName()] } export function getDefaultSetup(source: string): void { @@ -35,11 +35,11 @@ export function getDefaultSetup(source: string): void { api.Global.config = api.createConfig(getDefaultConfig()) } api.Global.context = api.createContextFromString(api.Global.config, source, getDefaultConfigFileName()) + 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 +68,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(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] + return api.updateFunctionDeclaration( + func, + undefined, + undefined, + func.name!, + undefined, + newParams, + undefined, + func.body + ) +} + export { nativeModule } from "../src/NativeModule" export { assert } from "chai" -- Gitee From e6a76f9681b5a99caeb98bcedada583c47f955c0 Mon Sep 17 00:00:00 2001 From: chernishevvictor Date: Fri, 4 Oct 2024 12:04:56 +0300 Subject: [PATCH 2/6] add builder-lambda first step test --- arkoala-arkts/libarkts/arktsconfig.json | 6 +- .../libarkts/native/src/es2panda_lib.cc | 55 ++++++++ .../libarkts/native/src/playground.cc | 77 ++++++++++- arkoala-arkts/libarkts/src/NativeModule.ts | 6 +- .../libarkts/src/arkts/factory/nodeImpls.ts | 126 ++++++++++++++++-- arkoala-arkts/libarkts/src/arkts/index.ts | 1 + .../create-function-declaration.test.ts | 8 +- .../es2panda/lambda-param-memoization.test.ts | 10 +- .../update-function-declaration.test.ts | 4 +- arkoala-arkts/libarkts/test/test-util.ts | 4 +- 10 files changed, 263 insertions(+), 34 deletions(-) diff --git a/arkoala-arkts/libarkts/arktsconfig.json b/arkoala-arkts/libarkts/arktsconfig.json index 8152e95b0..44bd3ebfa 100644 --- a/arkoala-arkts/libarkts/arktsconfig.json +++ b/arkoala-arkts/libarkts/arktsconfig.json @@ -1,12 +1,12 @@ { "compilerOptions": { - "baseUrl": "node_modules/@panda/sdk", + "baseUrl": "/home/huawei/arkts/arkcompiler/runtime_core/static_core", "paths": { "std": [ - "./ets/stdlib/std" + "/home/huawei/arkts/arkcompiler/runtime_core/static_core/plugins/ets/stdlib/std" ], "escompat": [ - "./ets/stdlib/escompat" + "/home/huawei/arkts/arkcompiler/runtime_core/static_core/plugins/ets/stdlib/escompat" ] }, "plugins": [ diff --git a/arkoala-arkts/libarkts/native/src/es2panda_lib.cc b/arkoala-arkts/libarkts/native/src/es2panda_lib.cc index ad3b19799..dd69104cf 100644 --- a/arkoala-arkts/libarkts/native/src/es2panda_lib.cc +++ b/arkoala-arkts/libarkts/native/src/es2panda_lib.cc @@ -181,6 +181,8 @@ enum AstNodeKind { ClassProperty = 7, TSTypeParameterDeclaration = 8, ETSFunctionType = 9, + CallExpression = 10, + ExpressionStatement = 11, }; KInt impl_GetKind(KNativePointer nodePtr) { @@ -213,6 +215,12 @@ KInt impl_GetKind(KNativePointer nodePtr) { if (GetImpl()->IsETSFunctionType(node)) { return AstNodeKind::ETSFunctionType; } + if (GetImpl()->IsCallExpression(node)) { + return AstNodeKind::CallExpression; + } + if (GetImpl()->IsExpressionStatement(node)) { + return AstNodeKind::ExpressionStatement; + } return -1; } @@ -406,6 +414,28 @@ KNativePointer impl_CreateCallExpression( } KOALA_INTEROP_7(CreateCallExpression, KNativePointer, KNativePointer, KNativePointer, KNativePointerArray, KInt, KNativePointer, KBoolean, KBoolean) +KNativePointer impl_UpdateCallExpression( + KNativePointer nodePtr, + KNativePointer contextPtr, + 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); @@ -561,3 +591,28 @@ KNativePointer impl_ScriptFunctionUpdateIrSignature(KNativePointer contextPtr, K 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) diff --git a/arkoala-arkts/libarkts/native/src/playground.cc b/arkoala-arkts/libarkts/native/src/playground.cc index 170a05bf1..e4ffda24c 100644 --- a/arkoala-arkts/libarkts/native/src/playground.cc +++ b/arkoala-arkts/libarkts/native/src/playground.cc @@ -23,13 +23,78 @@ es2panda_Impl *GetImpl() { return impl; } -static char* source = ""; +static char* source = "console.log('Hello world')"; 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"); + // 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"); - // playground + // std::cout << "ARGC: " << argc << std::endl; + + const char* args[] = {"/home/huawei/arkcompiler_ets_frontend/incremental/tools/panda/node_modules/@panda/sdk/linux_host_tools/bin/es2panda", "../input/main.ts"}; + // const char* args[] = {"/home/huawei/arkcompiler_ets_frontend/arkoala-arkts/libarkts/arktsconfig.json", "../input/main.ts"}; + auto config = GetImpl()->CreateConfig(2, args); + auto context = GetImpl()->CreateContextFromString(config, "", "../input/main.ts"); + + 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/src/NativeModule.ts b/arkoala-arkts/libarkts/src/NativeModule.ts index 9b075d018..ce121f312 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 + _ExpressionStatementGetExpression(context: KNativePointer, node: KNativePointer): KNativePointer _CallExpressionGetPropertyAccessExpression(node: KNativePointer): KNativePointer - _CallExpressionGetArguments(node: KNativePointer): KNativePointer + _CallExpressionArguments(context: KNativePointer, node: KNativePointer, returnLen: KNativePointer): KNativePointer _IdentifierGetText(node: KNativePointer): KNativePointer _PropertyAccessExpressionGetExpression(node: KNativePointer): KNativePointer _PropertyAccessExpressionGetName(node: KNativePointer): KNativePointer @@ -70,6 +70,8 @@ export interface NativeModule { _CreateMemberExpression(context: KNativePointer, object: KNativePointer, property: KNativePointer, kind: KInt, computed: KBoolean, optional: KBoolean): 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 _CreateETSParameterExpression(context: KNativePointer, identifier: KNativePointer): KNativePointer diff --git a/arkoala-arkts/libarkts/src/arkts/factory/nodeImpls.ts b/arkoala-arkts/libarkts/src/arkts/factory/nodeImpls.ts index 702206754..580792440 100644 --- a/arkoala-arkts/libarkts/src/arkts/factory/nodeImpls.ts +++ b/arkoala-arkts/libarkts/src/arkts/factory/nodeImpls.ts @@ -256,7 +256,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 @@ -276,7 +276,7 @@ class CallExpressionImpl extends NodeImpl implements api.CallExpression { 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 @@ -506,6 +506,28 @@ class BinaryOperatorTokenImpl extends NodeImpl implements api.BinaryOperatorToke 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) @@ -526,6 +548,8 @@ enum es2pandaKind { PropertyDeclaration = 7, Parameter = 8, ETSFunctionType = 9, + CallExpression = 10, + ExpressionStatement = 11, } const kinds = new Map([ @@ -538,6 +562,8 @@ const kinds = new Map([ [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], ]) export function makeView(peer: KNativePointer): api.Node { @@ -561,6 +587,8 @@ export function makeView(peer: KNativePointer): api.Node { 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) throw new Error(`Unknown node kind: ${kind}`) } @@ -695,8 +723,16 @@ export function updateFunctionDeclaration( 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) } @@ -737,11 +773,6 @@ export function createETSPrimitiveType(type: Es2pandaPrimitiveType) { 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._CreateETSTypeReferencePart(Global.context, getPeer(identifier), NULLPTR, NULLPTR) const peer = nativeModule._CreateETSTypeReference(Global.context, type_ref_part) @@ -749,6 +780,12 @@ export function createTypeReferenceNode(identifier: api.Identifier): api.TypeRef } 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) @@ -820,6 +857,31 @@ export function createCallExpression( 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( + getPeer(node), + Global.context, + 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) @@ -839,3 +901,49 @@ export function createBinaryExpression(left: api.Expression, operator: api.Binar 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) +} diff --git a/arkoala-arkts/libarkts/src/arkts/index.ts b/arkoala-arkts/libarkts/src/arkts/index.ts index 1fe3a78b5..9459b9988 100644 --- a/arkoala-arkts/libarkts/src/arkts/index.ts +++ b/arkoala-arkts/libarkts/src/arkts/index.ts @@ -81,5 +81,6 @@ export { BinaryOperatorToken, TokenSyntaxKind, BinaryExpression, + ArrowFunction, } 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 index bd42c5964..1cfccb0ba 100644 --- a/arkoala-arkts/libarkts/test/es2panda/create-function-declaration.test.ts +++ b/arkoala-arkts/libarkts/test/es2panda/create-function-declaration.test.ts @@ -33,7 +33,13 @@ suite(util.getSuiteTitle(__filename), () => { util.getDefaultSetup('') const typeAnnotation = api.createKeywordTypeNode(api.SyntaxKind.NumberKeyword) - const funcParams = [api.createParameterDeclaration(api.createIdentifier("x", typeAnnotation))] + const funcParams = [ + api.createParameterDeclaration( + undefined, + undefined, + api.createIdentifier("x", typeAnnotation) + ) + ] const funcDecl = api.createFunctionDeclaration( undefined, undefined, diff --git a/arkoala-arkts/libarkts/test/es2panda/lambda-param-memoization.test.ts b/arkoala-arkts/libarkts/test/es2panda/lambda-param-memoization.test.ts index 1bccd2ecb..68bc7669e 100644 --- a/arkoala-arkts/libarkts/test/es2panda/lambda-param-memoization.test.ts +++ b/arkoala-arkts/libarkts/test/es2panda/lambda-param-memoization.test.ts @@ -26,14 +26,6 @@ suite(util.getSuiteTitle(__filename), () => { } ` - util.getDefaultSetup(sample_in) - - // console.log(util.dumpFirst()) - - // let testFunc = api.makeView(util.getStatement(0)) as api.FunctionDeclaration - - // util.assertEqualsGolden(api.dumpJsonNode(testFunc), this) - - // api.proceedToState(api.ContextState.ES2PANDA_STATE_CHECKED) + 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 14498f362..1a2b8df3a 100644 --- a/arkoala-arkts/libarkts/test/es2panda/update-function-declaration.test.ts +++ b/arkoala-arkts/libarkts/test/es2panda/update-function-declaration.test.ts @@ -21,7 +21,7 @@ suite(util.getSuiteTitle(__filename), () => { 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] testFunc = api.updateFunctionDeclaration( testFunc, @@ -106,7 +106,7 @@ suite(util.getSuiteTitle(__filename), () => { util.assertEqualsGolden(api.dumpJsonNode(testFunc), this) - api.proceedToState(api.ContextState.ES2PANDA_STATE_BIN_GENERATED) + api.proceedToState(api.ContextState.ES2PANDA_STATE_CHECKED) }) test("add-property-access-expression-to-function-body", function() { diff --git a/arkoala-arkts/libarkts/test/test-util.ts b/arkoala-arkts/libarkts/test/test-util.ts index 95ae66248..079e35924 100644 --- a/arkoala-arkts/libarkts/test/test-util.ts +++ b/arkoala-arkts/libarkts/test/test-util.ts @@ -75,9 +75,9 @@ export function dumpFirst() { 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(api.createIdentifier("__memo_context", memoContextAnnotation)) + const memoContextParam = api.createParameterDeclaration(undefined, undefined, api.createIdentifier("__memo_context", memoContextAnnotation)) const memoIdAnnotation = api.createTypeReferenceNode(api.createIdentifier("__memo_id_type")) - const memoIdParam = api.createParameterDeclaration(api.createIdentifier("__memo_id", memoIdAnnotation)) + const memoIdParam = api.createParameterDeclaration(undefined, undefined, api.createIdentifier("__memo_id", memoIdAnnotation)) const newParams = [memoContextParam, memoIdParam, ...oldParams] return api.updateFunctionDeclaration( func, -- Gitee From dd1ce1bb552d0ba5b918bcd76c3b9eee73e4487d Mon Sep 17 00:00:00 2001 From: chernishevvictor Date: Fri, 4 Oct 2024 15:19:40 +0300 Subject: [PATCH 3/6] adding signature and body to builder-lambda param --- arkoala-arkts/libarkts/.gitignore | 2 + .../libarkts/native/src/playground.cc | 16 +-- .../es2panda/builder-lambda-rewrite.test.ts | 108 +++++++++++++++++ .../update-function-declaration.test.ts | 110 +++++++----------- ...e_adding-body-to-lambda-param.test.ts_dump | 93 +++++++++++++++ ...ing-lambda-param-to-signature.test.ts_dump | 50 ++++++++ 6 files changed, 302 insertions(+), 77 deletions(-) create mode 100644 arkoala-arkts/libarkts/test/es2panda/builder-lambda-rewrite.test.ts create mode 100644 arkoala-arkts/libarkts/test/golden/builder-lambda-rewrite_adding-body-to-lambda-param.test.ts_dump create mode 100644 arkoala-arkts/libarkts/test/golden/builder-lambda-rewrite_adding-lambda-param-to-signature.test.ts_dump diff --git a/arkoala-arkts/libarkts/.gitignore b/arkoala-arkts/libarkts/.gitignore index a54cdb4b3..defed4cdd 100644 --- a/arkoala-arkts/libarkts/.gitignore +++ b/arkoala-arkts/libarkts/.gitignore @@ -3,3 +3,5 @@ build* native/build-* native/*.ini lib +!test/es2panda/* +!test/golden/* diff --git a/arkoala-arkts/libarkts/native/src/playground.cc b/arkoala-arkts/libarkts/native/src/playground.cc index e4ffda24c..1a5656c23 100644 --- a/arkoala-arkts/libarkts/native/src/playground.cc +++ b/arkoala-arkts/libarkts/native/src/playground.cc @@ -23,20 +23,14 @@ es2panda_Impl *GetImpl() { return impl; } -static char* source = "console.log('Hello world')"; +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[] = {"", "--arktsconfig", "../arktsconfig.json", "../input/main.ts"}; + auto config = GetImpl()->CreateConfig(4, args); + auto context = GetImpl()->CreateContextFromString(config, source, args[3]); - // std::cout << "ARGC: " << argc << std::endl; - - const char* args[] = {"/home/huawei/arkcompiler_ets_frontend/incremental/tools/panda/node_modules/@panda/sdk/linux_host_tools/bin/es2panda", "../input/main.ts"}; - // const char* args[] = {"/home/huawei/arkcompiler_ets_frontend/arkoala-arkts/libarkts/arktsconfig.json", "../input/main.ts"}; - auto config = GetImpl()->CreateConfig(2, args); - auto context = GetImpl()->CreateContextFromString(config, "", "../input/main.ts"); + // playground GetImpl()->ProceedToState(context, ES2PANDA_STATE_PARSED); if(GetImpl()->ContextState(context) == ES2PANDA_STATE_ERROR) 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 000000000..5dacb0fc3 --- /dev/null +++ b/arkoala-arkts/libarkts/test/es2panda/builder-lambda-rewrite.test.ts @@ -0,0 +1,108 @@ +import * as util from "../test-util" +import * as api from "../../src/arkts" + +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) + }) +}) 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 1a2b8df3a..8961b9c4c 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,12 +15,6 @@ 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 @@ -39,7 +38,12 @@ suite(util.getSuiteTitle(__filename), () => { 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) { @@ -47,12 +51,6 @@ suite(util.getSuiteTitle(__filename), () => { } ` - // adding memo params to signature - - // function foo(__memo_context: __memo_context_type, __memo_id: __memo_id_type, x: number) { - // // empty - // } - util.getDefaultSetup(sample_in) let testFunc = api.makeView(util.getStatement(0)) as api.FunctionDeclaration @@ -64,7 +62,12 @@ suite(util.getSuiteTitle(__filename), () => { 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() { @@ -72,15 +75,6 @@ suite(util.getSuiteTitle(__filename), () => { } ` - // adding identifier x - - const sample_out = - ` - function foo() { - x - } - ` - util.getDefaultSetup(sample_in) let testFunc = api.makeView(util.getStatement(0)) as api.FunctionDeclaration @@ -109,7 +103,12 @@ suite(util.getSuiteTitle(__filename), () => { 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() { @@ -117,15 +116,6 @@ suite(util.getSuiteTitle(__filename), () => { } ` - // adding __memo_scope.recache - - // const sample_out = - // ` - // function foo() { - // __memo_scope.recache - // } - // ` - util.getDefaultSetup(sample_in) let testFunc = api.makeView(util.getStatement(0)) as api.FunctionDeclaration @@ -159,25 +149,21 @@ suite(util.getSuiteTitle(__filename), () => { api.proceedToState(api.ContextState.ES2PANDA_STATE_CHECKED) }) + // body memo rewrite (adding return statement) test("add-return-statement-to-function-body", function() { - const sample_in = - ` - function foo() { - // empty - } - ` - - // body memo rewrite (adding return statement) - - // const sample_out = - // ` // 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) @@ -214,25 +200,21 @@ suite(util.getSuiteTitle(__filename), () => { api.proceedToState(api.ContextState.ES2PANDA_STATE_CHECKED) }) + // body memo rewrite (adding if statement) test("add-if-statement-to-function-body", function() { - const sample_in = - ` - function foo() { - // empty - } - ` - - // body memo rewrite (adding if statement) - - // const sample_out = - // ` // 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) @@ -274,25 +256,21 @@ suite(util.getSuiteTitle(__filename), () => { api.proceedToState(api.ContextState.ES2PANDA_STATE_CHECKED) }) + // body memo rewrite test("function-declaration-memo-rewrite", function() { - const sample_in = - ` - function foo() { - // empty - } - ` - - // body memo rewrite - - // const sample_out = - // ` // 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) 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 000000000..19e83d1e6 --- /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 000000000..2676777ed --- /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 -- Gitee From e0ff3bcd82059c63547d7fa058d8453814aaeaa2 Mon Sep 17 00:00:00 2001 From: chernishevvictor Date: Mon, 7 Oct 2024 18:44:43 +0300 Subject: [PATCH 4/6] add builder-lambda-transformer --- arkoala-arkts/libarkts/.gitignore | 1 + .../compatible/src/AbstractVisitor.ts | 44 ++++++ .../src/builder-lambda-transformer.ts | 128 +++++++++++++++++ .../libarkts/native/src/es2panda_lib.cc | 87 ++++++++++- arkoala-arkts/libarkts/src/NativeModule.ts | 8 +- .../libarkts/src/arkts/factory/nodeImpls.ts | 136 +++++++++++++++++- arkoala-arkts/libarkts/src/es2panda.ts | 12 +- .../es2panda/builder-lambda-rewrite.test.ts | 45 ++++++ ...r-lambda-transformer-sample-1.test.ts_dump | 67 +++++++++ ...r-lambda-transformer-sample-2.test.ts_dump | 101 +++++++++++++ 10 files changed, 615 insertions(+), 14 deletions(-) create mode 100644 arkoala-arkts/libarkts/compatible/src/AbstractVisitor.ts create mode 100644 arkoala-arkts/libarkts/compatible/src/builder-lambda-transformer.ts create mode 100644 arkoala-arkts/libarkts/test/golden/builder-lambda-rewrite_builder-lambda-transformer-sample-1.test.ts_dump create mode 100644 arkoala-arkts/libarkts/test/golden/builder-lambda-rewrite_builder-lambda-transformer-sample-2.test.ts_dump diff --git a/arkoala-arkts/libarkts/.gitignore b/arkoala-arkts/libarkts/.gitignore index defed4cdd..d37d63bfd 100644 --- a/arkoala-arkts/libarkts/.gitignore +++ b/arkoala-arkts/libarkts/.gitignore @@ -5,3 +5,4 @@ native/*.ini lib !test/es2panda/* !test/golden/* +!compatible/src/* diff --git a/arkoala-arkts/libarkts/compatible/src/AbstractVisitor.ts b/arkoala-arkts/libarkts/compatible/src/AbstractVisitor.ts new file mode 100644 index 000000000..be5bae472 --- /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 000000000..9816d1b27 --- /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/native/src/es2panda_lib.cc b/arkoala-arkts/libarkts/native/src/es2panda_lib.cc index dd69104cf..b5b4194c4 100644 --- a/arkoala-arkts/libarkts/native/src/es2panda_lib.cc +++ b/arkoala-arkts/libarkts/native/src/es2panda_lib.cc @@ -183,6 +183,7 @@ enum AstNodeKind { ETSFunctionType = 9, CallExpression = 10, ExpressionStatement = 11, + MemberExpression = 12, }; KInt impl_GetKind(KNativePointer nodePtr) { @@ -221,6 +222,9 @@ KInt impl_GetKind(KNativePointer nodePtr) { if (GetImpl()->IsExpressionStatement(node)) { return AstNodeKind::ExpressionStatement; } + if (GetImpl()->IsMemberExpression(node)) { + return AstNodeKind::MemberExpression; + } return -1; } @@ -394,6 +398,49 @@ KNativePointer impl_CreateMemberExpression( } 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, @@ -415,8 +462,8 @@ KNativePointer impl_CreateCallExpression( KOALA_INTEROP_7(CreateCallExpression, KNativePointer, KNativePointer, KNativePointer, KNativePointerArray, KInt, KNativePointer, KBoolean, KBoolean) KNativePointer impl_UpdateCallExpression( - KNativePointer nodePtr, KNativePointer contextPtr, + KNativePointer nodePtr, KNativePointer calleePtr, KNativePointerArray argumentsPtr, KInt argumentsLen, @@ -444,6 +491,15 @@ KNativePointer impl_CreateExpressionStatement(KNativePointer contextPtr, KNative } 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); @@ -616,3 +672,32 @@ KNativePointer impl_CallExpressionArguments(KNativePointer contextPtr, KNativePo 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(BlockStatementSetStatements, KNativePointer, KNativePointer, KNativePointer, KNativePointerArray, KInt) diff --git a/arkoala-arkts/libarkts/src/NativeModule.ts b/arkoala-arkts/libarkts/src/NativeModule.ts index ce121f312..3ea74728c 100644 --- a/arkoala-arkts/libarkts/src/NativeModule.ts +++ b/arkoala-arkts/libarkts/src/NativeModule.ts @@ -35,8 +35,8 @@ export interface NativeModule { _FunctionDeclarationGetIdentifier(node: KNativePointer): KNativePointer _FunctionDeclarationGetBlock(node: KNativePointer): KNativePointer _ExpressionStatementGetExpression(context: KNativePointer, node: KNativePointer): KNativePointer - _CallExpressionGetPropertyAccessExpression(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 @@ -60,6 +60,7 @@ export interface NativeModule { _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 @@ -69,11 +70,15 @@ export interface NativeModule { _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 _CreateETSPrimitiveType(context: KNativePointer, type: KInt): KNativePointer _CreateETSTypeReference(context: KNativePointer, part: KNativePointer): KNativePointer @@ -87,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 580792440..62bac9c82 100644 --- a/arkoala-arkts/libarkts/src/arkts/factory/nodeImpls.ts +++ b/arkoala-arkts/libarkts/src/arkts/factory/nodeImpls.ts @@ -71,6 +71,89 @@ 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 { @@ -120,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.") } @@ -138,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 @@ -269,8 +356,12 @@ 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 @@ -296,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 @@ -550,6 +649,7 @@ enum es2pandaKind { ETSFunctionType = 9, CallExpression = 10, ExpressionStatement = 11, + MemberExpression = 12, } const kinds = new Map([ @@ -564,6 +664,7 @@ const kinds = new Map([ [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 { @@ -589,6 +690,7 @@ export function makeView(peer: KNativePointer): api.Node { 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}`) } @@ -821,6 +923,12 @@ export function createExpressionStatement(expression: api.Expression): api.Expre 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)) @@ -834,6 +942,12 @@ export function createPropertyAccessExpression(expression: api.Expression, name: 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, @@ -868,8 +982,8 @@ export function updateCallExpression( const peer = withPtrArray(args, Access.READWRITE, (args: BigUint64Array) => { return nativeModule._UpdateCallExpression( - getPeer(node), Global.context, + getPeer(node), getPeer(expression), args, args.length, @@ -947,3 +1061,13 @@ export function createArrowFunction( 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/es2panda.ts b/arkoala-arkts/libarkts/src/es2panda.ts index df84093e3..07ca6a9a5 100644 --- a/arkoala-arkts/libarkts/src/es2panda.ts +++ b/arkoala-arkts/libarkts/src/es2panda.ts @@ -24,21 +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.config = 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)[]> { diff --git a/arkoala-arkts/libarkts/test/es2panda/builder-lambda-rewrite.test.ts b/arkoala-arkts/libarkts/test/es2panda/builder-lambda-rewrite.test.ts index 5dacb0fc3..7e4e0eedd 100644 --- a/arkoala-arkts/libarkts/test/es2panda/builder-lambda-rewrite.test.ts +++ b/arkoala-arkts/libarkts/test/es2panda/builder-lambda-rewrite.test.ts @@ -1,5 +1,6 @@ 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() { @@ -105,4 +106,48 @@ suite(util.getSuiteTitle(__filename), () => { 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/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 000000000..74c555ff8 --- /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 000000000..f38314f65 --- /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 -- Gitee From 4a9210a8711bcf45e79d24940f8e780f4c091c2e Mon Sep 17 00:00:00 2001 From: chernishevvictor Date: Tue, 8 Oct 2024 17:56:43 +0300 Subject: [PATCH 5/6] fix arktsconfig + some refactoring --- arkoala-arkts/libarkts/arktsconfig.json | 8 +- arkoala-arkts/libarkts/input/main.sts | 1 + arkoala-arkts/libarkts/input/main.ts | 6 - arkoala-arkts/libarkts/native/meson.build | 7 +- .../libarkts/native/meson_options.txt | 2 - .../libarkts/native/src/dummy_lib.cc | 137 ------------------ .../libarkts/native/src/playground.cc | 11 +- arkoala-arkts/libarkts/package.json | 10 +- .../libarkts/src/arkts/factory/nodeImpls.ts | 4 +- arkoala-arkts/libarkts/test/test-util.ts | 15 +- 10 files changed, 27 insertions(+), 174 deletions(-) create mode 100644 arkoala-arkts/libarkts/input/main.sts delete mode 100644 arkoala-arkts/libarkts/input/main.ts delete mode 100644 arkoala-arkts/libarkts/native/src/dummy_lib.cc diff --git a/arkoala-arkts/libarkts/arktsconfig.json b/arkoala-arkts/libarkts/arktsconfig.json index 44bd3ebfa..356d756bc 100644 --- a/arkoala-arkts/libarkts/arktsconfig.json +++ b/arkoala-arkts/libarkts/arktsconfig.json @@ -1,12 +1,12 @@ { "compilerOptions": { - "baseUrl": "/home/huawei/arkts/arkcompiler/runtime_core/static_core", + "baseUrl": "../../../arkts/arkcompiler/runtime_core/static_core", "paths": { "std": [ - "/home/huawei/arkts/arkcompiler/runtime_core/static_core/plugins/ets/stdlib/std" + "plugins/ets/stdlib/std" ], "escompat": [ - "/home/huawei/arkts/arkcompiler/runtime_core/static_core/plugins/ets/stdlib/escompat" + "plugins/ets/stdlib/escompat" ] }, "plugins": [ @@ -15,4 +15,4 @@ } ] } -} \ No newline at end of file +} diff --git a/arkoala-arkts/libarkts/input/main.sts b/arkoala-arkts/libarkts/input/main.sts new file mode 100644 index 000000000..b7508f4fd --- /dev/null +++ b/arkoala-arkts/libarkts/input/main.sts @@ -0,0 +1 @@ +x: int = 5 diff --git a/arkoala-arkts/libarkts/input/main.ts b/arkoala-arkts/libarkts/input/main.ts deleted file mode 100644 index e9c6decc7..000000000 --- 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 4be47c81c..67ba73153 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 51966ed59..e69de29bb 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 f778c2a02..000000000 --- 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/playground.cc b/arkoala-arkts/libarkts/native/src/playground.cc index 1a5656c23..20c58ed85 100644 --- a/arkoala-arkts/libarkts/native/src/playground.cc +++ b/arkoala-arkts/libarkts/native/src/playground.cc @@ -26,7 +26,16 @@ es2panda_Impl *GetImpl() { static char* source = ""; int main() { - const char* args[] = {"", "--arktsconfig", "../arktsconfig.json", "../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" + }; + auto config = GetImpl()->CreateConfig(4, args); auto context = GetImpl()->CreateContextFromString(config, source, args[3]); diff --git a/arkoala-arkts/libarkts/package.json b/arkoala-arkts/libarkts/package.json index efd37bb0c..021a88ada 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/arkts/factory/nodeImpls.ts b/arkoala-arkts/libarkts/src/arkts/factory/nodeImpls.ts index 62bac9c82..c8605a574 100644 --- a/arkoala-arkts/libarkts/src/arkts/factory/nodeImpls.ts +++ b/arkoala-arkts/libarkts/src/arkts/factory/nodeImpls.ts @@ -163,9 +163,9 @@ export function createConfig(input: string[]): KNativePointer { } 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) }) }) } diff --git a/arkoala-arkts/libarkts/test/test-util.ts b/arkoala-arkts/libarkts/test/test-util.ts index 079e35924..8a185a8ed 100644 --- a/arkoala-arkts/libarkts/test/test-util.ts +++ b/arkoala-arkts/libarkts/test/test-util.ts @@ -21,20 +21,17 @@ 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) } -- Gitee From d88383eada01ab8b80d36864e6df24b26e7fb2ad Mon Sep 17 00:00:00 2001 From: n00860943 Date: Thu, 10 Oct 2024 03:40:23 -0700 Subject: [PATCH 6/6] fix upto undefined factory --- .../libarkts/compatible/src/example-transformer.ts | 4 ++-- arkoala-arkts/libarkts/input/main.sts | 2 +- arkoala-arkts/libarkts/src/es2panda.ts | 9 +++++---- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/arkoala-arkts/libarkts/compatible/src/example-transformer.ts b/arkoala-arkts/libarkts/compatible/src/example-transformer.ts index a933bffa0..11aaa6bdd 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 index b7508f4fd..2fa90fb45 100644 --- a/arkoala-arkts/libarkts/input/main.sts +++ b/arkoala-arkts/libarkts/input/main.sts @@ -1 +1 @@ -x: int = 5 +Foo("label") diff --git a/arkoala-arkts/libarkts/src/es2panda.ts b/arkoala-arkts/libarkts/src/es2panda.ts index 07ca6a9a5..71eb7dc62 100644 --- a/arkoala-arkts/libarkts/src/es2panda.ts +++ b/arkoala-arkts/libarkts/src/es2panda.ts @@ -30,7 +30,7 @@ function es2panda(configPath: string, filePath: string, transform: (ast: arkts.N configPath, filePath ]) - arkts.Global.config = arkts.createContextFromString(arkts.Global.config, source, filePath) + 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) @@ -50,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)() })) } -- Gitee