diff --git a/ui2abc/libarkts/.gitlab-ci.yml b/ui2abc/libarkts/.gitlab-ci.yml index acf29f5cd2cced0ffc321acb062326bbbd1ee908..41dd274d577a342a396387bb4a532b1ca1c00a1c 100644 --- a/ui2abc/libarkts/.gitlab-ci.yml +++ b/ui2abc/libarkts/.gitlab-ci.yml @@ -61,7 +61,6 @@ test plugin-api: - install node modules (arkoala-arkts) - install node modules (incremental) - install node modules (interop) - - regenerate plugin-api test example arkts-plugin: interruptible: true diff --git a/ui2abc/libarkts/src/arkts-api/node-utilities/ETSImportDeclaration.ts b/ui2abc/libarkts/src/arkts-api/node-utilities/ETSImportDeclaration.ts index 05a6d3bbcc4a565d91c9776cc6d83a7c702762b0..e2c54d327a72ed11b8114448d54354dc41fbe76c 100644 --- a/ui2abc/libarkts/src/arkts-api/node-utilities/ETSImportDeclaration.ts +++ b/ui2abc/libarkts/src/arkts-api/node-utilities/ETSImportDeclaration.ts @@ -17,7 +17,7 @@ import { ETSImportDeclaration, StringLiteral } from "../../generated" import { isSameNativeObject } from "../peers/ArktsObject" import { passNode, passNodeArray, unpackNonNullableNode, updateNodeByNode } from "../utilities/private" import { AstNode } from "../peers/AstNode" -import { Es2pandaImportFlags, Es2pandaImportKinds } from "../../generated/Es2pandaEnums" +import { Es2pandaContextState, Es2pandaImportFlags, Es2pandaImportKinds } from "../../generated/Es2pandaEnums" import { global } from "../static/global" import { Program } from "../peers/Program" @@ -27,8 +27,7 @@ export function createETSImportDeclaration( importKind: Es2pandaImportKinds, program: Program, flags: Es2pandaImportFlags -): ETSImportDeclaration { - // TODO: check that plugin is on parsed stage +) { const res = unpackNonNullableNode( global.es2panda._ETSParserBuildImportDeclaration( global.context, @@ -41,24 +40,44 @@ export function createETSImportDeclaration( ) ) global.es2panda._InsertETSImportDeclarationAndParse(global.context, program.peer, res.peer) - return new ETSImportDeclaration(res.peer) + // TODO: what if new files got added to external sources and they should be processed by plugin? + + // Actually this new import got added to AST by compiler, so we should not modify AST by plugin } +// TODO: It seems that this function currently updates AST not in proper way, so the old import declaration should be removed export function updateETSImportDeclaration( original: ETSImportDeclaration, - source: StringLiteral | undefined, specifiers: readonly AstNode[], - importKind: Es2pandaImportKinds -): ETSImportDeclaration { - if (isSameNativeObject(source, original.source) - && isSameNativeObject(specifiers, original.specifiers) + importKind: Es2pandaImportKinds, + program: Program = global.compilerContext.program, // TODO: pass program from plugin here (or maybe it should be main program actually?), + flags: Es2pandaImportFlags = Es2pandaImportFlags.IMPORT_FLAGS_NONE, +) { + if (isSameNativeObject(specifiers, original.specifiers) /* no getter for importKind */ ) { /* TODO: probably should set importMetadata, but no getter provided yet */ return original } + const res = unpackNonNullableNode( + global.es2panda._ETSParserBuildImportDeclaration( + global.context, + importKind, + passNodeArray(specifiers), + specifiers.length, + passNode(original.source), + program.peer, + flags + ) + ) + global.es2panda._InsertETSImportDeclarationAndParse(global.context, program.peer, res.peer) + // Actually this new import got added to AST by compiler, so return forgotten old import to continue traversal return updateNodeByNode( - ETSImportDeclaration.createETSImportDeclaration(source, specifiers, importKind), - original + ETSImportDeclaration.createETSImportDeclaration( + StringLiteral.create1StringLiteral(original.source?.str ?? ""), + [], // Compiler doesn't like this actually (possibly only in restart solution?) + importKind, + ), + original, ) } diff --git a/ui2abc/libarkts/src/arkts-api/visitor.ts b/ui2abc/libarkts/src/arkts-api/visitor.ts index 6d106ede3fe8c46eadd50b467e315c7c73937395..486bec7bbeae53d24df0774886a2e15e96b593b1 100644 --- a/ui2abc/libarkts/src/arkts-api/visitor.ts +++ b/ui2abc/libarkts/src/arkts-api/visitor.ts @@ -519,7 +519,6 @@ export function visitEachChild( if (isETSImportDeclaration(node)) { return factory.updateETSImportDeclaration( node, - nodeVisitor(node.source, visitor), nodesVisitor(node.specifiers, visitor), Es2pandaImportKinds.IMPORT_KINDS_ALL ) diff --git a/ui2abc/libarkts/test/arkts-api/general/recheck.test.ts b/ui2abc/libarkts/test/arkts-api/general/recheck.test.ts index ccde6f39fdae511ee2d25ed3d7afcdeb90bec69b..eaff410895146bdbcdf8e614192237e4de0c41e6 100644 --- a/ui2abc/libarkts/test/arkts-api/general/recheck.test.ts +++ b/ui2abc/libarkts/test/arkts-api/general/recheck.test.ts @@ -98,7 +98,7 @@ console.log("test"); arkts.proceedToState(arkts.Es2pandaContextState.ES2PANDA_STATE_BIN_GENERATED) }) - test.skip("change function name in main program and in dependency", function() { + test("change function name in main program and in dependency", function() { createConfig() const code = @@ -117,13 +117,13 @@ console.log("test"); if (!it.getName().includes("library")) return it.programs.forEach(program => { new RenameTestFunction().visitor(program.astNode) + arkts.arktsGlobal.es2panda._AstNodeUpdateAll(arkts.arktsGlobal.context, program.astNode.peer) }) }) - arkts.factory.createETSImportDeclaration( - arkts.factory.createStringLiteral( - './library' - ), + const statements = [...module.statements] // save statements + statements[0] = arkts.factory.updateETSImportDeclaration( + statements[0] as arkts.ETSImportDeclaration, [ arkts.factory.createImportSpecifier( arkts.factory.createIdentifier( @@ -139,6 +139,14 @@ console.log("test"); arkts.Es2pandaImportFlags.IMPORT_FLAGS_NONE ) + arkts.updateETSModuleByStatements( + module, + [ + ...module.statements.slice(0, 1), // this is added by compiler + ...statements.slice(1), // updated statements from the ones saved before + ] + ) + new RenameTestFunction().visitor(module) arkts.arktsGlobal.es2panda._AstNodeUpdateAll(arkts.arktsGlobal.context, module.peer) @@ -146,7 +154,12 @@ console.log("test"); util.assert.equal( module.dumpSrc(), ` -testFunctionChanged() +import { testFunctionChanged as testFunctionChanged } from "./library"; + +function main() {} + +testFunctionChanged(); + `, `invalid result: ${module.dumpSrc()}`) diff --git a/ui2abc/libarkts/test/arkts-api/recheck/imports/add-same-file/dump-src/main.ts b/ui2abc/libarkts/test/arkts-api/recheck/imports/add-same-file/dump-src/main.ts index 51d2896e435cdd0103ce61c0cccbf18790d679cc..7c84ccdd5eb2d732eec4ec5d3f6fef1ed81df917 100644 --- a/ui2abc/libarkts/test/arkts-api/recheck/imports/add-same-file/dump-src/main.ts +++ b/ui2abc/libarkts/test/arkts-api/recheck/imports/add-same-file/dump-src/main.ts @@ -1,5 +1,5 @@ -import { testFunction as testFunction } from "./library"; +import { anotherFunction as anotherFunction, testFunction as testFunction } from "./library"; import { anotherFunction as anotherFunction } from "./library"; diff --git a/ui2abc/libarkts/test/arkts-api/recheck/imports/add-same-file/index.ts b/ui2abc/libarkts/test/arkts-api/recheck/imports/add-same-file/index.ts index 5f77f7fb3b45930b756fbe80a361f1b9b2ebe71a..1e4e8618e37c09461312612c47db46c576ec4a27 100644 --- a/ui2abc/libarkts/test/arkts-api/recheck/imports/add-same-file/index.ts +++ b/ui2abc/libarkts/test/arkts-api/recheck/imports/add-same-file/index.ts @@ -2,23 +2,20 @@ import * as arkts from "../../../../../src/arkts-api" export function addImportSameFile(program: arkts.Program, options: arkts.CompilationOptions) { if (options.isMainProgram) { - arkts.factory.createETSImportDeclaration( - arkts.factory.createStringLiteral( - './library' - ), + arkts.factory.updateETSImportDeclaration( + (program.astNode.statements[0] as arkts.ETSImportDeclaration), [ + ...(program.astNode.statements[0] as arkts.ETSImportDeclaration).specifiers, arkts.factory.createImportSpecifier( arkts.factory.createIdentifier( 'testFunction' ), arkts.factory.createIdentifier( 'testFunction' - ) - ) + ), + ), ], - arkts.Es2pandaImportKinds.IMPORT_KINDS_ALL, - arkts.arktsGlobal.compilerContext.program, - arkts.Es2pandaImportFlags.IMPORT_FLAGS_NONE + arkts.Es2pandaImportKinds.IMPORT_KINDS_ALL ) } return program diff --git a/ui2abc/libarkts/test/arkts-api/recheck/imports/add-use-same-file/dump-src/main.ts b/ui2abc/libarkts/test/arkts-api/recheck/imports/add-use-same-file/dump-src/main.ts index d6401c452691033c05bbddbbb00ebe269c66cab8..d27c5a0a26368b5a425e65207ca4fad94c7ae02d 100644 --- a/ui2abc/libarkts/test/arkts-api/recheck/imports/add-use-same-file/dump-src/main.ts +++ b/ui2abc/libarkts/test/arkts-api/recheck/imports/add-use-same-file/dump-src/main.ts @@ -1,5 +1,5 @@ -import { testFunction as testFunction } from "./library"; +import { anotherFunction as anotherFunction, testFunction as testFunction } from "./library"; import { anotherFunction as anotherFunction } from "./library"; diff --git a/ui2abc/libarkts/test/arkts-api/recheck/imports/add-use-same-file/index.ts b/ui2abc/libarkts/test/arkts-api/recheck/imports/add-use-same-file/index.ts index 6da984d08a82d40e64b6a62293eccd006176fd14..e2b3d0684a791d0bd69e9675f827996b96d24af7 100644 --- a/ui2abc/libarkts/test/arkts-api/recheck/imports/add-use-same-file/index.ts +++ b/ui2abc/libarkts/test/arkts-api/recheck/imports/add-use-same-file/index.ts @@ -16,23 +16,20 @@ export function addUseImportSameFile(program: arkts.Program, options: arkts.Comp ) ] ) - arkts.factory.createETSImportDeclaration( - arkts.factory.createStringLiteral( - './library' - ), + arkts.factory.updateETSImportDeclaration( + (program.astNode.statements[0] as arkts.ETSImportDeclaration), [ + ...(program.astNode.statements[0] as arkts.ETSImportDeclaration).specifiers, arkts.factory.createImportSpecifier( arkts.factory.createIdentifier( 'testFunction' ), arkts.factory.createIdentifier( 'testFunction' - ) - ) + ), + ), ], arkts.Es2pandaImportKinds.IMPORT_KINDS_ALL, - arkts.arktsGlobal.compilerContext.program, - arkts.Es2pandaImportFlags.IMPORT_FLAGS_NONE ) } return program diff --git a/ui2abc/memo-plugin/test/golden/HQ/arrow-assignment.ets b/ui2abc/memo-plugin/test/golden/HQ/arrow-assignment.ets index f84f771c44aabe66ae420636c422edaf78d390d5..2640e146b3767915b44b701720cdc537e206ae6b 100644 --- a/ui2abc/memo-plugin/test/golden/HQ/arrow-assignment.ets +++ b/ui2abc/memo-plugin/test/golden/HQ/arrow-assignment.ets @@ -27,7 +27,7 @@ class Test { if (__memo_scope.unchanged) { return __memo_scope.cached; } - return __memo_scope.recache(((123) + (x))); + return __memo_scope.recache(((123) + (__memo_parameter_x.value))); }); const h = @memo() ((__memo_context: __memo_context_type, __memo_id: __memo_id_type): number => { const __memo_scope = __memo_context.scope(((__memo_id) + (__hash("id__arrow-assignment.ets"))), 0); diff --git a/ui2abc/memo-plugin/test/golden/test.ets b/ui2abc/memo-plugin/test/golden/test.ets index 264235366b056791ed8b907318a87f3508087f59..4fd8fc81e498197ac4adf0df7feea22409f8e201 100644 --- a/ui2abc/memo-plugin/test/golden/test.ets +++ b/ui2abc/memo-plugin/test/golden/test.ets @@ -286,7 +286,7 @@ class Test { if (__memo_scope.unchanged) { return __memo_scope.cached; } - return __memo_scope.recache(((123) + (x))); + return __memo_scope.recache(((123) + (__memo_parameter_x.value))); }); const h = @memo() ((__memo_context: __memo_context_type, __memo_id: __memo_id_type): number => { const __memo_scope = __memo_context.scope(((__memo_id) + (__hash("id__@test.test.ets"))), 0); diff --git a/ui2abc/ui-plugins/src/builder-lambda-transformer.ts b/ui2abc/ui-plugins/src/builder-lambda-transformer.ts index b90cf1bbca87b30a2425007b3499095a8500108b..77329bc8dedabf5a1144f6b7bad547cc89679127 100644 --- a/ui2abc/ui-plugins/src/builder-lambda-transformer.ts +++ b/ui2abc/ui-plugins/src/builder-lambda-transformer.ts @@ -169,7 +169,7 @@ function transformBuilderLambdaCall(node: arkts.CallExpression): arkts.CallExpre // in theory we don't add new files to import here, // only the new names from the same file, // to it should be okay. -function transformETSImportDeclaration(node: arkts.ETSImportDeclaration): arkts.ETSImportDeclaration { +function transformETSImportDeclaration(node: arkts.ETSImportDeclaration): boolean { const additionalNames: string[] = [] node.specifiers.forEach(it => { const name = (it as arkts.ImportSpecifier).imported @@ -185,12 +185,12 @@ function transformETSImportDeclaration(node: arkts.ETSImportDeclaration): arkts. } } }) - if (additionalNames.length == 0) return node + if (additionalNames.length == 0) return false - return arkts.factory.updateETSImportDeclaration( + arkts.factory.updateETSImportDeclaration( node, - node.source, - [ ...node.specifiers, + [ + ...node.specifiers, ...additionalNames.map(it => arkts.factory.createImportSpecifier( arkts.factory.createIdentifier(it), arkts.factory.createIdentifier(it) @@ -198,6 +198,7 @@ function transformETSImportDeclaration(node: arkts.ETSImportDeclaration): arkts. ], node.isTypeKind ? arkts.Es2pandaImportKinds.IMPORT_KINDS_TYPES : arkts.Es2pandaImportKinds.IMPORT_KINDS_ALL ) + return true } @@ -208,8 +209,36 @@ export class BuilderLambdaTransformer extends arkts.AbstractVisitor { if (arkts.isCallExpression(node)) { return transformBuilderLambdaCall(node) } - if (arkts.isETSImportDeclaration(node)) { - return transformETSImportDeclaration(node) + + if (arkts.isETSModule(node)) { + const statements = node.statements + const newStatements: arkts.Statement[] = [] + let createdImports = 0 + /* + Updated imports are added to the beginning of statements by node.statements by compiler, but not added to newStatements by plugin + Non-updated imports and other statements are added to newStatements + Then ETSModule is updated by proper joining of node.statement and newStatements + TODO: maybe move all import inserting logic to libarkts, not keep in plugins? + */ + for (const statement of statements) { + if (arkts.isETSImportDeclaration(statement)) { + const updated = transformETSImportDeclaration(statement) + if (!updated) { + newStatements.push(statement) + } else { + createdImports++ + } + } else { + newStatements.push(statement) + } + } + return arkts.updateETSModuleByStatements( + node, + [ + ...node.statements.slice(0, createdImports), + ...newStatements, + ] + ) } return node