• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (c) 2025 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16import * as path from 'path';
17import { PluginTestContext, PluginTester } from '../../../../utils/plugin-tester';
18import { BuildConfig, mockBuildConfig } from '../../../../utils/artkts-config';
19import { getRootPath, MOCK_ENTRY_DIR_PATH } from '../../../../utils/path-config';
20import { parseDumpSrc } from '../../../../utils/parse-string';
21import { recheck, uiNoRecheck } from '../../../../utils/plugins';
22import { uiTransform } from '../../../../../ui-plugins';
23import { Plugins } from '../../../../../common/plugin-context';
24
25const BUILDER_LAMBDA_DIR_PATH: string = 'builder-lambda';
26const CUSTOM_COMPONENT_DIR_PATH: string = 'custom-component';
27
28const buildConfig: BuildConfig = mockBuildConfig();
29buildConfig.compileFiles = [
30    path.resolve(getRootPath(), MOCK_ENTRY_DIR_PATH, BUILDER_LAMBDA_DIR_PATH, CUSTOM_COMPONENT_DIR_PATH, 'custom-component-call.ets'),
31];
32
33const pluginTester = new PluginTester('test custom component call transformation', buildConfig);
34
35const parsedTransform: Plugins = {
36    name: 'custom-component-call',
37    parsed: uiTransform().parsed
38};
39
40const expectedParsedScript: string = `
41import { __memo_id_type as __memo_id_type } from "@ohos.arkui.stateManagement";
42import { __memo_context_type as __memo_context_type } from "@ohos.arkui.stateManagement";
43import { memo as memo } from "@ohos.arkui.stateManagement";
44import { UIColumnAttribute as UIColumnAttribute } from "@ohos.arkui.component";
45import { UITextAttribute as UITextAttribute } from "@ohos.arkui.component";
46import { CustomComponent as CustomComponent } from "@ohos.arkui.component";
47import { Text as Text, Column as Column, Component as Component, Builder as Builder, BuilderParam as BuilderParam } from "@ohos.arkui.component";
48
49@Component() final class CustomContainer extends CustomComponent<CustomContainer, __Options_CustomContainer> {
50  @Builder() public closerBuilder() {}
51  @BuilderParam() public closer: (()=> void) = (this).closerBuilder;
52  public build() {}
53  public constructor() {}
54}
55
56@Component() final class CustomContainerUser extends CustomComponent<CustomContainerUser, __Options_CustomContainerUser> {
57  public build() {
58    Column(undefined){
59      CustomContainer(undefined){
60        Column(undefined){
61          Text("hello", undefined);
62        };
63      };
64      CustomContainer(({} as __Options_CustomContainer)){
65        Column(undefined){};
66      };
67      CustomContainer(undefined){};
68      CustomContainer();
69    };
70  }
71  public constructor() {}
72}
73
74interface __Options_CustomContainer {
75  closer?: @memo() (()=> void);
76}
77
78interface __Options_CustomContainerUser {
79}
80`;
81
82function testParedTransformer(this: PluginTestContext): void {
83    expect(parseDumpSrc(this.scriptSnapshot ?? '')).toBe(parseDumpSrc(expectedParsedScript));
84}
85
86const expectedBuilderLambdaScript: string = `
87import { __memo_id_type as __memo_id_type } from "@ohos.arkui.stateManagement";
88import { __memo_context_type as __memo_context_type } from "@ohos.arkui.stateManagement";
89import { memo as memo } from "@ohos.arkui.stateManagement";
90import { UIColumnAttribute as UIColumnAttribute } from "@ohos.arkui.component";
91import { UITextAttribute as UITextAttribute } from "@ohos.arkui.component";
92import { CustomComponent as CustomComponent } from "@ohos.arkui.component";
93import { Text as Text, Column as Column, Component as Component, Builder as Builder, BuilderParam as BuilderParam } from "@ohos.arkui.component";
94
95function main() {}
96
97@Component({freezeWhenInactive:false}) final class CustomContainer extends CustomComponent<CustomContainer, __Options_CustomContainer> {
98  public __initializeStruct(initializers: __Options_CustomContainer | undefined, @memo() content: (()=> void) | undefined): void {
99    (this).__backing_closer = ((((({let gensym___38813563 = initializers;
100    (((gensym___38813563) == (null)) ? undefined : gensym___38813563.closer)})) ?? (content))) ?? ((this).closerBuilder))
101  }
102  public __updateStruct(initializers: __Options_CustomContainer | undefined): void {}
103  private __backing_closer?: @memo() (()=> void);
104  public get closer(): @memo() (()=> void) {
105    return (this).__backing_closer!;
106  }
107  public set closer(@memo() value: (()=> void)) {
108    (this).__backing_closer = value;
109  }
110  @memo() public closerBuilder() {}
111  @memo() public _build(@memo() style: ((instance: CustomContainer)=> CustomContainer) | undefined, @memo() content: (()=> void) | undefined, initializers: __Options_CustomContainer | undefined): void {}
112  public constructor() {}
113}
114
115@Component({freezeWhenInactive:false}) final class CustomContainerUser extends CustomComponent<CustomContainerUser, __Options_CustomContainerUser> {
116  public __initializeStruct(initializers: __Options_CustomContainerUser | undefined, @memo() content: (()=> void) | undefined): void {}
117  public __updateStruct(initializers: __Options_CustomContainerUser | undefined): void {}
118  @memo() public _build(@memo() style: ((instance: CustomContainerUser)=> CustomContainerUser) | undefined, @memo() content: (()=> void) | undefined, initializers: __Options_CustomContainerUser | undefined): void {
119    Column(undefined, undefined, (() => {
120      CustomContainer._instantiateImpl(undefined, (() => {
121        return new CustomContainer();
122      }), undefined, (() => {
123        Column(undefined, undefined, (() => {
124          Text(undefined, "hello", undefined, undefined);
125        }));
126      }), undefined);
127      CustomContainer._instantiateImpl(undefined, (() => {
128        return new CustomContainer();
129      }), ({} as __Options_CustomContainer), (() => {
130        Column(undefined, undefined, (() => {}));
131      }), undefined);
132      CustomContainer._instantiateImpl(undefined, (() => {
133        return new CustomContainer();
134      }), undefined, (() => {}), undefined);
135      CustomContainer._instantiateImpl(undefined, (() => {
136        return new CustomContainer();
137      }), undefined, undefined, undefined);
138    }));
139  }
140  public constructor() {}
141}
142
143interface __Options_CustomContainer {
144  set closer(closer: @memo() (()=> void) | undefined)
145  get closer(): @memo() (()=> void) | undefined
146}
147
148interface __Options_CustomContainerUser {
149}
150`;
151
152function testCustomComponentTransformer(this: PluginTestContext): void {
153    expect(parseDumpSrc(this.scriptSnapshot ?? '')).toBe(parseDumpSrc(expectedBuilderLambdaScript));
154}
155
156pluginTester.run(
157    'test custom component call transformation',
158    [parsedTransform, recheck, uiNoRecheck],
159    {
160        parsed: [testParedTransformer],
161        'checked:builder-lambda-no-recheck': [testCustomComponentTransformer],
162    },
163    {
164        stopAfter: 'checked',
165    }
166);
167