diff --git a/arkui-plugins/common/log-collector.ts b/arkui-plugins/common/log-collector.ts index 16e00bde2e5c4735b2c3785930e8e535d1337146..5fa9ed7af815dca0e10d9c5bc469f3477762227d 100644 --- a/arkui-plugins/common/log-collector.ts +++ b/arkui-plugins/common/log-collector.ts @@ -35,9 +35,11 @@ export function generateDiagnosticKind(logItem: LogInfo): arkts.DiagnosticKind { export class LogCollector { public logInfos: LogInfo[]; private static instance: LogCollector; + private ignoreError: boolean; private constructor() { this.logInfos = []; + this.ignoreError = false; } static getInstance(): LogCollector { @@ -49,6 +51,7 @@ export class LogCollector { reset(): void { this.logInfos = []; + this.ignoreError = false; } collectLogInfo(logItem: LogInfo): void { @@ -56,8 +59,17 @@ export class LogCollector { } emitLogInfo(): void { + if (this.ignoreError) { + return; + } this.logInfos.forEach((logItem: LogInfo) => { arkts.Diagnostic.logDiagnostic(generateDiagnosticKind(logItem), arkts.getStartPosition(logItem.node)); }); } + + shouldIgnoreError(ignoreError: boolean | undefined): void { + if (!!ignoreError) { + this.ignoreError = true; + } + } } diff --git a/arkui-plugins/common/plugin-context.ts b/arkui-plugins/common/plugin-context.ts index 6396f7bf8a0b7b563369f0e5aa9579342014c308..333894b19fd064867a59f0ea1ba3c0a603906adc 100644 --- a/arkui-plugins/common/plugin-context.ts +++ b/arkui-plugins/common/plugin-context.ts @@ -58,7 +58,7 @@ export class PluginContext { } public setProjectConfig(projectConfig: ProjectConfig): void { - throw new Error('do not set projectConfig!'); + this.projectConfig = projectConfig; } public getProjectConfig(): ProjectConfig | undefined { @@ -103,6 +103,7 @@ export interface ProjectConfig { moduleType: string; moduleRootPath: string; aceModuleJsonPath: string; + ignoreError: boolean; } export type PluginHandlerFunction = () => void; diff --git a/arkui-plugins/jest-test.config.js b/arkui-plugins/jest-test.config.js index bd3fca4ea4c9be894067f97c6042784ac3128ad4..98b801f7012da41deebf5f3393dcb11d096b4acc 100644 --- a/arkui-plugins/jest-test.config.js +++ b/arkui-plugins/jest-test.config.js @@ -55,7 +55,4 @@ module.exports = { API_PATH: apiPath, KIT_PATH: kitPath }, - testPathIgnorePatterns: [ - './test/ut/ui-plugins/decorators/resource/', - ], }; diff --git a/arkui-plugins/test/demo/mock/decorators/resource/resource-in-build.ets b/arkui-plugins/test/demo/mock/decorators/resource/resource-in-build.ets index 49331e647034ca169b243def6931cf493705f231..f77f9a04b97aaf59e97607b85e067610159eed97 100644 --- a/arkui-plugins/test/demo/mock/decorators/resource/resource-in-build.ets +++ b/arkui-plugins/test/demo/mock/decorators/resource/resource-in-build.ets @@ -13,36 +13,46 @@ * limitations under the License. */ -import { Component, $r, $rawfile, Column, Text, Image, TextInput, Select, SelectOption, Margin, ImageAnimator } from "@ohos.arkui.component" +import { Component, $r, $rawfile, Column, Text, Image, TextInput, Select, SelectOption, Margin, ImageAnimator, Resource } from "@ohos.arkui.component" @Component struct ResourceComponent { str1: string = 'app.media.ri' str2: string = 'app.photo2.png' + numbers: string[] = ['0','1','3','5','8'] + aboutToAppear() { + let arr: Array = new Array() + for (let i = 0; i < 5; i++) { + arr.push($r('app.string.app_name')) + } + for (let item of this.numbers) { + arr.push($r('app.string.app_name')) + } + } build() { Column() { Text($r('app.string.app_name')) - Image($rawfile('app.photo.png')) - TextInput({ text: $r('app.string.input_content') }) + Image($rawfile('app.mock.txt')) + TextInput({ text: $r('app.string.module_desc') }) Text($r(this.str1)) Text($r(this.str2)) Select(new Array( - { value: 'aaa', icon: $r("app.media.selection") }, - { value: 'bbb', icon: $r("app.media.selection") }, - { value: 'ccc', icon: $r("app.media.selection") }, - { value: 'ddd', icon: $r("app.media.selection") } + { value: 'aaa', icon: $r("app.media.background") }, + { value: 'bbb', icon: $r("app.media.background") }, + { value: 'ccc', icon: $r("app.media.background") }, + { value: 'ddd', icon: $r("app.media.background") } )) Image($r('app.media.app_icon')) .margin({ - top: $r('app.float.elements_margin_horizontal_m'), - bottom: $r('app.float.elements_margin_horizontal_l') + top: $r('app.float.page_text_font_size'), + bottom: $r('app.float.page_text_font_size') } as Margin) ImageAnimator().images([ { - src: $r('app.media.aaa') + src: $r('app.media.app_icon') }, { - src: $r('app.media.bbb') + src: $r('app.media.layered_image') }, ]) } diff --git a/arkui-plugins/test/demo/mock/decorators/resource/resource-in-property.ets b/arkui-plugins/test/demo/mock/decorators/resource/resource-in-property.ets index 591311c7dd671e824d0ea6e39561dc4b8f4990ae..fca6a78a7096aef65412f00b4d3ebb233a7cc517 100644 --- a/arkui-plugins/test/demo/mock/decorators/resource/resource-in-property.ets +++ b/arkui-plugins/test/demo/mock/decorators/resource/resource-in-property.ets @@ -20,7 +20,7 @@ let i: Resource = $r('app.string.app_name'); @Component struct ResourceComponent { private str: Resource = $r('app.string.app_name'); - private icon: Resource = $rawfile('app.photo.png'); + private icon: Resource = $rawfile('app.mock.txt'); build() { Column() { Text(this.str) diff --git a/arkui-plugins/test/demo/mock/resource/ResourceTable.txt b/arkui-plugins/test/demo/mock/resource/ResourceTable.txt new file mode 100644 index 0000000000000000000000000000000000000000..6c0c36582e7895d8bd429ff1b6e98d965e14619c --- /dev/null +++ b/arkui-plugins/test/demo/mock/resource/ResourceTable.txt @@ -0,0 +1,13 @@ +string EntryAbility_desc 0x01000002 +string EntryAbility_label 0x01000003 +string app_name 0x01000000 +string module_desc 0x01000004 +color start_window_background 0x01000005 +float page_text_font_size 0x01000006 +media app_icon 0x01000001 +media background 0x01000007 +media foreground 0x01000008 +media layered_image 0x01000009 +media startIcon 0x0100000a +profile backup_config 0x0100000b +profile main_pages 0x0100000c \ No newline at end of file diff --git a/arkui-plugins/test/demo/mock/resource/rawfile/mock.txt b/arkui-plugins/test/demo/mock/resource/rawfile/mock.txt new file mode 100644 index 0000000000000000000000000000000000000000..1eb866e0e1f17b2af95ac2dbb7fee38d688e7612 --- /dev/null +++ b/arkui-plugins/test/demo/mock/resource/rawfile/mock.txt @@ -0,0 +1 @@ +mocking rawfile \ No newline at end of file diff --git a/arkui-plugins/test/ut/ui-plugins/decorators/resource/resource-in-build.test.ts b/arkui-plugins/test/ut/ui-plugins/decorators/resource/resource-in-build.test.ts index b194c8cea669d4b349fb4d55df8a3c455df8af33..ab9a379ca4ea28f1c901acee47a5d0d20711de74 100644 --- a/arkui-plugins/test/ut/ui-plugins/decorators/resource/resource-in-build.test.ts +++ b/arkui-plugins/test/ut/ui-plugins/decorators/resource/resource-in-build.test.ts @@ -38,31 +38,25 @@ const parsedTransform: Plugins = { }; const expectedScript: string = ` - import { memo as memo } from "arkui.stateManagement.runtime"; - import { _rawfile as _rawfile } from "arkui.component.resources"; - -import { _r as _r } from "arkui.component.resources"; - import { ImageAnimatorAttribute as ImageAnimatorAttribute } from "arkui.component.imageAnimator"; - import { ImageAttribute as ImageAttribute } from "arkui.component.image"; - +import { _r as _r } from "arkui.component.resources"; +import { LayoutCallback as LayoutCallback } from "arkui.component.customComponent"; +import { CustomComponentV2 as CustomComponentV2 } from "arkui.component.customComponent"; import { CustomComponent as CustomComponent } from "arkui.component.customComponent"; - -import { Component as Component, $r as $r, $rawfile as $rawfile, Column as Column, Text as Text, Image as Image, TextInput as TextInput, Select as Select, SelectOption as SelectOption, Margin as Margin, ImageAnimator as ImageAnimator } from "@ohos.arkui.component"; - +import { Component as Component, $r as $r, $rawfile as $rawfile, Column as Column, Text as Text, Image as Image, TextInput as TextInput, Select as Select, SelectOption as SelectOption, Margin as Margin, ImageAnimator as ImageAnimator, Resource as Resource } from "@ohos.arkui.component"; function main() {} - - -@Component({freezeWhenInactive:false}) final struct ResourceComponent extends CustomComponent { +@Component() final struct ResourceComponent extends CustomComponent { public __initializeStruct(initializers: __Options_ResourceComponent | undefined, @memo() content: (()=> void) | undefined): void { this.__backing_str1 = ((({let gensym___147578113 = initializers; (((gensym___147578113) == (null)) ? undefined : gensym___147578113.str1)})) ?? ("app.media.ri")); this.__backing_str2 = ((({let gensym___220149772 = initializers; (((gensym___220149772) == (null)) ? undefined : gensym___220149772.str2)})) ?? ("app.photo2.png")); + this.__backing_numbers = ((({let gensym___ = initializers; + (((gensym___) == (null)) ? undefined : gensym___.numbers)})) ?? (["0", "1", "3", "5", "8"])); } public __updateStruct(initializers: __Options_ResourceComponent | undefined): void {} @@ -86,41 +80,59 @@ function main() {} public set str2(value: string) { this.__backing_str2 = value; } + private __backing_numbers?: Array; + + public get numbers(): Array { + return (this.__backing_numbers as Array); + } + + public set numbers(value: Array) { + this.__backing_numbers = value; + } + public aboutToAppear() { + let arr: Array = new Array(); + for (let i = 0;((i) < (5));(i++)) { + arr.push(_r(16777216, 10003, "com.example.mock", "entry")); + } + for (let item of this.numbers) { + arr.push(_r(16777216, 10003, "com.example.mock", "entry")); + } + } - @memo() public _build(@memo() style: ((instance: ResourceComponent)=> ResourceComponent) | undefined, @memo() content: (()=> void) | undefined, initializers: __Options_ResourceComponent | undefined): void { + @memo() public build() { Column(undefined, (() => { - Text(undefined, _r("", "", "app.string.app_name")); - Image(undefined, _rawfile("", "", "app.photo.png")); + Text(undefined, _r(16777216, 10003, "com.example.mock", "entry")); + Image(undefined, _rawfile(0, 30000, "com.example.mock", "entry", "app.mock.txt")); TextInput(undefined, { - text: _r("", "", "app.string.input_content"), + text: _r(16777220, 10003, "com.example.mock", "entry"), }); - Text(undefined, _r("", "", this.str1)); - Text(undefined, _r("", "", this.str2)); + Text(undefined, _r(-1, -1, "com.example.mock", "entry", this.str1)); + Text(undefined, _r(-1, -1, "com.example.mock", "entry", this.str2)); Select(undefined, new Array({ value: "aaa", - icon: _r("", "", "app.media.selection"), + icon: _r(16777223, 20000, "com.example.mock", "entry"), }, { value: "bbb", - icon: _r("", "", "app.media.selection"), + icon: _r(16777223, 20000, "com.example.mock", "entry"), }, { value: "ccc", - icon: _r("", "", "app.media.selection"), + icon: _r(16777223, 20000, "com.example.mock", "entry"), }, { value: "ddd", - icon: _r("", "", "app.media.selection"), + icon: _r(16777223, 20000, "com.example.mock", "entry"), })); Image(((instance: ImageAttribute): void => { instance.margin(({ - top: _r("", "", "app.float.elements_margin_horizontal_m"), - bottom: _r("", "", "app.float.elements_margin_horizontal_l"), + top: _r(16777222, 10002, "com.example.mock", "entry"), + bottom: _r(16777222, 10002, "com.example.mock", "entry"), } as Margin)); return; - }), _r("", "", "app.media.app_icon")); + }), _r(16777217, 20000, "com.example.mock", "entry")); ImageAnimator(((instance: ImageAnimatorAttribute): void => { instance.images([{ - src: _r("", "", "app.media.aaa"), + src: _r(16777217, 20000, "com.example.mock", "entry"), }, { - src: _r("", "", "app.media.bbb"), + src: _r(16777225, 20000, "com.example.mock", "entry"), }]); return; })); @@ -131,14 +143,13 @@ function main() {} } -@Component({freezeWhenInactive:false}) export interface __Options_ResourceComponent { +@Component() export interface __Options_ResourceComponent { set str1(str1: string | undefined) - get str1(): string | undefined set str2(str2: string | undefined) - get str2(): string | undefined - + set numbers(numbers: Array | undefined) + get numbers(): Array | undefined } `; diff --git a/arkui-plugins/test/ut/ui-plugins/decorators/resource/resource-in-property.test.ts b/arkui-plugins/test/ut/ui-plugins/decorators/resource/resource-in-property.test.ts index 3a394627112872717358a50315b7fdeca289c16c..6d28f0fb682ae6bc56ecb36c3cce9f9d935f9ab8 100644 --- a/arkui-plugins/test/ut/ui-plugins/decorators/resource/resource-in-property.test.ts +++ b/arkui-plugins/test/ut/ui-plugins/decorators/resource/resource-in-property.test.ts @@ -38,73 +38,57 @@ const parsedTransform: Plugins = { }; const expectedScript: string = ` - import { memo as memo } from "arkui.stateManagement.runtime"; - import { _rawfile as _rawfile } from "arkui.component.resources"; - import { _r as _r } from "arkui.component.resources"; - +import { LayoutCallback as LayoutCallback } from "arkui.component.customComponent"; +import { CustomComponentV2 as CustomComponentV2 } from "arkui.component.customComponent"; import { CustomComponent as CustomComponent } from "arkui.component.customComponent"; - import { Component as Component, $r as $r, $rawfile as $rawfile, Column as Column, Text as Text, Image as Image, Resource as Resource } from "@ohos.arkui.component"; let i: Resource; function main() {} -i = _r("", "", "app.string.app_name"); - -@Component({freezeWhenInactive:false}) final struct ResourceComponent extends CustomComponent { +i = _r(16777216, 10003, "com.example.mock", "entry"); +@Component() final struct ResourceComponent extends CustomComponent { public __initializeStruct(initializers: __Options_ResourceComponent | undefined, @memo() content: (()=> void) | undefined): void { this.__backing_str = ((({let gensym___42103502 = initializers; - (((gensym___42103502) == (null)) ? undefined : gensym___42103502.str)})) ?? (_r("", "", "app.string.app_name"))); + (((gensym___42103502) == (null)) ? undefined : gensym___42103502.str)})) ?? (_r(16777216, 10003, "com.example.mock", "entry"))); this.__backing_icon = ((({let gensym___38135554 = initializers; - (((gensym___38135554) == (null)) ? undefined : gensym___38135554.icon)})) ?? (_rawfile("", "", "app.photo.png"))); + (((gensym___38135554) == (null)) ? undefined : gensym___38135554.icon)})) ?? (_rawfile(0, 30000, "com.example.mock", "entry", "app.mock.txt"))); } - public __updateStruct(initializers: __Options_ResourceComponent | undefined): void {} - private __backing_str?: Resource; - public get str(): Resource { return (this.__backing_str as Resource); } - public set str(value: Resource) { this.__backing_str = value; } - private __backing_icon?: Resource; - public get icon(): Resource { return (this.__backing_icon as Resource); } - public set icon(value: Resource) { this.__backing_icon = value; } - - @memo() public _build(@memo() style: ((instance: ResourceComponent)=> ResourceComponent) | undefined, @memo() content: (()=> void) | undefined, initializers: __Options_ResourceComponent | undefined): void { + @memo() public build() { Column(undefined, (() => { Text(undefined, this.str); Text(undefined, i); Image(undefined, this.icon); })); } - private constructor() {} } -@Component({freezeWhenInactive:false}) export interface __Options_ResourceComponent { +@Component() export interface __Options_ResourceComponent { set str(str: Resource | undefined) - get str(): Resource | undefined set icon(icon: Resource | undefined) - get icon(): Resource | undefined - } `; diff --git a/arkui-plugins/test/utils/artkts-config.ts b/arkui-plugins/test/utils/artkts-config.ts index cbe7f33db63753b400e4884419fdd402b463aa0e..d60db9b487410e6ca36b1493fe5a428870391a57 100644 --- a/arkui-plugins/test/utils/artkts-config.ts +++ b/arkui-plugins/test/utils/artkts-config.ts @@ -21,13 +21,17 @@ import { changeFileExtension, ensurePathExists, getFileName, + getResourcePath, getRootPath, + MOCK_BUNDLE_NAME, MOCK_DEP_ANALYZER_PATH, MOCK_ENTRY_DIR_PATH, MOCK_ENTRY_FILE_NAME, MOCK_OUTPUT_CACHE_PATH, MOCK_OUTPUT_DIR_PATH, MOCK_OUTPUT_FILE_NAME, + MOCK_RAWFILE_DIR_PATH, + MOCK_RESOURCE_TABLE_FILE_NAME, PANDA_SDK_STDLIB_PATH, STDLIB_ESCOMPAT_PATH, STDLIB_PATH, @@ -36,6 +40,7 @@ import { import { ArkTSConfigContextCache } from './cache'; import { BuildConfig, CompileFileInfo, DependentModule } from './shared-types'; import { setUpSoPath } from './global'; +import { ProjectConfig } from '../../common/plugin-context'; export interface ArkTSConfigObject { compilerOptions: { @@ -75,6 +80,10 @@ export interface ArktsConfigBuilder { mergedAbcFile: string; // logger: Logger; // TODO isDebug: boolean; + projectConfig: ProjectConfig; + + withBuildConfig(buildConfig: BuildConfig): this; + withProjectConfig(projectConfig: ProjectConfig): this; clear(): void; } @@ -162,28 +171,60 @@ function mockBuildConfig(): BuildConfig { }; } +function mockProjectConfig(): ProjectConfig { + return { + bundleName: MOCK_BUNDLE_NAME, + moduleName: 'entry', + cachePath: path.resolve(getRootPath(), MOCK_OUTPUT_CACHE_PATH), + dependentModuleList: [], + appResource: path.resolve(getResourcePath(), MOCK_RESOURCE_TABLE_FILE_NAME), + rawFileResource: path.resolve(getResourcePath(), MOCK_RAWFILE_DIR_PATH), + buildLoaderJson: '', + hspResourcesMap: false, + compileHar: false, + byteCodeHar: false, + uiTransformOptimization: false, + resetBundleName: false, + allowEmptyBundleName: false, + moduleType: 'entry', + moduleRootPath: path.resolve(getRootPath(), MOCK_ENTRY_DIR_PATH), + aceModuleJsonPath: '', + }; +} + class MockArktsConfigBuilder implements ArktsConfigBuilder { hashId: string; - buildConfig: BuildConfig; - entryFiles: Set; - compileFiles: Map; - outputDir: string; - cacheDir: string; - pandaSdkPath: string; - apiPath: string; - kitsPath: string; - packageName: string; - sourceRoots: string[]; - moduleRootPath: string; - dependentModuleList: DependentModule[]; - moduleInfos: Map; - mergedAbcFile: string; + buildConfig!: BuildConfig; + entryFiles!: Set; + compileFiles!: Map; + outputDir!: string; + cacheDir!: string; + pandaSdkPath!: string; + apiPath!: string; + kitsPath!: string; + packageName!: string; + sourceRoots!: string[]; + moduleRootPath!: string; + dependentModuleList!: DependentModule[]; + moduleInfos!: Map; + mergedAbcFile!: string; isDebug: boolean; + projectConfig: ProjectConfig; - constructor(hashId: string, buildConfig?: BuildConfig) { + constructor(hashId: string, buildConfig?: BuildConfig, projectConfig?: ProjectConfig) { this.hashId = hashId; const _buildConfig: BuildConfig = buildConfig ?? mockBuildConfig(); + this._setBuildConfig(_buildConfig); + + const _projectConfig: ProjectConfig = projectConfig ?? mockProjectConfig(); + this.projectConfig = _projectConfig; + + this.isDebug = true; + } + + private _setBuildConfig(buildConfig: BuildConfig): void { + const _buildConfig: BuildConfig = buildConfig; this.buildConfig = _buildConfig; this.entryFiles = new Set(_buildConfig.compileFiles as string[]); this.outputDir = _buildConfig.loaderOutPath as string; @@ -195,7 +236,6 @@ class MockArktsConfigBuilder implements ArktsConfigBuilder { this.sourceRoots = _buildConfig.sourceRoots as string[]; this.moduleRootPath = path.resolve(_buildConfig.moduleRootPath as string); this.dependentModuleList = _buildConfig.dependentModuleList as DependentModule[]; - this.isDebug = true; this.compileFiles = new Map(); this.moduleInfos = new Map(); @@ -306,9 +346,19 @@ class MockArktsConfigBuilder implements ArktsConfigBuilder { }); } + withBuildConfig(buildConfig: BuildConfig): this { + this._setBuildConfig(buildConfig); + return this; + } + + withProjectConfig(projectConfig: ProjectConfig): this { + this.projectConfig = projectConfig; + return this; + } + clear(): void { ArkTSConfigContextCache.getInstance().delete(this.hashId); } } -export { mockBuildConfig, MockArktsConfigBuilder }; +export { mockBuildConfig, mockProjectConfig, MockArktsConfigBuilder }; diff --git a/arkui-plugins/test/utils/compile.ts b/arkui-plugins/test/utils/compile.ts index 46f9fe81bab9df519304eefed4caf601a3aac78e..9dd53785551220e7c673eba23035a18b7fc63ad3 100644 --- a/arkui-plugins/test/utils/compile.ts +++ b/arkui-plugins/test/utils/compile.ts @@ -201,6 +201,7 @@ function createContextForExternalCompilation(jobInfo: JobInfo): arkts.Context { function compileAbcWithExternal(emitter: EventEmitter, jobInfo: JobInfo, tracing: TraceOptions): void { MockPluginDriver.getInstance().initPlugins(jobInfo.plugins ?? []); + MockPluginDriver.getInstance().getPluginContext().setProjectConfig(jobInfo.projectConfig!); const context = createContextFromString(jobInfo.filePaths!); MockPluginDriver.getInstance().getPluginContext().setContextPtr(context.peer); const stopAfter = jobInfo.stopAfter!; @@ -243,6 +244,7 @@ function compileAbcWithExternal(emitter: EventEmitter, jobInfo: Jo function compileAbc(emitter: EventEmitter, jobInfo: JobInfo, tracing: TraceOptions): void { MockPluginDriver.getInstance().initPlugins(jobInfo.plugins ?? []); + MockPluginDriver.getInstance().getPluginContext().setProjectConfig(jobInfo.projectConfig!); const context = createContextForAbcCompilation(jobInfo); MockPluginDriver.getInstance().getPluginContext().setContextPtr(context.peer); const stopAfter = jobInfo.stopAfter!; @@ -282,6 +284,7 @@ function compileAbc(emitter: EventEmitter, jobInfo: JobInfo, traci function compileExternalProgram(emitter: EventEmitter, jobInfo: JobInfo, tracing: TraceOptions): void { MockPluginDriver.getInstance().initPlugins(jobInfo.plugins ?? []); + MockPluginDriver.getInstance().getPluginContext().setProjectConfig(jobInfo.projectConfig!); const context = createContextForExternalCompilation(jobInfo); MockPluginDriver.getInstance().getPluginContext().setContextPtr(context.peer); arkts.proceedToState(arkts.Es2pandaContextState.ES2PANDA_STATE_PARSED, context.peer); diff --git a/arkui-plugins/test/utils/path-config.ts b/arkui-plugins/test/utils/path-config.ts index 4712832cf5abbfe7f0d8e0e1acbb93a614a6ecf0..ddf26c1e1dc6de58740af6a0dabe9ba3e9611469 100644 --- a/arkui-plugins/test/utils/path-config.ts +++ b/arkui-plugins/test/utils/path-config.ts @@ -16,7 +16,7 @@ import * as fs from 'fs'; import * as path from 'path'; -export const ARKTS_CONFIG_FILE_PATH: string = 'arktsconfig.json';; +export const ARKTS_CONFIG_FILE_PATH: string = 'arktsconfig.json'; export const PANDA_SDK_STDLIB_PATH: string = 'lib'; export const STDLIB_PATH: string = 'stdlib'; export const STDLIB_STD_PATH: string = 'stdlib/std'; @@ -29,6 +29,9 @@ export const MOCK_OUTPUT_FILE_NAME: string = 'entry.abc'; export const MOCK_DEP_ANALYZER_PATH: string = 'bin/dependency_analyzer'; export const MOCK_FILE_DEP_FILE_NAME: string = 'file_dependencies.json'; export const MOCK_DEP_INPUT_FILE_NAME: string = 'depInput.txt'; +export const MOCK_RESOURCE_TABLE_FILE_NAME: string = 'ResourceTable.txt'; +export const MOCK_BUNDLE_NAME: string = 'com.example.mock'; +export const MOCK_RAWFILE_DIR_PATH: string = 'rawfile'; export const ETS_SUFFIX: string = '.ets'; export const ABC_SUFFIX: string = '.abc'; export const DECL_ETS_SUFFIX: string = '.d.ets'; @@ -37,6 +40,10 @@ function getRootPath(): string { return path.resolve(__dirname, '..', '..', 'test'); } +function getResourcePath(): string { + return path.resolve(getRootPath(), MOCK_ENTRY_DIR_PATH, 'resource'); +} + function changeFileExtension(file: string, targetExt: string, originExt = ''): string { const currentExt: string = originExt.length === 0 ? path.extname(file) : originExt; const fileWithoutExt: string = file.substring(0, file.lastIndexOf(currentExt)); @@ -62,4 +69,4 @@ function ensurePathExists(filePath: string): void { } } -export { getRootPath, changeFileExtension, getFileName, ensurePathExists }; +export { getRootPath, getResourcePath, changeFileExtension, getFileName, ensurePathExists }; diff --git a/arkui-plugins/test/utils/plugin-tester.ts b/arkui-plugins/test/utils/plugin-tester.ts index d10c4ebd3dea1b553d60ce49a51ba03b6fc23d97..1fe0942377972764cc6a02bb553efbf10d0603ab 100644 --- a/arkui-plugins/test/utils/plugin-tester.ts +++ b/arkui-plugins/test/utils/plugin-tester.ts @@ -26,7 +26,7 @@ import { } from './shared-types'; import { HashGenerator } from './hash-generator'; import { PluginTestContextCache } from './cache'; -import { Plugins, PluginState } from '../../common/plugin-context'; +import { Plugins, PluginState, ProjectConfig } from '../../common/plugin-context'; import { concatObject } from './serializable'; import { ProcessorBuilder } from './processor-builder'; import { MainProcessor } from './processors/main-processor'; @@ -48,6 +48,7 @@ type TestHooks = { export interface PluginTesterOptions { stopAfter: PluginState; buildConfig?: BuildConfig; + projectConfig?: ProjectConfig; tracing?: TraceOptions; } @@ -58,7 +59,7 @@ class PluginTester { private taskProcessor?: Processor; private resolve?: Promise; - constructor(describe: string, buildConfig?: BuildConfig) { + constructor(describe: string, buildConfig?: BuildConfig, projectConfig?: ProjectConfig) { this.describe = describe; this.hashId = HashGenerator.getInstance().dynamicSha1Id(describe, 13); this.configBuilder = new MockArktsConfigBuilder(this.hashId, buildConfig); @@ -175,6 +176,7 @@ class PluginTester { MainProcessor, this.hashId, this.configBuilder.buildConfig, + this.configBuilder.projectConfig, tracing ); return this.taskProcessor.invokeWorkers(plugins, stopAfter); @@ -188,7 +190,10 @@ class PluginTester { testHooks?: TestHooks ): void { if (!!options.buildConfig) { - this.configBuilder = new MockArktsConfigBuilder(this.hashId, options.buildConfig); + this.configBuilder = this.configBuilder.withBuildConfig(options.buildConfig); + } + if (!!options.projectConfig) { + this.configBuilder = this.configBuilder.withProjectConfig(options.projectConfig); } const that = this; diff --git a/arkui-plugins/test/utils/processor-builder.ts b/arkui-plugins/test/utils/processor-builder.ts index bb68e31e64f5f992917ef94a73a71c1472642fc9..7be32e773b639ff283e5484fe125d6c5d164575b 100644 --- a/arkui-plugins/test/utils/processor-builder.ts +++ b/arkui-plugins/test/utils/processor-builder.ts @@ -13,16 +13,25 @@ * limitations under the License. */ +import { ProjectConfig } from 'common/plugin-context'; import { BuildConfig, Processor, TraceOptions } from './shared-types'; class ProcessorBuilder { static build( - Processor: { new (hashId: string, buildConfig?: BuildConfig, tracing?: TraceOptions): Processor }, + Processor: { + new ( + hashId: string, + buildConfig?: BuildConfig, + projectConfig?: ProjectConfig, + tracing?: TraceOptions + ): Processor; + }, hashId: string, buildConfig?: BuildConfig, + projectConfig?: ProjectConfig, tracing?: TraceOptions ): Processor { - return new Processor(hashId, buildConfig, tracing); + return new Processor(hashId, buildConfig, projectConfig, tracing); } } diff --git a/arkui-plugins/test/utils/processors/base-processor.ts b/arkui-plugins/test/utils/processors/base-processor.ts index d60d269e09a9b53ac8715e426d0d40c13da32af6..53e79ea52df1b646c673d71942e669edc79c9fa2 100644 --- a/arkui-plugins/test/utils/processors/base-processor.ts +++ b/arkui-plugins/test/utils/processors/base-processor.ts @@ -13,20 +13,21 @@ * limitations under the License. */ -import { Plugins, PluginState } from "common/plugin-context"; -import { mockBuildConfig } from "../artkts-config"; -import { ArkTSConfigContextCache } from "../cache"; -import { BuildConfig, CompileFileInfo, Processor, TraceOptions } from "../shared-types"; +import { Plugins, PluginState, ProjectConfig } from '../../../common/plugin-context'; +import { mockBuildConfig, mockProjectConfig } from '../artkts-config'; +import { ArkTSConfigContextCache } from '../cache'; +import { BuildConfig, CompileFileInfo, Processor, TraceOptions } from '../shared-types'; abstract class BaseProcessor implements Processor { hashId: string; buildConfig: BuildConfig; + projectConfig: ProjectConfig; tracing: TraceOptions; cacheDir: string; arktsConfigFile: string; compileFiles: Map; - constructor(hashId: string, buildConfig?: BuildConfig, tracing?: TraceOptions) { + constructor(hashId: string, buildConfig?: BuildConfig, projectConfig?: ProjectConfig, tracing?: TraceOptions) { this.hashId = hashId; this.tracing = tracing ?? { externalSourceNames: [] }; @@ -35,6 +36,9 @@ abstract class BaseProcessor implements Processor { this.cacheDir = _buildConfig.cachePath; this.arktsConfigFile = this.getArktsConfigFile(); this.compileFiles = this.getCompileFiles(); + + const _projectConfig: ProjectConfig = projectConfig ?? mockProjectConfig(); + this.projectConfig = _projectConfig; } private getArktsConfigFile(): string { @@ -62,4 +66,4 @@ abstract class BaseProcessor implements Processor { abstract clear(): void; } -export { BaseProcessor }; \ No newline at end of file +export { BaseProcessor }; diff --git a/arkui-plugins/test/utils/processors/main-processor.ts b/arkui-plugins/test/utils/processors/main-processor.ts index e033948d713a29c37419cda2695acbbfbc189328..4b8f2399d3c3d80d42c104c93ac7447592efaaf8 100644 --- a/arkui-plugins/test/utils/processors/main-processor.ts +++ b/arkui-plugins/test/utils/processors/main-processor.ts @@ -26,11 +26,8 @@ import { import { BaseProcessor } from './base-processor'; import { PluginTestContextCache } from '../cache'; import { concatObject, serializable } from '../serializable'; -import { Plugins, PluginState } from '../../../common/plugin-context'; -import { - createGlobalConfig, - destroyGlobalConfig, -} from '../global'; +import { Plugins, PluginState, ProjectConfig } from '../../../common/plugin-context'; +import { createGlobalConfig, destroyGlobalConfig } from '../global'; import { compileAbcWithExternal } from '../compile'; class MainProcessor extends BaseProcessor { @@ -38,8 +35,8 @@ class MainProcessor extends BaseProcessor { readonly emitter: EventEmitter = new EventEmitter(); - constructor(hashId: string, buildConfig?: BuildConfig, tracing?: TraceOptions) { - super(hashId, buildConfig, tracing); + constructor(hashId: string, buildConfig?: BuildConfig, projectConfig?: ProjectConfig, tracing?: TraceOptions) { + super(hashId, buildConfig, projectConfig, tracing); this.filePaths = this.getCompileFilePaths(); } @@ -65,19 +62,16 @@ class MainProcessor extends BaseProcessor { }); } - private assignTask( - fileInfo: CompileFileInfo, - plugins: Plugins[], - stopAfter?: PluginState - ): void { + private assignTask(fileInfo: CompileFileInfo, plugins: Plugins[], stopAfter?: PluginState): void { const jobInfo: JobInfo = { id: 'compile-abc-with-external', isCompileAbc: CompileStrategy.ABC_WTIH_EXTERNAL, compileFileInfo: fileInfo, buildConfig: serializable(this.buildConfig), + projectConfig: serializable(this.projectConfig), plugins, stopAfter, - filePaths: this.filePaths + filePaths: this.filePaths, }; compileAbcWithExternal(this.emitter, jobInfo, this.tracing); } diff --git a/arkui-plugins/test/utils/processors/task-processor.ts b/arkui-plugins/test/utils/processors/task-processor.ts index 5371d14a38c84b790edf82298c712216b5e784a4..a66b89eb4b8008351d27efd2b6e547c5d646035c 100644 --- a/arkui-plugins/test/utils/processors/task-processor.ts +++ b/arkui-plugins/test/utils/processors/task-processor.ts @@ -37,7 +37,7 @@ import { import { FileDependencyContextCache, PluginTestContextCache } from '../cache'; import { HashGenerator } from '../hash-generator'; import { createGlobalConfig, createGlobalContextPtr, destroyGlobalConfig, destroyGlobalContextPtr } from '../global'; -import { Plugins, PluginState } from '../../../common/plugin-context'; +import { Plugins, PluginState, ProjectConfig } from '../../../common/plugin-context'; import { concatObject, serializable } from '../serializable'; import { compileAbc, compileExternalProgram } from '../compile'; import { BaseProcessor } from './base-processor'; @@ -242,8 +242,8 @@ class TaskProcessor extends BaseProcessor { readonly emitter: EventEmitter = new EventEmitter(); private worker!: WorkerInfo; - constructor(hashId: string, buildConfig?: BuildConfig, tracing?: TraceOptions) { - super(hashId, buildConfig, tracing); + constructor(hashId: string, buildConfig?: BuildConfig, projectConfig?: ProjectConfig, tracing?: TraceOptions) { + super(hashId, buildConfig, projectConfig, tracing); this.entryFiles = new Set(this.buildConfig.compileFiles as string[]); this.depAnalyzerPath = this.buildConfig.depAnalyzerPath; this.depInputFile = path.resolve(this.buildConfig.cachePath, this.hashId, MOCK_DEP_INPUT_FILE_NAME); @@ -413,6 +413,7 @@ class TaskProcessor extends BaseProcessor { processingJobs.add(job.id); jobInfo.compileFileInfo = this.compileFiles.get(job.fileList[0]); jobInfo.buildConfig = serializable(this.buildConfig); + jobInfo.projectConfig = serializable(this.projectConfig); jobInfo.plugins = plugins; jobInfo.globalContextPtr = globalContextPtr; jobInfo.stopAfter = stopAfter; diff --git a/arkui-plugins/test/utils/shared-types.ts b/arkui-plugins/test/utils/shared-types.ts index 415e407be9681d73a934edacd16cd977eadaa0bb..83c365d53308bdf262bb294402a004f6de62d555 100644 --- a/arkui-plugins/test/utils/shared-types.ts +++ b/arkui-plugins/test/utils/shared-types.ts @@ -13,7 +13,7 @@ * limitations under the License. */ -import type { Plugins, PluginState } from '../../common/plugin-context'; +import type { Plugins, PluginState, ProjectConfig } from '../../common/plugin-context'; export type PluginTesterId = string | `${string}:${string}`; @@ -61,9 +61,10 @@ export interface BuildConfig { sourceRoots: string[]; moduleRootPath: string; dependentModuleList: DependentModule[]; + projectConfig?: ProjectConfig; } -export type ModuleType = 'har' | string; // TODO: module type unclear +export type ModuleType = 'har' | 'feature' | 'entry' | string; // TODO: module type unclear export interface DependentModule { packageName: string; @@ -79,6 +80,7 @@ export interface JobInfo { isCompileAbc: CompileStrategy; compileFileInfo?: CompileFileInfo; buildConfig?: BuildConfig; + projectConfig?: ProjectConfig; plugins?: Plugins[]; globalContextPtr?: number; stopAfter?: PluginState; @@ -124,6 +126,7 @@ export type ProcessEvent = { export interface Processor { hashId: string; buildConfig: BuildConfig; + projectConfig?: ProjectConfig; tracing: TraceOptions; cacheDir: string; arktsConfigFile: string; diff --git a/arkui-plugins/ui-plugins/checked-transformer.ts b/arkui-plugins/ui-plugins/checked-transformer.ts index d5c9d3942751b25d255e5ea2440635c13d383f4d..31ec5a48e9a87f14254831ba8ab4124941319f7e 100644 --- a/arkui-plugins/ui-plugins/checked-transformer.ts +++ b/arkui-plugins/ui-plugins/checked-transformer.ts @@ -145,8 +145,9 @@ export class CheckedTransformer extends AbstractVisitor { return structFactory.tranformInterfaceMembers(node, this.externalSourceName); } else if (findCanAddMemoFromArrowFunction(node)) { return addMemoAnnotation(node); - } else if (arkts.isEtsScript(node) && ImportCollector.getInstance().importInfos.length > 0) { + } else if (arkts.isEtsScript(node)) { ImportCollector.getInstance().insertCurrentImports(this.program); + LogCollector.getInstance().shouldIgnoreError(this.projectConfig?.ignoreError); LogCollector.getInstance().emitLogInfo(); } else if (arkts.isTSTypeAliasDeclaration(node)) { return structFactory.transformTSTypeAlias(node); diff --git a/arkui-plugins/ui-plugins/index.ts b/arkui-plugins/ui-plugins/index.ts index 6c780b2f6f9d15ebfc59f01b3f23889d9e830f06..8751ffc4f4576ed4cb56d16a5e09cb543dc033bd 100644 --- a/arkui-plugins/ui-plugins/index.ts +++ b/arkui-plugins/ui-plugins/index.ts @@ -16,7 +16,7 @@ import * as arkts from '@koalaui/libarkts'; import { ComponentTransformer } from './component-transformer'; import { CheckedTransformer } from './checked-transformer'; -import { Plugins, PluginContext } from '../common/plugin-context'; +import { Plugins, PluginContext, ProjectConfig } from '../common/plugin-context'; import { ProgramVisitor } from '../common/program-visitor'; import { EXTERNAL_SOURCE_PREFIX_NAMES } from '../common/predefines'; import { debugDump, debugLog, getDumpFileName } from '../common/debug'; @@ -142,7 +142,11 @@ function checkedProgramVisit(program: arkts.Program, context: PluginContext): ar debugLog('[SKIP PHASE] phase: ui-checked, moduleName: ', program.moduleName); } else { debugLog('[CANT SKIP PHASE] phase: ui-checked, moduleName: ', program.moduleName); - const checkedTransformer = new CheckedTransformer(context.getProjectConfig()); + const projectConfig: ProjectConfig | undefined = context.getProjectConfig(); + if (projectConfig && !projectConfig.appResource) { + projectConfig.ignoreError = true; + } + const checkedTransformer = new CheckedTransformer(projectConfig); const programVisitor = new ProgramVisitor({ pluginName: uiTransform.name, state: arkts.Es2pandaContextState.ES2PANDA_STATE_CHECKED, diff --git a/koala-wrapper/native/src/generated/bridges.cc b/koala-wrapper/native/src/generated/bridges.cc index d89b383f9462046f70aebb5ed3cebe73e231b121..73a311a4ad69033499c0903612a317e66fda7a97 100644 --- a/koala-wrapper/native/src/generated/bridges.cc +++ b/koala-wrapper/native/src/generated/bridges.cc @@ -11282,6 +11282,19 @@ KNativePointer impl_CreateForUpdateStatement(KNativePointer context, KNativePoin } KOALA_INTEROP_5(CreateForUpdateStatement, KNativePointer, KNativePointer, KNativePointer, KNativePointer, KNativePointer, KNativePointer); +KNativePointer impl_UpdateForUpdateStatement(KNativePointer context, KNativePointer original, KNativePointer init, KNativePointer test, KNativePointer update, KNativePointer body) +{ + const auto _context = reinterpret_cast(context); + const auto _original = reinterpret_cast(original); + const auto _init = reinterpret_cast(init); + const auto _test = reinterpret_cast(test); + const auto _update = reinterpret_cast(update); + const auto _body = reinterpret_cast(body); + auto result = GetImpl()->UpdateForUpdateStatement(_context, _original, _init, _test, _update, _body); + return result; +} +KOALA_INTEROP_6(UpdateForUpdateStatement, KNativePointer, KNativePointer, KNativePointer, KNativePointer, KNativePointer, KNativePointer, KNativePointer); + KNativePointer impl_ForUpdateStatementInit(KNativePointer context, KNativePointer receiver) { const auto _context = reinterpret_cast(context); diff --git a/koala-wrapper/src/arkts-api/factory/nodeFactory.ts b/koala-wrapper/src/arkts-api/factory/nodeFactory.ts index f9ad2411845d976924a1b0ccd47a7d8968e1dbe4..c780fdbf9e9b760ce14b9536ad5b386725d3772d 100644 --- a/koala-wrapper/src/arkts-api/factory/nodeFactory.ts +++ b/koala-wrapper/src/arkts-api/factory/nodeFactory.ts @@ -78,6 +78,9 @@ import { AnnotationDeclaration, TryStatement, TSClassImplements, + ForUpdateStatement, + ForInStatement, + ForOfStatement, } from '../../generated'; import { Es2pandaModifierFlags } from '../../generated/Es2pandaEnums'; import { classPropertySetOptional, hasModifierFlag } from '../utilities/public'; @@ -136,6 +139,9 @@ import { updateArrayExpression } from '../node-utilities/ArrayExpression'; import { updateAnnotationDeclaration } from '../node-utilities/AnnotationDeclaration'; import { updateTryStatement } from '../node-utilities/TryStatement'; import { updateTSClassImplements } from '../node-utilities/TSClassImplements'; +import { updateForUpdateStatement } from '../node-utilities/ForUpdateStatement'; +import { updateForInStatement } from '../node-utilities/ForInStatement'; +import { updateForOfStatement } from '../node-utilities/ForOfStatement'; export const factory = { get createIdentifier(): (...args: Parameters) => Identifier { @@ -567,12 +573,34 @@ export const factory = { get updateTryStatement(): (...args: Parameters) => TryStatement { return updateTryStatement; }, - get createTSClassImplements(): (...args: Parameters) => TSClassImplements { + get createTSClassImplements(): ( + ...args: Parameters + ) => TSClassImplements { return TSClassImplements.createTSClassImplements; }, get UpdateTSClassImplements(): (...args: Parameters) => TSClassImplements { return updateTSClassImplements; }, + get createForUpdateStatement(): ( + ...args: Parameters + ) => ForUpdateStatement { + return ForUpdateStatement.createForUpdateStatement; + }, + get updateForUpdateStatement(): (...args: Parameters) => ForUpdateStatement { + return updateForUpdateStatement; + }, + get createForInStatement(): (...args: Parameters) => ForInStatement { + return ForInStatement.createForInStatement; + }, + get updateForInStatement(): (...args: Parameters) => ForInStatement { + return updateForInStatement; + }, + get createForOfStatement(): (...args: Parameters) => ForOfStatement { + return ForOfStatement.createForOfStatement; + }, + get updateForOfStatement(): (...args: Parameters) => ForOfStatement { + return updateForOfStatement; + }, /** @deprecated */ createTypeParameter1_(name: Identifier, constraint?: TypeNode, defaultType?: TypeNode) { return TSTypeParameter.createTSTypeParameter(Identifier.create1Identifier(name.name), constraint, defaultType); diff --git a/koala-wrapper/src/arkts-api/node-utilities/ForInStatement.ts b/koala-wrapper/src/arkts-api/node-utilities/ForInStatement.ts new file mode 100644 index 0000000000000000000000000000000000000000..40f78ab063b300786aaddf46ff46f6d4abb8d7fc --- /dev/null +++ b/koala-wrapper/src/arkts-api/node-utilities/ForInStatement.ts @@ -0,0 +1,37 @@ +/* + * 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 { ForInStatement, Statement, Expression } from '../../generated'; +import { isSameNativeObject } from '../peers/ArktsObject'; +import { AstNode } from '../peers/AstNode'; +import { attachModifiers, updateThenAttach } from '../utilities/private'; + +export function updateForInStatement( + original: ForInStatement, + left?: AstNode, + right?: Expression, + body?: Statement +): ForInStatement { + if ( + isSameNativeObject(left, original.left) && + isSameNativeObject(right, original.right) && + isSameNativeObject(body, original.body) + ) { + return original; + } + + const updateNode = updateThenAttach(ForInStatement.updateForInStatement, attachModifiers); + return updateNode(original, left, right, body); +} diff --git a/koala-wrapper/src/arkts-api/node-utilities/ForOfStatement.ts b/koala-wrapper/src/arkts-api/node-utilities/ForOfStatement.ts new file mode 100644 index 0000000000000000000000000000000000000000..9c8d99a1d9f350572c5752a21b4e6dbdc5650908 --- /dev/null +++ b/koala-wrapper/src/arkts-api/node-utilities/ForOfStatement.ts @@ -0,0 +1,38 @@ +/* + * 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 { ForOfStatement, Statement, Expression } from '../../generated'; +import { isSameNativeObject } from '../peers/ArktsObject'; +import { AstNode } from '../peers/AstNode'; +import { attachModifiers, updateThenAttach } from '../utilities/private'; + +export function updateForOfStatement( + original: ForOfStatement, + left: AstNode | undefined, + right: Expression | undefined, + body: Statement | undefined, + isAwait: boolean +): ForOfStatement { + if ( + isSameNativeObject(left, original.left) && + isSameNativeObject(right, original.right) && + isSameNativeObject(body, original.body) + ) { + return original; + } + + const updateNode = updateThenAttach(ForOfStatement.updateForOfStatement, attachModifiers); + return updateNode(original, left, right, body, isAwait); +} diff --git a/koala-wrapper/src/arkts-api/node-utilities/ForUpdateStatement.ts b/koala-wrapper/src/arkts-api/node-utilities/ForUpdateStatement.ts new file mode 100644 index 0000000000000000000000000000000000000000..0fa41007b56654e89af71ec85e5973361f2e4057 --- /dev/null +++ b/koala-wrapper/src/arkts-api/node-utilities/ForUpdateStatement.ts @@ -0,0 +1,39 @@ +/* + * 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 { ForUpdateStatement, Statement, Expression } from '../../generated'; +import { isSameNativeObject } from '../peers/ArktsObject'; +import { AstNode } from '../peers/AstNode'; +import { attachModifiers, updateThenAttach } from '../utilities/private'; + +export function updateForUpdateStatement( + original: ForUpdateStatement, + init?: AstNode, + test?: Expression, + update?: Expression, + body?: Statement +): ForUpdateStatement { + if ( + isSameNativeObject(init, original.init) && + isSameNativeObject(test, original.test) && + isSameNativeObject(update, original.update) && + isSameNativeObject(body, original.body) + ) { + return original; + } + + const updateNode = updateThenAttach(ForUpdateStatement.updateForUpdateStatement, attachModifiers); + return updateNode(original, init, test, update, body); +} diff --git a/koala-wrapper/src/arkts-api/visitor.ts b/koala-wrapper/src/arkts-api/visitor.ts index b0a45fbda56a9a5f8d73833a7a64d9568876a392..d5f2be7d122e2b7f8ab952f93e30b7adef0fb731 100644 --- a/koala-wrapper/src/arkts-api/visitor.ts +++ b/koala-wrapper/src/arkts-api/visitor.ts @@ -48,6 +48,9 @@ import { isArrayExpression, isTryStatement, isBinaryExpression, + isForInStatement, + isForUpdateStatement, + isForOfStatement, } from '../generated'; import { isEtsScript, @@ -98,6 +101,7 @@ export function visitEachChild(node: AstNode, visitor: Visitor): AstNode { script = visitDefinition(script, visitor); script = visitDefinitionBody(script, visitor); script = visitStatement(script, visitor); + script = visitForLoopStatement(script, visitor); script = visitOuterExpression(script, visitor); script = visitInnerExpression(script, visitor); script = visitTrivialExpression(script, visitor); @@ -145,10 +149,7 @@ function visitOuterExpression(node: AstNode, visitor: Visitor): AstNode { } if (isArrayExpression(node)) { updated = true; - return factory.updateArrayExpression( - node, - nodesVisitor(node.elements, visitor) - ); + return factory.updateArrayExpression(node, nodesVisitor(node.elements, visitor)); } return node; } @@ -353,6 +354,42 @@ function visitStatement(node: AstNode, visitor: Visitor): AstNode { return node; } +function visitForLoopStatement(node: AstNode, visitor: Visitor): AstNode { + if (updated) { + return node; + } + if (isForUpdateStatement(node)) { + updated = true; + return factory.updateForUpdateStatement( + node, + nodeVisitor(node.init, visitor), + nodeVisitor(node.test, visitor), + nodeVisitor(node.update, visitor), + nodeVisitor(node.body, visitor) + ); + } + if (isForInStatement(node)) { + updated = true; + return factory.updateForInStatement( + node, + nodeVisitor(node.left, visitor), + nodeVisitor(node.right, visitor), + nodeVisitor(node.body, visitor) + ); + } + if (isForOfStatement(node)) { + updated = true; + return factory.updateForOfStatement( + node, + nodeVisitor(node.left, visitor), + nodeVisitor(node.right, visitor), + nodeVisitor(node.body, visitor), + node.isAwait + ); + } + return node; +} + function visitETSModule(node: AstNode, visitor: Visitor): AstNode { if (updated) { return node; diff --git a/koala-wrapper/src/generated/Es2pandaNativeModule.ts b/koala-wrapper/src/generated/Es2pandaNativeModule.ts index 7dcfda5a9e6fd221976438214656a28cdb7b1448..ef089731b19427e8bd01e8367ce692f5fda6ad31 100644 --- a/koala-wrapper/src/generated/Es2pandaNativeModule.ts +++ b/koala-wrapper/src/generated/Es2pandaNativeModule.ts @@ -3562,6 +3562,16 @@ export class Es2pandaNativeModule { _CreateForUpdateStatement(context: KNativePointer, init: KNativePointer, test: KNativePointer, update: KNativePointer, body: KNativePointer): KNativePointer { throw new Error("'CreateForUpdateStatement was not overloaded by native module initialization") } + _UpdateForUpdateStatement( + context: KNativePointer, + original: KNativePointer, + init: KNativePointer, + test: KNativePointer, + update: KNativePointer, + body: KNativePointer + ): KNativePointer { + throw new Error("'CreateForUpdateStatement was not overloaded by native module initialization"); + } _ForUpdateStatementInit(context: KNativePointer, receiver: KNativePointer): KNativePointer { throw new Error("'ForUpdateStatementInit was not overloaded by native module initialization") } diff --git a/koala-wrapper/src/generated/peers/ForInStatement.ts b/koala-wrapper/src/generated/peers/ForInStatement.ts index adb587a5e0ffbef7e9acff669298e42af3aab1d7..52d828bc18144096e4a20c57bfce70a5a8f991e8 100644 --- a/koala-wrapper/src/generated/peers/ForInStatement.ts +++ b/koala-wrapper/src/generated/peers/ForInStatement.ts @@ -16,47 +16,62 @@ import { global, passNode, - passNodeArray, - unpackNonNullableNode, unpackNode, - unpackNodeArray, assertValidPeer, AstNode, Es2pandaAstNodeType, KNativePointer, nodeByType, - ArktsObject, - unpackString -} from "../../reexport-for-generated" +} from '../../reexport-for-generated'; -import { LoopStatement } from "./LoopStatement" -import { Expression } from "./Expression" -import { Statement } from "./Statement" +import { LoopStatement } from './LoopStatement'; +import { Expression } from './Expression'; +import { Statement } from './Statement'; export class ForInStatement extends LoopStatement { - constructor(pointer: KNativePointer) { - assertValidPeer(pointer, Es2pandaAstNodeType.AST_NODE_TYPE_FOR_IN_STATEMENT) - super(pointer) - + constructor(pointer: KNativePointer) { + assertValidPeer(pointer, Es2pandaAstNodeType.AST_NODE_TYPE_FOR_IN_STATEMENT); + super(pointer); } static createForInStatement(left?: AstNode, right?: Expression, body?: Statement): ForInStatement { - return new ForInStatement(global.generatedEs2panda._CreateForInStatement(global.context, passNode(left), passNode(right), passNode(body))) + return new ForInStatement( + global.generatedEs2panda._CreateForInStatement( + global.context, + passNode(left), + passNode(right), + passNode(body) + ) + ); } - static updateForInStatement(original?: ForInStatement, left?: AstNode, right?: Expression, body?: Statement): ForInStatement { - return new ForInStatement(global.generatedEs2panda._UpdateForInStatement(global.context, passNode(original), passNode(left), passNode(right), passNode(body))) + static updateForInStatement( + original?: ForInStatement, + left?: AstNode, + right?: Expression, + body?: Statement + ): ForInStatement { + return new ForInStatement( + global.generatedEs2panda._UpdateForInStatement( + global.context, + passNode(original), + passNode(left), + passNode(right), + passNode(body) + ) + ); } get left(): AstNode | undefined { - return unpackNode(global.generatedEs2panda._ForInStatementLeftConst(global.context, this.peer)) + return unpackNode(global.generatedEs2panda._ForInStatementLeft(global.context, this.peer)); } get right(): Expression | undefined { - return unpackNode(global.generatedEs2panda._ForInStatementRightConst(global.context, this.peer)) + return unpackNode(global.generatedEs2panda._ForInStatementRight(global.context, this.peer)); } get body(): Statement | undefined { - return unpackNode(global.generatedEs2panda._ForInStatementBodyConst(global.context, this.peer)) + return unpackNode(global.generatedEs2panda._ForInStatementBody(global.context, this.peer)); } + protected readonly brandForInStatement: undefined; } -export function isForInStatement(node: AstNode): node is ForInStatement { - return node instanceof ForInStatement +export function isForInStatement(node: object | undefined): node is ForInStatement { + return node instanceof ForInStatement; } if (!nodeByType.has(Es2pandaAstNodeType.AST_NODE_TYPE_FOR_IN_STATEMENT)) { - nodeByType.set(Es2pandaAstNodeType.AST_NODE_TYPE_FOR_IN_STATEMENT, ForInStatement) + nodeByType.set(Es2pandaAstNodeType.AST_NODE_TYPE_FOR_IN_STATEMENT, ForInStatement); } diff --git a/koala-wrapper/src/generated/peers/ForOfStatement.ts b/koala-wrapper/src/generated/peers/ForOfStatement.ts index d958eb5a2dd27cab794199d6ef4402fdc69313f9..4ff443a2668991dd4a1ca0e18f7c36da8b4afc43 100644 --- a/koala-wrapper/src/generated/peers/ForOfStatement.ts +++ b/koala-wrapper/src/generated/peers/ForOfStatement.ts @@ -16,50 +16,73 @@ import { global, passNode, - passNodeArray, - unpackNonNullableNode, unpackNode, - unpackNodeArray, assertValidPeer, AstNode, Es2pandaAstNodeType, KNativePointer, nodeByType, - ArktsObject, - unpackString -} from "../../reexport-for-generated" +} from '../../reexport-for-generated'; -import { LoopStatement } from "./LoopStatement" -import { Expression } from "./Expression" -import { Statement } from "./Statement" +import { LoopStatement } from './LoopStatement'; +import { Expression } from './Expression'; +import { Statement } from './Statement'; export class ForOfStatement extends LoopStatement { - constructor(pointer: KNativePointer) { - assertValidPeer(pointer, Es2pandaAstNodeType.AST_NODE_TYPE_FOR_OF_STATEMENT) - super(pointer) - + constructor(pointer: KNativePointer) { + assertValidPeer(pointer, Es2pandaAstNodeType.AST_NODE_TYPE_FOR_OF_STATEMENT); + super(pointer); } - static createForOfStatement(left: AstNode | undefined, right: Expression | undefined, body: Statement | undefined, isAwait: boolean): ForOfStatement { - return new ForOfStatement(global.generatedEs2panda._CreateForOfStatement(global.context, passNode(left), passNode(right), passNode(body), isAwait)) + static createForOfStatement( + left: AstNode | undefined, + right: Expression | undefined, + body: Statement | undefined, + isAwait: boolean + ): ForOfStatement { + return new ForOfStatement( + global.generatedEs2panda._CreateForOfStatement( + global.context, + passNode(left), + passNode(right), + passNode(body), + isAwait + ) + ); } - static updateForOfStatement(original: ForOfStatement | undefined, left: AstNode | undefined, right: Expression | undefined, body: Statement | undefined, isAwait: boolean): ForOfStatement { - return new ForOfStatement(global.generatedEs2panda._UpdateForOfStatement(global.context, passNode(original), passNode(left), passNode(right), passNode(body), isAwait)) + static updateForOfStatement( + original: ForOfStatement | undefined, + left: AstNode | undefined, + right: Expression | undefined, + body: Statement | undefined, + isAwait: boolean + ): ForOfStatement { + return new ForOfStatement( + global.generatedEs2panda._UpdateForOfStatement( + global.context, + passNode(original), + passNode(left), + passNode(right), + passNode(body), + isAwait + ) + ); } get left(): AstNode | undefined { - return unpackNode(global.generatedEs2panda._ForOfStatementLeftConst(global.context, this.peer)) + return unpackNode(global.generatedEs2panda._ForOfStatementLeft(global.context, this.peer)); } get right(): Expression | undefined { - return unpackNode(global.generatedEs2panda._ForOfStatementRightConst(global.context, this.peer)) + return unpackNode(global.generatedEs2panda._ForOfStatementRight(global.context, this.peer)); } get body(): Statement | undefined { - return unpackNode(global.generatedEs2panda._ForOfStatementBodyConst(global.context, this.peer)) + return unpackNode(global.generatedEs2panda._ForOfStatementBody(global.context, this.peer)); } get isAwait(): boolean { - return global.generatedEs2panda._ForOfStatementIsAwaitConst(global.context, this.peer) + return global.generatedEs2panda._ForOfStatementIsAwaitConst(global.context, this.peer); } + protected readonly brandForOfStatement: undefined; } -export function isForOfStatement(node: AstNode): node is ForOfStatement { - return node instanceof ForOfStatement +export function isForOfStatement(node: object | undefined): node is ForOfStatement { + return node instanceof ForOfStatement; } if (!nodeByType.has(Es2pandaAstNodeType.AST_NODE_TYPE_FOR_OF_STATEMENT)) { - nodeByType.set(Es2pandaAstNodeType.AST_NODE_TYPE_FOR_OF_STATEMENT, ForOfStatement) + nodeByType.set(Es2pandaAstNodeType.AST_NODE_TYPE_FOR_OF_STATEMENT, ForOfStatement); } diff --git a/koala-wrapper/src/generated/peers/ForUpdateStatement.ts b/koala-wrapper/src/generated/peers/ForUpdateStatement.ts index cb7985248cb7769cf657b85d0b5cc2bbdb201619..ae39482c3d54921122b830f61ef6cab34e120896 100644 --- a/koala-wrapper/src/generated/peers/ForUpdateStatement.ts +++ b/koala-wrapper/src/generated/peers/ForUpdateStatement.ts @@ -16,47 +16,77 @@ import { global, passNode, - passNodeArray, - unpackNonNullableNode, unpackNode, - unpackNodeArray, assertValidPeer, AstNode, - Es2pandaAstNodeType, KNativePointer, nodeByType, - ArktsObject, - unpackString -} from "../../reexport-for-generated" + Es2pandaAstNodeType, +} from '../../reexport-for-generated'; +import { Expression } from './Expression'; +import { LoopStatement } from './LoopStatement'; +import { Statement } from './Statement'; -import { LoopStatement } from "./LoopStatement" -import { Expression } from "./Expression" -import { Statement } from "./Statement" export class ForUpdateStatement extends LoopStatement { - constructor(pointer: KNativePointer) { - assertValidPeer(pointer, Es2pandaAstNodeType.AST_NODE_TYPE_FOR_UPDATE_STATEMENT) - super(pointer) - + constructor(pointer: KNativePointer) { + assertValidPeer(pointer, Es2pandaAstNodeType.AST_NODE_TYPE_FOR_UPDATE_STATEMENT); + super(pointer); } - static createForUpdateStatement(init?: AstNode, test?: Expression, update?: Expression, body?: Statement): ForUpdateStatement { - return new ForUpdateStatement(global.generatedEs2panda._CreateForUpdateStatement(global.context, passNode(init), passNode(test), passNode(update), passNode(body))) + static createForUpdateStatement( + init?: AstNode, + test?: Expression, + update?: Expression, + body?: Statement + ): ForUpdateStatement { + return new ForUpdateStatement( + global.generatedEs2panda._CreateForUpdateStatement( + global.context, + passNode(init), + passNode(test), + passNode(update), + passNode(body) + ) + ); + } + + static updateForUpdateStatement( + original: ForUpdateStatement, + init?: AstNode, + test?: Expression, + update?: Expression, + body?: Statement + ): ForUpdateStatement { + return new ForUpdateStatement( + global.generatedEs2panda._UpdateForUpdateStatement( + global.context, + passNode(original), + passNode(init), + passNode(test), + passNode(update), + passNode(body) + ) + ); } + get init(): AstNode | undefined { - return unpackNode(global.generatedEs2panda._ForUpdateStatementInitConst(global.context, this.peer)) + return unpackNode(global.generatedEs2panda._ForUpdateStatementInit(global.context, this.peer)); } get test(): Expression | undefined { - return unpackNode(global.generatedEs2panda._ForUpdateStatementTestConst(global.context, this.peer)) + return unpackNode(global.generatedEs2panda._ForUpdateStatementTest(global.context, this.peer)); } get update(): Expression | undefined { - return unpackNode(global.generatedEs2panda._ForUpdateStatementUpdateConst(global.context, this.peer)) + return unpackNode(global.generatedEs2panda._ForUpdateStatementUpdateConst(global.context, this.peer)); } get body(): Statement | undefined { - return unpackNode(global.generatedEs2panda._ForUpdateStatementBodyConst(global.context, this.peer)) + return unpackNode(global.generatedEs2panda._ForUpdateStatementBody(global.context, this.peer)); } + protected readonly brandForUpdateStatement: undefined; } -export function isForUpdateStatement(node: AstNode): node is ForUpdateStatement { - return node instanceof ForUpdateStatement + +export function isForUpdateStatement(node: object | undefined): node is ForUpdateStatement { + return node instanceof ForUpdateStatement; } + if (!nodeByType.has(Es2pandaAstNodeType.AST_NODE_TYPE_FOR_UPDATE_STATEMENT)) { - nodeByType.set(Es2pandaAstNodeType.AST_NODE_TYPE_FOR_UPDATE_STATEMENT, ForUpdateStatement) + nodeByType.set(Es2pandaAstNodeType.AST_NODE_TYPE_FOR_UPDATE_STATEMENT, ForUpdateStatement); }