diff --git a/arkui-plugins/collectors/utils/collect-types.ts b/arkui-plugins/collectors/utils/collect-types.ts new file mode 100644 index 0000000000000000000000000000000000000000..73a3319eea820ab1c313aa28cb89b56c036a1a68 --- /dev/null +++ b/arkui-plugins/collectors/utils/collect-types.ts @@ -0,0 +1,240 @@ +/* + * 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 arkts from '@koalaui/libarkts'; + +export enum TypeRecordTypes { + PRIMITIVE, + FUNCTION, + UNION, + UNDEFINED, + NULL, + TYPE_REFERENCE, + TYPE_PARAMETER, + THIS, + ARRAY, +} + +export interface ThisTypeRecord { + type: TypeRecordTypes.THIS; +} + +export interface ArrayTypeRecord { + type: TypeRecordTypes.ARRAY; + elementType?: TypeRecord; +} + +export interface UndefinedTypeRecord { + type: TypeRecordTypes.UNDEFINED; +} + +export interface NullTypeRecord { + type: TypeRecordTypes.NULL; +} + +export interface TypeReferenceTypeRecord { + type: TypeRecordTypes.TYPE_REFERENCE; + typeName: string | string[]; + annotations: readonly arkts.AnnotationUsage[]; + typeParams?: TypeRecord[]; +} + +export interface PrimitiveTypeRecord { + type: TypeRecordTypes.PRIMITIVE; + typeName: string; +} + +export interface FunctionTypeRecord { + type: TypeRecordTypes.FUNCTION; + params: ParameterRecord[]; + returnType: TypeRecord; + annotations: readonly arkts.AnnotationUsage[]; + typeParams?: TypeParameterTypeRecord[]; +} + +export interface UnionTypeRecord { + type: TypeRecordTypes.UNION; + types: TypeRecord[]; +} + +export interface TypeParameterTypeRecord { + type: TypeRecordTypes.TYPE_PARAMETER; + annotations: readonly arkts.AnnotationUsage[]; + typeName?: string; + constraint?: TypeRecord; + defaultType?: TypeRecord; +} + +export type TypeRecord = + | ArrayTypeRecord + | ThisTypeRecord + | UndefinedTypeRecord + | NullTypeRecord + | TypeReferenceTypeRecord + | PrimitiveTypeRecord + | FunctionTypeRecord + | UnionTypeRecord; + +export interface ParameterRecord { + name: string; + typeRecord: TypeRecord; + annotations: readonly arkts.AnnotationUsage[]; + isOptional: boolean; +} + +export function collectTypeRecordFromTypeParameterInstatiation( + typeParams: arkts.TSTypeParameterInstantiation | undefined +): TypeRecord[] | undefined { + if (!typeParams) { + return undefined; + } + return typeParams.params.map((p) => collectTypeRecordFromType(p)!); +} + +export function collectTypeRecordFromTypeParameterDeclaration( + typeParams: arkts.TSTypeParameterDeclaration | undefined +): TypeParameterTypeRecord[] | undefined { + if (!typeParams) { + return undefined; + } + return typeParams.params.map((p) => collectTypeRecordFromTypeParameter(p)); +} + +export function collectTypeRecordFromTypeParameter(typeParameter: arkts.TSTypeParameter): TypeParameterTypeRecord { + const type = TypeRecordTypes.TYPE_PARAMETER; + const typeName = typeParameter.name?.name; + const annotations = typeParameter.annotations; + const constraint = collectTypeRecordFromType(typeParameter.constraint); + const defaultType = collectTypeRecordFromType(typeParameter.defaultType); + return { type, typeName, annotations, constraint, defaultType }; +} + +export function collectTypeRecordFromUnionType(unionType: arkts.TSUnionType): UnionTypeRecord { + const type = TypeRecordTypes.UNION; + const types = unionType.types.map((t) => collectTypeRecordFromType(t)!); + return { type, types }; +} + +export function collectTypeRecordFromFunctionType(funcType: arkts.ETSFunctionType): FunctionTypeRecord { + const type = TypeRecordTypes.FUNCTION; + const params = funcType.params.map((p) => collectTypeRecordFromParameter(p as arkts.ETSParameterExpression)); + const returnType = collectTypeRecordFromType(funcType.returnType)!; + const annotations = funcType.annotations; + const typeParams = collectTypeRecordFromTypeParameterDeclaration(funcType.typeParams); + return { type, params, returnType, annotations, typeParams }; +} + +export function collectTypeRecordFromParameter(param: arkts.ETSParameterExpression): ParameterRecord { + const name = param.identifier.name; + const typeRecord = collectTypeRecordFromType(param.type)!; + const annotations = param.annotations; + const isOptional = param.optional; + return { name, typeRecord, annotations, isOptional }; +} + +function coerceTypeNameToArray(name: string | string[] | undefined): string[] { + if (Array.isArray(name)) { + return name; + } + if (!!name) { + return [name]; + } + return []; +} + +function getTypeNameFromTypeReferencePartName(name: arkts.Expression | undefined): string | string[] | undefined { + if (!name) { + return undefined; + } + if (arkts.isIdentifier(name)) { + return name.name; + } + if (arkts.isTSQualifiedName(name)) { + const leftName: string | string[] | undefined = getTypeNameFromTypeReferencePartName(name.left); + const rightName: string | string[] | undefined = getTypeNameFromTypeReferencePartName(name.right); + const nameArr: string[] = [...coerceTypeNameToArray(leftName), ...coerceTypeNameToArray(rightName)]; + if (nameArr.length === 0) { + return undefined; + } + return nameArr; + } + return undefined; +} + +export function collectTypeRecordFromTypeReference(node: arkts.ETSTypeReference): TypeReferenceTypeRecord | undefined { + if (!node.part || !arkts.isETSTypeReferencePart(node.part)) { + return undefined; + } + if (!node.part.name) { + return undefined; + } + const typeName = getTypeNameFromTypeReferencePartName(node.part.name); + if (!typeName) { + return undefined; + } + const type = TypeRecordTypes.TYPE_REFERENCE; + const annotations = node.annotations; + const typeParams = collectTypeRecordFromTypeParameterInstatiation(node.part.typeParams); + return { type, typeName, annotations, typeParams }; +} + +export function collectTypeRecordFromUndefinedType(node: arkts.ETSUndefinedType): UndefinedTypeRecord { + const type = TypeRecordTypes.UNDEFINED; + return { type }; +} + +export function collectTypeRecordFromNullType(node: arkts.ETSNullType): NullTypeRecord { + const type = TypeRecordTypes.NULL; + return { type }; +} + +export function collectTypeRecordFromThisType(node: arkts.TSThisType): ThisTypeRecord { + const type = TypeRecordTypes.THIS; + return { type }; +} + +export function collectTypeRecordFromArrayType(node: arkts.TSArrayType): ArrayTypeRecord { + const type = TypeRecordTypes.ARRAY; + const elementType = collectTypeRecordFromType(node.elementType); + return { type, elementType }; +} + +export function collectTypeRecordFromPrimitiveType(node: arkts.ETSPrimitiveType): PrimitiveTypeRecord | undefined { + const type = TypeRecordTypes.PRIMITIVE; + const typeName: string = node.dumpSrc(); + return { type, typeName }; +} + +export function collectTypeRecordFromType(node: arkts.AstNode | undefined): TypeRecord | undefined { + if (!node) { + return undefined; + } + const type = arkts.nodeType(node); + if (collectTypeRecordByType.has(type)) { + return collectTypeRecordByType.get(type)!(node); + } + return undefined; +} + +const collectTypeRecordByType = new Map TypeRecord | undefined>([ + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_ETS_TYPE_REFERENCE, collectTypeRecordFromTypeReference], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_ETS_FUNCTION_TYPE, collectTypeRecordFromFunctionType], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_ETS_UNDEFINED_TYPE, collectTypeRecordFromUndefinedType], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_ETS_PRIMITIVE_TYPE, collectTypeRecordFromPrimitiveType], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_ETS_NULL_TYPE, collectTypeRecordFromNullType], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_ETS_UNION_TYPE, collectTypeRecordFromUnionType], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_TS_THIS_TYPE, collectTypeRecordFromThisType], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_TS_ARRAY_TYPE, collectTypeRecordFromArrayType], +]); diff --git a/arkui-plugins/common/safe-types.ts b/arkui-plugins/common/safe-types.ts index 899ef0c39b3dccec8dbbbe1fb68d6243a009dcc2..09ccd909234f3b704687e8653ab5b929eb5bd806 100644 --- a/arkui-plugins/common/safe-types.ts +++ b/arkui-plugins/common/safe-types.ts @@ -34,10 +34,12 @@ export type PartialNested = { type NestedKey = { [P in keyof T]: P extends K ? T[P] : T[P] extends object ? NestedKey : T[P]; - }; - +}; + export type PickNested = { [P in keyof T]: P extends K ? T[P] : T[P] extends object ? NestedKey : T[P]; }; -export type PartialNestedExcept = PartialNested> & PickNested; \ No newline at end of file +export type PartialNestedExcept = PartialNested> & PickNested; + +export type AstNodePointer = arkts.AstNode['peer']; diff --git a/arkui-plugins/test/demo/localtest/entry/src/main/ets/pages/new.ets b/arkui-plugins/test/demo/localtest/entry/src/main/ets/pages/new.ets index a665975076ca05f9e8111b218136fdbff21f123c..76b8150735a73f4c837ce9da39f669ca01e07c3e 100755 --- a/arkui-plugins/test/demo/localtest/entry/src/main/ets/pages/new.ets +++ b/arkui-plugins/test/demo/localtest/entry/src/main/ets/pages/new.ets @@ -42,7 +42,7 @@ struct MyStateSample { @Component struct Child { - @Link linkVar: string = ""; // TODO: remove this + @Link linkVar: string; @Prop propVar: string = "Prop"; changeValue1() { diff --git a/arkui-plugins/test/ut/ui-plugins/animation/animatable-extend-basic.test.ts b/arkui-plugins/test/ut/ui-plugins/animation/animatable-extend-basic.test.ts index d0f5ac29d50499a8173da1d11a6ccb61832c8924..850be5ba92b2448981d3ecf9c20c3e1c6fdf6be1 100644 --- a/arkui-plugins/test/ut/ui-plugins/animation/animatable-extend-basic.test.ts +++ b/arkui-plugins/test/ut/ui-plugins/animation/animatable-extend-basic.test.ts @@ -39,11 +39,16 @@ const animatableExtendTransform: Plugins = { const pluginTester = new PluginTester('test basic animatableExtend transform', buildConfig); const expectedScript: string = ` +import { ColumnAttribute as ColumnAttribute } from "arkui.component.column"; import { memo as memo } from "arkui.stateManagement.runtime"; import { TextAttribute as TextAttribute } from "arkui.component.text"; +import { TextImpl as TextImpl } from "arkui.component.text"; + +import { ColumnImpl as ColumnImpl } from "arkui.component.column"; + import { NavInterface as NavInterface } from "arkui.UserView"; import { PageLifeCycle as PageLifeCycle } from "arkui.component.customComponent"; @@ -76,9 +81,12 @@ __EntryWrapper.RegisterNamedRouter("", new __EntryWrapper(), ({ public __updateStruct(initializers: (__Options_AnimatablePropertyExample | undefined)): void {} @memo() public build() { - Column(undefined, undefined, (() => { - Text(@memo() ((instance: TextAttribute): void => { - instance.animationStart({ + ColumnImpl(@memo() ((instance: ColumnAttribute): void => { + instance.setColumnOptions(undefined).applyAttributesFinish(); + return; + }), (() => { + TextImpl(@memo() ((instance: TextAttribute): void => { + instance.setTextOptions("AnimatableProperty", undefined).animationStart({ duration: 2000, curve: Curve.Ease, }).backgroundColor(Color.Red).animationStop({ @@ -90,9 +98,9 @@ __EntryWrapper.RegisterNamedRouter("", new __EntryWrapper(), ({ }).fontSize(20).animationStop({ duration: 2000, curve: Curve.Ease, - }).width("100%"); + }).width("100%").applyAttributesFinish(); return; - }), "AnimatableProperty", undefined, undefined); + }), undefined); })); } diff --git a/arkui-plugins/test/ut/ui-plugins/animation/animation-basic.test.ts b/arkui-plugins/test/ut/ui-plugins/animation/animation-basic.test.ts index ac52cd1e5823253a82f4eeb27ca53abfebb99c25..6cf2fc9d7f76a6171f5ff77b42177a412ef5315b 100644 --- a/arkui-plugins/test/ut/ui-plugins/animation/animation-basic.test.ts +++ b/arkui-plugins/test/ut/ui-plugins/animation/animation-basic.test.ts @@ -38,11 +38,16 @@ const animationTransform: Plugins = { const pluginTester = new PluginTester('test basic animation transform', buildConfig); const expectedScript: string = ` +import { ColumnAttribute as ColumnAttribute } from "arkui.component.column"; import { memo as memo } from "arkui.stateManagement.runtime"; import { TextAttribute as TextAttribute } from "arkui.component.text"; +import { TextImpl as TextImpl } from "arkui.component.text"; + +import { ColumnImpl as ColumnImpl } from "arkui.component.column"; + import { NavInterface as NavInterface } from "arkui.UserView"; import { PageLifeCycle as PageLifeCycle } from "arkui.component.customComponent"; @@ -75,9 +80,12 @@ __EntryWrapper.RegisterNamedRouter("", new __EntryWrapper(), ({ public __updateStruct(initializers: (__Options_AnimatablePropertyExample | undefined)): void {} @memo() public build() { - Column(undefined, undefined, (() => { - Text(@memo() ((instance: TextAttribute): void => { - instance.animationStart({ + ColumnImpl(@memo() ((instance: ColumnAttribute): void => { + instance.setColumnOptions(undefined).applyAttributesFinish(); + return; + }), (() => { + TextImpl(@memo() ((instance: TextAttribute): void => { + instance.setTextOptions("AnimatableProperty", undefined).animationStart({ duration: 2000, curve: Curve.Ease, }).backgroundColor(Color.Red).animationStop({ @@ -89,9 +97,9 @@ __EntryWrapper.RegisterNamedRouter("", new __EntryWrapper(), ({ }).fontSize(20).animationStop({ duration: 2000, curve: Curve.Ease, - }).width("100%"); + }).width("100%").applyAttributesFinish(); return; - }), "AnimatableProperty", undefined, undefined); + }), undefined); })); } diff --git a/arkui-plugins/test/ut/ui-plugins/builder-lambda/custom-component/custom-component-call.test.ts b/arkui-plugins/test/ut/ui-plugins/builder-lambda/custom-component/custom-component-call.test.ts index 2f3702d00dc6a790f492c9bb0691191b4834e9df..932cce904ea316f71361cb0a783c0d361f4f042f 100644 --- a/arkui-plugins/test/ut/ui-plugins/builder-lambda/custom-component/custom-component-call.test.ts +++ b/arkui-plugins/test/ut/ui-plugins/builder-lambda/custom-component/custom-component-call.test.ts @@ -100,6 +100,13 @@ function testParedTransformer(this: PluginTestContext): void { } const expectedBuilderLambdaScript: string = ` +import { ColumnAttribute as ColumnAttribute } from "arkui.component.column"; + +import { TextAttribute as TextAttribute } from "arkui.component.text"; + +import { TextImpl as TextImpl } from "arkui.component.text"; + +import { ColumnImpl as ColumnImpl } from "arkui.component.column"; import { memo as memo } from "arkui.stateManagement.runtime"; @@ -147,18 +154,30 @@ function main() {} public __updateStruct(initializers: (__Options_CustomContainerUser | undefined)): void {} @memo() public build() { - Column(undefined, undefined, @memo() (() => { + ColumnImpl(@memo() ((instance: ColumnAttribute): void => { + instance.setColumnOptions(undefined).applyAttributesFinish(); + return; + }), @memo() (() => { CustomContainer._instantiateImpl(undefined, (() => { return new CustomContainer(); }), undefined, undefined, @memo() (() => { - Column(undefined, undefined, @memo() (() => { - Text(undefined, "hello", undefined, undefined); + ColumnImpl(@memo() ((instance: ColumnAttribute): void => { + instance.setColumnOptions(undefined).applyAttributesFinish(); + return; + }), @memo() (() => { + TextImpl(@memo() ((instance: TextAttribute): void => { + instance.setTextOptions("hello", undefined).applyAttributesFinish(); + return; + }), undefined); })); })); CustomContainer._instantiateImpl(undefined, (() => { return new CustomContainer(); }), {}, undefined, @memo() (() => { - Column(undefined, undefined, @memo() (() => {})); + ColumnImpl(@memo() ((instance: ColumnAttribute): void => { + instance.setColumnOptions(undefined).applyAttributesFinish(); + return; + }), @memo() (() => {})); })); CustomContainer._instantiateImpl(undefined, (() => { return new CustomContainer(); diff --git a/arkui-plugins/test/ut/ui-plugins/builder-lambda/simple-component.test.ts b/arkui-plugins/test/ut/ui-plugins/builder-lambda/simple-component.test.ts index e8e1ace16621ce77238c023b35f9aec5457e3673..d660394e195e4441cbc95fe5c6c7239ac10662bd 100644 --- a/arkui-plugins/test/ut/ui-plugins/builder-lambda/simple-component.test.ts +++ b/arkui-plugins/test/ut/ui-plugins/builder-lambda/simple-component.test.ts @@ -32,13 +32,18 @@ const pluginTester = new PluginTester('test builder-lambda simple component', bu function testBuilderLambdaTransformer(this: PluginTestContext): void { const expectedScript: string = ` +import { ColumnAttribute as ColumnAttribute } from "arkui.component.column"; import { memo as memo } from "arkui.stateManagement.runtime"; +import { ColumnImpl as ColumnImpl } from "arkui.component.column"; import { memo as memo } from \"@ohos.arkui.stateManagement\"; import { Column as Column, ColumnAttribute as ColumnAttribute } from \"arkui.component.column\"; function main() {} class MyStateSample { @memo() public build() { - Column(undefined, undefined, @memo() (() => {})); + ColumnImpl(@memo() ((instance: ColumnAttribute): void => { + instance.setColumnOptions(undefined).applyAttributesFinish(); + return; + }), @memo() (() => {})); } public constructor() {} } @@ -49,7 +54,9 @@ class MyStateSample { function testMemoTransformer(this: PluginTestContext): void { const expectedScript: string = ` import { __memo_context_type as __memo_context_type, __memo_id_type as __memo_id_type } from \"arkui.stateManagement.runtime\"; +import { ColumnAttribute as ColumnAttribute } from "arkui.component.column"; import { memo as memo } from "arkui.stateManagement.runtime"; +import { ColumnImpl as ColumnImpl } from "arkui.component.column"; import { memo as memo } from \"@ohos.arkui.stateManagement\"; import { Column as Column, ColumnAttribute as ColumnAttribute } from \"arkui.component.column\"; function main() {} @@ -60,7 +67,19 @@ class MyStateSample { __memo_scope.cached; return; } - Column(__memo_context, ((__memo_id) + (65509320)), undefined, undefined, @memo() ((__memo_context: __memo_context_type, __memo_id: __memo_id_type) => { + ColumnImpl(__memo_context, ((__memo_id) + ()), @memo() ((__memo_context: __memo_context_type, __memo_id: __memo_id_type, instance: ColumnAttribute): void => { + const __memo_scope = __memo_context.scope(((__memo_id) + ()), 1); + const __memo_parameter_instance = __memo_scope.param(0, instance); + if (__memo_scope.unchanged) { + __memo_scope.cached; + return; + } + __memo_parameter_instance.value.setColumnOptions(undefined).applyAttributesFinish(); + { + __memo_scope.recache(); + return; + } + }), @memo() ((__memo_context: __memo_context_type, __memo_id: __memo_id_type) => { const __memo_scope = __memo_context.scope(((__memo_id) + (147296800)), 0); if (__memo_scope.unchanged) { __memo_scope.cached; diff --git a/arkui-plugins/test/ut/ui-plugins/builder-lambda/style-with-receiver.test.ts b/arkui-plugins/test/ut/ui-plugins/builder-lambda/style-with-receiver.test.ts index 8e2c2dd05d7ff77e52ab79cbbd288f719d6fbc3e..079f19ff422505383d45fe6f493a239f922b6b6e 100644 --- a/arkui-plugins/test/ut/ui-plugins/builder-lambda/style-with-receiver.test.ts +++ b/arkui-plugins/test/ut/ui-plugins/builder-lambda/style-with-receiver.test.ts @@ -39,10 +39,16 @@ const parsedTransform: Plugins = { const expectedScript: string = ` +import { ColumnAttribute as ColumnAttribute } from "arkui.component.column"; + import { memo as memo } from "arkui.stateManagement.runtime"; import { TextAttribute as TextAttribute } from "arkui.component.text"; +import { TextImpl as TextImpl } from "arkui.component.text"; + +import { ColumnImpl as ColumnImpl } from "arkui.component.column"; + import { LayoutCallback as LayoutCallback } from "arkui.component.customComponent"; import { CustomComponentV2 as CustomComponentV2 } from "arkui.component.customComponent"; @@ -76,15 +82,18 @@ function main() {} public __updateStruct(initializers: (__Options_MM | undefined)): void {} @memo() public build() { - Column(undefined, undefined, @memo() (() => { - Text(@memo() ((instance: TextAttribute): void => { - style22(cardStyle(instance.height(200).fontColor("#000000"), 600, "#eeeeee").fontSize(60).fontWeight(400)).width(900); + ColumnImpl(@memo() ((instance: ColumnAttribute): void => { + instance.setColumnOptions(undefined).applyAttributesFinish(); + return; + }), @memo() (() => { + TextImpl(@memo() ((instance: TextAttribute): void => { + style22(cardStyle(instance.setTextOptions("hello world", undefined).height(200).fontColor("#000000"), 600, "#eeeeee").fontSize(60).fontWeight(400)).width(900).applyAttributesFinish(); return; - }), "hello world", undefined, undefined); - Text(@memo() ((instance: TextAttribute): void => { - cardStyle(instance, 600, "#eeeeee"); + }), undefined); + TextImpl(@memo() ((instance: TextAttribute): void => { + cardStyle(instance.setTextOptions("hello world", undefined), 600, "#eeeeee").applyAttributesFinish(); return; - }), "hello world", undefined, undefined); + }), undefined); })); } diff --git a/arkui-plugins/test/ut/ui-plugins/component/for-each.test.ts b/arkui-plugins/test/ut/ui-plugins/component/for-each.test.ts index fc931a33162d00f5023afac63ca2e321136b588f..21e842c9c12ad7d1951b566338754da203dc5bce 100644 --- a/arkui-plugins/test/ut/ui-plugins/component/for-each.test.ts +++ b/arkui-plugins/test/ut/ui-plugins/component/for-each.test.ts @@ -38,8 +38,16 @@ const parsedTransform: Plugins = { }; const expectedScript: string = ` +import { TextAttribute as TextAttribute } from "arkui.component.text"; + +import { TextImpl as TextImpl } from "arkui.component.text"; + +import { ColumnAttribute as ColumnAttribute } from "arkui.component.column"; + import { memo as memo } from "arkui.stateManagement.runtime"; +import { ColumnImpl as ColumnImpl } from "arkui.component.column"; + import { LayoutCallback as LayoutCallback } from "arkui.component.customComponent"; import { CustomComponentV2 as CustomComponentV2 } from "arkui.component.customComponent"; @@ -98,21 +106,33 @@ class AB { } @memo() public build() { - Column(undefined, undefined, @memo() (() => { + ColumnImpl(@memo() ((instance: ColumnAttribute): void => { + instance.setColumnOptions(undefined).applyAttributesFinish(); + return; + }), @memo() (() => { ForEach(((): Array => { return this.arr; }), ((item: string) => { - Text(undefined, item, undefined, undefined); + TextImpl(@memo() ((instance: TextAttribute): void => { + instance.setTextOptions(item, undefined).applyAttributesFinish(); + return; + }), undefined); })); ForEach(((): Array => { return this.getArray(); }), ((item: Person) => { - Text(undefined, item.name, undefined, undefined); + TextImpl(@memo() ((instance: TextAttribute): void => { + instance.setTextOptions(item.name, undefined).applyAttributesFinish(); + return; + }), undefined); })); ForEach(((): Array => { return new AB().bar; }), ((item: string) => { - Text(undefined, item, undefined, undefined); + TextImpl(@memo() ((instance: TextAttribute): void => { + instance.setTextOptions(item, undefined).applyAttributesFinish(); + return; + }), undefined); })); })); } diff --git a/arkui-plugins/test/ut/ui-plugins/decorators/builder-param/builder-param-passing.test.ts b/arkui-plugins/test/ut/ui-plugins/decorators/builder-param/builder-param-passing.test.ts index c95268bf16885e28c5f5835a3e0325726b1f55e5..a1f802675fecb472e33c86ce91368d8c1b9b4e3b 100644 --- a/arkui-plugins/test/ut/ui-plugins/decorators/builder-param/builder-param-passing.test.ts +++ b/arkui-plugins/test/ut/ui-plugins/decorators/builder-param/builder-param-passing.test.ts @@ -38,6 +38,14 @@ const parsedTransform: Plugins = { }; const expectedAfterUIScript: string = ` +import { ColumnAttribute as ColumnAttribute } from "arkui.component.column"; + +import { ColumnImpl as ColumnImpl } from "arkui.component.column"; + +import { TextAttribute as TextAttribute } from "arkui.component.text"; + +import { TextImpl as TextImpl } from "arkui.component.text"; + import { memo as memo } from "arkui.stateManagement.runtime"; import { LayoutCallback as LayoutCallback } from "arkui.component.customComponent"; @@ -84,11 +92,17 @@ function main() {} public __updateStruct(initializers: (__Options_Parent | undefined)): void {} @memo() public componentBuilder() { - Text(undefined, "Parent builder", undefined, undefined); + TextImpl(@memo() ((instance: TextAttribute): void => { + instance.setTextOptions("Parent builder", undefined).applyAttributesFinish(); + return; + }), undefined); } @memo() public build() { - Column(undefined, undefined, @memo() (() => { + ColumnImpl(@memo() ((instance: ColumnAttribute): void => { + instance.setColumnOptions(undefined).applyAttributesFinish(); + return; + }), @memo() (() => { Child._instantiateImpl(undefined, (() => { return new Child(); }), { @@ -104,7 +118,10 @@ function main() {} Child._instantiateImpl(undefined, (() => { return new Child(); }), undefined, undefined, @memo() (() => { - Text(undefined, "Parent builder", undefined, undefined); + TextImpl(@memo() ((instance: TextAttribute): void => { + instance.setTextOptions("Parent builder", undefined).applyAttributesFinish(); + return; + }), undefined); })); })); } @@ -127,6 +144,10 @@ function main() {} const expectedAfterMemoScript: string = ` import { __memo_context_type as __memo_context_type, __memo_id_type as __memo_id_type } from "arkui.stateManagement.runtime"; +import { ColumnAttribute as ColumnAttribute } from "arkui.component.column"; +import { ColumnImpl as ColumnImpl } from "arkui.component.column"; +import { TextAttribute as TextAttribute } from "arkui.component.text"; +import { TextImpl as TextImpl } from "arkui.component.text"; import { memo as memo } from "arkui.stateManagement.runtime"; import { LayoutCallback as LayoutCallback } from "arkui.component.customComponent"; import { CustomComponentV2 as CustomComponentV2 } from "arkui.component.customComponent"; @@ -193,7 +214,19 @@ function main() {} __memo_scope.cached; return; } - Text(__memo_context, ((__memo_id) + (137225318)), undefined, "Parent builder", undefined, undefined); + TextImpl(__memo_context, ((__memo_id) + (137225318)), @memo() ((__memo_context: __memo_context_type, __memo_id: __memo_id_type, instance: TextAttribute): void => { + const __memo_scope = __memo_context.scope(((__memo_id) + ()), 1); + const __memo_parameter_instance = __memo_scope.param(0, instance); + if (__memo_scope.unchanged) { + __memo_scope.cached; + return; + } + __memo_parameter_instance.value.setTextOptions("Parent builder", undefined).applyAttributesFinish(); + { + __memo_scope.recache(); + return; + } + }), undefined); { __memo_scope.recache(); return; @@ -206,7 +239,19 @@ function main() {} __memo_scope.cached; return; } - Column(__memo_context, ((__memo_id) + (136716185)), undefined, undefined, @memo() ((__memo_context: __memo_context_type, __memo_id: __memo_id_type) => { + ColumnImpl(__memo_context, ((__memo_id) + (136716185)), @memo() ((__memo_context: __memo_context_type, __memo_id: __memo_id_type, instance: ColumnAttribute): void => { + const __memo_scope = __memo_context.scope(((__memo_id) + ()), 1); + const __memo_parameter_instance = __memo_scope.param(0, instance); + if (__memo_scope.unchanged) { + __memo_scope.cached; + return; + } + __memo_parameter_instance.value.setColumnOptions(undefined).applyAttributesFinish(); + { + __memo_scope.recache(); + return; + } + }), @memo() ((__memo_context: __memo_context_type, __memo_id: __memo_id_type) => { const __memo_scope = __memo_context.scope(((__memo_id) + (54078781)), 0); if (__memo_scope.unchanged) { __memo_scope.cached; @@ -241,7 +286,19 @@ function main() {} __memo_scope.cached; return; } - Text(__memo_context, ((__memo_id) + (223657391)), undefined, "Parent builder", undefined, undefined); + TextImpl(__memo_context, ((__memo_id) + (223657391)), @memo() ((__memo_context: __memo_context_type, __memo_id: __memo_id_type, instance: TextAttribute): void => { + const __memo_scope = __memo_context.scope(((__memo_id) + ()), 1); + const __memo_parameter_instance = __memo_scope.param(0, instance); + if (__memo_scope.unchanged) { + __memo_scope.cached; + return; + } + __memo_parameter_instance.value.setTextOptions("Parent builder", undefined).applyAttributesFinish(); + { + __memo_scope.recache(); + return; + } + }), undefined); { __memo_scope.recache(); return; diff --git a/arkui-plugins/test/ut/ui-plugins/decorators/builder-param/optional-builder-param.test.ts b/arkui-plugins/test/ut/ui-plugins/decorators/builder-param/optional-builder-param.test.ts index c16283a4ef9fa1f197f59292bd161444a6c59884..1220e20c6e4853077954f11db981c5b63d37e736 100644 --- a/arkui-plugins/test/ut/ui-plugins/decorators/builder-param/optional-builder-param.test.ts +++ b/arkui-plugins/test/ut/ui-plugins/decorators/builder-param/optional-builder-param.test.ts @@ -38,7 +38,13 @@ const parsedTransform: Plugins = { }; const expectedUIScript: string = ` +import { ColumnAttribute as ColumnAttribute } from "arkui.component.column"; +import { ColumnImpl as ColumnImpl } from "arkui.component.column"; +import { RowAttribute as RowAttribute } from "arkui.component.row"; +import { RowImpl as RowImpl } from "arkui.component.row"; import { memo as memo } from "arkui.stateManagement.runtime"; +import { TextAttribute as TextAttribute } from "arkui.component.text"; +import { TextImpl as TextImpl } from "arkui.component.text"; import { LayoutCallback as LayoutCallback } from "arkui.component.customComponent"; import { CustomComponentV2 as CustomComponentV2 } from "arkui.component.customComponent"; import { CustomComponent as CustomComponent } from "arkui.component.customComponent"; @@ -47,7 +53,10 @@ import { Component as Component, Entry as Entry, Builder as Builder, BuilderPara function main() {} @memo() function showTextBuilder() { - Text(undefined, "Hello World", undefined, undefined); + TextImpl(@memo() ((instance: TextAttribute): void => { + instance.setTextOptions("Hello World", undefined).applyAttributesFinish(); + return; + }), undefined); } @Component() final struct Child extends CustomComponent { @@ -81,7 +90,10 @@ function main() {} } @memo() public build() { - Row(undefined, undefined, @memo() (() => { + RowImpl(@memo() ((instance: RowAttribute): void => { + instance.setRowOptions(undefined).applyAttributesFinish(); + return; + }), @memo() (() => { if (this.customBuilderParam2) { (this.customBuilderParam2 as (()=> void))(); } @@ -102,11 +114,17 @@ function main() {} public __updateStruct(initializers: (__Options_Parent | undefined)): void {} @memo() public componentBuilder() { - Text(undefined, "Parent builder", undefined, undefined); + TextImpl(@memo() ((instance: TextAttribute): void => { + instance.setTextOptions("Parent builder", undefined).applyAttributesFinish(); + return; + }), undefined); } @memo() public build() { - Column(undefined, undefined, @memo() (() => { + ColumnImpl(@memo() ((instance: ColumnAttribute): void => { + instance.setColumnOptions(undefined).applyAttributesFinish(); + return; + }), @memo() (() => { Child._instantiateImpl(undefined, (() => { return new Child(); }), { @@ -138,7 +156,13 @@ function main() {} const expectedMemoScript: string = ` import { __memo_context_type as __memo_context_type, __memo_id_type as __memo_id_type } from "arkui.stateManagement.runtime"; +import { ColumnAttribute as ColumnAttribute } from "arkui.component.column"; +import { ColumnImpl as ColumnImpl } from "arkui.component.column"; +import { RowAttribute as RowAttribute } from "arkui.component.row"; +import { RowImpl as RowImpl } from "arkui.component.row"; import { memo as memo } from "arkui.stateManagement.runtime"; +import { TextAttribute as TextAttribute } from "arkui.component.text"; +import { TextImpl as TextImpl } from "arkui.component.text"; import { LayoutCallback as LayoutCallback } from "arkui.component.customComponent"; import { CustomComponentV2 as CustomComponentV2 } from "arkui.component.customComponent"; import { CustomComponent as CustomComponent } from "arkui.component.customComponent"; @@ -152,7 +176,19 @@ function main() {} __memo_scope.cached; return; } - Text(__memo_context, ((__memo_id) + (47330804)), undefined, "Hello World", undefined, undefined); + TextImpl(__memo_context, ((__memo_id) + ()), @memo() ((__memo_context: __memo_context_type, __memo_id: __memo_id_type, instance: TextAttribute): void => { + const __memo_scope = __memo_context.scope(((__memo_id) + ()), 1); + const __memo_parameter_instance = __memo_scope.param(0, instance); + if (__memo_scope.unchanged) { + __memo_scope.cached; + return; + } + __memo_parameter_instance.value.setTextOptions("Hello World", undefined).applyAttributesFinish(); + { + __memo_scope.recache(); + return; + } + }), undefined); { __memo_scope.recache(); return; @@ -195,7 +231,19 @@ function main() {} __memo_scope.cached; return; } - Row(__memo_context, ((__memo_id) + (46726221)), undefined, undefined, @memo() ((__memo_context: __memo_context_type, __memo_id: __memo_id_type) => { + RowImpl(__memo_context, ((__memo_id) + ()), @memo() ((__memo_context: __memo_context_type, __memo_id: __memo_id_type, instance: RowAttribute): void => { + const __memo_scope = __memo_context.scope(((__memo_id) + ()), 1); + const __memo_parameter_instance = __memo_scope.param(0, instance); + if (__memo_scope.unchanged) { + __memo_scope.cached; + return; + } + __memo_parameter_instance.value.setRowOptions(undefined).applyAttributesFinish(); + { + __memo_scope.recache(); + return; + } + }), @memo() ((__memo_context: __memo_context_type, __memo_id: __memo_id_type) => { const __memo_scope = __memo_context.scope(((__memo_id) + (213104625)), 0); if (__memo_scope.unchanged) { __memo_scope.cached; @@ -234,7 +282,19 @@ function main() {} __memo_scope.cached; return; } - Text(__memo_context, ((__memo_id) + (218979098)), undefined, "Parent builder", undefined, undefined); + TextImpl(__memo_context, ((__memo_id) + ()), @memo() ((__memo_context: __memo_context_type, __memo_id: __memo_id_type, instance: TextAttribute): void => { + const __memo_scope = __memo_context.scope(((__memo_id) + ()), 1); + const __memo_parameter_instance = __memo_scope.param(0, instance); + if (__memo_scope.unchanged) { + __memo_scope.cached; + return; + } + __memo_parameter_instance.value.setTextOptions("Parent builder", undefined).applyAttributesFinish(); + { + __memo_scope.recache(); + return; + } + }), undefined); { __memo_scope.recache(); return; @@ -247,7 +307,19 @@ function main() {} __memo_scope.cached; return; } - Column(__memo_context, ((__memo_id) + (78055758)), undefined, undefined, @memo() ((__memo_context: __memo_context_type, __memo_id: __memo_id_type) => { + ColumnImpl(__memo_context, ((__memo_id) + (78055758)), @memo() ((__memo_context: __memo_context_type, __memo_id: __memo_id_type, instance: ColumnAttribute): void => { + const __memo_scope = __memo_context.scope(((__memo_id) + ()), 1); + const __memo_parameter_instance = __memo_scope.param(0, instance); + if (__memo_scope.unchanged) { + __memo_scope.cached; + return; + } + __memo_parameter_instance.value.setColumnOptions(undefined).applyAttributesFinish(); + { + __memo_scope.recache(); + return; + } + }), @memo() ((__memo_context: __memo_context_type, __memo_id: __memo_id_type) => { const __memo_scope = __memo_context.scope(((__memo_id) + (136716185)), 0); if (__memo_scope.unchanged) { __memo_scope.cached; diff --git a/arkui-plugins/test/ut/ui-plugins/decorators/builder/global-builder.test.ts b/arkui-plugins/test/ut/ui-plugins/decorators/builder/global-builder.test.ts index 3ecead48626553fc65ae98091666d645454816d7..3cbcc39998deb552776699c5a475256c61a172fd 100644 --- a/arkui-plugins/test/ut/ui-plugins/decorators/builder/global-builder.test.ts +++ b/arkui-plugins/test/ut/ui-plugins/decorators/builder/global-builder.test.ts @@ -37,8 +37,16 @@ const parsedTransform: Plugins = { const expectedScript: string = ` +import { RowAttribute as RowAttribute } from "arkui.component.row"; + +import { RowImpl as RowImpl } from "arkui.component.row"; + import { memo as memo } from "arkui.stateManagement.runtime"; +import { TextAttribute as TextAttribute } from "arkui.component.text"; + +import { TextImpl as TextImpl } from "arkui.component.text"; + import { LayoutCallback as LayoutCallback } from "arkui.component.customComponent"; import { CustomComponentV2 as CustomComponentV2 } from "arkui.component.customComponent"; @@ -51,12 +59,21 @@ function main() {} @memo() function showTextBuilder() { - Text(undefined, "Hello World", undefined, undefined); + TextImpl(@memo() ((instance: TextAttribute): void => { + instance.setTextOptions("Hello World", undefined).applyAttributesFinish(); + return; + }), undefined); } @memo() function overBuilder(params: Tmp) { - Row(undefined, undefined, @memo() (() => { - Text(undefined, (("UseStateVarByReference: ") + (params.paramA1)), undefined, undefined); + RowImpl(@memo() ((instance: RowAttribute): void => { + instance.setRowOptions(undefined).applyAttributesFinish(); + return; + }), @memo() (() => { + TextImpl(@memo() ((instance: TextAttribute): void => { + instance.setTextOptions((("UseStateVarByReference: ") + (params.paramA1)), undefined).applyAttributesFinish(); + return; + }), undefined); })); } @@ -74,7 +91,10 @@ class Tmp { public __updateStruct(initializers: (__Options_BuilderDemo | undefined)): void {} @memo() public build() { - Row(undefined, undefined, @memo() (() => { + RowImpl(@memo() ((instance: RowAttribute): void => { + instance.setRowOptions(undefined).applyAttributesFinish(); + return; + }), @memo() (() => { showTextBuilder(); overBuilder({ paramA1: "Hello", diff --git a/arkui-plugins/test/ut/ui-plugins/decorators/builder/local-builder.test.ts b/arkui-plugins/test/ut/ui-plugins/decorators/builder/local-builder.test.ts index 318d1ee717f7352f70b154979ad33c5291a79957..6b3f935b2d5895db4f9664ae74d89d33ae84271a 100644 --- a/arkui-plugins/test/ut/ui-plugins/decorators/builder/local-builder.test.ts +++ b/arkui-plugins/test/ut/ui-plugins/decorators/builder/local-builder.test.ts @@ -36,11 +36,16 @@ const parsedTransform: Plugins = { }; const expectedScript: string = ` +import { ColumnAttribute as ColumnAttribute } from "arkui.component.column"; + +import { ColumnImpl as ColumnImpl } from "arkui.component.column"; import { memo as memo } from "arkui.stateManagement.runtime"; import { TextAttribute as TextAttribute } from "arkui.component.text"; +import { TextImpl as TextImpl } from "arkui.component.text"; + import { LayoutCallback as LayoutCallback } from "arkui.component.customComponent"; import { CustomComponentV2 as CustomComponentV2 } from "arkui.component.customComponent"; @@ -59,21 +64,24 @@ function main() {} public __updateStruct(initializers: (__Options_BuilderDemo | undefined)): void {} @memo() public showTextBuilder() { - Text(@memo() ((instance: TextAttribute): void => { - instance.fontSize(30); + TextImpl(@memo() ((instance: TextAttribute): void => { + instance.setTextOptions("Hello World", undefined).fontSize(30).applyAttributesFinish(); return; - }), "Hello World", undefined, undefined); + }), undefined); } @memo() public showTextValueBuilder(param: string) { - Text(@memo() ((instance: TextAttribute): void => { - instance.fontSize(30); + TextImpl(@memo() ((instance: TextAttribute): void => { + instance.setTextOptions(param, undefined).fontSize(30).applyAttributesFinish(); return; - }), param, undefined, undefined); + }), undefined); } @memo() public build() { - Column(undefined, undefined, @memo() (() => { + ColumnImpl(@memo() ((instance: ColumnAttribute): void => { + instance.setColumnOptions(undefined).applyAttributesFinish(); + return; + }), @memo() (() => { this.showTextBuilder(); this.showTextValueBuilder("Hello @Builder"); })); diff --git a/arkui-plugins/test/ut/ui-plugins/decorators/link/link-to-link-prop-state.test.ts b/arkui-plugins/test/ut/ui-plugins/decorators/link/link-to-link-prop-state.test.ts index a507ebd52061f906a5d636684d07045d6f6eef01..14f9ab48bbbb5f4a3579a6cef4c19a0c1e96a6d9 100644 --- a/arkui-plugins/test/ut/ui-plugins/decorators/link/link-to-link-prop-state.test.ts +++ b/arkui-plugins/test/ut/ui-plugins/decorators/link/link-to-link-prop-state.test.ts @@ -48,8 +48,16 @@ import { LinkSourceType as LinkSourceType } from "arkui.stateManagement.decorato import { ILinkDecoratedVariable as ILinkDecoratedVariable } from "arkui.stateManagement.decorator"; +import { ColumnAttribute as ColumnAttribute } from "arkui.component.column"; + import { memo as memo } from "arkui.stateManagement.runtime"; +import { TextInputAttribute as TextInputAttribute } from "arkui.component.textInput"; + +import { TextInputImpl as TextInputImpl } from "arkui.component.textInput"; + +import { ColumnImpl as ColumnImpl } from "arkui.component.column"; + import { LayoutCallback as LayoutCallback } from "arkui.component.customComponent"; import { CustomComponentV2 as CustomComponentV2 } from "arkui.component.customComponent"; @@ -83,10 +91,16 @@ function main() {} } @memo() public build() { - Column(undefined, undefined, @memo() (() => { - TextInput(undefined, { - text: this.text1, - }, undefined); + ColumnImpl(@memo() ((instance: ColumnAttribute): void => { + instance.setColumnOptions(undefined).applyAttributesFinish(); + return; + }), @memo() (() => { + TextInputImpl(@memo() ((instance: TextInputAttribute): void => { + instance.setTextInputOptions({ + text: this.text1, + }).applyAttributesFinish(); + return; + }), undefined); Child._instantiateImpl(undefined, (() => { return new Child(); }), { @@ -167,9 +181,12 @@ function main() {} } @memo() public build() { - TextInput(undefined, { - text: this.childText, - }, undefined); + TextInputImpl(@memo() ((instance: TextInputAttribute): void => { + instance.setTextInputOptions({ + text: this.childText, + }).applyAttributesFinish(); + return; + }), undefined); } private constructor() {} diff --git a/arkui-plugins/test/ut/ui-plugins/decorators/link/state-to-link.test.ts b/arkui-plugins/test/ut/ui-plugins/decorators/link/state-to-link.test.ts index 111874d8cab45adbff9973641a6ffbb6de9d8674..1e9d1a3ec9c85145ff996cb66434ab94eaf50614 100644 --- a/arkui-plugins/test/ut/ui-plugins/decorators/link/state-to-link.test.ts +++ b/arkui-plugins/test/ut/ui-plugins/decorators/link/state-to-link.test.ts @@ -46,10 +46,20 @@ import { LinkSourceType as LinkSourceType } from "arkui.stateManagement.decorato import { ILinkDecoratedVariable as ILinkDecoratedVariable } from "arkui.stateManagement.decorator"; +import { ColumnAttribute as ColumnAttribute } from "arkui.component.column"; + +import { DatePickerAttribute as DatePickerAttribute } from "arkui.component.datePicker"; + +import { DatePickerImpl as DatePickerImpl } from "arkui.component.datePicker"; + import { memo as memo } from "arkui.stateManagement.runtime"; import { ButtonAttribute as ButtonAttribute } from "arkui.component.button"; +import { ButtonImpl as ButtonImpl } from "arkui.component.button"; + +import { ColumnImpl as ColumnImpl } from "arkui.component.column"; + import { NavInterface as NavInterface } from "arkui.UserView"; import { PageLifeCycle as PageLifeCycle } from "arkui.component.customComponent"; @@ -97,24 +107,30 @@ __EntryWrapper.RegisterNamedRouter("", new __EntryWrapper(), ({ } @memo() public build() { - Column(undefined, undefined, @memo() (() => { - Button(@memo() ((instance: ButtonAttribute): void => { - instance.onClick(((e: ClickEvent) => { + ColumnImpl(@memo() ((instance: ColumnAttribute): void => { + instance.setColumnOptions(undefined).applyAttributesFinish(); + return; + }), @memo() (() => { + ButtonImpl(@memo() ((instance: ButtonAttribute): void => { + instance.setButtonOptions("child increase the year by 1", undefined).onClick(((e: ClickEvent) => { this.selectedDate.setFullYear(((this.selectedDate.getFullYear()) + (1))); - })); + })).applyAttributesFinish(); return; - }), "child increase the year by 1", undefined, undefined); - Button(@memo() ((instance: ButtonAttribute): void => { - instance.margin(10).onClick(((e: ClickEvent) => { + }), undefined); + ButtonImpl(@memo() ((instance: ButtonAttribute): void => { + instance.setButtonOptions("child update the new date", undefined).margin(10).onClick(((e: ClickEvent) => { this.selectedDate = new Date("2023-09-09"); - })); + })).applyAttributesFinish(); + return; + }), undefined); + DatePickerImpl(@memo() ((instance: DatePickerAttribute): void => { + instance.setDatePickerOptions({ + start: new Date("1970-1-1"), + end: new Date("2100-1-1"), + selected: this.selectedDate, + }).applyAttributesFinish(); return; - }), "child update the new date", undefined, undefined); - DatePicker(undefined, { - start: new Date("1970-1-1"), - end: new Date("2100-1-1"), - selected: this.selectedDate, - }, undefined); + }), undefined); })); } @@ -141,24 +157,30 @@ __EntryWrapper.RegisterNamedRouter("", new __EntryWrapper(), ({ } @memo() public build() { - Column(undefined, undefined, @memo() (() => { - Button(@memo() ((instance: ButtonAttribute): void => { - instance.margin(10).onClick(((e: ClickEvent) => { + ColumnImpl(@memo() ((instance: ColumnAttribute): void => { + instance.setColumnOptions(undefined).applyAttributesFinish(); + return; + }), @memo() (() => { + ButtonImpl(@memo() ((instance: ButtonAttribute): void => { + instance.setButtonOptions("parent increase the month by 1", undefined).margin(10).onClick(((e: ClickEvent) => { this.parentSelectedDate.setMonth(((this.parentSelectedDate.getMonth()) + (1))); - })); + })).applyAttributesFinish(); return; - }), "parent increase the month by 1", undefined, undefined); - Button(@memo() ((instance: ButtonAttribute): void => { - instance.margin(10).onClick(((e: ClickEvent) => { + }), undefined); + ButtonImpl(@memo() ((instance: ButtonAttribute): void => { + instance.setButtonOptions("parent update the new date", undefined).margin(10).onClick(((e: ClickEvent) => { this.parentSelectedDate = new Date("2023-07-07"); - })); + })).applyAttributesFinish(); + return; + }), undefined); + DatePickerImpl(@memo() ((instance: DatePickerAttribute): void => { + instance.setDatePickerOptions({ + start: new Date("1970-1-1"), + end: new Date("2100-1-1"), + selected: this.parentSelectedDate, + }).applyAttributesFinish(); return; - }), "parent update the new date", undefined, undefined); - DatePicker(undefined, { - start: new Date("1970-1-1"), - end: new Date("2100-1-1"), - selected: this.parentSelectedDate, - }, undefined); + }), undefined); DateComponent._instantiateImpl(undefined, (() => { return new DateComponent(); }), { diff --git a/arkui-plugins/test/ut/ui-plugins/decorators/objectlink/objectlink-observed.test.ts b/arkui-plugins/test/ut/ui-plugins/decorators/objectlink/objectlink-observed.test.ts index aef8d5ccb2c8754fe1fb27991b780f98354d9506..668b7487aa89924a72d314b70d323390ef3cfd12 100644 --- a/arkui-plugins/test/ut/ui-plugins/decorators/objectlink/objectlink-observed.test.ts +++ b/arkui-plugins/test/ut/ui-plugins/decorators/objectlink/objectlink-observed.test.ts @@ -43,10 +43,16 @@ import { IStateDecoratedVariable as IStateDecoratedVariable } from "arkui.stateM import { IObjectLinkDecoratedVariable as IObjectLinkDecoratedVariable } from "arkui.stateManagement.decorator"; +import { ColumnAttribute as ColumnAttribute } from "arkui.component.column"; + import { memo as memo } from "arkui.stateManagement.runtime"; import { ButtonAttribute as ButtonAttribute } from "arkui.component.button"; +import { ButtonImpl as ButtonImpl } from "arkui.component.button"; + +import { ColumnImpl as ColumnImpl } from "arkui.component.column"; + import { IObservedObject as IObservedObject } from "arkui.stateManagement.decorator"; import { OBSERVE as OBSERVE } from "arkui.stateManagement.decorator"; @@ -204,13 +210,16 @@ __EntryWrapper.RegisterNamedRouter("", new __EntryWrapper(), ({ } @memo() public build() { - Column(undefined, undefined, @memo() (() => { - Button(@memo() ((instance: ButtonAttribute): void => { - instance.onClick(((e: ClickEvent) => { + ColumnImpl(@memo() ((instance: ColumnAttribute): void => { + instance.setColumnOptions(undefined).applyAttributesFinish(); + return; + }), @memo() (() => { + ButtonImpl(@memo() ((instance: ButtonAttribute): void => { + instance.setButtonOptions("child increase the day by 1", undefined).onClick(((e: ClickEvent) => { this.data.setDate(((this.data.getDate()) + (1))); - })); + })).applyAttributesFinish(); return; - }), "child increase the day by 1", undefined, undefined); + }), undefined); })); } @@ -237,25 +246,28 @@ __EntryWrapper.RegisterNamedRouter("", new __EntryWrapper(), ({ } @memo() public build() { - Column(undefined, undefined, @memo() (() => { + ColumnImpl(@memo() ((instance: ColumnAttribute): void => { + instance.setColumnOptions(undefined).applyAttributesFinish(); + return; + }), @memo() (() => { Child._instantiateImpl(undefined, (() => { return new Child(); }), { label: "date", data: this.newData.data, }, undefined, undefined); - Button(@memo() ((instance: ButtonAttribute): void => { - instance.onClick(((e: ClickEvent) => { + ButtonImpl(@memo() ((instance: ButtonAttribute): void => { + instance.setButtonOptions("parent update the new date", undefined).onClick(((e: ClickEvent) => { this.newData.data = new DateClass("2023-07-07"); - })); + })).applyAttributesFinish(); return; - }), "parent update the new date", undefined, undefined); - Button(@memo() ((instance: ButtonAttribute): void => { - instance.onClick(((e: ClickEvent) => { + }), undefined); + ButtonImpl(@memo() ((instance: ButtonAttribute): void => { + instance.setButtonOptions("ViewB: this.newData = new NewDate(new DateClass('2023-08-20'))", undefined).onClick(((e: ClickEvent) => { this.newData = new NewDate(new DateClass("2023-08-20")); - })); + })).applyAttributesFinish(); return; - }), "ViewB: this.newData = new NewDate(new DateClass('2023-08-20'))", undefined, undefined); + }), undefined); })); } diff --git a/arkui-plugins/test/ut/ui-plugins/decorators/prop/state-to-prop.test.ts b/arkui-plugins/test/ut/ui-plugins/decorators/prop/state-to-prop.test.ts index 620bd9884aedd66cff9d10617dc9117009a53c70..049d3b72972f54c9eea3480a2dd0b96425111b9d 100644 --- a/arkui-plugins/test/ut/ui-plugins/decorators/prop/state-to-prop.test.ts +++ b/arkui-plugins/test/ut/ui-plugins/decorators/prop/state-to-prop.test.ts @@ -44,10 +44,20 @@ import { STATE_MGMT_FACTORY as STATE_MGMT_FACTORY } from "arkui.stateManagement. import { IPropDecoratedVariable as IPropDecoratedVariable } from "arkui.stateManagement.decorator"; -import { memo as memo } from "arkui.stateManagement.runtime"; +import { ColumnAttribute as ColumnAttribute } from "arkui.component.column"; import { ButtonAttribute as ButtonAttribute } from "arkui.component.button"; +import { ButtonImpl as ButtonImpl } from "arkui.component.button"; + +import { memo as memo } from "arkui.stateManagement.runtime"; + +import { TextAttribute as TextAttribute } from "arkui.component.text"; + +import { TextImpl as TextImpl } from "arkui.component.text"; + +import { ColumnImpl as ColumnImpl } from "arkui.component.column"; + import { LayoutCallback as LayoutCallback } from "arkui.component.customComponent"; import { CustomComponentV2 as CustomComponentV2 } from "arkui.component.customComponent"; @@ -96,18 +106,27 @@ function main() {} } @memo() public build() { - Column(undefined, undefined, @memo() (() => { + ColumnImpl(@memo() ((instance: ColumnAttribute): void => { + instance.setColumnOptions(undefined).applyAttributesFinish(); + return; + }), @memo() (() => { if (((this.count) > (0))) { - Text(undefined, (((("You have") + (this.count))) + ("Nuggets left")), undefined, undefined); + TextImpl(@memo() ((instance: TextAttribute): void => { + instance.setTextOptions((((("You have") + (this.count))) + ("Nuggets left")), undefined).applyAttributesFinish(); + return; + }), undefined); } else { - Text(undefined, "Game over!", undefined, undefined); + TextImpl(@memo() ((instance: TextAttribute): void => { + instance.setTextOptions("Game over!", undefined).applyAttributesFinish(); + return; + }), undefined); } - Button(@memo() ((instance: ButtonAttribute): void => { - instance.onClick(((e: ClickEvent) => { + ButtonImpl(@memo() ((instance: ButtonAttribute): void => { + instance.setButtonOptions("Try again", undefined).onClick(((e: ClickEvent) => { this.count -= this.costOfOneAttempt; - })); + })).applyAttributesFinish(); return; - }), "Try again", undefined, undefined); + }), undefined); })); } @@ -134,20 +153,26 @@ function main() {} } @memo() public build() { - Column(undefined, undefined, @memo() (() => { - Text(undefined, (((("Grant") + (this.countDownStartValue))) + ("nuggets to play.")), undefined, undefined); - Button(@memo() ((instance: ButtonAttribute): void => { - instance.onClick(((e: ClickEvent) => { + ColumnImpl(@memo() ((instance: ColumnAttribute): void => { + instance.setColumnOptions(undefined).applyAttributesFinish(); + return; + }), @memo() (() => { + TextImpl(@memo() ((instance: TextAttribute): void => { + instance.setTextOptions((((("Grant") + (this.countDownStartValue))) + ("nuggets to play.")), undefined).applyAttributesFinish(); + return; + }), undefined); + ButtonImpl(@memo() ((instance: ButtonAttribute): void => { + instance.setButtonOptions("+1 - Nuggets in New Game", undefined).onClick(((e: ClickEvent) => { this.countDownStartValue += 1; - })); + })).applyAttributesFinish(); return; - }), "+1 - Nuggets in New Game", undefined, undefined); - Button(@memo() ((instance: ButtonAttribute): void => { - instance.onClick(((e: ClickEvent) => { + }), undefined); + ButtonImpl(@memo() ((instance: ButtonAttribute): void => { + instance.setButtonOptions("-1 - Nuggets in New Game", undefined).onClick(((e: ClickEvent) => { this.countDownStartValue -= 1; - })); + })).applyAttributesFinish(); return; - }), "-1 - Nuggets in New Game", undefined, undefined); + }), undefined); CountDownComponent._instantiateImpl(undefined, (() => { return new CountDownComponent(); }), { 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 643f1955b746eb9274a35b2db1f17e6ed9f6740c..6a45a6bd2f0fbb2636140e250d07fcf77c56848e 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 @@ -40,12 +40,32 @@ const parsedTransform: Plugins = { const expectedScript: string = ` import { _rawfile as _rawfile } from "arkui.component.resources"; +import { ColumnAttribute as ColumnAttribute } from "arkui.component.column"; + import { ImageAnimatorAttribute as ImageAnimatorAttribute } from "arkui.component.imageAnimator"; -import { memo as memo } from "arkui.stateManagement.runtime"; +import { ImageAnimatorImpl as ImageAnimatorImpl } from "arkui.component.imageAnimator"; + +import { SelectAttribute as SelectAttribute } from "arkui.component.select"; + +import { SelectImpl as SelectImpl } from "arkui.component.select"; + +import { TextInputAttribute as TextInputAttribute } from "arkui.component.textInput"; + +import { TextInputImpl as TextInputImpl } from "arkui.component.textInput"; import { ImageAttribute as ImageAttribute } from "arkui.component.image"; +import { ImageImpl as ImageImpl } from "arkui.component.image"; + +import { memo as memo } from "arkui.stateManagement.runtime"; + +import { TextAttribute as TextAttribute } from "arkui.component.text"; + +import { TextImpl as TextImpl } from "arkui.component.text"; + +import { ColumnImpl as ColumnImpl } from "arkui.component.column"; + import { _r as _r } from "arkui.component.resources"; import { LayoutCallback as LayoutCallback } from "arkui.component.customComponent"; @@ -109,40 +129,61 @@ function main() {} } @memo() public build() { - Column(undefined, undefined, @memo() (() => { - Text(undefined, _r(16777216, 10003, "com.example.mock", "entry"), undefined, undefined); - Image(undefined, _rawfile(0, 30000, "com.example.mock", "entry", "app.mock.txt"), undefined, undefined); - TextInput(undefined, { - text: _r(16777220, 10003, "com.example.mock", "entry"), - }, undefined); - Text(undefined, _r(-1, -1, "com.example.mock", "entry", this.str1), undefined, undefined); - Text(undefined, _r(-1, -1, "com.example.mock", "entry", this.str2), undefined, undefined); - Select(undefined, new Array({ - value: "aaa", - icon: _r(16777223, 20000, "com.example.mock", "entry"), - }, { - value: "bbb", - icon: _r(16777223, 20000, "com.example.mock", "entry"), - }, { - value: "ccc", - icon: _r(16777223, 20000, "com.example.mock", "entry"), - }, { - value: "ddd", - icon: _r(16777223, 20000, "com.example.mock", "entry"), + ColumnImpl(@memo() ((instance: ColumnAttribute): void => { + instance.setColumnOptions(undefined).applyAttributesFinish(); + return; + }), @memo() (() => { + TextImpl(@memo() ((instance: TextAttribute): void => { + instance.setTextOptions(_r(16777216, 10003, "com.example.mock", "entry"), undefined).applyAttributesFinish(); + return; }), undefined); - Image(@memo() ((instance: ImageAttribute): void => { - instance.margin(({ + ImageImpl(@memo() ((instance: ImageAttribute): void => { + instance.setImageOptions(_rawfile(0, 30000, "com.example.mock", "entry", "app.mock.txt"), undefined).applyAttributesFinish(); + return; + }), undefined); + TextInputImpl(@memo() ((instance: TextInputAttribute): void => { + instance.setTextInputOptions({ + text: _r(16777220, 10003, "com.example.mock", "entry"), + }).applyAttributesFinish(); + return; + }), undefined); + TextImpl(@memo() ((instance: TextAttribute): void => { + instance.setTextOptions(_r(-1, -1, "com.example.mock", "entry", this.str1), undefined).applyAttributesFinish(); + return; + }), undefined); + TextImpl(@memo() ((instance: TextAttribute): void => { + instance.setTextOptions(_r(-1, -1, "com.example.mock", "entry", this.str2), undefined).applyAttributesFinish(); + return; + }), undefined); + SelectImpl(@memo() ((instance: SelectAttribute): void => { + instance.setSelectOptions(new Array({ + value: "aaa", + icon: _r(16777223, 20000, "com.example.mock", "entry"), + }, { + value: "bbb", + icon: _r(16777223, 20000, "com.example.mock", "entry"), + }, { + value: "ccc", + icon: _r(16777223, 20000, "com.example.mock", "entry"), + }, { + value: "ddd", + icon: _r(16777223, 20000, "com.example.mock", "entry"), + })).applyAttributesFinish(); + return; + }), undefined); + ImageImpl(@memo() ((instance: ImageAttribute): void => { + instance.setImageOptions(_r(16777217, 20000, "com.example.mock", "entry"), undefined).margin(({ top: _r(16777222, 10002, "com.example.mock", "entry"), bottom: _r(16777222, 10002, "com.example.mock", "entry"), - } as Margin)); + } as Margin)).applyAttributesFinish(); return; - }), _r(16777217, 20000, "com.example.mock", "entry"), undefined, undefined); - ImageAnimator(@memo() ((instance: ImageAnimatorAttribute): void => { - instance.images([{ + }), undefined); + ImageAnimatorImpl(@memo() ((instance: ImageAnimatorAttribute): void => { + instance.setImageAnimatorOptions().images([{ src: _r(16777217, 20000, "com.example.mock", "entry"), }, { src: _r(16777225, 20000, "com.example.mock", "entry"), - }]); + }]).applyAttributesFinish(); return; })); })); 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 89b0c4750721f5b34a7d114f845f3b4728471aaa..dc2b6e0fd9a4311a946466255f377ba55aef3dac 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,7 +38,13 @@ const parsedTransform: Plugins = { }; const expectedScript: string = ` +import { ColumnAttribute as ColumnAttribute } from "arkui.component.column"; +import { ImageAttribute as ImageAttribute } from "arkui.component.image"; +import { ImageImpl as ImageImpl } from "arkui.component.image"; import { memo as memo } from "arkui.stateManagement.runtime"; +import { TextAttribute as TextAttribute } from "arkui.component.text"; +import { TextImpl as TextImpl } from "arkui.component.text"; +import { ColumnImpl as ColumnImpl } from "arkui.component.column"; import { _rawfile as _rawfile } from "arkui.component.resources"; import { _r as _r } from "arkui.component.resources"; import { LayoutCallback as LayoutCallback } from "arkui.component.customComponent"; @@ -75,10 +81,22 @@ i = _r(16777216, 10003, "com.example.mock", "entry"); } @memo() public build() { - Column(undefined, undefined, @memo() (() => { - Text(undefined, this.str, undefined, undefined); - Text(undefined, i, undefined, undefined); - Image(undefined, this.icon, undefined, undefined); + ColumnImpl(@memo() ((instance: ColumnAttribute): void => { + instance.setColumnOptions(undefined).applyAttributesFinish(); + return; + }), @memo() (() => { + TextImpl(@memo() ((instance: TextAttribute): void => { + instance.setTextOptions(this.str, undefined).applyAttributesFinish(); + return; + }), undefined); + TextImpl(@memo() ((instance: TextAttribute): void => { + instance.setTextOptions(i, undefined).applyAttributesFinish(); + return; + }), undefined); + ImageImpl(@memo() ((instance: ImageAttribute): void => { + instance.setImageOptions(this.icon, undefined).applyAttributesFinish(); + return; + }), undefined); })); } private constructor() {} diff --git a/arkui-plugins/test/ut/ui-plugins/decorators/reusable/reusable-complex.test.ts b/arkui-plugins/test/ut/ui-plugins/decorators/reusable/reusable-complex.test.ts index e3f98d4159c59c420350875c8627589b1ca50cef..7b9250b8fd3ca8eb92ae574d8303b472a06a4951 100644 --- a/arkui-plugins/test/ut/ui-plugins/decorators/reusable/reusable-complex.test.ts +++ b/arkui-plugins/test/ut/ui-plugins/decorators/reusable/reusable-complex.test.ts @@ -41,15 +41,21 @@ const expectedScript: string = ` import { TextAttribute as TextAttribute } from "arkui.component.text"; +import { TextImpl as TextImpl } from "arkui.component.text"; + import { STATE_MGMT_FACTORY as STATE_MGMT_FACTORY } from "arkui.stateManagement.decorator"; import { IStateDecoratedVariable as IStateDecoratedVariable } from "arkui.stateManagement.decorator"; -import { ButtonAttribute as ButtonAttribute } from "arkui.component.button"; +import { ColumnAttribute as ColumnAttribute } from "arkui.component.column"; import { memo as memo } from "arkui.stateManagement.runtime"; -import { ColumnAttribute as ColumnAttribute } from "arkui.component.column"; +import { ButtonAttribute as ButtonAttribute } from "arkui.component.button"; + +import { ButtonImpl as ButtonImpl } from "arkui.component.button"; + +import { ColumnImpl as ColumnImpl } from "arkui.component.column"; import { NavInterface as NavInterface } from "arkui.UserView"; @@ -105,16 +111,16 @@ class Message { } @memo() public build() { - Column(@memo() ((instance: ColumnAttribute): void => { - instance.height("100%").width("100%"); + ColumnImpl(@memo() ((instance: ColumnAttribute): void => { + instance.setColumnOptions(undefined).height("100%").width("100%").applyAttributesFinish(); return; - }), undefined, @memo() (() => { - Button(@memo() ((instance: ButtonAttribute): void => { - instance.fontSize(30).fontWeight(FontWeight.Bold).onClick(((e: ClickEvent) => { + }), @memo() (() => { + ButtonImpl(@memo() ((instance: ButtonAttribute): void => { + instance.setButtonOptions("Hello", undefined).fontSize(30).fontWeight(FontWeight.Bold).onClick(((e: ClickEvent) => { this.display = !(this.display); - })); + })).applyAttributesFinish(); return; - }), "Hello", undefined, undefined); + }), undefined); if (this.display) { Child._instantiateImpl(undefined, (() => { return new Child(); @@ -159,14 +165,14 @@ class Message { } @memo() public build() { - Column(@memo() ((instance: ColumnAttribute): void => { - instance.borderWidth(1).height(100); + ColumnImpl(@memo() ((instance: ColumnAttribute): void => { + instance.setColumnOptions(undefined).borderWidth(1).height(100).applyAttributesFinish(); return; - }), undefined, @memo() (() => { - Text(@memo() ((instance: TextAttribute): void => { - instance.fontSize(30); + }), @memo() (() => { + TextImpl(@memo() ((instance: TextAttribute): void => { + instance.setTextOptions(this.message.value, undefined).fontSize(30).applyAttributesFinish(); return; - }), this.message.value, undefined, undefined); + }), undefined); })); } diff --git a/arkui-plugins/test/ut/ui-plugins/decorators/state/state-basic-type.test.ts b/arkui-plugins/test/ut/ui-plugins/decorators/state/state-basic-type.test.ts index c47bd027b7b07e0346803f7752b3ae88a41393f6..fa8ae1076a3a12b0c8058c8d1ee0c9daf947059e 100644 --- a/arkui-plugins/test/ut/ui-plugins/decorators/state/state-basic-type.test.ts +++ b/arkui-plugins/test/ut/ui-plugins/decorators/state/state-basic-type.test.ts @@ -167,10 +167,6 @@ function main() {} `; function testParsedAndCheckedTransformer(this: PluginTestContext): void { - console.log("[testParsedAndCheckedTransformer] this: ", this); - console.log("[testParsedAndCheckedTransformer] parseDumpSrc(this.scriptSnapshot ?? ''): ", parseDumpSrc(this.scriptSnapshot ?? '')); - console.log("[testParsedAndCheckedTransformer] parseDumpSrc(expectedScript): ", parseDumpSrc(expectedScript)); - expect(parseDumpSrc(this.scriptSnapshot ?? '')).toBe(parseDumpSrc(expectedScript)); } diff --git a/arkui-plugins/test/ut/ui-plugins/decorators/state/state-to-state.test.ts b/arkui-plugins/test/ut/ui-plugins/decorators/state/state-to-state.test.ts index b470b7a1068dd37d4298a312f3f04ae11dd9263a..cf716891bebd3a4f0f30fe89475ac9aebd0c9052 100644 --- a/arkui-plugins/test/ut/ui-plugins/decorators/state/state-to-state.test.ts +++ b/arkui-plugins/test/ut/ui-plugins/decorators/state/state-to-state.test.ts @@ -38,13 +38,20 @@ const parsedTransform: Plugins = { }; const expectedScript: string = ` +import { TextAttribute as TextAttribute } from "arkui.component.text"; + +import { TextImpl as TextImpl } from "arkui.component.text"; import { STATE_MGMT_FACTORY as STATE_MGMT_FACTORY } from "arkui.stateManagement.decorator"; import { IStateDecoratedVariable as IStateDecoratedVariable } from "arkui.stateManagement.decorator"; +import { ColumnAttribute as ColumnAttribute } from "arkui.component.column"; + import { memo as memo } from "arkui.stateManagement.runtime"; +import { ColumnImpl as ColumnImpl } from "arkui.component.column"; + import { LayoutCallback as LayoutCallback } from "arkui.component.customComponent"; import { CustomComponentV2 as CustomComponentV2 } from "arkui.component.customComponent"; @@ -87,7 +94,10 @@ class Per { } @memo() public build() { - Column(undefined, undefined, @memo() (() => { + ColumnImpl(@memo() ((instance: ColumnAttribute): void => { + instance.setColumnOptions(undefined).applyAttributesFinish(); + return; + }), @memo() (() => { Child._instantiateImpl(undefined, (() => { return new Child(); }), { @@ -119,7 +129,10 @@ class Per { } @memo() public build() { - Text(undefined, this.childVar1.str, undefined, undefined); + TextImpl(@memo() ((instance: TextAttribute): void => { + instance.setTextOptions(this.childVar1.str, undefined).applyAttributesFinish(); + return; + }), undefined); } private constructor() {} diff --git a/arkui-plugins/test/ut/ui-plugins/decorators/storagelink/storagelink-appstorage.test.ts b/arkui-plugins/test/ut/ui-plugins/decorators/storagelink/storagelink-appstorage.test.ts index b6d7d10b2ed230be50ef4305501e1c4c0b77d78e..6544ab5c7c1cb28eab345abbeaeba827bf2a88be 100644 --- a/arkui-plugins/test/ut/ui-plugins/decorators/storagelink/storagelink-appstorage.test.ts +++ b/arkui-plugins/test/ut/ui-plugins/decorators/storagelink/storagelink-appstorage.test.ts @@ -40,8 +40,11 @@ const pluginTester = new PluginTester('test storagelink with appstorage', buildC const expectedScript: string = ` import { STATE_MGMT_FACTORY as STATE_MGMT_FACTORY } from "arkui.stateManagement.decorator"; import { IStorageLinkDecoratedVariable as IStorageLinkDecoratedVariable } from "arkui.stateManagement.decorator"; +import { ColumnAttribute as ColumnAttribute } from "arkui.component.column"; import { memo as memo } from "arkui.stateManagement.runtime"; import { TextAttribute as TextAttribute } from "arkui.component.text"; +import { TextImpl as TextImpl } from "arkui.component.text"; +import { ColumnImpl as ColumnImpl } from "arkui.component.column"; import { NavInterface as NavInterface } from "arkui.UserView"; import { PageLifeCycle as PageLifeCycle } from "arkui.component.customComponent"; import { EntryPoint as EntryPoint } from "arkui.UserView"; @@ -100,19 +103,22 @@ class Data { } @memo() public build() { - Column(undefined, undefined, @memo() (() => { - Text(@memo() ((instance: TextAttribute): void => { - instance.onClick(((e: ClickEvent) => { + ColumnImpl(@memo() ((instance: ColumnAttribute): void => { + instance.setColumnOptions(undefined).applyAttributesFinish(); + return; + }), @memo() (() => { + TextImpl(@memo() ((instance: TextAttribute): void => { + instance.setTextOptions(\`From AppStorage \${this.storageLink}\`, undefined).onClick(((e: ClickEvent) => { this.storageLink += 1; - })); + })).applyAttributesFinish(); return; - }), \`From AppStorage \${this.storageLink}\`, undefined, undefined); - Text(@memo() ((instance: TextAttribute): void => { - instance.onClick(((e: ClickEvent) => { + }), undefined); + TextImpl(@memo() ((instance: TextAttribute): void => { + instance.setTextOptions(\`From AppStorage \${this.storageLinkObject.code}\`, undefined).onClick(((e: ClickEvent) => { this.storageLinkObject.code += 1; - })); + })).applyAttributesFinish(); return; - }), \`From AppStorage \${this.storageLinkObject.code}\`, undefined, undefined); + }), undefined); })); } diff --git a/arkui-plugins/test/ut/ui-plugins/decorators/storageprop/storageprop-appstorage.test.ts b/arkui-plugins/test/ut/ui-plugins/decorators/storageprop/storageprop-appstorage.test.ts index cbd0b0844779a8d64073f95dc1899f5b045a754a..d048e1f0c83bfdc88059a4b6052f7696e13c65cd 100644 --- a/arkui-plugins/test/ut/ui-plugins/decorators/storageprop/storageprop-appstorage.test.ts +++ b/arkui-plugins/test/ut/ui-plugins/decorators/storageprop/storageprop-appstorage.test.ts @@ -42,10 +42,16 @@ import { STATE_MGMT_FACTORY as STATE_MGMT_FACTORY } from "arkui.stateManagement. import { IStoragePropRefDecoratedVariable as IStoragePropRefDecoratedVariable } from "arkui.stateManagement.decorator"; +import { ColumnAttribute as ColumnAttribute } from "arkui.component.column"; + import { memo as memo } from "arkui.stateManagement.runtime"; import { TextAttribute as TextAttribute } from "arkui.component.text"; +import { TextImpl as TextImpl } from "arkui.component.text"; + +import { ColumnImpl as ColumnImpl } from "arkui.component.column"; + import { NavInterface as NavInterface } from "arkui.UserView"; import { PageLifeCycle as PageLifeCycle } from "arkui.component.customComponent"; @@ -113,19 +119,22 @@ class Data { } @memo() public build() { - Column(undefined, undefined, @memo() (() => { - Text(@memo() ((instance: TextAttribute): void => { - instance.onClick(((e: ClickEvent) => { + ColumnImpl(@memo() ((instance: ColumnAttribute): void => { + instance.setColumnOptions(undefined).applyAttributesFinish(); + return; + }), @memo() (() => { + TextImpl(@memo() ((instance: TextAttribute): void => { + instance.setTextOptions(\`From AppStorage \${this.storageProp}\`, undefined).onClick(((e: ClickEvent) => { this.storageProp += 1; - })); + })).applyAttributesFinish(); return; - }), \`From AppStorage \${this.storageProp}\`, undefined, undefined); - Text(@memo() ((instance: TextAttribute): void => { - instance.onClick(((e: ClickEvent) => { + }), undefined); + TextImpl(@memo() ((instance: TextAttribute): void => { + instance.setTextOptions(\`From AppStorage \${this.storagePropObject.code}\`, undefined).onClick(((e: ClickEvent) => { this.storagePropObject.code += 1; - })); + })).applyAttributesFinish(); return; - }), \`From AppStorage \${this.storagePropObject.code}\`, undefined, undefined); + }), 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 9857c430b120911c767beab00edac722431433c1..5c28732ef686a0de511ea7be0dcc4d9dc569f2db 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 @@ -56,8 +56,12 @@ import { IPropDecoratedVariable as IPropDecoratedVariable } from "arkui.stateMan import { IStateDecoratedVariable as IStateDecoratedVariable } from "arkui.stateManagement.decorator"; +import { ColumnAttribute as ColumnAttribute } from "arkui.component.column"; + import { memo as memo } from "arkui.stateManagement.runtime"; +import { ColumnImpl as ColumnImpl } from "arkui.component.column"; + import { IObservedObject as IObservedObject } from "arkui.stateManagement.decorator"; import { OBSERVE as OBSERVE } from "arkui.stateManagement.decorator"; @@ -272,7 +276,10 @@ __EntryWrapper.RegisterNamedRouter("", new __EntryWrapper(), ({ public ProvideOnChange(propName: string) {} @memo() public build() { - Column(undefined, undefined, @memo() (() => { + ColumnImpl(@memo() ((instance: ColumnAttribute): void => { + instance.setColumnOptions(undefined).applyAttributesFinish(); + return; + }), @memo() (() => { Child._instantiateImpl(undefined, (() => { return new Child(); }), undefined, undefined, undefined); diff --git a/arkui-plugins/test/ut/ui-plugins/double-dollar/double-dollar-griditem.test.ts b/arkui-plugins/test/ut/ui-plugins/double-dollar/double-dollar-griditem.test.ts index 74d90e24922360f2d60d18824b28ddceb37994a4..4463a00305904a9b63c7e362de3c5c6d0df65479 100644 --- a/arkui-plugins/test/ut/ui-plugins/double-dollar/double-dollar-griditem.test.ts +++ b/arkui-plugins/test/ut/ui-plugins/double-dollar/double-dollar-griditem.test.ts @@ -42,12 +42,26 @@ import { STATE_MGMT_FACTORY as STATE_MGMT_FACTORY } from "arkui.stateManagement. import { IStateDecoratedVariable as IStateDecoratedVariable } from "arkui.stateManagement.decorator"; -import { memo as memo } from "arkui.stateManagement.runtime"; +import { ColumnAttribute as ColumnAttribute } from "arkui.component.column"; + +import { GridAttribute as GridAttribute } from "arkui.component.grid"; import { GridItemAttribute as GridItemAttribute } from "arkui.component.gridItem"; +import { memo as memo } from "arkui.stateManagement.runtime"; + +import { TextAttribute as TextAttribute } from "arkui.component.text"; + +import { TextImpl as TextImpl } from "arkui.component.text"; + import { Bindable as Bindable } from "arkui.component.common"; +import { GridItemImpl as GridItemImpl } from "arkui.component.gridItem"; + +import { GridImpl as GridImpl } from "arkui.component.grid"; + +import { ColumnImpl as ColumnImpl } from "arkui.component.column"; + import { NavInterface as NavInterface } from "arkui.UserView"; import { PageLifeCycle as PageLifeCycle } from "arkui.component.customComponent"; @@ -97,29 +111,41 @@ __EntryWrapper.RegisterNamedRouter("", new __EntryWrapper(), ({ } @memo() public build() { - Column(undefined, undefined, @memo() (() => { - Grid(undefined, undefined, undefined, @memo() (() => { - GridItem(@memo() ((instance: GridItemAttribute): void => { - instance.selected(({ + ColumnImpl(@memo() ((instance: ColumnAttribute): void => { + instance.setColumnOptions(undefined).applyAttributesFinish(); + return; + }), @memo() (() => { + GridImpl(@memo() ((instance: GridAttribute): void => { + instance.setGridOptions(undefined, undefined).applyAttributesFinish(); + return; + }), @memo() (() => { + GridItemImpl(@memo() ((instance: GridItemAttribute): void => { + instance.setGridItemOptions(undefined).selected(({ value: this.boo, onChange: ((value: boolean) => { this.boo = value; }), - } as Bindable)); + } as Bindable)).applyAttributesFinish(); return; - }), undefined, @memo() (() => { - Text(undefined, "nihao", undefined, undefined); + }), @memo() (() => { + TextImpl(@memo() ((instance: TextAttribute): void => { + instance.setTextOptions("nihao", undefined).applyAttributesFinish(); + return; + }), undefined); })); - GridItem(@memo() ((instance: GridItemAttribute): void => { - instance.selected(({ + GridItemImpl(@memo() ((instance: GridItemAttribute): void => { + instance.setGridItemOptions(undefined).selected(({ value: c, onChange: ((value: boolean) => { c = value; }), - } as Bindable)); + } as Bindable)).applyAttributesFinish(); return; - }), undefined, @memo() (() => { - Text(undefined, "nihao", undefined, undefined); + }), @memo() (() => { + TextImpl(@memo() ((instance: TextAttribute): void => { + instance.setTextOptions("nihao", undefined).applyAttributesFinish(); + return; + }), undefined); })); })); })); diff --git a/arkui-plugins/test/ut/ui-plugins/imports/import-struct.test.ts b/arkui-plugins/test/ut/ui-plugins/imports/import-struct.test.ts index dc71b2bd38dd8f8738bd020bc1aa912cc1c03ab1..0e9102f0838ef83406029124e162811852fc594a 100644 --- a/arkui-plugins/test/ut/ui-plugins/imports/import-struct.test.ts +++ b/arkui-plugins/test/ut/ui-plugins/imports/import-struct.test.ts @@ -75,6 +75,10 @@ const expectedCheckedScript: string = ` import { memo as memo } from "arkui.stateManagement.runtime"; +import { TextAttribute as TextAttribute } from "arkui.component.text"; + +import { TextImpl as TextImpl } from "arkui.component.text"; + import { LayoutCallback as LayoutCallback } from "arkui.component.customComponent"; import { CustomComponentV2 as CustomComponentV2 } from "arkui.component.customComponent"; @@ -106,7 +110,10 @@ function main() {} SimpleStruct._instantiateImpl(undefined, (() => { return new SimpleStruct(); }), undefined, undefined, @memo() (() => { - Text(undefined, "a", undefined, undefined); + TextImpl(@memo() ((instance: TextAttribute): void => { + instance.setTextOptions("a", undefined).applyAttributesFinish(); + return; + }), undefined); })); } diff --git a/arkui-plugins/test/ut/ui-plugins/imports/kit-import.test.ts b/arkui-plugins/test/ut/ui-plugins/imports/kit-import.test.ts index 53bb01be8d98fcdb61429fae034b76a6f55881e0..7eabfe3d60661a3038e8c1b11ec677fa3a138c61 100644 --- a/arkui-plugins/test/ut/ui-plugins/imports/kit-import.test.ts +++ b/arkui-plugins/test/ut/ui-plugins/imports/kit-import.test.ts @@ -109,12 +109,20 @@ import { STATE_MGMT_FACTORY as STATE_MGMT_FACTORY } from "arkui.stateManagement. import { IStateDecoratedVariable as IStateDecoratedVariable } from "arkui.stateManagement.decorator"; +import { ColumnAttribute as ColumnAttribute } from "arkui.component.column"; + import { TextAttribute as TextAttribute } from "arkui.component.text"; +import { TextImpl as TextImpl } from "arkui.component.text"; + import { memo as memo } from "arkui.stateManagement.runtime"; import { ButtonAttribute as ButtonAttribute } from "arkui.component.button"; +import { ButtonImpl as ButtonImpl } from "arkui.component.button"; + +import { ColumnImpl as ColumnImpl } from "arkui.component.column"; + import { NavInterface as NavInterface } from "arkui.UserView"; import { PageLifeCycle as PageLifeCycle } from "arkui.component.customComponent"; @@ -182,15 +190,18 @@ __EntryWrapper.RegisterNamedRouter("", new __EntryWrapper(), ({ } @memo() public build() { - Column(undefined, undefined, @memo() (() => { - Button(@memo() ((instance: ButtonAttribute): void => { - instance.onClick(((e: ClickEvent) => {})); + ColumnImpl(@memo() ((instance: ColumnAttribute): void => { + instance.setColumnOptions(undefined).applyAttributesFinish(); + return; + }), @memo() (() => { + ButtonImpl(@memo() ((instance: ButtonAttribute): void => { + instance.setButtonOptions("button", undefined).onClick(((e: ClickEvent) => {})).applyAttributesFinish(); return; - }), "button", undefined, undefined); - Text(@memo() ((instance: TextAttribute): void => { - instance.fontSize(20); + }), undefined); + TextImpl(@memo() ((instance: TextAttribute): void => { + instance.setTextOptions("text", undefined).fontSize(20).applyAttributesFinish(); return; - }), "text", undefined, undefined); + }), undefined); })); } diff --git a/arkui-plugins/test/ut/ui-plugins/wrap-builder/init-with-builder.test.ts b/arkui-plugins/test/ut/ui-plugins/wrap-builder/init-with-builder.test.ts index b88e465bd50c76f361cacdb49b8baa89fc825673..b7b786f6e88fcac9ed0e8168255cfce4ce13748f 100644 --- a/arkui-plugins/test/ut/ui-plugins/wrap-builder/init-with-builder.test.ts +++ b/arkui-plugins/test/ut/ui-plugins/wrap-builder/init-with-builder.test.ts @@ -38,8 +38,11 @@ const parsedTransform: Plugins = { }; const expectedUIScript: string = ` +import { ColumnAttribute as ColumnAttribute } from "arkui.component.column"; +import { ColumnImpl as ColumnImpl } from "arkui.component.column"; import { memo as memo } from "arkui.stateManagement.runtime"; import { TextAttribute as TextAttribute } from "arkui.component.text"; +import { TextImpl as TextImpl } from "arkui.component.text"; import { LayoutCallback as LayoutCallback } from "arkui.component.customComponent"; import { CustomComponentV2 as CustomComponentV2 } from "arkui.component.customComponent"; import { CustomComponent as CustomComponent } from "arkui.component.customComponent"; @@ -51,10 +54,10 @@ function main() {} globalBuilder = wrapBuilder(myBuilder); @memo() function myBuilder(value: string, size: number) { - Text(@memo() ((instance: TextAttribute): void => { - instance.fontSize(size); + TextImpl(@memo() ((instance: TextAttribute): void => { + instance.setTextOptions(value, undefined).fontSize(size).applyAttributesFinish(); return; - }), value, undefined, undefined); + }), undefined); } @@ -66,7 +69,10 @@ globalBuilder = wrapBuilder(myBuilder); public __updateStruct(initializers: (__Options_ImportStruct | undefined)): void {} @memo() public build() { - Column(undefined, undefined, @memo() (() => { + ColumnImpl(@memo() ((instance: ColumnAttribute): void => { + instance.setColumnOptions(undefined).applyAttributesFinish(); + return; + }), @memo() (() => { globalBuilder.builder("hello", 50); })); } @@ -88,10 +94,16 @@ const expectedMemoScript: string = ` import { __memo_context_type as __memo_context_type, __memo_id_type as __memo_id_type } from "arkui.stateManagement.runtime"; +import { ColumnAttribute as ColumnAttribute } from "arkui.component.column"; + +import { ColumnImpl as ColumnImpl } from "arkui.component.column"; + import { memo as memo } from "arkui.stateManagement.runtime"; import { TextAttribute as TextAttribute } from "arkui.component.text"; +import { TextImpl as TextImpl } from "arkui.component.text"; + import { LayoutCallback as LayoutCallback } from "arkui.component.customComponent"; import { CustomComponentV2 as CustomComponentV2 } from "arkui.component.customComponent"; @@ -112,19 +124,19 @@ globalBuilder = wrapBuilder(myBuilder); __memo_scope.cached; return; } - Text(__memo_context, ((__memo_id) + (175145513)), @memo() ((__memo_context: __memo_context_type, __memo_id: __memo_id_type, instance: TextAttribute): void => { + TextImpl(__memo_context, ((__memo_id) + (175145513)), @memo() ((__memo_context: __memo_context_type, __memo_id: __memo_id_type, instance: TextAttribute): void => { const __memo_scope = __memo_context.scope(((__memo_id) + (47330804)), 1); const __memo_parameter_instance = __memo_scope.param(0, instance); if (__memo_scope.unchanged) { __memo_scope.cached; return; } - __memo_parameter_instance.value.fontSize(__memo_parameter_size.value); + __memo_parameter_instance.value.setTextOptions(__memo_parameter_value.value, undefined).fontSize(__memo_parameter_size.value).applyAttributesFinish(); { __memo_scope.recache(); return; } - }), __memo_parameter_value.value, undefined, undefined); + }), undefined); { __memo_scope.recache(); return; @@ -145,7 +157,19 @@ globalBuilder = wrapBuilder(myBuilder); __memo_scope.cached; return; } - Column(__memo_context, ((__memo_id) + (213104625)), undefined, undefined, @memo() ((__memo_context: __memo_context_type, __memo_id: __memo_id_type) => { + ColumnImpl(__memo_context, ((__memo_id) + (213104625)), @memo() ((__memo_context: __memo_context_type, __memo_id: __memo_id_type, instance: ColumnAttribute): void => { + const __memo_scope = __memo_context.scope(((__memo_id) + ()), 1); + const __memo_parameter_instance = __memo_scope.param(0, instance); + if (__memo_scope.unchanged) { + __memo_scope.cached; + return; + } + __memo_parameter_instance.value.setColumnOptions(undefined).applyAttributesFinish(); + { + __memo_scope.recache(); + return; + } + }), @memo() ((__memo_context: __memo_context_type, __memo_id: __memo_id_type) => { const __memo_scope = __memo_context.scope(((__memo_id) + (211301233)), 0); if (__memo_scope.unchanged) { __memo_scope.cached; diff --git a/arkui-plugins/test/ut/ui-plugins/wrap-builder/wrap-builder-in-ui.test.ts b/arkui-plugins/test/ut/ui-plugins/wrap-builder/wrap-builder-in-ui.test.ts index 42bb161d17100424a3e0dbfca01bd02e8ac88537..45c1a805e0f52d7ebf8f7bb0138eb072434e9b17 100644 --- a/arkui-plugins/test/ut/ui-plugins/wrap-builder/wrap-builder-in-ui.test.ts +++ b/arkui-plugins/test/ut/ui-plugins/wrap-builder/wrap-builder-in-ui.test.ts @@ -38,10 +38,16 @@ const parsedTransform: Plugins = { }; const expectedUIScript: string = ` +import { ColumnAttribute as ColumnAttribute } from "arkui.component.column"; + +import { ColumnImpl as ColumnImpl } from "arkui.component.column"; + import { memo as memo } from "arkui.stateManagement.runtime"; import { TextAttribute as TextAttribute } from "arkui.component.text"; +import { TextImpl as TextImpl } from "arkui.component.text"; + import { LayoutCallback as LayoutCallback } from "arkui.component.customComponent"; import { CustomComponentV2 as CustomComponentV2 } from "arkui.component.customComponent"; @@ -56,17 +62,17 @@ function main() {} @memo() function myBuilder(value: string, size: number) { - Text(@memo() ((instance: TextAttribute): void => { - instance.fontSize(size); + TextImpl(@memo() ((instance: TextAttribute): void => { + instance.setTextOptions(value, undefined).fontSize(size).applyAttributesFinish(); return; - }), value, undefined, undefined); + }), undefined); } @memo() function yourBuilder(value: string, size: number) { - Text(@memo() ((instance: TextAttribute): void => { - instance.fontSize(size); + TextImpl(@memo() ((instance: TextAttribute): void => { + instance.setTextOptions(value, undefined).fontSize(size).applyAttributesFinish(); return; - }), value, undefined, undefined); + }), undefined); } @@ -86,7 +92,10 @@ function main() {} } @memo() public build() { - Column(undefined, undefined, @memo() (() => { + ColumnImpl(@memo() ((instance: ColumnAttribute): void => { + instance.setColumnOptions(undefined).applyAttributesFinish(); + return; + }), @memo() (() => { this.testBuilder(); })); } @@ -107,10 +116,16 @@ function testUITransformer(this: PluginTestContext): void { const expectedMemoScript: string = ` import { __memo_context_type as __memo_context_type, __memo_id_type as __memo_id_type } from "arkui.stateManagement.runtime"; +import { ColumnAttribute as ColumnAttribute } from "arkui.component.column"; + +import { ColumnImpl as ColumnImpl } from "arkui.component.column"; + import { memo as memo } from "arkui.stateManagement.runtime"; import { TextAttribute as TextAttribute } from "arkui.component.text"; +import { TextImpl as TextImpl } from "arkui.component.text"; + import { LayoutCallback as LayoutCallback } from "arkui.component.customComponent"; import { CustomComponentV2 as CustomComponentV2 } from "arkui.component.customComponent"; @@ -131,19 +146,19 @@ function main() {} __memo_scope.cached; return; } - Text(__memo_context, ((__memo_id) + (175145513)), @memo() ((__memo_context: __memo_context_type, __memo_id: __memo_id_type, instance: TextAttribute): void => { + TextImpl(__memo_context, ((__memo_id) + (175145513)), @memo() ((__memo_context: __memo_context_type, __memo_id: __memo_id_type, instance: TextAttribute): void => { const __memo_scope = __memo_context.scope(((__memo_id) + (47330804)), 1); const __memo_parameter_instance = __memo_scope.param(0, instance); if (__memo_scope.unchanged) { __memo_scope.cached; return; } - __memo_parameter_instance.value.fontSize(__memo_parameter_size.value); + __memo_parameter_instance.value.setTextOptions(__memo_parameter_value.value, undefined).fontSize(__memo_parameter_size.value).applyAttributesFinish(); { __memo_scope.recache(); return; } - }), __memo_parameter_value.value, undefined, undefined); + }), undefined); { __memo_scope.recache(); return; @@ -157,19 +172,19 @@ function main() {} __memo_scope.cached; return; } - Text(__memo_context, ((__memo_id) + (211301233)), @memo() ((__memo_context: __memo_context_type, __memo_id: __memo_id_type, instance: TextAttribute): void => { + TextImpl(__memo_context, ((__memo_id) + (211301233)), @memo() ((__memo_context: __memo_context_type, __memo_id: __memo_id_type, instance: TextAttribute): void => { const __memo_scope = __memo_context.scope(((__memo_id) + (137225318)), 1); const __memo_parameter_instance = __memo_scope.param(0, instance); if (__memo_scope.unchanged) { __memo_scope.cached; return; } - __memo_parameter_instance.value.fontSize(__memo_parameter_size.value); + __memo_parameter_instance.value.setTextOptions(__memo_parameter_value.value, undefined).fontSize(__memo_parameter_size.value).applyAttributesFinish(); { __memo_scope.recache(); return; } - }), __memo_parameter_value.value, undefined, undefined); + }), undefined); { __memo_scope.recache(); return; @@ -217,7 +232,19 @@ function main() {} __memo_scope.cached; return; } - Column(__memo_context, ((__memo_id) + (54078781)), undefined, undefined, @memo() ((__memo_context: __memo_context_type, __memo_id: __memo_id_type) => { + ColumnImpl(__memo_context, ((__memo_id) + (54078781)), @memo() ((__memo_context: __memo_context_type, __memo_id: __memo_id_type, instance: ColumnAttribute): void => { + const __memo_scope = __memo_context.scope(((__memo_id) + ()), 1); + const __memo_parameter_instance = __memo_scope.param(0, instance); + if (__memo_scope.unchanged) { + __memo_scope.cached; + return; + } + __memo_parameter_instance.value.setColumnOptions(undefined).applyAttributesFinish(); + { + __memo_scope.recache(); + return; + } + }), @memo() ((__memo_context: __memo_context_type, __memo_id: __memo_id_type) => { const __memo_scope = __memo_context.scope(((__memo_id) + (213687742)), 0); if (__memo_scope.unchanged) { __memo_scope.cached; diff --git a/arkui-plugins/test/ut/ui-plugins/wrap-builder/wrap-builder-with-lambda.test.ts b/arkui-plugins/test/ut/ui-plugins/wrap-builder/wrap-builder-with-lambda.test.ts index caa6e8154b579a1a1d1551c133bb8b15b241d591..06ce39ccfd963dfbb008f7481610abb748ac849e 100644 --- a/arkui-plugins/test/ut/ui-plugins/wrap-builder/wrap-builder-with-lambda.test.ts +++ b/arkui-plugins/test/ut/ui-plugins/wrap-builder/wrap-builder-with-lambda.test.ts @@ -43,6 +43,8 @@ import { IStateDecoratedVariable as IStateDecoratedVariable } from "arkui.stateM import { ButtonAttribute as ButtonAttribute } from "arkui.component.button"; +import { ButtonImpl as ButtonImpl } from "arkui.component.button"; + import { IObservedObject as IObservedObject } from "arkui.stateManagement.decorator"; import { OBSERVE as OBSERVE } from "arkui.stateManagement.decorator"; @@ -57,8 +59,16 @@ import { ISubscribedWatches as ISubscribedWatches } from "arkui.stateManagement. import { STATE_MGMT_FACTORY as STATE_MGMT_FACTORY } from "arkui.stateManagement.decorator"; +import { ColumnAttribute as ColumnAttribute } from "arkui.component.column"; + import { memo as memo } from "arkui.stateManagement.runtime"; +import { TextAttribute as TextAttribute } from "arkui.component.text"; + +import { TextImpl as TextImpl } from "arkui.component.text"; + +import { ColumnImpl as ColumnImpl } from "arkui.component.column"; + import { LayoutCallback as LayoutCallback } from "arkui.component.customComponent"; import { CustomComponentV2 as CustomComponentV2 } from "arkui.component.customComponent"; @@ -77,8 +87,14 @@ function main() {} @memo() function overBuilder(param: (()=> Tmp)) { - Column(undefined, undefined, @memo() (() => { - Text(undefined, \`wrapBuildervalue:\${param().paramA2}\`, undefined, undefined); + ColumnImpl(@memo() ((instance: ColumnAttribute): void => { + instance.setColumnOptions(undefined).applyAttributesFinish(); + return; + }), @memo() (() => { + TextImpl(@memo() ((instance: TextAttribute): void => { + instance.setTextOptions(\`wrapBuildervalue:\${param().paramA2}\`, undefined).applyAttributesFinish(); + return; + }), undefined); })); } @@ -152,18 +168,21 @@ function main() {} } @memo() public build() { - Column(undefined, undefined, @memo() (() => { + ColumnImpl(@memo() ((instance: ColumnAttribute): void => { + instance.setColumnOptions(undefined).applyAttributesFinish(); + return; + }), @memo() (() => { wBuilder.builder((() => { return { paramA2: this.label.paramA2, }; })); - Button(@memo() ((instance: ButtonAttribute): void => { - instance.onClick(((e: ClickEvent) => { + ButtonImpl(@memo() ((instance: ButtonAttribute): void => { + instance.setButtonOptions("Click me", undefined).onClick(((e: ClickEvent) => { this.label.paramA2 = "ArkUI"; - })); + })).applyAttributesFinish(); return; - }), "Click me", undefined, undefined); + }), undefined); })); } @@ -194,6 +213,8 @@ import { IStateDecoratedVariable as IStateDecoratedVariable } from "arkui.stateM import { ButtonAttribute as ButtonAttribute } from "arkui.component.button"; +import { ButtonImpl as ButtonImpl } from "arkui.component.button"; + import { IObservedObject as IObservedObject } from "arkui.stateManagement.decorator"; import { OBSERVE as OBSERVE } from "arkui.stateManagement.decorator"; @@ -208,8 +229,16 @@ import { ISubscribedWatches as ISubscribedWatches } from "arkui.stateManagement. import { STATE_MGMT_FACTORY as STATE_MGMT_FACTORY } from "arkui.stateManagement.decorator"; +import { ColumnAttribute as ColumnAttribute } from "arkui.component.column"; + import { memo as memo } from "arkui.stateManagement.runtime"; +import { TextAttribute as TextAttribute } from "arkui.component.text"; + +import { TextImpl as TextImpl } from "arkui.component.text"; + +import { ColumnImpl as ColumnImpl } from "arkui.component.column"; + import { LayoutCallback as LayoutCallback } from "arkui.component.customComponent"; import { CustomComponentV2 as CustomComponentV2 } from "arkui.component.customComponent"; @@ -234,13 +263,37 @@ function main() {} __memo_scope.cached; return; } - Column(__memo_context, ((__memo_id) + (241913892)), undefined, undefined, @memo() ((__memo_context: __memo_context_type, __memo_id: __memo_id_type) => { + ColumnImpl(__memo_context, ((__memo_id) + (241913892)), @memo() ((__memo_context: __memo_context_type, __memo_id: __memo_id_type, instance: ColumnAttribute): void => { + const __memo_scope = __memo_context.scope(((__memo_id) + ()), 1); + const __memo_parameter_instance = __memo_scope.param(0, instance); + if (__memo_scope.unchanged) { + __memo_scope.cached; + return; + } + __memo_parameter_instance.value.setColumnOptions(undefined).applyAttributesFinish(); + { + __memo_scope.recache(); + return; + } + }), @memo() ((__memo_context: __memo_context_type, __memo_id: __memo_id_type) => { const __memo_scope = __memo_context.scope(((__memo_id) + (175145513)), 0); if (__memo_scope.unchanged) { __memo_scope.cached; return; } - Text(__memo_context, ((__memo_id) + (47330804)), undefined, \`wrapBuildervalue:\${__memo_parameter_param.value().paramA2}\`, undefined, undefined); + TextImpl(__memo_context, ((__memo_id) + (47330804)), @memo() ((__memo_context: __memo_context_type, __memo_id: __memo_id_type, instance: TextAttribute): void => { + const __memo_scope = __memo_context.scope(((__memo_id) + ()), 1); + const __memo_parameter_instance = __memo_scope.param(0, instance); + if (__memo_scope.unchanged) { + __memo_scope.cached; + return; + } + __memo_parameter_instance.value.setTextOptions(\`wrapBuildervalue:\${__memo_parameter_param.value().paramA2}\`, undefined).applyAttributesFinish(); + { + __memo_scope.recache(); + return; + } + }), undefined); { __memo_scope.recache(); return; @@ -327,7 +380,19 @@ function main() {} __memo_scope.cached; return; } - Column(__memo_context, ((__memo_id) + (218979098)), undefined, undefined, @memo() ((__memo_context: __memo_context_type, __memo_id: __memo_id_type) => { + ColumnImpl(__memo_context, ((__memo_id) + (218979098)), @memo() ((__memo_context: __memo_context_type, __memo_id: __memo_id_type, instance: ColumnAttribute): void => { + const __memo_scope = __memo_context.scope(((__memo_id) + ()), 1); + const __memo_parameter_instance = __memo_scope.param(0, instance); + if (__memo_scope.unchanged) { + __memo_scope.cached; + return; + } + __memo_parameter_instance.value.setColumnOptions(undefined).applyAttributesFinish(); + { + __memo_scope.recache(); + return; + } + }), @memo() ((__memo_context: __memo_context_type, __memo_id: __memo_id_type) => { const __memo_scope = __memo_context.scope(((__memo_id) + (76711614)), 0); if (__memo_scope.unchanged) { __memo_scope.cached; @@ -338,21 +403,21 @@ function main() {} paramA2: this.label.paramA2, }; })); - Button(__memo_context, ((__memo_id) + (46726221)), @memo() ((__memo_context: __memo_context_type, __memo_id: __memo_id_type, instance: ButtonAttribute): void => { + ButtonImpl(__memo_context, ((__memo_id) + (46726221)), @memo() ((__memo_context: __memo_context_type, __memo_id: __memo_id_type, instance: ButtonAttribute): void => { const __memo_scope = __memo_context.scope(((__memo_id) + (213104625)), 1); const __memo_parameter_instance = __memo_scope.param(0, instance); if (__memo_scope.unchanged) { __memo_scope.cached; return; } - __memo_parameter_instance.value.onClick(((e: ClickEvent) => { + __memo_parameter_instance.value.setButtonOptions("Click me", undefined).onClick(((e: ClickEvent) => { this.label.paramA2 = "ArkUI"; - })); + })).applyAttributesFinish(); { __memo_scope.recache(); return; } - }), "Click me", undefined, undefined); + }), undefined); { __memo_scope.recache(); return; diff --git a/arkui-plugins/ui-plugins/builder-lambda-translators/factory.ts b/arkui-plugins/ui-plugins/builder-lambda-translators/factory.ts index 4aede630988609c741f39ea51db5b1e189fee1d8..db16f4359fcb96ea89d274257d2e451ce2268324 100644 --- a/arkui-plugins/ui-plugins/builder-lambda-translators/factory.ts +++ b/arkui-plugins/ui-plugins/builder-lambda-translators/factory.ts @@ -44,12 +44,26 @@ import { BuilderLambdaSecondLastArgInfo, buildSecondLastArgInfo, checkIsSpecialComponentAttributeFromType, + ComponentAttributeCache, + ComponentRecord, + getDeclaredSetAttribtueMethodName, + BuilderLambdaStyleBodyInfo, + checkIsTrailingLambdaInLastParam, + getTransformedComponentName, } from './utils'; import { isDecoratorIntrinsicAnnotation } from '../property-translators/utils'; import { factory as PropertyFactory } from '../property-translators/factory'; +import { factory as TypeFactory } from '../type-translators/factory'; +import { factory as UIFactory } from '../ui-factory'; import { AnimationNames, BindableDecl, DecoratorIntrinsicNames, DecoratorNames } from '../../common/predefines'; import { ImportCollector } from '../../common/import-collector'; -import { addMemoAnnotation, collectMemoableInfoInParameter } from '../../collectors/memo-collectors/utils'; +import { + addMemoAnnotation, + checkIsMemoFromMemoableInfo, + collectMemoableInfoInParameter, +} from '../../collectors/memo-collectors/utils'; +import { TypeRecord } from '../../collectors/utils/collect-types'; +import { StyleInternalsVisitor } from './style-internals-visitor'; export class factory { /** @@ -59,14 +73,11 @@ export class factory { node: arkts.MethodDefinition, prefixArgs: arkts.ETSParameterExpression[], newAnno: arkts.AnnotationUsage[], - newName: string | undefined, - externalSourceName?: string + newName: string | undefined ): arkts.MethodDefinition { const func: arkts.ScriptFunction = node.scriptFunction; - let newParams: arkts.Expression[] = []; - if (func.params.length > 0) { - newParams.push(...prefixArgs, ...func.params); - } + const isFunctionCall: boolean = node.name.name !== BuilderLambdaNames.ORIGIN_METHOD_NAME; + const newParams: arkts.Expression[] = [...prefixArgs, ...func.params]; const updateFunc = arkts.factory .updateScriptFunction( func, @@ -86,7 +97,7 @@ export class factory { node, node.kind, arkts.factory.updateIdentifier(node.name, newName ?? node.name.name), - node.name.name === BuilderLambdaNames.ORIGIN_METHOD_NAME ? addMemoAnnotation(updateFunc) : updateFunc, + isFunctionCall ? updateFunc : addMemoAnnotation(updateFunc), node.modifiers, false ); @@ -158,6 +169,40 @@ export class factory { } } + /** + * add `instance.()` call as the initial style argument body for components. + * The initial style argument body is `undefined` for custom components. + */ + static createInitLambdaBody(declInfo: BuilderLambdaDeclInfo): BuilderLambdaStyleBodyInfo { + const { name, isFunctionCall, hasReceiver } = declInfo; + const lambdaBodyInfo: BuilderLambdaStyleBodyInfo = { lambdaBody: undefined, initCallPtr: undefined }; + if (!isFunctionCall) { + return lambdaBodyInfo; + } + let lambdaBody: arkts.Identifier | arkts.CallExpression = arkts.factory.createIdentifier( + BuilderLambdaNames.STYLE_ARROW_PARAM_NAME + ); + arkts.NodeCache.getInstance().collect(lambdaBody); + const methodName = arkts.factory.createIdentifier(getDeclaredSetAttribtueMethodName(name)); + if (!hasReceiver) { + lambdaBodyInfo.lambdaBody = arkts.factory.createCallExpression( + arkts.factory.createMemberExpression( + lambdaBody, + methodName, + arkts.Es2pandaMemberExpressionKind.MEMBER_EXPRESSION_KIND_PROPERTY_ACCESS, + false, + false + ), + undefined, + [] + ); + } else { + lambdaBodyInfo.lambdaBody = arkts.factory.createCallExpression(methodName, undefined, [lambdaBody]); + } + lambdaBodyInfo.initCallPtr = lambdaBodyInfo.lambdaBody.peer; + return lambdaBodyInfo; + } + /* * update parameter passing, e.g. `: __backing_`. */ @@ -226,12 +271,12 @@ export class factory { return addMemoAnnotation(arkts.factory.createArrowFunction(func)); } - /* - * create style arguments in builder lambda declaration. + /** + * create style argument in builder lambda declaration. */ static createStyleArgInBuilderLambdaDecl( typeNode: arkts.TypeNode | undefined, - isFunctionCall: boolean + isFunctionCall?: boolean ): arkts.ETSParameterExpression { const styleLambdaParam: arkts.ETSParameterExpression = arkts.factory.createParameterDeclaration( arkts.factory.createIdentifier(BuilderLambdaNames.STYLE_ARROW_PARAM_NAME, typeNode), @@ -258,6 +303,31 @@ export class factory { return parameter; } + /** + * create content argument in builder lambda declaration. + */ + static createContentArgInBuilderLambdaDecl(): arkts.ETSParameterExpression { + const funcType = arkts.factory.createFunctionType( + arkts.FunctionSignature.createFunctionSignature( + undefined, + [], + arkts.factory.createPrimitiveType(arkts.Es2pandaPrimitiveType.PRIMITIVE_TYPE_VOID), + false + ), + arkts.Es2pandaScriptFunctionFlags.SCRIPT_FUNCTION_FLAGS_ARROW + ); + addMemoAnnotation(funcType); + + const parameter: arkts.ETSParameterExpression = arkts.factory + .createParameterDeclaration( + arkts.factory.createIdentifier(BuilderLambdaNames.CONTENT_PARAM_NAME, funcType), + undefined + ) + .setOptional(true); + arkts.NodeCache.getInstance().collect(parameter); + return parameter; + } + /** * If a builder lambda's argument is an arrow function, * then transform any builder lambda in the function body. @@ -287,7 +357,7 @@ export class factory { /** * transform options argument in a builder lambda call. */ - static processOptionsArg(arg: T, typeName: string): T { + static processOptionsArg(arg: T): T { let expr: arkts.ObjectExpression | undefined; if (arkts.isTSAsExpression(arg) && !!arg.expr && arkts.isObjectExpression(arg.expr)) { expr = arg.expr; @@ -352,7 +422,6 @@ export class factory { static createOrUpdateArgInBuilderLambda( fallback: arkts.AstNode | undefined, arg: arkts.Expression | undefined, - typeName?: string, canAddMemo?: boolean ): arkts.AstNode | undefined { if (!arg) { @@ -367,7 +436,7 @@ export class factory { } // this is too optimistic to check if this is an options argument... if (arkts.isTSAsExpression(arg) || arkts.isObjectExpression(arg)) { - return this.processOptionsArg(arg, typeName!); + return this.processOptionsArg(arg); } return arg; } @@ -387,16 +456,17 @@ export class factory { */ static generateArgsInBuilderLambda( leaf: arkts.CallExpression, - lambdaBody: arkts.Identifier | arkts.CallExpression, + lambdaBodyInfo: BuilderLambdaStyleBodyInfo, declInfo: BuilderLambdaDeclInfo ): (arkts.AstNode | undefined)[] { const { isFunctionCall, params, returnType, moduleName } = declInfo; const type: arkts.Identifier | undefined = builderLambdaType(leaf); - const args: (arkts.AstNode | undefined)[] = [ - this.createStyleArgInBuilderLambda(lambdaBody, returnType, moduleName, leaf.typeArguments?.at(0)), - ]; + const args: (arkts.AstNode | undefined)[] = []; + const modifiedArgs: (arkts.AstNode | undefined)[] = []; const secondLastArgInfo = buildSecondLastArgInfo(type, isFunctionCall); const isTrailingCall = leaf.isTrailingCall; + const typeArguments = leaf.typeArguments; + const hasLastTrailingLambda = checkIsTrailingLambdaInLastParam(params); forEachArgWithParam( leaf.arguments, params, @@ -407,20 +477,67 @@ export class factory { } if (!modifiedArg) { const memoableInfo = collectMemoableInfoInParameter(param); - const canAddMemo = - (!!memoableInfo.hasBuilder || !!memoableInfo.hasMemo) && !!memoableInfo.hasProperType; - modifiedArg = this.createOrUpdateArgInBuilderLambda( - arkts.factory.createUndefinedLiteral(), - arg, - type?.name, - canAddMemo - ); + const canAddMemo = checkIsMemoFromMemoableInfo(memoableInfo, false); + const fallback = arkts.factory.createUndefinedLiteral(); + modifiedArg = this.createOrUpdateArgInBuilderLambda(fallback, arg, canAddMemo); + } + const shouldInsertToArgs = !isFunctionCall || (index === params.length - 1 && hasLastTrailingLambda); + if (shouldInsertToArgs) { + args.push(modifiedArg); + } else { + modifiedArgs.push(modifiedArg); } - args.push(modifiedArg); }, { isTrailingCall } ); - return filterDefined(args); + const lambdaBody = this.addOptionsArgsToLambdaBodyInStyleArg(lambdaBodyInfo, modifiedArgs, typeArguments); + const typeNode = !isFunctionCall && !!type ? UIFactory.createTypeReferenceFromString(type.name) : returnType; + const styleArg = this.createStyleArgInBuilderLambda(lambdaBody, typeNode, moduleName, typeArguments?.at(0)); + args.unshift(styleArg); + return args; + } + + /** + * add options arguments to set methods in style argument body. + */ + static addOptionsArgsToLambdaBodyInStyleArg( + lambdaBodyInfo: BuilderLambdaStyleBodyInfo, + args: (arkts.AstNode | undefined)[], + typeArguments: readonly arkts.TypeNode[] | undefined + ): arkts.CallExpression | arkts.Identifier | undefined { + const { lambdaBody, initCallPtr } = lambdaBodyInfo; + if (!lambdaBody) { + return undefined; + } + if (!initCallPtr || arkts.isIdentifier(lambdaBody)) { + return this.addApplyAttributesFinishToLambdaBodyEnd(lambdaBody); + } + const styleInternalsVisitor = new StyleInternalsVisitor(); + const newLambdaBody = styleInternalsVisitor + .registerInitCall(initCallPtr) + .registerInitCallArgs(filterDefined(args)) + .registerInitCallTypeArguments(typeArguments) + .visitor(lambdaBody) as arkts.CallExpression | arkts.Identifier; + return this.addApplyAttributesFinishToLambdaBodyEnd(newLambdaBody); + } + + /** + * add `.applyAttributesFinish()` at the end of style argument body. + */ + static addApplyAttributesFinishToLambdaBodyEnd( + lambdaBody: arkts.CallExpression | arkts.Identifier + ): arkts.CallExpression | arkts.Identifier { + return arkts.factory.createCallExpression( + arkts.factory.createMemberExpression( + lambdaBody, + arkts.factory.createIdentifier(BuilderLambdaNames.APPLY_ATTRIBUTES_FINISH_METHOD), + arkts.Es2pandaMemberExpressionKind.MEMBER_EXPRESSION_KIND_PROPERTY_ACCESS, + false, + false + ), + undefined, + [] + ); } /** @@ -467,8 +584,11 @@ export class factory { /** * replace function call's name to the corresponding transformed name. */ - static builderLambdaReplace(leaf: arkts.CallExpression): arkts.Identifier | arkts.MemberExpression | undefined { - if (!callIsGoodForBuilderLambda(leaf)) { + static builderLambdaReplace( + leaf: arkts.CallExpression, + declInfo: BuilderLambdaDeclInfo | undefined + ): arkts.Identifier | arkts.MemberExpression | undefined { + if (!callIsGoodForBuilderLambda(leaf) || !declInfo) { return undefined; } const node = leaf.expression; @@ -477,6 +597,9 @@ export class factory { return undefined; } if (arkts.isIdentifier(node)) { + const { moduleName } = declInfo; + ImportCollector.getInstance().collectSource(funcName, moduleName); + ImportCollector.getInstance().collectImport(funcName); return arkts.factory.createIdentifier(funcName); } if (arkts.isMemberExpression(node)) { @@ -494,23 +617,21 @@ export class factory { /** * transform `@ComponentBuilder` in declared methods. */ - static transformBuilderLambdaMethodDecl( - node: arkts.MethodDefinition, - externalSourceName?: string - ): arkts.MethodDefinition { + static transformBuilderLambdaMethodDecl(node: arkts.MethodDefinition): arkts.MethodDefinition { const func: arkts.ScriptFunction = node.scriptFunction; const isFunctionCall: boolean = isBuilderLambdaFunctionCall(node); + if (isFunctionCall) { + ComponentAttributeCache.getInstance().collect(node); + } const typeNode: arkts.TypeNode | undefined = builderLambdaMethodDeclType(node); const newOverloads: arkts.MethodDefinition[] = node.overloads.map((method) => factory.transformBuilderLambdaMethodDecl(method) ); - const newNode = this.updateBuilderLambdaMethodDecl( node, [this.createStyleArgInBuilderLambdaDecl(typeNode, isFunctionCall)], removeAnnotationByName(func.annotations, BuilderLambdaNames.ANNOTATION_NAME), - replaceBuilderLambdaDeclMethodName(node.name.name), - externalSourceName + replaceBuilderLambdaDeclMethodName(node.name.name) ).setOverloads(newOverloads); arkts.NodeCache.getInstance().collect(newNode); return newNode; @@ -556,7 +677,6 @@ export class factory { static transformBuilderLambda(node: arkts.CallExpression): arkts.AstNode { let instanceCalls: InstanceCallInfo[] = []; let leaf: arkts.CallExpression = node; - while (isStyleChainedCall(leaf) || isStyleWithReceiverCall(leaf)) { if (isStyleChainedCall(leaf)) { instanceCalls.push({ @@ -569,7 +689,6 @@ export class factory { }); leaf = (leaf.expression as arkts.MemberExpression).object as arkts.CallExpression; } - if (isStyleWithReceiverCall(leaf)) { instanceCalls.push({ isReceiver: true, @@ -578,30 +697,29 @@ export class factory { leaf = leaf.arguments[0] as arkts.CallExpression; } } - const decl: arkts.AstNode | undefined = findBuilderLambdaDecl(leaf); if (!decl) { return node; } - - const replace: arkts.Identifier | arkts.MemberExpression | undefined = this.builderLambdaReplace(leaf); const declInfo: BuilderLambdaDeclInfo | undefined = findBuilderLambdaDeclInfo(decl); + const replace: arkts.Identifier | arkts.MemberExpression | undefined = this.builderLambdaReplace( + leaf, + declInfo + ); if (!replace || !declInfo) { return node; } - - let lambdaBody: arkts.Identifier | arkts.CallExpression | undefined; + const lambdaBodyInfo = factory.createInitLambdaBody(declInfo); + let lambdaBody: arkts.Identifier | arkts.CallExpression | undefined = lambdaBodyInfo.lambdaBody; if (instanceCalls.length > 0) { instanceCalls = instanceCalls.reverse(); this.updateAnimation(instanceCalls); - lambdaBody = arkts.factory.createIdentifier(BuilderLambdaNames.STYLE_ARROW_PARAM_NAME); - arkts.NodeCache.getInstance().collect(lambdaBody); instanceCalls.forEach((callInfo) => { lambdaBody = this.createStyleLambdaBody(lambdaBody!, callInfo); }); } - - const args: (arkts.AstNode | undefined)[] = this.generateArgsInBuilderLambda(leaf, lambdaBody!, declInfo); + lambdaBodyInfo.lambdaBody = lambdaBody; + const args: (arkts.AstNode | undefined)[] = this.generateArgsInBuilderLambda(leaf, lambdaBodyInfo, declInfo); const newNode = arkts.factory.updateCallExpression(node, replace, leaf.typeArguments, filterDefined(args)); arkts.NodeCache.getInstance().collect(newNode); return newNode; @@ -689,4 +807,159 @@ export class factory { ) ); } + + /** + * add declared set methods in `@ComponentBuilder` Attribute interface + */ + static addDeclaredSetMethodsInAttributeInterface(node: arkts.TSInterfaceDeclaration): arkts.TSInterfaceDeclaration { + if (!node.body) { + return node; + } + const records = ComponentAttributeCache.getInstance().getAllComponentRecords(); + if (records.length === 0) { + return node; + } + let rootMethod = factory.createDeclaredSetMethodFromRecord(records.at(0)!); + const overloads: arkts.MethodDefinition[] = []; + for (let i = 0; i < records.length - 1; i++) { + const newMethod = factory.createDeclaredSetMethodFromRecord(records.at(i + 1)!); + overloads.push(newMethod); + } + rootMethod.setOverloads(overloads); + return arkts.factory.updateInterfaceDeclaration( + node, + node.extends, + node.id, + node.typeParams, + arkts.factory.updateInterfaceBody(node.body, [...node.body.body, rootMethod]), + node.isStatic, + node.isFromExternal + ); + } + + /** + * generate declared set method from `ComponentRecord` + */ + static createDeclaredSetMethodFromRecord(record: ComponentRecord): arkts.MethodDefinition { + const name = getDeclaredSetAttribtueMethodName(record.name); + const hasReceiver = !!record.hasReceiver; + const params = record.attributeRecords.map((record) => TypeFactory.createParameterFromRecord(record)); + const typeParams = record.typeParams?.map((p) => TypeFactory.createTypeParameterFromRecord(p)); + + const key = arkts.factory.createIdentifier(name); + const kind = arkts.Es2pandaMethodDefinitionKind.METHOD_DEFINITION_KIND_METHOD; + const modifiers = arkts.Es2pandaModifierFlags.MODIFIER_FLAGS_DECLARE; + const funcTypeParams = typeParams + ? arkts.factory.createTypeParameterDeclaration(typeParams, typeParams.length) + : undefined; + const returnTypeAnnotation = arkts.factory.createTSThisType(); + const flags = arkts.Es2pandaScriptFunctionFlags.SCRIPT_FUNCTION_FLAGS_METHOD; + + return UIFactory.createMethodDefinition({ + key, + kind, + function: { + key, + flags, + params, + typeParams: funcTypeParams, + returnTypeAnnotation, + modifiers, + hasReceiver, + }, + modifiers, + }); + } + + /** + * generate `applyAttributesFinish(): void;` in `CommonMethod` interface + */ + static createDeclaredApplyAttributesFinish(): arkts.MethodDefinition { + const key = arkts.factory.createIdentifier(BuilderLambdaNames.APPLY_ATTRIBUTES_FINISH_METHOD); + const kind = arkts.Es2pandaMethodDefinitionKind.METHOD_DEFINITION_KIND_METHOD; + const modifiers = arkts.Es2pandaModifierFlags.MODIFIER_FLAGS_DECLARE; + const returnTypeAnnotation = arkts.factory.createPrimitiveType(arkts.Es2pandaPrimitiveType.PRIMITIVE_TYPE_VOID); + const flags = arkts.Es2pandaScriptFunctionFlags.SCRIPT_FUNCTION_FLAGS_METHOD; + return UIFactory.createMethodDefinition({ + key, + kind, + function: { + key, + flags, + returnTypeAnnotation, + modifiers, + }, + modifiers, + }); + } + + /** + * generate `@ComponentBuilder` component Impl function in ETSGLOBAL class + */ + static createDeclaredComponentFunctionFromRecord( + record: ComponentRecord, + attributeName: string, + attributeTypeParams?: TypeRecord[] + ): arkts.MethodDefinition { + const newName: string = getTransformedComponentName(record.name); + const key: arkts.Identifier = arkts.factory.createIdentifier(newName); + const kind = arkts.Es2pandaMethodDefinitionKind.METHOD_DEFINITION_KIND_METHOD; + const modifiers = + arkts.Es2pandaModifierFlags.MODIFIER_FLAGS_DECLARE | + arkts.Es2pandaModifierFlags.MODIFIER_FLAGS_STATIC | + arkts.Es2pandaModifierFlags.MODIFIER_FLAGS_EXPORT; + const returnTypeAnnotation = arkts.factory.createPrimitiveType(arkts.Es2pandaPrimitiveType.PRIMITIVE_TYPE_VOID); + const flags = arkts.Es2pandaScriptFunctionFlags.SCRIPT_FUNCTION_FLAGS_METHOD; + const params = factory.createDeclaredComponentFunctionParameters( + attributeName, + attributeTypeParams, + record.hasLastTrailingLambda + ); + const typeParamItems = record.typeParams?.map((p) => TypeFactory.createTypeParameterFromRecord(p)); + const typeParams = !!typeParamItems + ? arkts.factory.createTypeParameterDeclaration(typeParamItems, typeParamItems.length) + : undefined; + const newMethod = UIFactory.createMethodDefinition({ + key, + kind, + function: { + key, + flags, + params, + typeParams, + returnTypeAnnotation, + modifiers, + }, + modifiers, + }); + addMemoAnnotation(newMethod.scriptFunction); + arkts.NodeCache.getInstance().collect(newMethod); + return newMethod; + } + + /** + * generate parameters in `@ComponentBuilder` component Impl function + */ + static createDeclaredComponentFunctionParameters( + attributeName: string, + attributeTypeParams?: TypeRecord[], + hasLastTrailingLambda?: boolean + ): arkts.ETSParameterExpression[] { + const params: arkts.ETSParameterExpression[] = []; + + const typeParamItems = attributeTypeParams?.map((p) => TypeFactory.createTypeNodeFromRecord(p)); + const typeParams = !!typeParamItems + ? arkts.factory.createTSTypeParameterInstantiation(typeParamItems) + : undefined; + const typeNode: arkts.TypeNode = UIFactory.createTypeReferenceFromString(attributeName, typeParams); + const styleArg: arkts.ETSParameterExpression = this.createStyleArgInBuilderLambdaDecl(typeNode, true); + params.push(styleArg); + + if (!!hasLastTrailingLambda) { + const contentArg: arkts.ETSParameterExpression = this.createContentArgInBuilderLambdaDecl(); + params.push(contentArg); + } + + return params; + } } diff --git a/arkui-plugins/ui-plugins/builder-lambda-translators/style-internals-visitor.ts b/arkui-plugins/ui-plugins/builder-lambda-translators/style-internals-visitor.ts new file mode 100644 index 0000000000000000000000000000000000000000..fc46594bfc1fc5671f84bfa1bf6559dfc0c4e659 --- /dev/null +++ b/arkui-plugins/ui-plugins/builder-lambda-translators/style-internals-visitor.ts @@ -0,0 +1,51 @@ +/* + * 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 arkts from '@koalaui/libarkts'; +import { AbstractVisitor } from '../../common/abstract-visitor'; +import { AstNodePointer } from '../../common/safe-types'; + +export class StyleInternalsVisitor extends AbstractVisitor { + private initCallPtr: AstNodePointer | undefined; + private initCallArgs: arkts.AstNode[] | undefined; + private initCallTypeArguments: readonly arkts.TypeNode[] | undefined; + + registerInitCall(initCallPtr: AstNodePointer): this { + this.initCallPtr = initCallPtr; + return this; + } + + registerInitCallArgs(initCallArgs: arkts.AstNode[]): this { + this.initCallArgs = initCallArgs; + return this; + } + + registerInitCallTypeArguments(initCallTypeArguments: readonly arkts.TypeNode[] | undefined): this { + this.initCallTypeArguments = initCallTypeArguments; + return this; + } + + visitor(node: arkts.CallExpression): arkts.AstNode { + if (!!this.initCallPtr && !!this.initCallArgs && node.peer === this.initCallPtr) { + return arkts.factory.updateCallExpression( + node, + node.expression, + this.initCallTypeArguments ?? node.typeArguments, + this.initCallArgs + ); + } + return this.visitEachChild(node); + } +} diff --git a/arkui-plugins/ui-plugins/builder-lambda-translators/utils.ts b/arkui-plugins/ui-plugins/builder-lambda-translators/utils.ts index f4975507ff3e6e5ebfd171f2554f695b8d5788dc..1ccf6a3f4b85b1ac0c2f00e1d8735295f5cc4151 100644 --- a/arkui-plugins/ui-plugins/builder-lambda-translators/utils.ts +++ b/arkui-plugins/ui-plugins/builder-lambda-translators/utils.ts @@ -19,12 +19,29 @@ import { BuilderLambdaNames, isCustomComponentAnnotation } from '../utils'; import { DeclarationCollector } from '../../common/declaration-collector'; import { ARKUI_IMPORT_PREFIX_NAMES, BindableDecl, Dollars, StructDecoratorNames } from '../../common/predefines'; import { ImportCollector } from '../../common/import-collector'; +import { + collectTypeRecordFromParameter, + collectTypeRecordFromTypeParameterDeclaration, + collectTypeRecordFromTypeParameterInstatiation, + ParameterRecord, + TypeParameterTypeRecord, + TypeRecord, +} from '../../collectors/utils/collect-types'; +import { hasMemoAnnotation } from '../../collectors/memo-collectors/utils'; +import { AstNodePointer } from 'common/safe-types'; export type BuilderLambdaDeclInfo = { + name: string; isFunctionCall: boolean; // isFunctionCall means it is from $_instantiate. params: readonly arkts.Expression[]; returnType: arkts.TypeNode | undefined; moduleName: string; + hasReceiver?: boolean; +}; + +export type BuilderLambdaStyleBodyInfo = { + lambdaBody: arkts.Identifier | arkts.CallExpression | undefined; + initCallPtr: AstNodePointer | undefined; }; export type BuilderLambdaAstNode = arkts.ScriptFunction | arkts.ETSParameterExpression | arkts.FunctionDeclaration; @@ -333,10 +350,12 @@ export function findBuilderLambdaDeclInfo(decl: arkts.AstNode | undefined): Buil return undefined; } if (arkts.isMethodDefinition(decl)) { + const name = decl.name.name; const params = decl.scriptFunction.params.map((p) => p.clone()); const returnType = decl.scriptFunction.returnTypeAnnotation?.clone(); const isFunctionCall = isBuilderLambdaFunctionCall(decl); - return { isFunctionCall, params, returnType, moduleName }; + const hasReceiver = decl.scriptFunction.hasReceiver; + return { name, isFunctionCall, params, returnType, moduleName, hasReceiver }; } return undefined; @@ -417,7 +436,7 @@ export function builderLambdaFunctionName(node: arkts.CallExpression): string | return undefined; } if (arkts.isIdentifier(node.expression)) { - return node.expression.name; + return getTransformedComponentName(node.expression.name); } if ( arkts.isMemberExpression(node.expression) && @@ -558,3 +577,154 @@ export function collectComponentAttributeImport(type: arkts.TypeNode | undefined ImportCollector.getInstance().collectImport(attributeName); } } + +/** + * check whether the last parameter is trailing lambda in components. + */ +export function checkIsTrailingLambdaInLastParam(params: readonly arkts.Expression[]): boolean { + if (params.length === 0) { + return false; + } + const lastParam = params.at(params.length - 1)! as arkts.ETSParameterExpression; + return hasMemoAnnotation(lastParam) && lastParam.identifier.name === BuilderLambdaNames.COMPONENT_PARAM_ORI; +} + +/** + * remove any parameters except possible last trailing lambda parameter in components. + */ +export function filterParamsExpectTrailingLambda(params: readonly arkts.Expression[]): readonly arkts.Expression[] { + if (checkIsTrailingLambdaInLastParam(params)) { + return [params.at(params.length - 1)!]; + } + return []; +} + +/** + * check whether interface is `XXXAttribute` that implies the component's attribute interface. + */ +export function isComponentAttributeInterface(node: arkts.AstNode): node is arkts.TSInterfaceDeclaration { + if (!ComponentAttributeCache.getInstance().isCollected()) { + return false; + } + if (!arkts.isTSInterfaceDeclaration(node) || !node.id) { + return false; + } + return ComponentAttributeCache.getInstance().attributeName === node.id.name; +} + +/** + * get set method name for components. + */ +export function getDeclaredSetAttribtueMethodName(componentName: string): string { + return `set${componentName}Options`; +} + +/** + * get after-transformed component name + */ +export function getTransformedComponentName(componentName: string): string { + return `${componentName}Impl`; +} + +// CACHE +export interface ComponentRecord { + name: string; + attributeRecords: ParameterRecord[]; + typeParams?: TypeParameterTypeRecord[]; + hasRestParameter?: boolean; + hasReceiver?: boolean; + hasLastTrailingLambda?: boolean; +} + +export class ComponentAttributeCache { + private _cache: Map; + private _attributeName: string | undefined; + private _attributeTypeParams: TypeRecord[] | undefined; + private _isCollected: boolean = false; + private static instance: ComponentAttributeCache; + + private constructor() { + this._cache = new Map(); + } + + static getInstance(): ComponentAttributeCache { + if (!this.instance) { + this.instance = new ComponentAttributeCache(); + } + return this.instance; + } + + private collectAttributeName(type: arkts.TypeNode | undefined): string | undefined { + if ( + !type || + !arkts.isETSTypeReference(type) || + !type.part || + !type.part.name || + !arkts.isIdentifier(type.part.name) + ) { + return; + } + this._attributeName = type.part.name.name; + if (type.part.typeParams) { + this._attributeTypeParams = collectTypeRecordFromTypeParameterInstatiation(type.part.typeParams); + } + } + + get attributeName(): string | undefined { + return this._attributeName; + } + + get attributeTypeParams(): TypeRecord[] | undefined { + return this._attributeTypeParams; + } + + reset(): void { + this._cache.clear(); + this._attributeName = undefined; + this._attributeTypeParams = undefined; + this._isCollected = false; + } + + isCollected(): boolean { + return this._isCollected; + } + + collect(node: arkts.MethodDefinition): void { + this.collectAttributeName(node.scriptFunction.returnTypeAnnotation); + if (!this._attributeName) { + return; + } + const name: string = node.name.name; + const hasRestParameter = node.scriptFunction.hasRestParameter; + const hasReceiver = node.scriptFunction.hasReceiver; + const typeParams = collectTypeRecordFromTypeParameterDeclaration(node.scriptFunction.typeParams); + const params = node.scriptFunction.params as arkts.ETSParameterExpression[]; + const attributeRecords: ParameterRecord[] = []; + const hasLastTrailingLambda = checkIsTrailingLambdaInLastParam(params); + params.forEach((p, index) => { + if (index === params.length - 1 && hasLastTrailingLambda) { + return; + } + const record = collectTypeRecordFromParameter(p); + attributeRecords.push(record); + }); + const componentRecord: ComponentRecord = { + name, + attributeRecords, + typeParams, + hasRestParameter, + hasReceiver, + hasLastTrailingLambda, + }; + this._cache.set(name, componentRecord); + this._isCollected = true; + } + + getComponentRecord(name: string): ComponentRecord | undefined { + return this._cache.get(name); + } + + getAllComponentRecords(): ComponentRecord[] { + return Array.from(this._cache.values()); + } +} diff --git a/arkui-plugins/ui-plugins/checked-transformer.ts b/arkui-plugins/ui-plugins/checked-transformer.ts index 0dbc8b4458dfb19a07dc4ca473510db86443c33a..80b686edb4667e5a9d36f39bdf2b89b113d2b297 100644 --- a/arkui-plugins/ui-plugins/checked-transformer.ts +++ b/arkui-plugins/ui-plugins/checked-transformer.ts @@ -19,7 +19,11 @@ import { factory as structFactory } from './struct-translators/factory'; import { factory as builderLambdaFactory } from './builder-lambda-translators/factory'; import { factory as entryFactory } from './entry-translators/factory'; import { AbstractVisitor } from '../common/abstract-visitor'; -import { isBuilderLambda, isBuilderLambdaMethodDecl } from './builder-lambda-translators/utils'; +import { + ComponentAttributeCache, + isBuilderLambda, + isBuilderLambdaMethodDecl, +} from './builder-lambda-translators/utils'; import { isEntryWrapperClass } from './entry-translators/utils'; import { ImportCollector } from '../common/import-collector'; import { DeclarationCollector } from '../common/declaration-collector'; @@ -33,7 +37,7 @@ import { LoaderJson, ResourceInfo, ScopeInfoCollection, - isForEachDecl + isForEachDecl, } from './struct-translators/utils'; import { collectCustomComponentScopeInfo, CustomComponentNames, isCustomComponentClass } from './utils'; import { findAndCollectMemoableNode } from '../collectors/memo-collectors/factory'; @@ -56,6 +60,7 @@ export class CheckedTransformer extends AbstractVisitor { super.reset(); this.scope = { customComponents: [] }; PropertyCache.getInstance().reset(); + ComponentAttributeCache.getInstance().reset(); ImportCollector.getInstance().reset(); DeclarationCollector.getInstance().reset(); LogCollector.getInstance().reset(); @@ -98,8 +103,12 @@ export class CheckedTransformer extends AbstractVisitor { if (arkts.isEtsScript(node)) { insertImportDeclaration(this.program); } - if (arkts.isClassDeclaration(node) && node.definition && node.definition.ident && - node.definition.ident.name === 'CustomDialogController') { + if ( + arkts.isClassDeclaration(node) && + node.definition && + node.definition.ident && + node.definition.ident.name === 'CustomDialogController' + ) { return transformDeclaration(node as arkts.ClassDeclaration); } return node; @@ -111,10 +120,7 @@ export class CheckedTransformer extends AbstractVisitor { const lambda = builderLambdaFactory.transformBuilderLambda(beforeChildren); return this.visitEachChild(lambda); } else if (arkts.isMethodDefinition(beforeChildren) && isBuilderLambdaMethodDecl(beforeChildren)) { - const lambda = builderLambdaFactory.transformBuilderLambdaMethodDecl( - beforeChildren, - this.externalSourceName - ); + const lambda = builderLambdaFactory.transformBuilderLambdaMethodDecl(beforeChildren); return this.visitEachChild(lambda); } const node = this.visitEachChild(beforeChildren); diff --git a/arkui-plugins/ui-plugins/struct-translators/factory.ts b/arkui-plugins/ui-plugins/struct-translators/factory.ts index c450bf11ee2ede2d78346f0346b0c250e13e5171..00768a14b4c2cece6a3039399bb1ee93db9fc4de 100644 --- a/arkui-plugins/ui-plugins/struct-translators/factory.ts +++ b/arkui-plugins/ui-plugins/struct-translators/factory.ts @@ -21,10 +21,11 @@ import { getTypeNameFromTypeParameter, getTypeParamsFromClassDecl, isCustomComponentInterface, - isKnownMethodDefinition + isKnownMethodDefinition, } from '../utils'; import { factory as uiFactory } from '../ui-factory'; import { factory as propertyFactory } from '../property-translators/factory'; +import { factory as builderLambdaFactory } from '../builder-lambda-translators/factory'; import { collect, filterDefined } from '../../common/arkts-utils'; import { classifyObservedTrack, @@ -49,6 +50,7 @@ import { isForEachCall, } from './utils'; import { collectStateManagementTypeImport, hasDecorator, PropertyCache } from '../property-translators/utils'; +import { ComponentAttributeCache, isComponentAttributeInterface } from '../builder-lambda-translators/utils'; import { ProjectConfig } from '../../common/plugin-context'; import { ImportCollector } from '../../common/import-collector'; import { @@ -252,13 +254,18 @@ export class factory { } /** - * add headers for animation & @AnimatableExtend in CommonMethod + * add following declared methods in `CommonMethod` interface: + * - `animationStart` and `animationStop` for `Animation` component; + * - `__createOrSetAnimatableProperty` for `@AnimatableExtend` function with receiver; + * - `applyAttributesFinish` for component's style set options method. */ static modifyExternalComponentCommon(node: arkts.TSInterfaceDeclaration): arkts.TSInterfaceDeclaration { const animationStart = factory.createAnimationMethod(AnimationNames.ANIMATION_START); const animationStop = factory.createAnimationMethod(AnimationNames.ANIMATION_STOP); const createOrSetAniProperty = factory.createOrSetAniProperty(); + const applyAttributesFinish = builderLambdaFactory.createDeclaredApplyAttributesFinish(); const updatedBody = arkts.factory.updateInterfaceBody(node.body!, [ + applyAttributesFinish, animationStart, animationStop, createOrSetAniProperty, @@ -604,13 +611,17 @@ export class factory { if (!node.id || !node.body) { return node; } - if (externalSourceName === ARKUI_COMPONENT_COMMON_SOURCE_NAME && node.id.name === 'CommonMethod') { - return factory.modifyExternalComponentCommon(node); + const newNode = factory.tranformInterfaceBuildMember(node); + if (externalSourceName === ARKUI_COMPONENT_COMMON_SOURCE_NAME && newNode.id!.name === 'CommonMethod') { + return factory.modifyExternalComponentCommon(newNode); } - if (isCustomComponentInterface(node)) { - return factory.tranformCustomComponentInterfaceMembers(node); + if (isCustomComponentInterface(newNode)) { + return factory.tranformCustomComponentInterfaceMembers(newNode); } - return factory.tranformInterfaceBuildMember(node); + if (isComponentAttributeInterface(newNode)) { + return builderLambdaFactory.addDeclaredSetMethodsInAttributeInterface(newNode); + } + return newNode; } static tranformInterfaceBuildMember(node: arkts.TSInterfaceDeclaration): arkts.TSInterfaceDeclaration { @@ -680,6 +691,14 @@ export class factory { } return member; }); + if (ComponentAttributeCache.getInstance().isCollected()) { + const record = ComponentAttributeCache.getInstance().getAllComponentRecords().at(0)!; + const name = ComponentAttributeCache.getInstance().attributeName!; + const typeParams = ComponentAttributeCache.getInstance().attributeTypeParams; + updatedBody.push( + builderLambdaFactory.createDeclaredComponentFunctionFromRecord(record, name, typeParams) + ); + } return arkts.factory.updateClassDeclaration( node, arkts.factory.updateClassDefinition( diff --git a/arkui-plugins/ui-plugins/type-translators/factory.ts b/arkui-plugins/ui-plugins/type-translators/factory.ts new file mode 100644 index 0000000000000000000000000000000000000000..14e2650429732fef51864d6ddd6d0565b35ea1ae --- /dev/null +++ b/arkui-plugins/ui-plugins/type-translators/factory.ts @@ -0,0 +1,216 @@ +/* + * 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 arkts from '@koalaui/libarkts'; +import { + ArrayTypeRecord, + FunctionTypeRecord, + NullTypeRecord, + PrimitiveTypeRecord, + ThisTypeRecord, + TypeRecord, + TypeRecordTypes, + TypeReferenceTypeRecord, + UndefinedTypeRecord, + UnionTypeRecord, + ParameterRecord, + TypeParameterTypeRecord, +} from '../../collectors/utils/collect-types'; + +export class factory { + /** + * generate type node from `TypeRecord` + */ + static createTypeNodeFromRecord(record: TypeRecord): arkts.TypeNode { + const type = record?.type; + switch (type) { + case TypeRecordTypes.ARRAY: + return factory.createArrayTypeFromRecord(record); + case TypeRecordTypes.FUNCTION: + return factory.createFunctionTypeFromRecord(record); + case TypeRecordTypes.NULL: + return factory.createNullTypeFromRecord(record); + case TypeRecordTypes.UNDEFINED: + return factory.createUndefinedTypeFromRecord(record); + case TypeRecordTypes.THIS: + return factory.createThisTypeFromRecord(record); + case TypeRecordTypes.UNION: + return factory.createUnionTypeFromRecord(record); + case TypeRecordTypes.TYPE_REFERENCE: + return factory.createTypeReferenceFromRecord(record); + case TypeRecordTypes.PRIMITIVE: + return factory.createPrimitiveTypeFromRecord(record); + default: + throw new Error(`Unknown type node's type: ${type}`); + } + } + + /** + * generate `arkts.ETSPrimitiveType` node from `PrimitiveTypeRecord` + */ + static createPrimitiveTypeFromRecord(record: PrimitiveTypeRecord): arkts.ETSPrimitiveType { + const typeName = record?.typeName; + switch (typeName) { + case 'boolean': + return arkts.factory.createPrimitiveType(arkts.Es2pandaPrimitiveType.PRIMITIVE_TYPE_BOOLEAN); + case 'byte': + return arkts.factory.createPrimitiveType(arkts.Es2pandaPrimitiveType.PRIMITIVE_TYPE_BYTE); + case 'char': + return arkts.factory.createPrimitiveType(arkts.Es2pandaPrimitiveType.PRIMITIVE_TYPE_CHAR); + case 'double': + return arkts.factory.createPrimitiveType(arkts.Es2pandaPrimitiveType.PRIMITIVE_TYPE_DOUBLE); + case 'float': + return arkts.factory.createPrimitiveType(arkts.Es2pandaPrimitiveType.PRIMITIVE_TYPE_FLOAT); + case 'int': + return arkts.factory.createPrimitiveType(arkts.Es2pandaPrimitiveType.PRIMITIVE_TYPE_INT); + case 'long': + return arkts.factory.createPrimitiveType(arkts.Es2pandaPrimitiveType.PRIMITIVE_TYPE_LONG); + case 'short': + return arkts.factory.createPrimitiveType(arkts.Es2pandaPrimitiveType.PRIMITIVE_TYPE_SHORT); + case 'void': + return arkts.factory.createPrimitiveType(arkts.Es2pandaPrimitiveType.PRIMITIVE_TYPE_VOID); + default: + throw new Error(`Cannot create primitive type because of name: ${typeName}`); + } + } + + /** + * generate `arkts.ETSParameterExpression` node from `ParameterRecord` + */ + static createParameterFromRecord(record: ParameterRecord): arkts.ETSParameterExpression { + const name = record.name; + const annotations = record.annotations.map((a) => a.clone()); + const isOptional = record.isOptional; + const typeAnnotation = factory.createTypeNodeFromRecord(record.typeRecord); + const parameter = arkts.factory.createParameterDeclaration( + arkts.factory.createIdentifier(name, typeAnnotation), + undefined + ); + parameter.annotations = annotations; + if (isOptional) { + parameter.setOptional(true); + } + return parameter; + } + + /** + * generate `arkts.TSTypeParameter` node from `TypeParameterTypeRecord` + */ + static createTypeParameterFromRecord(record: TypeParameterTypeRecord): arkts.TSTypeParameter { + const annotations = record.annotations.map((a) => a.clone()); + const typeName = record.typeName ? arkts.factory.createIdentifier(record.typeName) : undefined; + const defaultType = record.defaultType ? factory.createTypeNodeFromRecord(record.defaultType) : undefined; + const constraint = record.constraint ? factory.createTypeNodeFromRecord(record.constraint) : undefined; + const typeParameter = arkts.factory.createTypeParameter(typeName, constraint, defaultType); + typeParameter.setAnnotations(annotations); + return typeParameter; + } + + /** + * generate `arkts.TSArrayType` node from `ArrayTypeRecord` + */ + static createArrayTypeFromRecord(record: ArrayTypeRecord): arkts.TSArrayType { + const elementType = record.elementType ? factory.createTypeNodeFromRecord(record.elementType) : undefined; + return arkts.factory.createTSArrayType(elementType); + } + + /** + * generate `arkts.ETSNullType` node from `NullTypeRecord` + */ + static createNullTypeFromRecord(record: NullTypeRecord): arkts.ETSNullType { + return arkts.factory.createETSNullType(); + } + + /** + * generate `arkts.ETSUndefinedType` node from `UndefinedTypeRecord` + */ + static createUndefinedTypeFromRecord(record: UndefinedTypeRecord): arkts.ETSUndefinedType { + return arkts.factory.createETSUndefinedType(); + } + + /** + * generate `arkts.TSThisType` node from `ThisTypeRecord` + */ + static createThisTypeFromRecord(record: ThisTypeRecord): arkts.TSThisType { + return arkts.factory.createTSThisType(); + } + + /** + * generate `arkts.ETSFunctionType` node from `FunctionTypeRecord` + */ + static createFunctionTypeFromRecord(record: FunctionTypeRecord): arkts.ETSFunctionType { + const annotations = record.annotations.map((a) => a.clone()); + const returnType = factory.createTypeNodeFromRecord(record.returnType); + const params = record.params.map((p) => factory.createParameterFromRecord(p)); + const typeParams = record.typeParams?.map((p) => factory.createTypeParameterFromRecord(p)); + const funcType = arkts.factory.createFunctionType( + arkts.factory.createFunctionSignature( + typeParams ? arkts.factory.createTypeParameterDeclaration(typeParams, typeParams.length) : undefined, + params, + returnType, + false + ), + arkts.Es2pandaScriptFunctionFlags.SCRIPT_FUNCTION_FLAGS_ARROW + ); + funcType.setAnnotations(annotations); + return funcType; + } + + /** + * generate `arkts.ETSUnionType` node from `UnionTypeRecord` + */ + static createUnionTypeFromRecord(record: UnionTypeRecord): arkts.ETSUnionType { + const types = record.types.map((t) => factory.createTypeNodeFromRecord(t)); + return arkts.factory.createUnionType(types); + } + + /** + * @internal + */ + static createTypeNameForTypeReferencePart(name: string | string[]): arkts.Expression { + if (!Array.isArray(name)) { + return arkts.factory.createIdentifier(name); + } + const names = name.map((n) => arkts.factory.createIdentifier(n)); + if (names.length === 1) { + return names.at(0)!; + } + const leftName = names.shift(); + const rightName = names.shift(); + let nameNode: arkts.TSQualifiedName = arkts.factory.createTSQualifiedName(leftName, rightName); + while (names.length > 0) { + const currName = names.shift(); + nameNode = arkts.factory.updateTSQualifiedName(nameNode, nameNode, currName); + } + return nameNode; + } + + /** + * generate `arkts.ETSTypeReference` node from `TypeReferenceTypeRecord` + */ + static createTypeReferenceFromRecord(record: TypeReferenceTypeRecord): arkts.ETSTypeReference { + const name = record.typeName; + const annotations = record.annotations; + const typeParams = record.typeParams?.map((p) => factory.createTypeNodeFromRecord(p)); + const typeRef = arkts.factory.createTypeReference( + arkts.factory.createTypeReferencePart( + factory.createTypeNameForTypeReferencePart(name), + typeParams ? arkts.factory.createTSTypeParameterInstantiation(typeParams) : undefined + ) + ); + typeRef.setAnnotations(annotations); + return typeRef; + } +} diff --git a/arkui-plugins/ui-plugins/ui-factory.ts b/arkui-plugins/ui-plugins/ui-factory.ts index f6718b6522323180b54aec23ef1c741c2d59677b..8d732252c6195cde9ee30360c978588ff26c6436 100644 --- a/arkui-plugins/ui-plugins/ui-factory.ts +++ b/arkui-plugins/ui-plugins/ui-factory.ts @@ -144,10 +144,17 @@ export class factory { /** * create type from string */ - static createTypeReferenceFromString(name: string): arkts.TypeNode { - return arkts.factory.createTypeReference( - arkts.factory.createTypeReferencePart(arkts.factory.createIdentifier(name)) - ); + static createTypeReferenceFromString( + name: string, + typeParams?: arkts.TSTypeParameterInstantiation + ): arkts.TypeNode { + let part: arkts.ETSTypeReferencePart; + if (!!typeParams) { + part = arkts.factory.createTypeReferencePart(arkts.factory.createIdentifier(name), typeParams); + } else { + part = arkts.factory.createTypeReferencePart(arkts.factory.createIdentifier(name)); + } + return arkts.factory.createTypeReference(part); } /** diff --git a/arkui-plugins/ui-plugins/utils.ts b/arkui-plugins/ui-plugins/utils.ts index 562c74f4ed6619f53fcd07cf76251a9d9a615122..cb6ae080e45d2756c222b4659d907bbf1e56b385 100644 --- a/arkui-plugins/ui-plugins/utils.ts +++ b/arkui-plugins/ui-plugins/utils.ts @@ -43,7 +43,9 @@ export enum BuilderLambdaNames { TRANSFORM_METHOD_NAME = '_instantiateImpl', STYLE_PARAM_NAME = 'style', STYLE_ARROW_PARAM_NAME = 'instance', - CONTENT_PARAM_NAME = 'content' + CONTENT_PARAM_NAME = 'content', + COMPONENT_PARAM_ORI = 'content_', + APPLY_ATTRIBUTES_FINISH_METHOD = 'applyAttributesFinish' } // IMPORT diff --git a/koala-wrapper/src/arkts-api/factory/nodeFactory.ts b/koala-wrapper/src/arkts-api/factory/nodeFactory.ts index c780fdbf9e9b760ce14b9536ad5b386725d3772d..cabad86df388a5d31543bd73be742afbab273d70 100644 --- a/koala-wrapper/src/arkts-api/factory/nodeFactory.ts +++ b/koala-wrapper/src/arkts-api/factory/nodeFactory.ts @@ -81,6 +81,10 @@ import { ForUpdateStatement, ForInStatement, ForOfStatement, + TSArrayType, + ETSNullType, + TSThisType, + TSQualifiedName, } from '../../generated'; import { Es2pandaModifierFlags } from '../../generated/Es2pandaEnums'; import { classPropertySetOptional, hasModifierFlag } from '../utilities/public'; @@ -142,6 +146,10 @@ import { updateTSClassImplements } from '../node-utilities/TSClassImplements'; import { updateForUpdateStatement } from '../node-utilities/ForUpdateStatement'; import { updateForInStatement } from '../node-utilities/ForInStatement'; import { updateForOfStatement } from '../node-utilities/ForOfStatement'; +import { updateTSArrayType } from '../node-utilities/TSArrayType'; +import { updateETSNullType } from '../node-utilities/ETSNullType'; +import { updateTSThisType } from '../node-utilities/TSThisType'; +import { updateTSQualifiedName } from '../node-utilities/TSQualifiedName'; export const factory = { get createIdentifier(): (...args: Parameters) => Identifier { @@ -601,6 +609,30 @@ export const factory = { get updateForOfStatement(): (...args: Parameters) => ForOfStatement { return updateForOfStatement; }, + get createTSArrayType(): (...args: Parameters) => TSArrayType { + return TSArrayType.createTSArrayType; + }, + get updateTSArrayType(): (...args: Parameters) => TSArrayType { + return updateTSArrayType; + }, + get createETSNullType(): (...args: Parameters) => ETSNullType { + return ETSNullType.createETSNullType; + }, + get updateETSNullType(): (...args: Parameters) => ETSNullType { + return updateETSNullType; + }, + get createTSThisType(): (...args: Parameters) => TSThisType { + return TSThisType.createTSThisType; + }, + get updateTSThisType(): (...args: Parameters) => TSThisType { + return updateTSThisType; + }, + get createTSQualifiedName(): (...args: Parameters) => TSQualifiedName { + return TSQualifiedName.createTSQualifiedName; + }, + get updateTSQualifiedName(): (...args: Parameters) => TSQualifiedName { + return updateTSQualifiedName; + }, /** @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/index.ts b/koala-wrapper/src/arkts-api/index.ts index eef8304a59881a93eb1c6b9e7167d5b73492062e..e76f056e47297107a129e2c928abb95456c48de1 100644 --- a/koala-wrapper/src/arkts-api/index.ts +++ b/koala-wrapper/src/arkts-api/index.ts @@ -63,6 +63,7 @@ export * from '../generated/peers/TSArrayType'; export * from '../generated/peers/ArrayExpression'; export * from '../generated/peers/TryStatement'; export * from '../generated/peers/ETSNullType'; +export * from '../generated/peers/TSQualifiedName'; export * from './types'; export * from './utilities/private'; diff --git a/koala-wrapper/src/arkts-api/node-utilities/ETSNullType.ts b/koala-wrapper/src/arkts-api/node-utilities/ETSNullType.ts new file mode 100644 index 0000000000000000000000000000000000000000..7e1b10940f0bf7207120c7bf3dca258758b652d7 --- /dev/null +++ b/koala-wrapper/src/arkts-api/node-utilities/ETSNullType.ts @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2024 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 { ETSNullType } from '../../generated'; +import { attachModifiers, updateThenAttach } from '../utilities/private'; + +export function updateETSNullType( + original: ETSNullType +): ETSNullType { + /* TODO: no getter provided yet */ + + const update = updateThenAttach(ETSNullType.updateETSNullType, attachModifiers); + return update(original); +} diff --git a/koala-wrapper/src/arkts-api/node-utilities/TSArrayType.ts b/koala-wrapper/src/arkts-api/node-utilities/TSArrayType.ts new file mode 100644 index 0000000000000000000000000000000000000000..fcbfdb5da3a47a7a51ee5694e85a0764287c07af --- /dev/null +++ b/koala-wrapper/src/arkts-api/node-utilities/TSArrayType.ts @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2024 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 { TSArrayType, TypeNode } from '../../generated'; +import { isSameNativeObject } from '../peers/ArktsObject'; +import { attachModifiers, updateThenAttach } from '../utilities/private'; + +export function updateTSArrayType( + original: TSArrayType, + elementType?: TypeNode +): TSArrayType { + if ( + isSameNativeObject(elementType, original.elementType) + ) { + return original; + } + + const update = updateThenAttach(TSArrayType.updateTSArrayType, attachModifiers); + return update(original, elementType); +} diff --git a/koala-wrapper/src/arkts-api/node-utilities/TSQualifiedName.ts b/koala-wrapper/src/arkts-api/node-utilities/TSQualifiedName.ts new file mode 100644 index 0000000000000000000000000000000000000000..655c3239c64dd850214b046b519c6f8299ba2665 --- /dev/null +++ b/koala-wrapper/src/arkts-api/node-utilities/TSQualifiedName.ts @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2024 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 { Expression, Identifier, TSQualifiedName } from '../../generated'; +import { isSameNativeObject } from '../peers/ArktsObject'; +import { attachModifiers, updateThenAttach } from '../utilities/private'; + +export function updateTSQualifiedName( + original: TSQualifiedName, + left?: Expression, + right?: Identifier +): TSQualifiedName { + if (isSameNativeObject(left, original.left) && isSameNativeObject(right, original.right)) { + return original; + } + + const update = updateThenAttach(TSQualifiedName.updateTSQualifiedName, attachModifiers); + return update(original); +} diff --git a/koala-wrapper/src/arkts-api/node-utilities/TSThisType.ts b/koala-wrapper/src/arkts-api/node-utilities/TSThisType.ts new file mode 100644 index 0000000000000000000000000000000000000000..77b1c0e60daa4232f10d2f244febcf7eff6fa7db --- /dev/null +++ b/koala-wrapper/src/arkts-api/node-utilities/TSThisType.ts @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2024 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 { TSThisType } from '../../generated'; +import { attachModifiers, updateThenAttach } from '../utilities/private'; + +export function updateTSThisType( + original: TSThisType +): TSThisType { + /* TODO: no getter provided yet */ + + const update = updateThenAttach(TSThisType.updateTSThisType, attachModifiers); + return update(original); +} diff --git a/koala-wrapper/src/arkts-api/types.ts b/koala-wrapper/src/arkts-api/types.ts index d73f539d0750207a7aacaa766b37e2d78a15a0fa..9241a12d1a6dc2e26928ebfc8d346085bbe3c757 100644 --- a/koala-wrapper/src/arkts-api/types.ts +++ b/koala-wrapper/src/arkts-api/types.ts @@ -572,7 +572,7 @@ export class ETSParameterExpression extends Expression { global.generatedEs2panda._ETSParameterExpressionSetTypeAnnotation(global.context, this.peer, t.peer); } - get optional(): Boolean { + get optional(): boolean { return global.generatedEs2panda._ETSParameterExpressionIsOptionalConst(global.context, this.peer); }