diff --git a/arkui-plugins/test/demo/mock/decorators/custom-dialog/declare-custom-dialog.ets b/arkui-plugins/test/demo/mock/decorators/custom-dialog/declare-custom-dialog.ets new file mode 100644 index 0000000000000000000000000000000000000000..72cc017a539e4492813d6a860ad6ad8ee381a1d9 --- /dev/null +++ b/arkui-plugins/test/demo/mock/decorators/custom-dialog/declare-custom-dialog.ets @@ -0,0 +1,44 @@ +/* + * 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 { State } from "@ohos.arkui.stateManagement" +import { CustomDialog, CustomDialogController, ComponentV2, Component, Builder } from "@ohos.arkui.component" + +@CustomDialog +export declare struct CustomDialogExample { + aaController?: CustomDialogController; + @State text: string; + hh: string + + @Builder build(): void; +} + +@Component +struct CustomDialogUserV1 { + dialogController: CustomDialogController | null = new CustomDialogController({ + builder: CustomDialogExample(), + }) + + build() {} +} + +@ComponentV2 +struct CustomDialogUserV2 { + dialogController: CustomDialogController | null = new CustomDialogController({ + builder: CustomDialogExample(), + }) + + build() {} +} \ No newline at end of file diff --git a/arkui-plugins/test/demo/mock/decorators/once/once-only.ets b/arkui-plugins/test/demo/mock/decorators/once/once-only.ets new file mode 100644 index 0000000000000000000000000000000000000000..ba4f2892a3073c55d0f35594b46651fa82a5c7e9 --- /dev/null +++ b/arkui-plugins/test/demo/mock/decorators/once/once-only.ets @@ -0,0 +1,25 @@ +/* + * 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 { ComponentV2 } from "@ohos.arkui.component" +import { Once } from "@ohos.arkui.stateManagement" + +@ComponentV2 +struct Child { + @Once onceParamNum: number = 0; + @Once onceVar4: Set = new Set(new Array('aa', 'bb')); + + build() {} +} \ No newline at end of file diff --git a/arkui-plugins/test/ut/ui-plugins/decorators/custom-dialog/base-custom-dialog.test.ts b/arkui-plugins/test/ut/ui-plugins/decorators/custom-dialog/base-custom-dialog.test.ts index 7547b4bfe17a101048e2c8d8eac4c05f11dd47a2..df184fdb7827bc067c66446406c36403a04538d6 100644 --- a/arkui-plugins/test/ut/ui-plugins/decorators/custom-dialog/base-custom-dialog.test.ts +++ b/arkui-plugins/test/ut/ui-plugins/decorators/custom-dialog/base-custom-dialog.test.ts @@ -131,10 +131,6 @@ function main() {} this.__backing_hh!.set(value); } - public __setDialogController__(controller: CustomDialogController): void { - this.__backing_aaController = controller; - } - @memo() public build() { Column(undefined, undefined, @memo() (() => { Text(@memo() ((instance: TextAttribute): void => { @@ -153,6 +149,10 @@ function main() {} } private constructor() {} + + public __setDialogController__(controller: CustomDialogController): void { + this.__backing_aaController = controller; + } } diff --git a/arkui-plugins/test/ut/ui-plugins/decorators/custom-dialog/controller-in-build.test.ts b/arkui-plugins/test/ut/ui-plugins/decorators/custom-dialog/controller-in-build.test.ts index 9ad581f09cae75e99d9b61ba4101a9b9f5eae658..f0f66427db6d876b6cf307d3ac9cd506964a854f 100644 --- a/arkui-plugins/test/ut/ui-plugins/decorators/custom-dialog/controller-in-build.test.ts +++ b/arkui-plugins/test/ut/ui-plugins/decorators/custom-dialog/controller-in-build.test.ts @@ -107,10 +107,6 @@ function main() {} this.__backing_hh!.set(value); } - public __setDialogController__(controller: CustomDialogController): void { - this.__backing_aaController = controller; - } - @memo() public build() { Column(undefined, undefined, @memo() (() => { Text(undefined, "CustomDialog One", undefined, undefined); @@ -119,6 +115,10 @@ function main() {} private constructor() {} + public __setDialogController__(controller: CustomDialogController): void { + this.__backing_aaController = controller; + } + } @Component() final struct CustomDialogUser extends CustomComponent { diff --git a/arkui-plugins/test/ut/ui-plugins/decorators/custom-dialog/controller-in-method.test.ts b/arkui-plugins/test/ut/ui-plugins/decorators/custom-dialog/controller-in-method.test.ts index ea1b773addc3dc8845ccd7c6e7a63be604ac2650..25ec60f3e776c24a11887c52d902adbf86df0203 100644 --- a/arkui-plugins/test/ut/ui-plugins/decorators/custom-dialog/controller-in-method.test.ts +++ b/arkui-plugins/test/ut/ui-plugins/decorators/custom-dialog/controller-in-method.test.ts @@ -66,15 +66,14 @@ function main() {} public set aaController(value: (CustomDialogController | undefined)) { this.__backing_aaController = value; } - - public __setDialogController__(controller: CustomDialogController): void { - this.__backing_aaController = controller; - } - + @memo() public build() {} private constructor() {} + public __setDialogController__(controller: CustomDialogController): void { + this.__backing_aaController = controller; + } } @Component() final struct CustomDialogUser extends CustomComponent { diff --git a/arkui-plugins/test/ut/ui-plugins/decorators/custom-dialog/declare-custom-dialog.test.ts b/arkui-plugins/test/ut/ui-plugins/decorators/custom-dialog/declare-custom-dialog.test.ts new file mode 100644 index 0000000000000000000000000000000000000000..4066e0c2edb2229ce168c4640de46017ccd3a442 --- /dev/null +++ b/arkui-plugins/test/ut/ui-plugins/decorators/custom-dialog/declare-custom-dialog.test.ts @@ -0,0 +1,180 @@ +/* + * 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 * as path from 'path'; +import { PluginTester } from '../../../../utils/plugin-tester'; +import { mockBuildConfig } from '../../../../utils/artkts-config'; +import { getRootPath, MOCK_ENTRY_DIR_PATH } from '../../../../utils/path-config'; +import { parseDumpSrc } from '../../../../utils/parse-string'; +import { memoNoRecheck, recheck, uiNoRecheck } from '../../../../utils/plugins'; +import { BuildConfig, PluginTestContext } from '../../../../utils/shared-types'; +import { uiTransform } from '../../../../../ui-plugins'; +import { Plugins } from '../../../../../common/plugin-context'; + +const FUNCTION_DIR_PATH: string = 'decorators/custom-dialog'; + +const buildConfig: BuildConfig = mockBuildConfig(); +buildConfig.compileFiles = [ + path.resolve(getRootPath(), MOCK_ENTRY_DIR_PATH, FUNCTION_DIR_PATH, 'declare-custom-dialog.ets'), +]; + +const pluginTester = new PluginTester('test declared struct @CustomDialog transformation', buildConfig); + +const parsedTransform: Plugins = { + name: 'parsedTrans', + parsed: uiTransform().parsed, +}; + +const expectedCheckedScript: string = ` +import { IStateDecoratedVariable as IStateDecoratedVariable } from "arkui.stateManagement.decorator"; +import { memo as memo } from "arkui.stateManagement.runtime"; +import { BaseCustomDialog as BaseCustomDialog } from "arkui.component.customComponent"; +import { CustomComponentV2 as CustomComponentV2 } from "arkui.component.customComponent"; +import { CustomComponent as CustomComponent } from "arkui.component.customComponent"; +import { State as State } from "@ohos.arkui.stateManagement"; +import { CustomDialog as CustomDialog, CustomDialogController as CustomDialogController, ComponentV2 as ComponentV2, Component as Component, Builder as Builder } from "@ohos.arkui.component"; + +function main() {} + +@CustomDialog() export declare final struct CustomDialogExample extends BaseCustomDialog { + public aaController?: (CustomDialogController | undefined); + + @State() public text: string; + + public hh: string; + + @Builder() @memo() public build(): void + + public constructor() {} + + public static _buildCompatibleNode(options: __Options_CustomDialogExample): void + +} + +@Component() final struct CustomDialogUserV1 extends CustomComponent { + public __initializeStruct(initializers: (__Options_CustomDialogUserV1 | undefined), @memo() content: ((()=> void) | undefined)): void { + this.__backing_dialogController = ((({let gensym___51459619 = initializers; + (((gensym___51459619) == (null)) ? undefined : gensym___51459619.dialogController)})) ?? (({let gensym___203542966: Any; + gensym___203542966 = new CustomDialogController({ + builder: @memo() (() => { + CustomDialogExample._instantiateImpl(undefined, (() => { + const instance = new CustomDialogExample(); + instance.__setDialogController__((gensym___203542966 as CustomDialogController)); + return instance; + }), undefined, undefined); + }), + baseComponent: this, + }) + (gensym___203542966 as CustomDialogController)}))); + } + + public __updateStruct(initializers: (__Options_CustomDialogUserV1 | undefined)): void {} + + private __backing_dialogController?: (CustomDialogController | null); + + public get dialogController(): (CustomDialogController | null) { + return (this.__backing_dialogController as (CustomDialogController | null)); + } + + public set dialogController(value: (CustomDialogController | null)) { + this.__backing_dialogController = value; + } + + @memo() public build() {} + + private constructor() {} + +} + +@ComponentV2() final struct CustomDialogUserV2 extends CustomComponentV2 { + public __initializeStruct(initializers: (__Options_CustomDialogUserV2 | undefined), @memo() content: ((()=> void) | undefined)): void { + this.__backing_dialogController = ((({let gensym___176924847 = initializers; + (((gensym___176924847) == (null)) ? undefined : gensym___176924847.dialogController)})) ?? (({let gensym___46528967: Any; + gensym___46528967 = new CustomDialogController({ + builder: @memo() (() => { + CustomDialogExample._instantiateImpl(undefined, (() => { + const instance = new CustomDialogExample(); + instance.__setDialogController__((gensym___46528967 as CustomDialogController)); + return instance; + }), undefined, undefined); + }), + baseComponent: this, + }) + (gensym___46528967 as CustomDialogController)}))); + } + + public __updateStruct(initializers: (__Options_CustomDialogUserV2 | undefined)): void {} + + private __backing_dialogController?: (CustomDialogController | null); + + public get dialogController(): (CustomDialogController | null) { + return (this.__backing_dialogController as (CustomDialogController | null)); + } + + public set dialogController(value: (CustomDialogController | null)) { + this.__backing_dialogController = value; + } + + @memo() public build() {} + + private constructor() {} + +} + +@CustomDialog() export declare interface __Options_CustomDialogExample { + set aaController(aaController: ((CustomDialogController | undefined) | undefined)) + + get aaController(): ((CustomDialogController | undefined) | undefined) + set text(text: (string | undefined)) + + get text(): (string | undefined) + set __backing_text(__backing_text: (IStateDecoratedVariable | undefined)) + + get __backing_text(): (IStateDecoratedVariable | undefined) + set hh(hh: (string | undefined)) + + get hh(): (string | undefined) + +} + +@Component() export interface __Options_CustomDialogUserV1 { + set dialogController(dialogController: ((CustomDialogController | null) | undefined)) + + get dialogController(): ((CustomDialogController | null) | undefined) + +} + +@ComponentV2() export interface __Options_CustomDialogUserV2 { + set dialogController(dialogController: ((CustomDialogController | null) | undefined)) + + get dialogController(): ((CustomDialogController | null) | undefined) + +} +`; + +function testCheckedTransformer(this: PluginTestContext): void { + expect(parseDumpSrc(this.scriptSnapshot ?? '')).toBe(parseDumpSrc(expectedCheckedScript)); +} + +pluginTester.run( + 'test declared struct @CustomDialog transformation', + [parsedTransform, uiNoRecheck, memoNoRecheck, recheck], + { + 'checked:ui-no-recheck': [testCheckedTransformer], + }, + { + stopAfter: 'checked', + } +); diff --git a/arkui-plugins/test/ut/ui-plugins/decorators/custom-dialog/extends-dialog-controller.test.ts b/arkui-plugins/test/ut/ui-plugins/decorators/custom-dialog/extends-dialog-controller.test.ts index 1785866b1612271345d6d1533d4f195af72fc34f..c58b6de221edc58cc41e647e2f27b196294819b5 100644 --- a/arkui-plugins/test/ut/ui-plugins/decorators/custom-dialog/extends-dialog-controller.test.ts +++ b/arkui-plugins/test/ut/ui-plugins/decorators/custom-dialog/extends-dialog-controller.test.ts @@ -73,16 +73,16 @@ function main() {} this.__backing_aaController = value; } - public __setDialogController__(controller: CustomDialogController): void { - this.__backing_aaController = controller; - } - @memo() public build() { Column(undefined, undefined, @memo() (() => {})); } private constructor() {} + public __setDialogController__(controller: CustomDialogController): void { + this.__backing_aaController = controller; + } + } class DialogControllerV2 extends CustomDialogController { diff --git a/arkui-plugins/test/ut/ui-plugins/decorators/once/once-only.test.ts b/arkui-plugins/test/ut/ui-plugins/decorators/once/once-only.test.ts new file mode 100644 index 0000000000000000000000000000000000000000..4212ed0b9e0c982989664be2f2b3652cc9ca8653 --- /dev/null +++ b/arkui-plugins/test/ut/ui-plugins/decorators/once/once-only.test.ts @@ -0,0 +1,116 @@ +/* + * 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 * as path from 'path'; +import { PluginTester } from '../../../../utils/plugin-tester'; +import { mockBuildConfig } from '../../../../utils/artkts-config'; +import { getRootPath, MOCK_ENTRY_DIR_PATH } from '../../../../utils/path-config'; +import { parseDumpSrc } from '../../../../utils/parse-string'; +import { recheck, uiNoRecheck } from '../../../../utils/plugins'; +import { BuildConfig, PluginTestContext } from '../../../../utils/shared-types'; +import { uiTransform } from '../../../../../ui-plugins'; +import { Plugins } from '../../../../../common/plugin-context'; + +const OBSERVED_DIR_PATH: string = 'decorators/once'; + +const buildConfig: BuildConfig = mockBuildConfig(); +buildConfig.compileFiles = [ + path.resolve(getRootPath(), MOCK_ENTRY_DIR_PATH, OBSERVED_DIR_PATH, 'once-only.ets'), +]; + +const parsedTransform: Plugins = { + name: 'parsedTrans', + parsed: uiTransform().parsed, +} + +const pluginTester = new PluginTester('test only @Once decorated variables transformation', buildConfig); + +const expectedScript: string = ` +import { memo as memo } from "arkui.stateManagement.runtime"; +import { STATE_MGMT_FACTORY as STATE_MGMT_FACTORY } from "arkui.stateManagement.decorator"; +import { IParamOnceDecoratedVariable as IParamOnceDecoratedVariable } from "arkui.stateManagement.decorator"; +import { CustomComponentV2 as CustomComponentV2 } from "arkui.component.customComponent"; +import { ComponentV2 as ComponentV2 } from "@ohos.arkui.component"; +import { Once as Once } from "@ohos.arkui.stateManagement"; + +function main() {} + +@ComponentV2() final struct Child extends CustomComponentV2 { + public __initializeStruct(initializers: (__Options_Child | undefined), @memo() content: ((()=> void) | undefined)): void { + this.__backing_onceParamNum = STATE_MGMT_FACTORY.makeParamOnce(this, "onceParamNum", ((({let gensym___118919021 = initializers; + (((gensym___118919021) == (null)) ? undefined : gensym___118919021.onceParamNum)})) ?? (0))); + this.__backing_onceVar4 = STATE_MGMT_FACTORY.makeParamOnce>(this, "onceVar4", ((({let gensym___71001521 = initializers; + (((gensym___71001521) == (null)) ? undefined : gensym___71001521.onceVar4)})) ?? (new Set(new Array("aa", "bb"))))); + } + + public __updateStruct(initializers: (__Options_Child | undefined)): void {} + + private __backing_onceParamNum?: IParamOnceDecoratedVariable; + + public get onceParamNum(): number { + return this.__backing_onceParamNum!.get(); + } + + public set onceParamNum(value: number) { + this.__backing_onceParamNum!.set(value); + } + + private __backing_onceVar4?: IParamOnceDecoratedVariable>; + + public get onceVar4(): Set { + return this.__backing_onceVar4!.get(); + } + + public set onceVar4(value: Set) { + this.__backing_onceVar4!.set(value); + } + + @memo() public build() {} + + private constructor() {} + +} + +@ComponentV2() export interface __Options_Child { + set onceParamNum(onceParamNum: (number | undefined)) + + get onceParamNum(): (number | undefined) + set __backing_onceParamNum(__backing_onceParamNum: (IParamOnceDecoratedVariable | undefined)) + + get __backing_onceParamNum(): (IParamOnceDecoratedVariable | undefined) + set onceVar4(onceVar4: (Set | undefined)) + + get onceVar4(): (Set | undefined) + set __backing_onceVar4(__backing_onceVar4: (IParamOnceDecoratedVariable> | undefined)) + + get __backing_onceVar4(): (IParamOnceDecoratedVariable> | undefined) + +} +`; + +function testParsedAndCheckedTransformer(this: PluginTestContext): void { + expect(parseDumpSrc(this.scriptSnapshot ?? '')).toBe(parseDumpSrc(expectedScript)); +} + +pluginTester.run( + 'test only @Once decorated variables transformation', + [parsedTransform, uiNoRecheck, recheck], + { + 'checked:ui-no-recheck': [testParsedAndCheckedTransformer], + }, + { + stopAfter: 'checked', + } +); diff --git a/arkui-plugins/test/ut/ui-plugins/decorators/once/once-with-require.test.ts b/arkui-plugins/test/ut/ui-plugins/decorators/once/once-with-require.test.ts index 98dd8f1286ec7e1b17eb676f87c0e8760139ebd5..dade76adca247401e09905d05e3053683924150c 100644 --- a/arkui-plugins/test/ut/ui-plugins/decorators/once/once-with-require.test.ts +++ b/arkui-plugins/test/ut/ui-plugins/decorators/once/once-with-require.test.ts @@ -92,9 +92,9 @@ import { Param as Param, Once as Once, ObservedV2 as ObservedV2, Trace as Trace, @ComponentV2() export interface __Options_Child { onceParamNum?: number; - @Once() @Param() __backing_onceParamNum?: number; + @Param() @Once() __backing_onceParamNum?: number; onceParamInfo?: Info; - @Once() @Param() __backing_onceParamInfo?: Info; + @Param() @Once() @Require() __backing_onceParamInfo?: Info; } @@ -283,9 +283,9 @@ function main() {} set onceParamInfo(onceParamInfo: (Info | undefined)) get onceParamInfo(): (Info | undefined) - @Param() set __backing_onceParamInfo(__backing_onceParamInfo: (IParamOnceDecoratedVariable | undefined)) + @Param() @Require() set __backing_onceParamInfo(__backing_onceParamInfo: (IParamOnceDecoratedVariable | undefined)) - @Param() get __backing_onceParamInfo(): (IParamOnceDecoratedVariable | undefined) + @Param() @Require() get __backing_onceParamInfo(): (IParamOnceDecoratedVariable | undefined) } diff --git a/arkui-plugins/test/ut/ui-plugins/decorators/param/param-with-require.test.ts b/arkui-plugins/test/ut/ui-plugins/decorators/param/param-with-require.test.ts index 5833664982d56b03e2717f0e0a971e72f962c9bc..488decbf21500a31fb40407961d24a77d6b6521f 100644 --- a/arkui-plugins/test/ut/ui-plugins/decorators/param/param-with-require.test.ts +++ b/arkui-plugins/test/ut/ui-plugins/decorators/param/param-with-require.test.ts @@ -131,13 +131,13 @@ class Info { @ComponentV2() export interface __Options_MiddleComponent { info?: Info; - @Param() __backing_info?: Info; + @Require() @Param() __backing_info?: Info; } @ComponentV2() export interface __Options_SubComponent { region?: Region; - @Param() __backing_region?: Region; + @Require() @Param() __backing_region?: Region; } `; @@ -309,9 +309,9 @@ class Info { set info(info: (Info | undefined)) get info(): (Info | undefined) - set __backing_info(__backing_info: (IParamDecoratedVariable | undefined)) + @Require() set __backing_info(__backing_info: (IParamDecoratedVariable | undefined)) - get __backing_info(): (IParamDecoratedVariable | undefined) + @Require() get __backing_info(): (IParamDecoratedVariable | undefined) } @@ -319,9 +319,9 @@ class Info { set region(region: (Region | undefined)) get region(): (Region | undefined) - set __backing_region(__backing_region: (IParamDecoratedVariable | undefined)) + @Require() set __backing_region(__backing_region: (IParamDecoratedVariable | undefined)) - get __backing_region(): (IParamDecoratedVariable | undefined) + @Require() get __backing_region(): (IParamDecoratedVariable | undefined) } `; diff --git a/arkui-plugins/test/ut/ui-plugins/decorators/require/basic-require.test.ts b/arkui-plugins/test/ut/ui-plugins/decorators/require/basic-require.test.ts index 659935b0028cadb56a65258f91ae607ee1f508a7..a4b93ab3eaadedffd491d5e21e3de99c892f8a85 100644 --- a/arkui-plugins/test/ut/ui-plugins/decorators/require/basic-require.test.ts +++ b/arkui-plugins/test/ut/ui-plugins/decorators/require/basic-require.test.ts @@ -76,24 +76,24 @@ import { State as State, Require as Require, Prop as Prop, Provide as Provide, P @State() __backing_state1?: boolean; select100?: string; select0?: number; - @State() __backing_select0?: number; + @Require() @State() __backing_select0?: number; select3?: (number | null); - @State() __backing_select3?: (number | null); + @Require() @State() __backing_select3?: (number | null); select4?: undefined; - @State() __backing_select4?: undefined; + @Require() @State() __backing_select4?: undefined; select1?: string; - @Prop() __backing_select1?: string; + @Require() @Prop() __backing_select1?: string; select2?: string[]; - @Provide({alias:"15"}) __backing_select2?: string[]; + @Require() @Provide({alias:"15"}) __backing_select2?: string[]; select6?: (string[] | undefined | string); - @Provide({alias:"t"}) __backing_select6?: (string[] | undefined | string); + @Require() @Provide({alias:"t"}) __backing_select6?: (string[] | undefined | string); @BuilderParam() builder?: (()=> void); } @ComponentV2() export interface __Options_V2222 { select1?: string; - @Param() __backing_select1?: string; + @Require() @Param() __backing_select1?: string; } `; @@ -283,39 +283,39 @@ function main() {} set select0(select0: (number | undefined)) get select0(): (number | undefined) - set __backing_select0(__backing_select0: (IStateDecoratedVariable | undefined)) + @Require() set __backing_select0(__backing_select0: (IStateDecoratedVariable | undefined)) - get __backing_select0(): (IStateDecoratedVariable | undefined) + @Require() get __backing_select0(): (IStateDecoratedVariable | undefined) set select3(select3: ((number | null) | undefined)) get select3(): ((number | null) | undefined) - set __backing_select3(__backing_select3: (IStateDecoratedVariable<(number | null)> | undefined)) + @Require() set __backing_select3(__backing_select3: (IStateDecoratedVariable<(number | null)> | undefined)) - get __backing_select3(): (IStateDecoratedVariable<(number | null)> | undefined) + @Require() get __backing_select3(): (IStateDecoratedVariable<(number | null)> | undefined) set select4(select4: (undefined | undefined)) get select4(): (undefined | undefined) - set __backing_select4(__backing_select4: (IStateDecoratedVariable | undefined)) + @Require() set __backing_select4(__backing_select4: (IStateDecoratedVariable | undefined)) - get __backing_select4(): (IStateDecoratedVariable | undefined) + @Require() get __backing_select4(): (IStateDecoratedVariable | undefined) set select1(select1: (string | undefined)) get select1(): (string | undefined) - set __backing_select1(__backing_select1: (IPropDecoratedVariable | undefined)) + @Require() set __backing_select1(__backing_select1: (IPropDecoratedVariable | undefined)) - get __backing_select1(): (IPropDecoratedVariable | undefined) + @Require() get __backing_select1(): (IPropDecoratedVariable | undefined) set select2(select2: (Array | undefined)) get select2(): (Array | undefined) - set __backing_select2(__backing_select2: (IProvideDecoratedVariable> | undefined)) + @Require() set __backing_select2(__backing_select2: (IProvideDecoratedVariable> | undefined)) - get __backing_select2(): (IProvideDecoratedVariable> | undefined) + @Require() get __backing_select2(): (IProvideDecoratedVariable> | undefined) set select6(select6: ((Array | undefined | string) | undefined)) get select6(): ((Array | undefined | string) | undefined) - set __backing_select6(__backing_select6: (IProvideDecoratedVariable<(Array | undefined | string)> | undefined)) + @Require() set __backing_select6(__backing_select6: (IProvideDecoratedVariable<(Array | undefined | string)> | undefined)) - get __backing_select6(): (IProvideDecoratedVariable<(Array | undefined | string)> | undefined) + @Require() get __backing_select6(): (IProvideDecoratedVariable<(Array | undefined | string)> | undefined) set builder(builder: (@memo() (()=> void) | undefined)) get builder(): (@memo() (()=> void) | undefined) @@ -326,9 +326,9 @@ function main() {} set select1(select1: (string | undefined)) get select1(): (string | undefined) - set __backing_select1(__backing_select1: (IParamDecoratedVariable | undefined)) + @Require() set __backing_select1(__backing_select1: (IParamDecoratedVariable | undefined)) - get __backing_select1(): (IParamDecoratedVariable | undefined) + @Require() get __backing_select1(): (IParamDecoratedVariable | undefined) } `; diff --git a/arkui-plugins/test/ut/ui-plugins/decorators/watch/watch-basic.test.ts b/arkui-plugins/test/ut/ui-plugins/decorators/watch/watch-basic.test.ts index 5cda30f78d7ee3003f509342463f848a241e0643..115ed67c5292fef9ad4ae8a2da993fbfabc181fe 100644 --- a/arkui-plugins/test/ut/ui-plugins/decorators/watch/watch-basic.test.ts +++ b/arkui-plugins/test/ut/ui-plugins/decorators/watch/watch-basic.test.ts @@ -313,45 +313,45 @@ __EntryWrapper.RegisterNamedRouter("", new __EntryWrapper(), ({ set statevar(statevar: (string | undefined)) get statevar(): (string | undefined) - set __backing_statevar(__backing_statevar: (IStateDecoratedVariable | undefined)) + @Watch({value:"stateOnChange"}) set __backing_statevar(__backing_statevar: (IStateDecoratedVariable | undefined)) - get __backing_statevar(): (IStateDecoratedVariable | undefined) + @Watch({value:"stateOnChange"}) get __backing_statevar(): (IStateDecoratedVariable | undefined) set propvar(propvar: (string | undefined)) get propvar(): (string | undefined) - set __backing_propvar(__backing_propvar: (IPropDecoratedVariable | undefined)) + @Watch({value:"propOnChange"}) set __backing_propvar(__backing_propvar: (IPropDecoratedVariable | undefined)) - get __backing_propvar(): (IPropDecoratedVariable | undefined) + @Watch({value:"propOnChange"}) get __backing_propvar(): (IPropDecoratedVariable | undefined) @__Link_intrinsic() set linkvar(linkvar: (string | undefined)) @__Link_intrinsic() get linkvar(): (string | undefined) - set __backing_linkvar(__backing_linkvar: (LinkSourceType | undefined)) + @Watch({value:"linkOnChange"}) set __backing_linkvar(__backing_linkvar: (LinkSourceType | undefined)) - get __backing_linkvar(): (LinkSourceType | undefined) + @Watch({value:"linkOnChange"}) get __backing_linkvar(): (LinkSourceType | undefined) set storagelinkvar(storagelinkvar: (string | undefined)) get storagelinkvar(): (string | undefined) - set __backing_storagelinkvar(__backing_storagelinkvar: (IStorageLinkDecoratedVariable | undefined)) + @Watch({value:"storageLinkOnChange"}) set __backing_storagelinkvar(__backing_storagelinkvar: (IStorageLinkDecoratedVariable | undefined)) - get __backing_storagelinkvar(): (IStorageLinkDecoratedVariable | undefined) + @Watch({value:"storageLinkOnChange"}) get __backing_storagelinkvar(): (IStorageLinkDecoratedVariable | undefined) set storagepropvar(storagepropvar: (string | undefined)) get storagepropvar(): (string | undefined) - set __backing_storagepropvar(__backing_storagepropvar: (IStoragePropRefDecoratedVariable | undefined)) + @Watch({value:"storagePropOnChange"}) set __backing_storagepropvar(__backing_storagepropvar: (IStoragePropRefDecoratedVariable | undefined)) - get __backing_storagepropvar(): (IStoragePropRefDecoratedVariable | undefined) + @Watch({value:"storagePropOnChange"}) get __backing_storagepropvar(): (IStoragePropRefDecoratedVariable | undefined) set objectlinkvar(objectlinkvar: (A | undefined)) get objectlinkvar(): (A | undefined) - set __backing_objectlinkvar(__backing_objectlinkvar: (IObjectLinkDecoratedVariable | undefined)) + @Watch({value:"objectLinkOnChange"}) set __backing_objectlinkvar(__backing_objectlinkvar: (IObjectLinkDecoratedVariable | undefined)) - get __backing_objectlinkvar(): (IObjectLinkDecoratedVariable | undefined) + @Watch({value:"objectLinkOnChange"}) get __backing_objectlinkvar(): (IObjectLinkDecoratedVariable | undefined) set providevar(providevar: (string | undefined)) get providevar(): (string | undefined) - set __backing_providevar(__backing_providevar: (IProvideDecoratedVariable | undefined)) + @Watch({value:"ProvideOnChange"}) set __backing_providevar(__backing_providevar: (IProvideDecoratedVariable | undefined)) - get __backing_providevar(): (IProvideDecoratedVariable | undefined) + @Watch({value:"ProvideOnChange"}) get __backing_providevar(): (IProvideDecoratedVariable | undefined) } @@ -359,9 +359,9 @@ __EntryWrapper.RegisterNamedRouter("", new __EntryWrapper(), ({ set providevar(providevar: (string | undefined)) get providevar(): (string | undefined) - set __backing_providevar(__backing_providevar: (IConsumeDecoratedVariable | undefined)) + @Watch({value:"ConsumeOnChange"}) set __backing_providevar(__backing_providevar: (IConsumeDecoratedVariable | undefined)) - get __backing_providevar(): (IConsumeDecoratedVariable | undefined) + @Watch({value:"ConsumeOnChange"}) get __backing_providevar(): (IConsumeDecoratedVariable | undefined) } diff --git a/arkui-plugins/ui-plugins/component-transformer.ts b/arkui-plugins/ui-plugins/component-transformer.ts index a4c436972cfdb33ca6422c8112069ea3f6e933a7..37db0024f5b3ea6ce69facc144e4fa580015e668 100644 --- a/arkui-plugins/ui-plugins/component-transformer.ts +++ b/arkui-plugins/ui-plugins/component-transformer.ts @@ -462,7 +462,6 @@ export class ComponentTransformer extends AbstractVisitor { originMember.setAnnotations([buildParamInfo.annotation.clone()]); return [originMember]; } - const OnceInfo = infos.find((it) => it.name === DecoratorNames.ONCE); const targetInfo = infos.find((it) => DECORATOR_TYPE_MAP.has(it.name)); if (!!targetInfo) { const newName: string = backingField(originalName); @@ -472,10 +471,7 @@ export class ComponentTransformer extends AbstractVisitor { undefined, arkts.Es2pandaModifierFlags.MODIFIER_FLAGS_PUBLIC ); - const annos = !!OnceInfo - ? [OnceInfo.annotation.clone(), targetInfo.annotation.clone()] - : [targetInfo.annotation.clone()]; - newMember.setAnnotations(annos); + newMember.setAnnotations(member.annotations); if (isDecoratorAnnotation(targetInfo.annotation, DecoratorNames.LINK, true)) { this.shouldAddLinkIntrinsic = true; originMember.setAnnotations([annotation(DecoratorIntrinsicNames.LINK)]); diff --git a/arkui-plugins/ui-plugins/struct-translators/factory.ts b/arkui-plugins/ui-plugins/struct-translators/factory.ts index d4fd4e5d1d88d7b00caed14fdf65a0e4da916e03..7b0fdfb8f0b36a4a202ab37443212b369a77de1c 100644 --- a/arkui-plugins/ui-plugins/struct-translators/factory.ts +++ b/arkui-plugins/ui-plugins/struct-translators/factory.ts @@ -502,25 +502,15 @@ export class factory { if (!className) { throw new Error('Non Empty className expected for Component'); } - + const body: readonly arkts.AstNode[] = definition.body; const propertyTranslators: (PropertyTranslator | MethodTranslator)[] = filterDefined( - definition.body.map((it) => classifyStructMembers(it, scope)) + body.map((it) => classifyStructMembers(it, scope)) ); const translatedMembers: arkts.AstNode[] = this.tranformPropertyMembers( propertyTranslators, classOptionsName ?? getCustomComponentOptionsName(className), scope ); - if (hasDecorator(node.definition, DecoratorNames.CUSTOM_DIALOG)) { - const dialogControllerProperty: arkts.ClassProperty | undefined = definition.body.find( - (item: arkts.AstNode) => arkts.isClassProperty(item) && getCustomDialogController(item).length > 0 - ) as arkts.ClassProperty | undefined; - if (!!dialogControllerProperty) { - translatedMembers.push( - this.createCustomDialogMethod(getCustomDialogController(dialogControllerProperty)) - ); - } - } const updateMembers: arkts.AstNode[] = definition.body .filter( (member) => @@ -533,9 +523,28 @@ export class factory { ...translatedMembers, ...updateMembers, ]); + if (!!scope.annotations.customdialog || scope.name === CustomComponentNames.BASE_CUSTOM_DIALOG_NAME) { + updateClassDef.addProperties(factory.addControllerSetMethod(scope.isDecl, body)); + } return arkts.factory.updateClassDeclaration(node, updateClassDef); } + /** + * add `__setDialogController__` method in `@CustomDialog` component. + */ + static addControllerSetMethod(isDecl: boolean, body: readonly arkts.AstNode[]): arkts.MethodDefinition[] { + if (isDecl) { + return [this.createCustomDialogMethod(isDecl)]; + } + const dialogControllerProperty: arkts.ClassProperty | undefined = body.find( + (item: arkts.AstNode) => arkts.isClassProperty(item) && getCustomDialogController(item).length > 0 + ) as arkts.ClassProperty | undefined; + if (!!dialogControllerProperty) { + return [this.createCustomDialogMethod(isDecl, getCustomDialogController(dialogControllerProperty))]; + } + return []; + } + /** * transform `$r` and `$rawfile` function calls. */ @@ -612,7 +621,11 @@ export class factory { } } - static createCustomDialogMethod(controller: string): arkts.MethodDefinition { + static createCustomDialogMethod(isDecl: boolean, controller?: string): arkts.MethodDefinition { + let block: arkts.BlockStatement | undefined = undefined; + if (!!controller) { + block = arkts.factory.createBlock(this.createSetControllerElements(controller)); + } const param: arkts.ETSParameterExpression = arkts.factory.createParameterDeclaration( arkts.factory.createIdentifier( CustomDialogNames.CONTROLLER, @@ -620,38 +633,42 @@ export class factory { ), undefined ); - const block = arkts.factory.createBlock( - controller.length !== 0 - ? [ - arkts.factory.createExpressionStatement( - arkts.factory.createAssignmentExpression( - generateThisBacking(backingField(controller)), - arkts.Es2pandaTokenType.TOKEN_TYPE_PUNCTUATOR_SUBSTITUTION, - arkts.factory.createIdentifier(CustomDialogNames.CONTROLLER) - ) - ), - ] - : [] - ); - const script = arkts.factory.createScriptFunction( - block, - arkts.FunctionSignature.createFunctionSignature( - undefined, - [param], - arkts.factory.createPrimitiveType(arkts.Es2pandaPrimitiveType.PRIMITIVE_TYPE_VOID), - false - ), - arkts.Es2pandaScriptFunctionFlags.SCRIPT_FUNCTION_FLAGS_METHOD, - arkts.Es2pandaModifierFlags.MODIFIER_FLAGS_PUBLIC - ); + const modifiers = isDecl + ? arkts.Es2pandaModifierFlags.MODIFIER_FLAGS_PUBLIC | arkts.Es2pandaModifierFlags.MODIFIER_FLAGS_DECLARE + : arkts.Es2pandaModifierFlags.MODIFIER_FLAGS_PUBLIC; - return arkts.factory.createMethodDefinition( - arkts.Es2pandaMethodDefinitionKind.METHOD_DEFINITION_KIND_METHOD, - arkts.factory.createIdentifier(CustomDialogNames.SET_DIALOG_CONTROLLER_METHOD), - script, - arkts.Es2pandaModifierFlags.MODIFIER_FLAGS_PUBLIC, - false - ); + return UIFactory.createMethodDefinition({ + key: arkts.factory.createIdentifier(CustomDialogNames.SET_DIALOG_CONTROLLER_METHOD), + kind: arkts.Es2pandaMethodDefinitionKind.METHOD_DEFINITION_KIND_METHOD, + function: { + body: block, + params: [param], + returnTypeAnnotation: arkts.factory.createPrimitiveType( + arkts.Es2pandaPrimitiveType.PRIMITIVE_TYPE_VOID + ), + hasReceiver: false, + flags: arkts.Es2pandaScriptFunctionFlags.SCRIPT_FUNCTION_FLAGS_METHOD, + modifiers: modifiers, + }, + modifiers: modifiers, + }); + } + + /* + * create assignment expression `this.__backing = controller`. + */ + static createSetControllerElements(controller: string): arkts.AstNode[] { + return controller.length !== 0 + ? [ + arkts.factory.createExpressionStatement( + arkts.factory.createAssignmentExpression( + generateThisBacking(backingField(controller)), + arkts.Es2pandaTokenType.TOKEN_TYPE_PUNCTUATOR_SUBSTITUTION, + arkts.factory.createIdentifier(CustomDialogNames.CONTROLLER) + ) + ), + ] + : []; } /* diff --git a/arkui-plugins/ui-plugins/utils.ts b/arkui-plugins/ui-plugins/utils.ts index 5bcfa691802aa287fc5fb41092f0ed976b0323d3..5c7f7200455176e88f7cf5fb628f63f532c85140 100644 --- a/arkui-plugins/ui-plugins/utils.ts +++ b/arkui-plugins/ui-plugins/utils.ts @@ -240,7 +240,7 @@ export function collectCustomComponentScopeInfo( ...(isReusable && !annotations?.reusable && { reusable: anno }), ...(isReusableV2 && !annotations?.reusableV2 && { reusableV2: anno }), ...(isCustomLayout && !annotations?.customLayout && { customLayout: anno }), - ...(isCustomDialog && !annotations?.reusable && { customdialog: anno }), + ...(isCustomDialog && !annotations?.customdialog && { customdialog: anno }), }; } if (!isCustomComponent) {