diff --git a/arkoala-arkts/trivial/user/src/ets/entry.ets b/arkoala-arkts/trivial/user/src/ets/entry.ets index eff1a9d4a7aa7edfd2fce416e453501e485f52db..cb12df953aecea07d48c1cca7a5e2f7156253e76 100644 --- a/arkoala-arkts/trivial/user/src/ets/entry.ets +++ b/arkoala-arkts/trivial/user/src/ets/entry.ets @@ -4,7 +4,7 @@ import { Page1 } from "./page1" @memo -function RunEntry() { +function RunEntry(): void { Page1() } diff --git a/arkoala-arkts/trivial/user/src/ets/page1.ets b/arkoala-arkts/trivial/user/src/ets/page1.ets index 818f771cfd9806a9b209ca3276d8e25869c2a281..1cef00bf7e9274376d33f2b1b7d3a2b563410d9c 100644 --- a/arkoala-arkts/trivial/user/src/ets/page1.ets +++ b/arkoala-arkts/trivial/user/src/ets/page1.ets @@ -1,4 +1,4 @@ -import { Button, Column, Image, ForEach } from "@ohos.arkui" +import { Button, UIButtonAttribute, Column, UIColumnAttribute, Image, UIImageAttribute, ForEach } from "@ohos.arkui" //@Entry @Component @@ -13,7 +13,7 @@ struct TestConsume { Button(`Consume: ` + this.state) .width(200).height(100) .backgroundColor(this.color) - .onClick((e?: ClickEvent) => { this.inc() }) + .onClick((e?: ClickEvent): void => { this.inc() }) } inc(stateName?: string) { @@ -41,7 +41,7 @@ struct TestProvide { Button('Provide: ' + this.state1) .width(200).height(100) .backgroundColor('#b420a0') - .onClick((e?: ClickEvent) => { this.inc() }) + .onClick((e?: ClickEvent): void => { this.inc() }) TestConsume(/*{ linkState: this.aState }*/) TestConsume() } @@ -105,41 +105,41 @@ struct Page1 { Column({}) { if (this.visible) { nLog("With blinker") - Button("Blinker") + Button("Blinker", undefined) .width(200).height(100) .backgroundColor('#ff0000') Child1() } ForEach( this.data, - (item: string) => { + (item: string): void => { Column({}) { - Button("Hi") + Button("Hi", undefined) .backgroundColor(this.color1) .width(200).height(100) - .onClick((e?: ClickEvent) => { + .onClick((e?: ClickEvent): void => { nLog("Hi button") this.swap() }) - Button("Bye") + Button("Bye", undefined) .backgroundColor(this.color2) .width(200).height(100) - .onClick((e?: ClickEvent) => { + .onClick((e?: ClickEvent): void => { nLog("Bye button") this.swap() }) Text($r('app.string.my_text')).height(50) - Button("Click! " + this.state) + Button("Click! " + this.state, undefined) .width(200).height(100) .backgroundColor($r('app.color.my_color')) - .onClick((e?: ClickEvent) => { + .onClick((e?: ClickEvent): void => { this.state++ nLog("Click button") nLog("#### Set Button onClick! #" + this.state) }) - Image($r('app.media.startIcon')).width(60).height(60) - Image($rawfile('koala.png')).width(400) - Text("Set Button onClick! #" + this.state) + Image($r('app.media.startIcon'), undefined).width(60).height(60) + Image($rawfile('koala.png'), undefined).width(400) + Text("Set Button onClick! #" + this.state, undefined) .width(200).height(100) TestProvide() //TestStructBuilder().width('100%') @@ -149,7 +149,7 @@ struct Page1 { .backgroundColor(Color.Gray) .justifyContent(FlexAlign.Center) }, - (item:string) => item + (item:string): string => item ) } } diff --git a/arkoala-arkts/trivial/user/src/ets/page2.ets b/arkoala-arkts/trivial/user/src/ets/page2.ets index df0b89101907766fbad899ad64bd5f51c75753eb..082374be00becdabf50394484fb7169618b952ae 100644 --- a/arkoala-arkts/trivial/user/src/ets/page2.ets +++ b/arkoala-arkts/trivial/user/src/ets/page2.ets @@ -1,4 +1,4 @@ -import { Button, Column, ColumnOptions, ClickEvent, State, PageTransitionEnter, PageTransitionExit } from "@ohos.arkui" +import { Button, UIButtonAttribute, Column, UIColumnAttribute, ColumnOptions, ClickEvent, State, PageTransitionEnter, PageTransitionExit } from "@ohos.arkui" import router from '@ohos.router' @@ -28,14 +28,14 @@ struct Page2 { build() { nLog(`In Page2 build()`) Column({}) { - Button("Click") + Button("Click", undefined) .width(200).height(100) .backgroundColor('#ff0000') .onClick((e?: ClickEvent): void => { this.value++ nLog(`Page2: clicked ${this.value}`) }) - Button("Back") + Button("Back", undefined) .width(200).height(100) .backgroundColor('#ff0000') .onClick((e?: ClickEvent): void => { diff --git a/arkoala-arkts/trivial/user/src/ets/page3.ets b/arkoala-arkts/trivial/user/src/ets/page3.ets index 92ed773a714e4ff04bd0fdea10480d14f3aa17a3..0734d5741257e33c14647240ba10a437a674bffd 100644 --- a/arkoala-arkts/trivial/user/src/ets/page3.ets +++ b/arkoala-arkts/trivial/user/src/ets/page3.ets @@ -1,5 +1,5 @@ import router from '@ohos.router' -import { Button, Column, ColumnOptions, ClickEvent, State, PageTransitionEnter, PageTransitionExit, PageTransitionOptions } from "@ohos.arkui" +import { Button, UIButtonAttribute, Column, UIColumnAttribute, ColumnOptions, ClickEvent, State, PageTransitionEnter, PageTransitionExit, PageTransitionOptions } from "@ohos.arkui" function nLog(message: string) { console.log(message) @@ -26,18 +26,18 @@ struct Page3 { } build() { nLog(`In Page3 build()`) - Column({}) { + Column({} as ColumnOptions) { Button("Click") .width(200).height(100) .backgroundColor('#ff0000') - .onClick((e?: ClickEvent) => { + .onClick((e?: ClickEvent): void => { this.value++ nLog(`Page3: clicked ${this.value}`) }) Button("Go") .width(200).height(100) .backgroundColor('#ff0000') - .onClick((e?: ClickEvent) => { + .onClick((e?: ClickEvent): void => { nLog(`Page3: Go clicked`) router.push({ url: "page2" }) }) diff --git a/incremental/tools/panda/arkts/ui2abc b/incremental/tools/panda/arkts/ui2abc index 34fc7967e3504e88d3c15b5f1714c065a685506c..244e74bc2a29eeb4cb26027ef07e219bf750f61f 100755 --- a/incremental/tools/panda/arkts/ui2abc +++ b/incremental/tools/panda/arkts/ui2abc @@ -14,5 +14,5 @@ # limitations under the License. SCRIPT_DIR=`dirname "${BASH_SOURCE[0]}"` -PANDA_SDK_PATH=$SCRIPT_DIR/../node_modules/@panda/sdk node $SCRIPT_DIR/../../../../ui2abc/libarkts/lib/es2panda.js "$@" +PANDA_SDK_PATH=$SCRIPT_DIR/../node_modules/@panda/sdk node $SCRIPT_DIR/../../../../ui2abc/libarkts/lib/es2panda.js "$@" --dump-plugin-ast diff --git a/ui2abc/libarkts/src-host/es2panda.ts b/ui2abc/libarkts/src-host/es2panda.ts index 3031d9a79690e18bc0409f4d1cec9b62ee61050a..d84c7b63d3db48a2a2395fa9577fbb82aa261cb1 100644 --- a/ui2abc/libarkts/src-host/es2panda.ts +++ b/ui2abc/libarkts/src-host/es2panda.ts @@ -15,7 +15,7 @@ import * as fs from "node:fs" import * as path from "node:path" -import { arktsGlobal as global } from "@koalaui/libarkts" +import { arktsGlobal as global, ImportStorage } from "@koalaui/libarkts" import { CheckedBackFilter, ChainExpressionFilter } from "@koalaui/libarkts" import { Command } from "commander" import { filterSource, isNumber, throwError, withWarning } from "@koalaui/libarkts" @@ -84,12 +84,20 @@ function insertPlugin( return } const ast = program.program.astNode + const importStorage = new ImportStorage(program.program, state == Es2pandaContextState.ES2PANDA_STATE_PARSED) + transform?.(program.program, { isMainProgram: false, name: program.name, stage: state }) + setBaseOverloads(ast) + if (!restart) { + importStorage.update() + } setAllParents(ast) }) } + const importStorage = new ImportStorage(global.compilerContext.program, state == Es2pandaContextState.ES2PANDA_STATE_PARSED) + transform?.(global.compilerContext.program, { isMainProgram: true, name: `${global.packageName}.${global.filePathFromPackageRoot}`, stage: state }) const afterTransform = Date.now() @@ -106,6 +114,9 @@ function insertPlugin( if (!restart) stageSpecificFilters(script, state) setBaseOverloads(script) + if (!restart) { + importStorage.update() + } setAllParents(script) if (!restart) { diff --git a/ui2abc/libarkts/src/arkts-api/ImportStorage.ts b/ui2abc/libarkts/src/arkts-api/ImportStorage.ts new file mode 100644 index 0000000000000000000000000000000000000000..132a4656c62bfba5247e26289f4b64bc6c9f30d5 --- /dev/null +++ b/ui2abc/libarkts/src/arkts-api/ImportStorage.ts @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2025 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 { KNativePointer } from "@koalaui/interop" +import { ImportDeclaration, isETSImportDeclaration, Statement } from "../generated" +import { Program } from "./peers/Program" +import { updateETSModuleByStatements } from "./utilities/public" +import { passNode, passNodeArray, unpackNonNullableNode } from "./utilities/private" +import { global } from "./static/global" +import { Es2pandaImportFlags, Es2pandaImportKinds } from "../generated/Es2pandaEnums" + +export class ImportStorage { + // TODO: migrate to wrappers instead of pointers + private imports: Set = new Set() + private importSources: Set = new Set() + + constructor(private program: Program, private isParserStage: boolean) { + for (const statement of program.astNode.statements) { + if (isETSImportDeclaration(statement)) { + this.imports.add(statement.peer) + if (!isParserStage) { + // TODO: is source non nullable? + this.importSources.add(statement.source?.str) + } + } + } + } + + update() { + // Save current statements + const statements = this.program.astNode.statements + + // Update parser information + const newStatements: Statement[] = [] + for (const statement of statements) { + if (isETSImportDeclaration(statement) && !this.imports.has(statement.peer)) { + if (!this.isParserStage && !this.importSources.has(statement.source?.str)) { + console.warn("Attempt to insert import from new source after parsed stage:") + console.warn(statement.dumpSrc()) + } + + const importDeclaration = unpackNonNullableNode( + // Note: this call is important, we cannot just pass "statement" to "InsertETSImportDeclarationAndParse" + global.es2panda._ETSParserBuildImportDeclaration( + global.context, + Es2pandaImportKinds.IMPORT_KINDS_ALL, // TODO: do we use IMPORT_KINDS_TYPES? + passNodeArray(statement.specifiers), + statement.specifiers.length, + passNode(statement.source), + this.program.peer, + Es2pandaImportFlags.IMPORT_FLAGS_NONE, // TODO: where to get it? + ) + ) as ImportDeclaration + global.es2panda._InsertETSImportDeclarationAndParse(global.context, this.program.peer, importDeclaration.peer) + newStatements.push(importDeclaration) + } else { + newStatements.push(statement) + } + } + + // Drop import statements generated by compiler in the beginning of the ETSModule + updateETSModuleByStatements( + this.program.astNode, + newStatements, + ) + } +} diff --git a/ui2abc/libarkts/src/arkts-api/factory/nodeFactory.ts b/ui2abc/libarkts/src/arkts-api/factory/nodeFactory.ts index 9b806770fe16668b6faa627ec9eb5878f5a982f3..efda20b6ba3cf63f873f56189778bcb57dea9114 100644 --- a/ui2abc/libarkts/src/arkts-api/factory/nodeFactory.ts +++ b/ui2abc/libarkts/src/arkts-api/factory/nodeFactory.ts @@ -25,6 +25,7 @@ import { VariableDeclarator, ObjectExpression, ETSTuple, + ETSImportDeclaration, } from "../../generated" import { factory as generatedFactory } from "../../generated/factory" import { createScriptFunction, updateScriptFunction } from "../node-utilities/ScriptFunction" @@ -34,7 +35,7 @@ import { updateMemberExpression } from "../node-utilities/MemberExpression" import { createETSParameterExpression, updateETSParameterExpression } from "../node-utilities/ETSParameterExpression" import { updateTSTypeParameter } from "../node-utilities/TSTypeParameter" import { updateETSTypeReferencePart } from "../node-utilities/TSTypeReferencePart" -import { createETSImportDeclaration, updateETSImportDeclaration } from "../node-utilities/ETSImportDeclaration" +import { updateETSImportDeclaration } from "../node-utilities/ETSImportDeclaration" import { updateVariableDeclarator } from "../node-utilities/VariableDeclarator" import { updateClassDefinition } from "../node-utilities/ClassDefinition" import { updateETSStructDeclaration } from "../node-utilities/ETSStructDeclaration" @@ -75,7 +76,7 @@ export const factory = { createETSTypeReferencePart: ETSTypeReferencePart.createETSTypeReferencePart, updateETSTypeReferencePart, - createETSImportDeclaration, + createETSImportDeclaration: ETSImportDeclaration.createETSImportDeclaration, updateETSImportDeclaration, createVariableDeclarator: VariableDeclarator.create1VariableDeclarator, diff --git a/ui2abc/libarkts/src/arkts-api/index.ts b/ui2abc/libarkts/src/arkts-api/index.ts index c6a3f9d25cbecde3f80c53b347fd1299c29790fd..438d3eaf266dee8f2c05660768aaa9e59928a994 100644 --- a/ui2abc/libarkts/src/arkts-api/index.ts +++ b/ui2abc/libarkts/src/arkts-api/index.ts @@ -25,6 +25,7 @@ export * from "./ChainExpressionFilter" export * from "./CheckedBackFilter" export * from "./SetBaseOverloads" export * from "./plugins" +export * from "./ImportStorage" export * from "./peers/AstNode" export * from "./peers/Config" diff --git a/ui2abc/libarkts/src/arkts-api/node-utilities/ETSImportDeclaration.ts b/ui2abc/libarkts/src/arkts-api/node-utilities/ETSImportDeclaration.ts index 05a6d3bbcc4a565d91c9776cc6d83a7c702762b0..a809a0acba600252bc2f512677af9f049d778f17 100644 --- a/ui2abc/libarkts/src/arkts-api/node-utilities/ETSImportDeclaration.ts +++ b/ui2abc/libarkts/src/arkts-api/node-utilities/ETSImportDeclaration.ts @@ -15,34 +15,9 @@ import { ETSImportDeclaration, StringLiteral } from "../../generated" import { isSameNativeObject } from "../peers/ArktsObject" -import { passNode, passNodeArray, unpackNonNullableNode, updateNodeByNode } from "../utilities/private" +import { updateNodeByNode } from "../utilities/private" import { AstNode } from "../peers/AstNode" -import { Es2pandaImportFlags, Es2pandaImportKinds } from "../../generated/Es2pandaEnums" -import { global } from "../static/global" -import { Program } from "../peers/Program" - -export function createETSImportDeclaration( - source: StringLiteral | undefined, - specifiers: readonly AstNode[], - importKind: Es2pandaImportKinds, - program: Program, - flags: Es2pandaImportFlags -): ETSImportDeclaration { - // TODO: check that plugin is on parsed stage - const res = unpackNonNullableNode( - global.es2panda._ETSParserBuildImportDeclaration( - global.context, - importKind, - passNodeArray(specifiers), - specifiers.length, - passNode(source), - program.peer, - flags - ) - ) - global.es2panda._InsertETSImportDeclarationAndParse(global.context, program.peer, res.peer) - return new ETSImportDeclaration(res.peer) -} +import { Es2pandaImportKinds } from "../../generated/Es2pandaEnums" export function updateETSImportDeclaration( original: ETSImportDeclaration, diff --git a/ui2abc/libarkts/src/index.ts b/ui2abc/libarkts/src/index.ts index b538e70d26f5104437715191e5df3f7777b0db26..c5f7ecc9625906a13a51a2f52cbd64547bad3b85 100644 --- a/ui2abc/libarkts/src/index.ts +++ b/ui2abc/libarkts/src/index.ts @@ -27,6 +27,7 @@ export * from "./arkts-api/ChainExpressionFilter" export * from "./arkts-api/CheckedBackFilter" export * from "./arkts-api/SetBaseOverloads" export * from "./arkts-api/plugins" +export * from "./arkts-api/ImportStorage" export * from "./arkts-api/peers/AstNode" export * from "./arkts-api/peers/Config" diff --git a/ui2abc/libarkts/test/arkts-api/general/recheck.test.ts b/ui2abc/libarkts/test/arkts-api/general/recheck.test.ts index ccde6f39fdae511ee2d25ed3d7afcdeb90bec69b..3f05e834791f8831c9190fce28f76bb18a3ab922 100644 --- a/ui2abc/libarkts/test/arkts-api/general/recheck.test.ts +++ b/ui2abc/libarkts/test/arkts-api/general/recheck.test.ts @@ -59,26 +59,32 @@ suite(util.basename(__filename), () => { arkts.proceedToState(arkts.Es2pandaContextState.ES2PANDA_STATE_PARSED) + const importStorage = new arkts.ImportStorage(arkts.arktsGlobal.compilerContext.program, true) const module = arkts.createETSModuleFromContext() - arkts.factory.createETSImportDeclaration( - arkts.factory.createStringLiteral( - './library' - ), + arkts.updateETSModuleByStatements( + module, [ - arkts.factory.createImportSpecifier( - arkts.factory.createIdentifier( - 'testFunction' + arkts.factory.createETSImportDeclaration( + arkts.factory.createStringLiteral( + './library' ), - arkts.factory.createIdentifier( - 'testFunction' - ) - ) - ], - arkts.Es2pandaImportKinds.IMPORT_KINDS_ALL, - arkts.arktsGlobal.compilerContext.program, - arkts.Es2pandaImportFlags.IMPORT_FLAGS_NONE + [ + arkts.factory.createImportSpecifier( + arkts.factory.createIdentifier( + 'testFunction' + ), + arkts.factory.createIdentifier( + 'testFunction' + ) + ) + ], + arkts.Es2pandaImportKinds.IMPORT_KINDS_ALL, + ), + ...module.statements, + ] ) + importStorage.update() arkts.arktsGlobal.es2panda._AstNodeUpdateAll(arkts.arktsGlobal.context, module.peer) arkts.proceedToState(arkts.Es2pandaContextState.ES2PANDA_STATE_CHECKED) @@ -98,7 +104,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 = @@ -111,42 +117,55 @@ console.log("test"); arkts.proceedToState(arkts.Es2pandaContextState.ES2PANDA_STATE_CHECKED) + const importStorage = new arkts.ImportStorage(arkts.arktsGlobal.compilerContext.program, true) const module = arkts.createETSModuleFromContext() arkts.arktsGlobal.compilerContext.program.externalSources.forEach(it => { if (!it.getName().includes("library")) return it.programs.forEach(program => { new RenameTestFunction().visitor(program.astNode) + arkts.arktsGlobal.es2panda._AstNodeUpdateAll(program.astNode.peer, module.peer) }) }) - arkts.factory.createETSImportDeclaration( - arkts.factory.createStringLiteral( - './library' - ), + arkts.updateETSModuleByStatements( + module, [ - arkts.factory.createImportSpecifier( - arkts.factory.createIdentifier( - 'testFunctionChanged' + arkts.factory.updateETSImportDeclaration( + module.statements[0] as arkts.ETSImportDeclaration, + arkts.factory.createStringLiteral( + './library' ), - arkts.factory.createIdentifier( - 'testFunctionChanged' - ) - ) - ], - arkts.Es2pandaImportKinds.IMPORT_KINDS_ALL, - arkts.arktsGlobal.compilerContext.program, - arkts.Es2pandaImportFlags.IMPORT_FLAGS_NONE + [ + arkts.factory.createImportSpecifier( + arkts.factory.createIdentifier( + 'testFunctionChanged' + ), + arkts.factory.createIdentifier( + 'testFunctionChanged' + ) + ) + ], + arkts.Es2pandaImportKinds.IMPORT_KINDS_ALL, + ), + ...module.statements.slice(1), + ] ) new RenameTestFunction().visitor(module) + importStorage.update() arkts.arktsGlobal.es2panda._AstNodeUpdateAll(arkts.arktsGlobal.context, module.peer) arkts.recheckSubtree(module) 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/import-export/import.test.ts b/ui2abc/libarkts/test/arkts-api/import-export/import.test.ts index 8871498412c1c0c77513949d055ffb08111e3817..72138030b224260d0a11c3d23a6a80fbc1387deb 100644 --- a/ui2abc/libarkts/test/arkts-api/import-export/import.test.ts +++ b/ui2abc/libarkts/test/arkts-api/import-export/import.test.ts @@ -26,23 +26,26 @@ suite(util.basename(__filename), () => { let script = arkts.createETSModuleFromSource(sample_in) - arkts.factory.createETSImportDeclaration( - arkts.factory.createStringLiteral( - './variable' - ), + arkts.updateETSModuleByStatements( + script, [ - arkts.factory.createImportSpecifier( - arkts.factory.createIdentifier( - 'X' + arkts.factory.createETSImportDeclaration( + arkts.factory.createStringLiteral( + './variable' ), - arkts.factory.createIdentifier( - 'X' - ) + [ + arkts.factory.createImportSpecifier( + arkts.factory.createIdentifier( + 'X' + ), + arkts.factory.createIdentifier( + 'X' + ) + ) + ], + arkts.Es2pandaImportKinds.IMPORT_KINDS_ALL, ) - ], - arkts.Es2pandaImportKinds.IMPORT_KINDS_ALL, - global.compilerContext.program, - arkts.Es2pandaImportFlags.IMPORT_FLAGS_DEFAULT_IMPORT + ] ) util.ARKTS_TEST_ASSERTION( @@ -63,23 +66,27 @@ suite(util.basename(__filename), () => { let script = arkts.createETSModuleFromSource(sample_in) const importDeclaration = script.statements[0] as arkts.ETSImportDeclaration - arkts.factory.createETSImportDeclaration( - arkts.factory.createStringLiteral( - './variable' - ), + arkts.updateETSModuleByStatements( + script, [ - arkts.factory.createImportSpecifier( - arkts.factory.createIdentifier( - 'X' + arkts.factory.createETSImportDeclaration( + arkts.factory.createStringLiteral( + './variable' ), - arkts.factory.createIdentifier( - 'X' - ) - ) - ], - arkts.Es2pandaImportKinds.IMPORT_KINDS_ALL, - global.compilerContext.program, - arkts.Es2pandaImportFlags.IMPORT_FLAGS_DEFAULT_IMPORT + [ + arkts.factory.createImportSpecifier( + arkts.factory.createIdentifier( + 'X' + ), + arkts.factory.createIdentifier( + 'X' + ) + ) + ], + arkts.Es2pandaImportKinds.IMPORT_KINDS_ALL, + ), + ...script.statements, + ] ) util.ARKTS_TEST_ASSERTION( @@ -105,23 +112,27 @@ suite(util.basename(__filename), () => { let script = arkts.createETSModuleFromSource(sample_in) const importDeclaration = script.statements[0] as arkts.ETSImportDeclaration - arkts.factory.createETSImportDeclaration( - arkts.factory.createStringLiteral( - './variable' - ), + arkts.updateETSModuleByStatements( + script, [ - arkts.factory.createImportSpecifier( - arkts.factory.createIdentifier( - 'X' + arkts.factory.createETSImportDeclaration( + arkts.factory.createStringLiteral( + './variable' ), - arkts.factory.createIdentifier( - 'X' - ) - ) - ], - arkts.Es2pandaImportKinds.IMPORT_KINDS_ALL, - global.compilerContext.program, - arkts.Es2pandaImportFlags.IMPORT_FLAGS_DEFAULT_IMPORT + [ + arkts.factory.createImportSpecifier( + arkts.factory.createIdentifier( + 'X' + ), + arkts.factory.createIdentifier( + 'X' + ) + ) + ], + arkts.Es2pandaImportKinds.IMPORT_KINDS_ALL, + ), + ...script.statements, + ] ) util.ARKTS_TEST_ASSERTION( diff --git a/ui2abc/libarkts/test/arkts-api/recheck/imports/add-new-file/index.ts b/ui2abc/libarkts/test/arkts-api/recheck/imports/add-new-file/index.ts index 2946c3485038426074c89c2b27695117b4087db1..a8723904f0d306e0e82bde2f930af70cdf618fd0 100644 --- a/ui2abc/libarkts/test/arkts-api/recheck/imports/add-new-file/index.ts +++ b/ui2abc/libarkts/test/arkts-api/recheck/imports/add-new-file/index.ts @@ -16,9 +16,7 @@ export function addImportNewFile(program: arkts.Program, options: arkts.Compilat ) ) ], - 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-same-file/index.ts b/ui2abc/libarkts/test/arkts-api/recheck/imports/add-same-file/index.ts index 5f77f7fb3b45930b756fbe80a361f1b9b2ebe71a..4cdce2cb1e0f8d7eb5fdf2a416c73d53b7409e73 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,27 @@ 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.updateETSModuleByStatements( + program.astNode, [ - arkts.factory.createImportSpecifier( - arkts.factory.createIdentifier( - 'testFunction' + arkts.factory.createETSImportDeclaration( + arkts.factory.createStringLiteral( + './library' ), - arkts.factory.createIdentifier( - 'testFunction' - ) - ) - ], - arkts.Es2pandaImportKinds.IMPORT_KINDS_ALL, - arkts.arktsGlobal.compilerContext.program, - arkts.Es2pandaImportFlags.IMPORT_FLAGS_NONE + [ + arkts.factory.createImportSpecifier( + arkts.factory.createIdentifier( + 'testFunction' + ), + arkts.factory.createIdentifier( + 'testFunction' + ) + ) + ], + arkts.Es2pandaImportKinds.IMPORT_KINDS_ALL + ), + ...program.astNode.statements, + ] ) } return program 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..2731b8a93f774caaf3ffad270ec824f125186aee 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,27 @@ export function addUseImportSameFile(program: arkts.Program, options: arkts.Comp ) ] ) - arkts.factory.createETSImportDeclaration( - arkts.factory.createStringLiteral( - './library' - ), + arkts.updateETSModuleByStatements( + program.astNode, [ - arkts.factory.createImportSpecifier( - arkts.factory.createIdentifier( - 'testFunction' + arkts.factory.createETSImportDeclaration( + arkts.factory.createStringLiteral( + './library' ), - arkts.factory.createIdentifier( - 'testFunction' - ) - ) - ], - arkts.Es2pandaImportKinds.IMPORT_KINDS_ALL, - arkts.arktsGlobal.compilerContext.program, - arkts.Es2pandaImportFlags.IMPORT_FLAGS_NONE + [ + arkts.factory.createImportSpecifier( + arkts.factory.createIdentifier( + 'testFunction' + ), + arkts.factory.createIdentifier( + 'testFunction' + ) + ) + ], + arkts.Es2pandaImportKinds.IMPORT_KINDS_ALL + ), + ...program.astNode.statements, + ] ) } return program diff --git a/ui2abc/libarkts/test/arkts-api/recheck/recheck.test.ts b/ui2abc/libarkts/test/arkts-api/recheck/recheck.test.ts index 9fb45b5d0ce0adf5320726631fd36f42e35bcd2e..f421ab4146fe87ce8d8168e4966d5e690a20aaf2 100644 --- a/ui2abc/libarkts/test/arkts-api/recheck/recheck.test.ts +++ b/ui2abc/libarkts/test/arkts-api/recheck/recheck.test.ts @@ -67,17 +67,21 @@ function applyTransform(transform?: arkts.ProgramTransformer, onlyModifyMain?: b if (it.getName().startsWith("escompat")) return it.programs.forEach(program => { const ast = program.astNode + const importStorage = new arkts.ImportStorage(program, false) if (!onlyModifyMain) { transform?.(program, { isMainProgram: false, name: "", stage: arkts.Es2pandaContextState.ES2PANDA_STATE_CHECKED }) } arkts.setBaseOverloads(ast) + importStorage.update() arkts.arktsGlobal.es2panda._AstNodeUpdateAll(arkts.arktsGlobal.context, ast.peer) }) }) const script = arkts.createETSModuleFromContext() + const importStorage = new arkts.ImportStorage(arkts.arktsGlobal.compilerContext.program, false) transform?.(arkts.arktsGlobal.compilerContext.program, { isMainProgram: true, name: "", stage: arkts.Es2pandaContextState.ES2PANDA_STATE_CHECKED }) arkts.setBaseOverloads(script) + importStorage.update() arkts.arktsGlobal.es2panda._AstNodeUpdateAll(arkts.arktsGlobal.context, script.peer) } diff --git a/ui2abc/memo-plugin/src/FunctionTransformer.ts b/ui2abc/memo-plugin/src/FunctionTransformer.ts index ebfa49711171c1511114578c156fd4d754fe9dc8..e9f457364faa7332e5e097b745ee335c536b4d12 100644 --- a/ui2abc/memo-plugin/src/FunctionTransformer.ts +++ b/ui2abc/memo-plugin/src/FunctionTransformer.ts @@ -298,6 +298,7 @@ export class FunctionTransformer extends arkts.AbstractVisitor { return this.signatureTransformer.visitor(node) } + visitor(beforeChildren: arkts.ETSModule, options?: FunctionTransformerOptions): arkts.ETSModule visitor(beforeChildren: arkts.AstNode, options?: FunctionTransformerOptions): arkts.AstNode { this.enter(beforeChildren) const node = this.visitEachChild(beforeChildren, { diff --git a/ui2abc/memo-plugin/src/MemoFactory.ts b/ui2abc/memo-plugin/src/MemoFactory.ts index 9feefa275fefa4f29c7825d0b6f16f279447a0b1..4f0a7712dab2304cb8c0a50a4ad83ca8d6d9c2df 100644 --- a/ui2abc/memo-plugin/src/MemoFactory.ts +++ b/ui2abc/memo-plugin/src/MemoFactory.ts @@ -37,14 +37,12 @@ export class factory { ) } - static createContextTypesImportDeclaration(program: arkts.Program, debug: boolean, path?: string) { + static createContextTypesImportDeclaration(debug: boolean, path?: string): arkts.ETSImportDeclaration { const mandatory = [factory.createContextTypeImportSpecifier(), factory.createIdTypeImportSpecifier()] - arkts.factory.createETSImportDeclaration( + return arkts.factory.createETSImportDeclaration( arkts.factory.createStringLiteral(path ?? RuntimeNames.CONTEXT_TYPE_DEFAULT_IMPORT), debug ? [...mandatory, factory.createHashImportSpecifier()] : mandatory, - arkts.Es2pandaImportKinds.IMPORT_KINDS_ALL, - program, - arkts.Es2pandaImportFlags.IMPORT_FLAGS_DEFAULT_IMPORT + arkts.Es2pandaImportKinds.IMPORT_KINDS_ALL ) } @@ -133,30 +131,34 @@ export class factory { parameters.map((name, id) => { return factory.createMemoParameterDeclarator(id, name) }), ) } - static createMemoParameterModifiedLogging(parameters: string[]): arkts.CallExpression { - return arkts.factory.createCallExpression( - arkts.factory.createMemberExpression( - arkts.factory.createIdentifier(DebugNames.CONSOLE, undefined), - arkts.factory.createIdentifier(DebugNames.LOG, undefined), - arkts.Es2pandaMemberExpressionKind.MEMBER_EXPRESSION_KIND_NONE, - false, - false, - ), - [ - arkts.factory.createStringLiteral(DebugNames.BANNER_PARAMETER), - ...parameters.flatMap((name) => { return [ - arkts.factory.createStringLiteral(`( ${name} modified:`), - arkts.factory.createMemberExpression( - factory.createMemoParameterIdentifier(name), - arkts.factory.createIdentifier("modified", undefined), - arkts.Es2pandaMemberExpressionKind.MEMBER_EXPRESSION_KIND_GETTER, - false, - false - ), - arkts.factory.createStringLiteral(`)`), - ] }) - ], - undefined, + static createMemoParameterModifiedLogging(parameters: string[]): arkts.ExpressionStatement { + return arkts.factory.createExpressionStatement( + arkts.factory.createCallExpression( + arkts.factory.createMemberExpression( + arkts.factory.createIdentifier(DebugNames.CONSOLE, undefined), + arkts.factory.createIdentifier(DebugNames.LOG, undefined), + arkts.Es2pandaMemberExpressionKind.MEMBER_EXPRESSION_KIND_NONE, + false, + false, + ), + [ + arkts.factory.createStringLiteral(DebugNames.BANNER_PARAMETER), + ...parameters.flatMap((name) => { + return [ + arkts.factory.createStringLiteral(`( ${name} modified:`), + arkts.factory.createMemberExpression( + factory.createMemoParameterIdentifier(name), + arkts.factory.createIdentifier("modified", undefined), + arkts.Es2pandaMemberExpressionKind.MEMBER_EXPRESSION_KIND_GETTER, + false, + false + ), + arkts.factory.createStringLiteral(`)`), + ] + }) + ], + undefined, + ) ) } static createMemoParameterAccess(name: string): arkts.MemberExpression { @@ -281,26 +283,28 @@ export class factory { undefined, ) } - static createUnchangedLogging() { - return arkts.factory.createCallExpression( - arkts.factory.createMemberExpression( - arkts.factory.createIdentifier(DebugNames.CONSOLE, undefined), - arkts.factory.createIdentifier(DebugNames.LOG, undefined), - arkts.Es2pandaMemberExpressionKind.MEMBER_EXPRESSION_KIND_NONE, - false, - false, - ), - [ - arkts.factory.createStringLiteral(DebugNames.BANNER_UNCHANGED), + static createUnchangedLogging(): arkts.Statement { + return arkts.factory.createExpressionStatement( + arkts.factory.createCallExpression( arkts.factory.createMemberExpression( - arkts.factory.createIdentifier(RuntimeNames.SCOPE, undefined), - arkts.factory.createIdentifier(RuntimeNames.INTERNAL_VALUE_OK, undefined), - arkts.Es2pandaMemberExpressionKind.MEMBER_EXPRESSION_KIND_GETTER, + arkts.factory.createIdentifier(DebugNames.CONSOLE, undefined), + arkts.factory.createIdentifier(DebugNames.LOG, undefined), + arkts.Es2pandaMemberExpressionKind.MEMBER_EXPRESSION_KIND_NONE, false, - false - ) - ], - undefined, + false, + ), + [ + arkts.factory.createStringLiteral(DebugNames.BANNER_UNCHANGED), + arkts.factory.createMemberExpression( + arkts.factory.createIdentifier(RuntimeNames.SCOPE, undefined), + arkts.factory.createIdentifier(RuntimeNames.INTERNAL_VALUE_OK, undefined), + arkts.Es2pandaMemberExpressionKind.MEMBER_EXPRESSION_KIND_GETTER, + false, + false + ) + ], + undefined, + ) ) } diff --git a/ui2abc/memo-plugin/src/MemoTransformer.ts b/ui2abc/memo-plugin/src/MemoTransformer.ts index d995da83c705cdb209acccb490414b1db26ff79e..c60a6868c303aed842cc3b16628e984094f144bf 100644 --- a/ui2abc/memo-plugin/src/MemoTransformer.ts +++ b/ui2abc/memo-plugin/src/MemoTransformer.ts @@ -64,7 +64,13 @@ export default function memoTransformer( let result = functionTransformer.visitor(node) if (userPluginOptions?.manuallyDisableInsertingImport != true) { if ((functionTransformer.modified || signatureTransformer.modified)) { - factory.createContextTypesImportDeclaration(program, userPluginOptions?.stableForTests ?? false, userPluginOptions?.contextImport) + result = arkts.updateETSModuleByStatements( + result, + [ + factory.createContextTypesImportDeclaration(userPluginOptions?.stableForTests ?? false, userPluginOptions?.contextImport), + ...result.statements + ] + ) } } if (userPluginOptions?.keepTransformed) { diff --git a/ui2abc/memo-plugin/src/ParserTransformer.ts b/ui2abc/memo-plugin/src/ParserTransformer.ts index 731c04e1628cd1c37a3a8c60b845195f15425b1f..20672ef53574c4115accf462d67471a05fd82feb 100644 --- a/ui2abc/memo-plugin/src/ParserTransformer.ts +++ b/ui2abc/memo-plugin/src/ParserTransformer.ts @@ -30,6 +30,12 @@ export default function memoParserTransformer( if (options.name.startsWith('@koalaui/common') || options.name.startsWith('@koalaui/compat')) return if (options.name.startsWith('@koalaui/runtime.internals') || options.name.startsWith('@koalaui/runtime/annotations')) return } - factory.createContextTypesImportDeclaration(program, userPluginOptions?.stableForTests ?? false, userPluginOptions?.contextImport) + return arkts.updateETSModuleByStatements( + program.astNode, + [ + factory.createContextTypesImportDeclaration(userPluginOptions?.stableForTests ?? false, userPluginOptions?.contextImport), + ...program.astNode.statements, + ] + ) } } diff --git a/ui2abc/ui-plugins/src/builder-lambda-transformer.ts b/ui2abc/ui-plugins/src/builder-lambda-transformer.ts index a374206c2223271c8f31d4a1b9ba4390f40f356c..d4542bd2cd14614b57cf682923ce2c18f3282651 100644 --- a/ui2abc/ui-plugins/src/builder-lambda-transformer.ts +++ b/ui2abc/ui-plugins/src/builder-lambda-transformer.ts @@ -89,15 +89,15 @@ export function builderLambdaFunctionName(node: arkts.CallExpression): string | TODO: remove this once compiler is capable of inferring type on it's own whole function is a couple of hacks */ -function inferType(node: arkts.CallExpression): arkts.Identifier | undefined { +function inferType(node: arkts.CallExpression): string | undefined { if (arkts.isIdentifier(node.callee)) { const component = node.callee.name - return arkts.factory.createIdentifier(uiAttributeName(component)) + return uiAttributeName(component) } const decl = arkts.getDecl(node.callee!) if (arkts.isMethodDefinition(decl)) { if (arkts.isClassDefinition(decl.parent)) { - return decl.parent.ident + return decl.parent.ident?.name } } return undefined @@ -107,9 +107,18 @@ function createBuilderLambdaInstanceLambda(node: arkts.CallExpression): arkts.Ex return createInstanceLambda(node.arguments[0], inferType(node)) } +function typeReferenceByName(name: string|undefined): arkts.TypeNode|undefined { + if (name == undefined) return undefined + return arkts.factory.createETSTypeReference( + arkts.factory.createETSTypeReferencePart( + arkts.factory.createIdentifier(name), undefined, undefined + ) + ) +} + function createInstanceLambda( instanceArgument: arkts.Expression, - parameterTypeName?: arkts.Identifier + parameterTypeName?: string ): arkts.Expression { if (arkts.isUndefinedLiteral(instanceArgument)) { return instanceArgument @@ -117,13 +126,7 @@ function createInstanceLambda( const lambdaParameter = arkts.factory.createETSParameterExpression( arkts.factory.createIdentifier( styledInstance, - parameterTypeName !== undefined ? - arkts.factory.createETSTypeReference( - arkts.factory.createETSTypeReferencePart( - parameterTypeName, undefined, undefined - ) - ) - : undefined + typeReferenceByName(parameterTypeName), ), false ) @@ -135,7 +138,8 @@ function createInstanceLambda( instanceLambdaBody, undefined, [lambdaParameter], - undefined, + //typeReferenceByName(parameterTypeName), + arkts.factory.createETSPrimitiveType(arkts.Es2pandaPrimitiveType.PRIMITIVE_TYPE_VOID), false, arkts.Es2pandaScriptFunctionFlags.SCRIPT_FUNCTION_FLAGS_ARROW, arkts.Es2pandaModifierFlags.MODIFIER_FLAGS_NONE, @@ -145,6 +149,20 @@ function createInstanceLambda( ) } +function builderLambdaCallee(name: string) { + if (!name.includes('.')) { + return arkts.factory.createIdentifier(name) + } + // TODO: What are the restrictions on builderLambda name? + return arkts.factory.createMemberExpression( + arkts.factory.createIdentifier(name.split('.')[0]), + arkts.factory.createIdentifier(name.split('.')[1]), + arkts.Es2pandaMemberExpressionKind.MEMBER_EXPRESSION_KIND_PROPERTY_ACCESS, + false, + false + ) +} + function transformBuilderLambdaCall(node: arkts.CallExpression): arkts.CallExpression { const implFunction = builderLambdaFunctionName(node) if (implFunction === undefined) { @@ -152,7 +170,7 @@ function transformBuilderLambdaCall(node: arkts.CallExpression): arkts.CallExpre } return arkts.factory.updateCallExpression( node, - arkts.factory.createIdentifier(implFunction, undefined), + builderLambdaCallee(implFunction), [ createBuilderLambdaInstanceLambda(node), ...node.arguments.slice(1) @@ -209,7 +227,7 @@ export class BuilderLambdaTransformer extends arkts.AbstractVisitor { return transformBuilderLambdaCall(node) } if (arkts.isETSImportDeclaration(node)) { - return transformETSImportDeclaration(node) + // return transformETSImportDeclaration(node) } return node diff --git a/ui2abc/ui-plugins/src/checked-stage-plugin.ts b/ui2abc/ui-plugins/src/checked-stage-plugin.ts index 22bdad7e59b9bb6082d477887604a32a830e8b48..177e41083541382108b75c878b1118d0def313b8 100644 --- a/ui2abc/ui-plugins/src/checked-stage-plugin.ts +++ b/ui2abc/ui-plugins/src/checked-stage-plugin.ts @@ -17,6 +17,7 @@ import * as arkts from "@koalaui/libarkts" import { StyleTransformer } from "./style-transformer" import { EtsFirstArgTransformer } from "./ets-first-arg-transformer" import { BuilderLambdaTransformer } from "./builder-lambda-transformer" +import { InstantiateFactoryHelper } from "./instantiate-factory-helper" export interface TransformerOptions { trace?: boolean, @@ -27,6 +28,7 @@ export default function checkedTransformer( ) { console.log("CHECKED: ", userPluginOptions) return (program: arkts.Program) => [ + new InstantiateFactoryHelper(), new EtsFirstArgTransformer(), new StyleTransformer(), new BuilderLambdaTransformer() diff --git a/ui2abc/ui-plugins/src/component-transformer.ts b/ui2abc/ui-plugins/src/component-transformer.ts index 14a08d2ebb17a64ab2b7b44db4b0dc315725a5b0..a321becedd5cc07dd865b99e09572f7e21f1e1cd 100644 --- a/ui2abc/ui-plugins/src/component-transformer.ts +++ b/ui2abc/ui-plugins/src/component-transformer.ts @@ -52,6 +52,7 @@ class StructCallRewriter extends arkts.AbstractVisitor { currentStructRewritten: arkts.ETSStructDeclaration | undefined = undefined currentStructCalled: StructDescriptor | undefined = undefined + visitor(node: arkts.ClassDeclaration, options?: object): arkts.ClassDeclaration visitor(node: arkts.AstNode, options?: object): arkts.AstNode { if (arkts.isCallExpression(node) && arkts.isIdentifier(node.callee)) { const struct = this.structTable.findStruct(node.callee as arkts.Identifier) @@ -414,7 +415,12 @@ export class ComponentTransformer extends arkts.AbstractVisitor { private rewriteStruct(node: arkts.ETSStructDeclaration, result: arkts.Statement[]) { this.callRewriter.currentStructRewritten = node - result.push(this.callRewriter.visitor(arkts.factory.createClassDeclaration(this.rewriteStructToClass(node)))) + const classDeclaration = arkts.factory.createClassDeclaration(this.rewriteStructToClass(node)) + const updatedClassDeclaration = this.callRewriter.visitor(classDeclaration) + updatedClassDeclaration.modifierFlags |= arkts.Es2pandaModifierFlags.MODIFIER_FLAGS_EXPORT + // TODO: move this "addToExportedClasses" logic to libarkts + updatedClassDeclaration.definition?.addToExportedClasses(updatedClassDeclaration) + result.push(updatedClassDeclaration) result.push(this.rewriteStructToOptions(node)) this.callRewriter.currentStructRewritten = undefined } diff --git a/ui2abc/ui-plugins/src/imports-transformer.ts b/ui2abc/ui-plugins/src/imports-transformer.ts index b1eed018cbca496048993d455614916279956397..6515b63ac684f332551e48389102988a1f9e7a3c 100644 --- a/ui2abc/ui-plugins/src/imports-transformer.ts +++ b/ui2abc/ui-plugins/src/imports-transformer.ts @@ -17,16 +17,18 @@ import { Importer } from "./utils" import * as arkts from "@koalaui/libarkts" export class ImportsTransformer { - constructor(private program: arkts.Program, private imports: Importer) {} + constructor(private imports: Importer) {} - private addImports() { - this.imports.emit(this.program) + private addImports(statements: readonly arkts.Statement[]): arkts.Statement[] { + return this.imports.emit(statements) } visitor(node: arkts.AstNode): arkts.AstNode { if (arkts.isETSModule(node)) { - this.addImports() - return node + return arkts.updateETSModuleByStatements( + node, + this.addImports(node.statements) + ) } throw new Error(`Must not be there`) } diff --git a/ui2abc/ui-plugins/src/parsed-stage-plugin.ts b/ui2abc/ui-plugins/src/parsed-stage-plugin.ts index 80c9058bc168e5e832a51061ec8ed27f842813fd..4fa5c888bc8af69cc52af2c625d7bf3cca487a9b 100644 --- a/ui2abc/ui-plugins/src/parsed-stage-plugin.ts +++ b/ui2abc/ui-plugins/src/parsed-stage-plugin.ts @@ -31,7 +31,7 @@ export default function parsedTransformer( new ComponentTransformer(imports, structTable, userPluginOptions), new AnnotationsTransformer(), new CallTransformer(imports, userPluginOptions), - new ImportsTransformer(program, imports) + new ImportsTransformer(imports) ] .reduce((node: arkts.AstNode, transformer) => transformer.visitor(node), program.astNode) } diff --git a/ui2abc/ui-plugins/src/utils.ts b/ui2abc/ui-plugins/src/utils.ts index d4b7dc7c91f45eb506e0752011b10958251f1cbb..0156cdeb8d8024d55e795bbfec1e652d0825d234 100644 --- a/ui2abc/ui-plugins/src/utils.ts +++ b/ui2abc/ui-plugins/src/utils.ts @@ -115,9 +115,9 @@ export function createStageManagementType(stageManagementIdent: string, property ); } -export function makeImport(program: arkts.Program, what: string, asWhat: string, where: string) { +export function makeImport(what: string, asWhat: string, where: string) { const source: arkts.StringLiteral = arkts.factory.createStringLiteral(where) - arkts.factory.createETSImportDeclaration( + return arkts.factory.createETSImportDeclaration( source, [ arkts.factory.createImportSpecifier( @@ -125,9 +125,7 @@ export function makeImport(program: arkts.Program, what: string, asWhat: string, arkts.factory.createIdentifier(asWhat) ) ], - arkts.Es2pandaImportKinds.IMPORT_KINDS_ALL, - program, - arkts.Es2pandaImportFlags.IMPORT_FLAGS_NONE + arkts.Es2pandaImportKinds.IMPORT_KINDS_ALL ) } @@ -170,10 +168,12 @@ export class Importer { throw new Error(`Mismatching import ${what} from ${where}`) this.storage.set(what, [where, asWhat]) } - emit(program: arkts.Program): void { + emit(statements: readonly arkts.Statement[]): arkts.Statement[] { + const newStatements = [...statements] this.storage.forEach(([where, asWhat], what) => { - makeImport(program, what, asWhat, where) + newStatements.unshift(makeImport(what, asWhat, where)) }) + return newStatements } }