diff --git a/arkui-plugins/test/demo/interop/builder_interop.ets b/arkui-plugins/test/demo/interop/builder_interop.ets new file mode 100644 index 0000000000000000000000000000000000000000..a5b3fafb0c400637383650e8784e66742390ac95 --- /dev/null +++ b/arkui-plugins/test/demo/interop/builder_interop.ets @@ -0,0 +1,80 @@ +/* + * 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. + */ + + +// ArkTS1.2 +'use static' +import { Entry, Text, Column, Component, Button, ClickEvent } from '@ohos.arkui.component' +import { State } from '@ohos.arkui.stateManagement' +import hilog from '@ohos.hilog' +import { demoBuilder1_1 } from 'har1' + +@Entry +@Component +struct MyStateSample { + @State stateVar: string = 'state var'; + message: string = 'var'; + + build() { + Column(undefined) { + Text('Hello World').fontSize(20) + Button(this.message).backgroundColor('#FFFF00FF') + .onClick((e: ClickEvent) => { + hilog.info(0x0000, 'testTag', 'On Click'); + }) + Text(this.stateVar).fontSize(20) + demoBuilder1_1({ a:"a23", b:this.stateVar}) + } + } +} + + +//ArkT1.1 +@Builder +export function demoBuilder1_1( param1:aa) { + +} +export class aa { + a:string = '' + b:string = '' +} + + +//transform 1.1 Builder to compatibleComponent + +compatibleComponent((() => { + let global = ESValue.getGlobal(); + let viewStackProcessor = global.getProperty("ViewStackProcessor"); + let createId = viewStackProcessor.getProperty("AllocateNewElmetIdForNextComponent"); + let elmtId = createId.invoke(); + let createCompatibleNode = global.getProperty("createCompatibleNodeWithFunc"); + let paramObject0 = ESValue.instantiateEmptyObject(); + paramObject0.setProperty("a", ESValue.wrap("a23")); + paramObject0.setProperty("b", ESValue.wrap(this.stateVar)); + let component = createCompatibleNode.invoke(ESValue.wrap(demoBuilder1_1), elmtId, paramObject0); + let viewPUCreate = global.getProperty("viewPUCreate"); + viewPUCreate.invoke(component); + return { + component: component, + name: "demoBuilder1_1", + }; +}), ((instance: ESValue) => { + let param = instance.getProperty("arg1"); + param.setProperty("a", ESValue.wrap("a23")); + param.setProperty("b", ESValue.wrap(this.stateVar)); + let global = ESValue.getGlobal(); + let afterUpdateProperty = global.getProperty("afterUpdateProperty"); + afterUpdateProperty.invoke(); +})); diff --git a/arkui-plugins/ui-plugins/builder-lambda-translators/utils.ts b/arkui-plugins/ui-plugins/builder-lambda-translators/utils.ts index ab738bc3d0d3b8ad0b9c0621be0fb9fbe564109c..48405da31acfba21274776cd6ea808f3cfc14fa3 100644 --- a/arkui-plugins/ui-plugins/builder-lambda-translators/utils.ts +++ b/arkui-plugins/ui-plugins/builder-lambda-translators/utils.ts @@ -84,8 +84,8 @@ export function builderLambdaArgumentName(annotation: arkts.AnnotationUsage): st return property.value.str; } -export function isBuilderLambda(node: arkts.AstNode): boolean { - const builderLambdaCall: arkts.AstNode | undefined = getDeclForBuilderLambda(node); +export function isBuilderLambda(node: arkts.AstNode, nodeDecl?:arkts.AstNode | undefined): boolean { + const builderLambdaCall: arkts.AstNode | undefined = getDeclForBuilderLambda(node, nodeDecl); if (!builderLambdaCall) { return arkts.isCallExpression(node) && node.arguments.length > 0 && isBuilderLambda(node.arguments[0]); } @@ -176,7 +176,7 @@ export function getDeclForBuilderLambdaMethodDecl(node: arkts.AstNode): arkts.As return undefined; } -export function getDeclForBuilderLambda(node: arkts.AstNode): arkts.AstNode | undefined { +export function getDeclForBuilderLambda(node: arkts.AstNode, nodeDecl?:arkts.AstNode | undefined): arkts.AstNode | undefined { if (!node || !arkts.isCallExpression(node)) { return undefined; } @@ -201,15 +201,18 @@ export function getDeclForBuilderLambda(node: arkts.AstNode): arkts.AstNode | un currNode = _node.object; } - if (isBuilderLambdaCall(node)) { + if (isBuilderLambdaCall(node, nodeDecl)) { return node; } return undefined; } -export function isBuilderLambdaCall(node: arkts.CallExpression | arkts.Identifier): boolean { - const expr = arkts.isIdentifier(node) ? node : node.expression; - const decl = arkts.getDecl(expr); +export function isBuilderLambdaCall(node: arkts.CallExpression | arkts.Identifier, nodeDecl?:arkts.AstNode | undefined): boolean { + let decl = nodeDecl; + if (decl === undefined) { + const expr = arkts.isIdentifier(node) ? node : node.expression; + decl = arkts.getDecl(expr); + } if (!decl) { return false; diff --git a/arkui-plugins/ui-plugins/checked-transformer.ts b/arkui-plugins/ui-plugins/checked-transformer.ts index d5efa568a48aa7ec32eb22f29fcecf461b1ddbab..81d3df185d92c63ae513cac26e97bee2fb10d7a5 100644 --- a/arkui-plugins/ui-plugins/checked-transformer.ts +++ b/arkui-plugins/ui-plugins/checked-transformer.ts @@ -42,9 +42,13 @@ import { isSpecificNewClass, } from './utils'; import { findAndCollectMemoableNode } from '../collectors/memo-collectors/factory'; +import { InteroperAbilityNames } from './interop/predefines'; +import { generateBuilderCompatible } from './interop/builder-interop'; export class CheckedTransformer extends AbstractVisitor { private scope: ScopeInfoCollection; + private legacyBuilderSet: Set = new Set(); + private needCompatibleComponent : boolean = false; projectConfig: ProjectConfig | undefined; aceBuildJson: LoaderJson; resourceInfo: ResourceInfo; @@ -55,11 +59,31 @@ export class CheckedTransformer extends AbstractVisitor { this.scope = { customComponents: [] }; this.aceBuildJson = loadBuildJson(this.projectConfig); this.resourceInfo = initResourceInfo(this.projectConfig, this.aceBuildJson); + this.legacyBuilderSet = new Set(); + this.initBuilderMap(); + } + + initBuilderMap(): void { + const moduleList = this.projectConfig?.dependentModuleList; + if (moduleList === undefined) { + return; + } + for (const module of moduleList) { + const language = module.language; + const moduleName = module.moduleName; + if (language !== InteroperAbilityNames.ARKTS_1_1) { + continue; + } + if (!this.legacyBuilderSet.has(moduleName)) { + this.legacyBuilderSet.add(moduleName); + } + } } reset(): void { super.reset(); this.scope = { customComponents: [] }; + this.needCompatibleComponent = false; PropertyCache.getInstance().reset(); ImportCollector.getInstance().reset(); DeclarationCollector.getInstance().reset(); @@ -92,11 +116,51 @@ export class CheckedTransformer extends AbstractVisitor { } } + isFromBuilder1_1(decl: arkts.AstNode | undefined): boolean { + if (!decl || this.legacyBuilderSet.size === 0) { + return false; + } + const moduleName = arkts.getProgramFromAstNode(decl).moduleName?.split('/')[0]; + + if (!this.legacyBuilderSet.has(moduleName)) { + return false; + } + + let isFrom1_1 = false; + if (arkts.isMethodDefinition(decl)) { + const annotations = decl.scriptFunction.annotations; + const decorators: string[] = annotations.map(annotation => { + return (annotation.expr as arkts.Identifier).name; + }); + decorators.forEach(element => { + if (element === 'Builder') { + isFrom1_1 = true; + return; + } + }); + } + return isFrom1_1; + } + + addcompatibleComponentImport(node: arkts.EtsScript): void { + if (this.needCompatibleComponent) { + ImportCollector.getInstance().collectSource('compatibleComponent', 'arkui.component.interop'); + ImportCollector.getInstance().collectImport('compatibleComponent'); + } + } + visitor(beforeChildren: arkts.AstNode): arkts.AstNode { this.enter(beforeChildren); - if (arkts.isCallExpression(beforeChildren) && isBuilderLambda(beforeChildren)) { - const lambda = builderLambdaFactory.transformBuilderLambda(beforeChildren); - return this.visitEachChild(lambda); + if (arkts.isCallExpression(beforeChildren)) { + const decl = arkts.getDecl(beforeChildren.expression); + if (arkts.isIdentifier(beforeChildren.expression) && this.isFromBuilder1_1(decl)) { + // Builder + this.needCompatibleComponent = true; + return generateBuilderCompatible(beforeChildren, beforeChildren.expression.name); + } else if (isBuilderLambda(beforeChildren, decl)) { + const lambda = builderLambdaFactory.transformBuilderLambda(beforeChildren); + return this.visitEachChild(lambda); + } } else if (arkts.isMethodDefinition(beforeChildren) && isBuilderLambdaMethodDecl(beforeChildren)) { const lambda = builderLambdaFactory.transformBuilderLambdaMethodDecl( beforeChildren, @@ -115,7 +179,13 @@ export class CheckedTransformer extends AbstractVisitor { const newClass: arkts.ClassDeclaration = structFactory.tranformClassMembers(node, scope); this.exit(beforeChildren); return newClass; - } else if (isEntryWrapperClass(node)) { + } + + return this.visitorAstNode(node); + } + + visitorAstNode(node: arkts.AstNode): arkts.AstNode { + if (isEntryWrapperClass(node)) { entryFactory.addMemoToEntryWrapperClassMethods(node); return node; } else if (arkts.isClassDeclaration(node)) { @@ -129,10 +199,14 @@ export class CheckedTransformer extends AbstractVisitor { } else if (arkts.isETSNewClassInstanceExpression(node) && isSpecificNewClass(node, CustomDialogNames.CUSTOM_DIALOG_CONTROLLER)) { return structFactory.transformCustomDialogController(node); } - if (arkts.isEtsScript(node) && ImportCollector.getInstance().importInfos.length > 0) { - ImportCollector.getInstance().insertCurrentImports(this.program); - LogCollector.getInstance().shouldIgnoreError(this.projectConfig?.ignoreError); - LogCollector.getInstance().emitLogInfo(); + + if (arkts.isEtsScript(node)) { + this.addcompatibleComponentImport(node); + if (ImportCollector.getInstance().importInfos.length > 0) { + ImportCollector.getInstance().insertCurrentImports(this.program); + LogCollector.getInstance().shouldIgnoreError(this.projectConfig?.ignoreError); + LogCollector.getInstance().emitLogInfo(); + } } return node; } diff --git a/arkui-plugins/ui-plugins/interop/builder-interop.ts b/arkui-plugins/ui-plugins/interop/builder-interop.ts new file mode 100644 index 0000000000000000000000000000000000000000..7d2b63282437ffc324144d111f134d09d3341b2b --- /dev/null +++ b/arkui-plugins/ui-plugins/interop/builder-interop.ts @@ -0,0 +1,263 @@ +/* + * 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 { ESValueMethodNames, builderMethodNames, InteroperAbilityNames } from './predefines'; +import { + createELMTID, + createEmptyESValue, + createGlobal, + createInitReturn, + getPropertyESValue, + getWrapValue, + setPropertyESValue +} from './utils'; + +interface builderParam { + args: arkts.AstNode[], + paramsInfo: arkts.Statement[] +} + +function invokeFunctionWithParam(functionName: string, result: string, className: string, args: arkts.AstNode[]): arkts.Statement { + return arkts.factory.createVariableDeclaration( + arkts.Es2pandaModifierFlags.MODIFIER_FLAGS_NONE, + arkts.Es2pandaVariableDeclarationKind.VARIABLE_DECLARATION_KIND_LET, + [arkts.factory.createVariableDeclarator( + arkts.Es2pandaVariableDeclaratorFlag.VARIABLE_DECLARATOR_FLAG_LET, + arkts.factory.createIdentifier(result), + arkts.factory.createCallExpression( + arkts.factory.createMemberExpression( + arkts.factory.createIdentifier(functionName), + arkts.factory.createIdentifier(ESValueMethodNames.INVOKE), + arkts.Es2pandaMemberExpressionKind.MEMBER_EXPRESSION_KIND_PROPERTY_ACCESS, + false, + false + ), + undefined, + [ + getWrapValue(arkts.factory.createIdentifier(className)), + arkts.factory.createIdentifier(InteroperAbilityNames.ELMTID), + ...args + ] + ) + )] + ); +} + +function invokeAfterUpdateProperty(): arkts.Statement { + return arkts.factory.createExpressionStatement( + arkts.factory.createCallExpression( + arkts.factory.createMemberExpression( + arkts.factory.createIdentifier(builderMethodNames.AFTERUPDATEPROPERTY), + arkts.factory.createIdentifier(ESValueMethodNames.INVOKE), + arkts.Es2pandaMemberExpressionKind.MEMBER_EXPRESSION_KIND_PROPERTY_ACCESS, + false, + false + ), + undefined, + undefined + ) + ); +} + +function invokeComponent(): arkts.Statement[] { + const viewPU = getPropertyESValue('viewPUCreate', InteroperAbilityNames.GLOBAL, 'viewPUCreate'); + const create = arkts.factory.createExpressionStatement( + arkts.factory.createCallExpression( + arkts.factory.createMemberExpression( + arkts.factory.createIdentifier('viewPUCreate'), + arkts.factory.createIdentifier('invoke'), + arkts.Es2pandaMemberExpressionKind.MEMBER_EXPRESSION_KIND_PROPERTY_ACCESS, + false, + false + ), + undefined, + [ + arkts.factory.createIdentifier(InteroperAbilityNames.COMPONENT) + ] + ) + ); + return [viewPU, create]; +} + +function createBuilderInitializer(className: string, functionName: string, param: builderParam): arkts.ArrowFunctionExpression { + const block = arkts.factory.createBlock( + [ + createGlobal(), + ...createELMTID(), + getPropertyESValue(builderMethodNames.CREATECOMPATIBLENODE, InteroperAbilityNames.GLOBAL, functionName), + ...param.paramsInfo, + invokeFunctionWithParam(builderMethodNames.CREATECOMPATIBLENODE, InteroperAbilityNames.COMPONENT, className, param.args), + ...invokeComponent(), + createInitReturn(className) + ] + ); + return arkts.factory.createArrowFunction( + arkts.factory.createScriptFunction( + block, + arkts.factory.createFunctionSignature( + undefined, + [], + undefined, + false, + ), + arkts.Es2pandaScriptFunctionFlags.SCRIPT_FUNCTION_FLAGS_ARROW, + arkts.Es2pandaModifierFlags.MODIFIER_FLAGS_NONE, + ) + ); +} + +function getUpdateArgs(node: arkts.CallExpression): arkts.Statement[] { + if (node.arguments.length !== 1) { + return []; + } + let body: arkts.Statement[] = []; + let argument = node.arguments[0]; + if (arkts.isObjectExpression(argument)) { + body?.push(getPropertyESValue('param', InteroperAbilityNames.INSTANCE, 'arg1')); + for (const property of argument.properties) { + if (!(property instanceof arkts.Property)) { + continue; + } + const key = property.key; + const value = property.value; + if (!(key instanceof arkts.Identifier) || value === undefined) { + throw Error('Error arguments in Legacy Builder Function'); + } + body?.push(setPropertyESValue('param', key.name, getWrapValue(value))); + } + const endBody = + [ + createGlobal(), + getPropertyESValue(builderMethodNames.AFTERUPDATEPROPERTY, + InteroperAbilityNames.GLOBAL, + builderMethodNames.AFTERUPDATEPROPERTY), + invokeAfterUpdateProperty() + ]; + body?.push(...endBody); + } + + return body; +} + +function createBuilderUpdate(node: arkts.CallExpression): arkts.ArrowFunctionExpression { + return arkts.factory.createArrowFunction( + arkts.factory.createScriptFunction( + arkts.factory.createBlock( + [ + ...getUpdateArgs(node) + ] + ), + arkts.factory.createFunctionSignature( + undefined, + [ + arkts.factory.createParameterDeclaration( + arkts.factory.createIdentifier(InteroperAbilityNames.INSTANCE, + arkts.factory.createTypeReference( + arkts.factory.createTypeReferencePart( + arkts.factory.createIdentifier(ESValueMethodNames.ESVALUE) + ) + ) + ), + undefined, + ), + ], + undefined, + false, + ), + arkts.Es2pandaScriptFunctionFlags.SCRIPT_FUNCTION_FLAGS_ARROW, + arkts.Es2pandaModifierFlags.MODIFIER_FLAGS_NONE, + ) + ); +} + +function getInitArgs(node: arkts.CallExpression): builderParam { + const args: arkts.AstNode[] = []; + let ObjectExpressionNum: number = 0; + const body: arkts.Statement[] = []; + node.arguments.forEach((argument) => { + if (arkts.isObjectExpression(argument)) { + processArgument(argument, ObjectExpressionNum, body, args); + ObjectExpressionNum++; + } else { + args.push(getWrapValue(argument)); + } + }); + return { args: args, paramsInfo: body }; +} + +function processArgument(argument: arkts.ObjectExpression, ObjectExpressionNum:number, + body: arkts.Statement[], args: arkts.AstNode[]): void { + const paramName: string = 'paramObject' + ObjectExpressionNum; + body.push(createEmptyESValue(paramName)); + for (const property of argument.properties) { + if (!(property instanceof arkts.Property)) { + continue; + } + const key = property.key; + const value = property.value; + if (!(key instanceof arkts.Identifier) || value === undefined) { + throw Error('Error arguments in Legacy Builder Function'); + } + body.push(setPropertyESValue(paramName, key.name, getWrapValue(value))); + } + args.push(arkts.factory.createIdentifier(paramName)); +} + +/** + * + * @param node node + * @param moduleName moduleName + * @returns After Checked, transform builder/WrappedBuilder -> compatibleComponent + */ +export function generateBuilderCompatible(node: arkts.CallExpression, moduleName: string): arkts.CallExpression { + let functionName; + switch (node.arguments.length) { + case 0: + functionName = 'createCompatibleNodeWithFuncVoid'; + break; + case 1: + functionName = 'createCompatibleNodeWithFunc'; + break; + case 2: + functionName = 'createCompatibleNodeWithFunc2'; + break; + case 3: + functionName = 'createCompatibleNodeWithFunc3'; + break; + case 4: + functionName = 'createCompatibleNodeWithFunc4'; + break; + case 5: + functionName = 'createCompatibleNodeWithFunc5'; + break; + default: + throw Error('Error arguments in Legacy Builder Function'); + } + let param: builderParam = getInitArgs(node); + const initializer = createBuilderInitializer(moduleName, functionName, param); + const updater: arkts.ArrowFunctionExpression = createBuilderUpdate(node); + const result = arkts.factory.updateCallExpression( + node, + arkts.factory.createIdentifier(InteroperAbilityNames.ARKUICOMPATIBLE), + undefined, + [ + initializer, + updater, + ] + ); + arkts.NodeCache.getInstance().collect(result); + return result; +} \ No newline at end of file diff --git a/arkui-plugins/ui-plugins/interop/interop.ts b/arkui-plugins/ui-plugins/interop/interop.ts index bfbceccadb2f89d250f05c0ab9a657b45e1ce429..433265a8083ec4d1b508c5d1a12ea02381754cb7 100644 --- a/arkui-plugins/ui-plugins/interop/interop.ts +++ b/arkui-plugins/ui-plugins/interop/interop.ts @@ -21,7 +21,15 @@ import { getCustomComponentOptionsName } from '../utils'; import { InteropContext } from '../component-transformer'; import { createVariableLet, initialArgs} from './initstatevar'; import { createProvideInterop, setAndResetFindProvide } from './provide'; -import { getPropertyESValue, getWrapValue, setPropertyESValue, createEmptyESValue } from './utils'; +import { + getPropertyESValue, + getWrapValue, + setPropertyESValue, + createEmptyESValue, + createGlobal, + createELMTID, + createInitReturn +} from './utils'; import { ImportCollector } from '../../common/import-collector'; @@ -66,25 +74,6 @@ function paramsLambdaDeclaration(name: string, args?: arkts.ObjectExpression): a return result; } -function createInitReturn(componentName: string): arkts.ReturnStatement { - return arkts.factory.createReturnStatement( - arkts.ObjectExpression.createObjectExpression( - arkts.Es2pandaAstNodeType.AST_NODE_TYPE_OBJECT_EXPRESSION, - [ - arkts.Property.createProperty( - arkts.factory.createIdentifier(InteroperAbilityNames.COMPONENT), - arkts.factory.createIdentifier(InteroperAbilityNames.COMPONENT) - ), - arkts.Property.createProperty( - arkts.factory.createIdentifier('name'), - arkts.factory.createStringLiteral(componentName) - ) - ], - false - ), - ); -} - function createExtraInfo(properties: string[], value: string[]): arkts.Statement[] { const body: arkts.AstNode[] = []; body.push(createEmptyESValue(InteroperAbilityNames.EXTRAINFO)); @@ -99,59 +88,6 @@ function createExtraInfo(properties: string[], value: string[]): arkts.Statement return body; } - -function createGlobal(): arkts.Statement { - return arkts.factory.createVariableDeclaration( - arkts.Es2pandaModifierFlags.MODIFIER_FLAGS_NONE, - arkts.Es2pandaVariableDeclarationKind.VARIABLE_DECLARATION_KIND_LET, - [arkts.factory.createVariableDeclarator( - arkts.Es2pandaVariableDeclaratorFlag.VARIABLE_DECLARATOR_FLAG_LET, - arkts.factory.createIdentifier(InteroperAbilityNames.GLOBAL), - arkts.factory.createCallExpression( - arkts.factory.createMemberExpression( - arkts.factory.createIdentifier(ESValueMethodNames.ESVALUE), - arkts.factory.createIdentifier('getGlobal'), - arkts.Es2pandaMemberExpressionKind.MEMBER_EXPRESSION_KIND_PROPERTY_ACCESS, - false, - false - ), - undefined, - undefined - ) - )] - ); -} - -function createELMTID(): arkts.Statement[] { - const body: arkts.Statement[] = []; - const viewStackProcessor = getPropertyESValue('viewStackProcessor', InteroperAbilityNames.GLOBAL, 'ViewStackProcessor'); - body.push(viewStackProcessor); - const createId = getPropertyESValue('createId', 'viewStackProcessor', 'AllocateNewElmetIdForNextComponent'); - body.push(createId); - const elmtId = arkts.factory.createVariableDeclaration( - arkts.Es2pandaModifierFlags.MODIFIER_FLAGS_NONE, - arkts.Es2pandaVariableDeclarationKind.VARIABLE_DECLARATION_KIND_LET, - [arkts.factory.createVariableDeclarator( - arkts.Es2pandaVariableDeclaratorFlag.VARIABLE_DECLARATOR_FLAG_LET, - arkts.factory.createIdentifier(InteroperAbilityNames.ELMTID), - arkts.factory.createCallExpression( - arkts.factory.createMemberExpression( - arkts.factory.createIdentifier('createId'), - arkts.factory.createIdentifier(ESValueMethodNames.INVOKE), - arkts.Es2pandaMemberExpressionKind.MEMBER_EXPRESSION_KIND_PROPERTY_ACCESS, - false, - false - ), - undefined, - undefined - ) - )] - ); - body.push(elmtId); - return body; -} - - function generateTSASExpression(expression: arkts.AstNode): arkts.Expression { return arkts.factory.createTSAsExpression( arkts.factory.createCallExpression( diff --git a/arkui-plugins/ui-plugins/interop/legacy-transformer.ts b/arkui-plugins/ui-plugins/interop/legacy-transformer.ts index 14a7a4b95546750144f8b9cb8d0e5f2aa8bc40d8..e3248f6e92f99cd07b194c107fb7a8afe0e8a4a7 100644 --- a/arkui-plugins/ui-plugins/interop/legacy-transformer.ts +++ b/arkui-plugins/ui-plugins/interop/legacy-transformer.ts @@ -259,6 +259,56 @@ export class LegacyTransformer extends AbstractVisitor { } } + handleWrappedBuilderNode(node: arkts.ETSTypeReference): arkts.ETSTypeReference { + if (node.part && arkts.isETSTypeReferencePart(node.part) && node.part.name && + arkts.isIdentifier(node.part.name) && node.part.name.name === 'WrappedBuilder') { + return arkts.factory.createTypeReference( + arkts.factory.createTypeReferencePart( + arkts.factory.createIdentifier('Any') + ) + ); + } + return node; + } + + // handle WrappedBuilder + handleWrappedBuilder(node: arkts.VariableDeclarator): arkts.VariableDeclarator { + if (arkts.isIdentifier(node.name) && node.name.typeAnnotation) { + let typeAnnotation = node.name.typeAnnotation; + // WrappedBuilder<[aa]>[] => Any[] + if (arkts.isTSArrayType(typeAnnotation) && typeAnnotation.elementType && + arkts.isETSTypeReference(typeAnnotation.elementType)) { + return arkts.factory.updateVariableDeclarator( + node, + node.flag, + arkts.factory.updateIdentifier( + node.name, + node.name.name, + arkts.TSArrayType.updateTSArrayType( + typeAnnotation, + this.handleWrappedBuilderNode(typeAnnotation.elementType) + ) + ), + node.initializer + ); + } + // WrappedBuilder<[aa]> => Any + if (arkts.isETSTypeReference(typeAnnotation)) { + return arkts.factory.updateVariableDeclarator( + node, + node.flag, + arkts.factory.updateIdentifier( + node.name, + node.name.name, + this.handleWrappedBuilderNode(typeAnnotation) + ), + node.initializer + ); + } + } + return node; + } + visitor(node: arkts.AstNode): arkts.AstNode { this.enter(node); const newNode = this.visitEachChild(node); @@ -285,6 +335,9 @@ export class LegacyTransformer extends AbstractVisitor { return updateNode; } } + if (arkts.isVariableDeclarator(newNode)) { + return this.handleWrappedBuilder(newNode); + } return newNode; } } \ No newline at end of file diff --git a/arkui-plugins/ui-plugins/interop/predefines.ts b/arkui-plugins/ui-plugins/interop/predefines.ts index 6762902a09264db690a251e9d718052f46e6acd7..f169741bd4b160ae90b0a5e4f58dbac5682462fa 100644 --- a/arkui-plugins/ui-plugins/interop/predefines.ts +++ b/arkui-plugins/ui-plugins/interop/predefines.ts @@ -60,4 +60,9 @@ export enum InteropProvideNames { SETFINDPROVIDE = 'setFindProvideInterop', SETVIEWPUFINDPROVIDE = 'setViewPUFindProvideInterop', FINDPROVIDECALLBACK = 'findProvideInterop', +} + +export enum builderMethodNames { + AFTERUPDATEPROPERTY = 'afterUpdateProperty', + CREATECOMPATIBLENODE = 'createCompatibleNode', } \ No newline at end of file diff --git a/arkui-plugins/ui-plugins/interop/utils.ts b/arkui-plugins/ui-plugins/interop/utils.ts index 14574a264b19bbab41047aca2fc6ff5b3ff3daec..8ce38fe3035fd82d2e9fad29effb64c52cf39bf4 100644 --- a/arkui-plugins/ui-plugins/interop/utils.ts +++ b/arkui-plugins/ui-plugins/interop/utils.ts @@ -16,7 +16,7 @@ import * as arkts from '@koalaui/libarkts'; -import { ESValueMethodNames } from './predefines'; +import { ESValueMethodNames, InteroperAbilityNames } from './predefines'; /** @@ -133,3 +133,91 @@ export function stateProxy(stateVarName: string): string { return `__Proxy_${stateVarName}`; } +/** + * get elmtId + * @returns + * let viewStackProcessor = global.getProperty("ViewStackProcessor"); + * let createId = viewStackProcessor.getProperty("AllocateNewElmetIdForNextComponent"); + * let elmtId = createId.invoke(); + */ +export function createELMTID(): arkts.Statement[] { + const body: arkts.Statement[] = []; + const viewStackProcessor = getPropertyESValue('viewStackProcessor', InteroperAbilityNames.GLOBAL, 'ViewStackProcessor'); + body.push(viewStackProcessor); + const createId = getPropertyESValue('createId', 'viewStackProcessor', 'AllocateNewElmetIdForNextComponent'); + body.push(createId); + const elmtId = arkts.factory.createVariableDeclaration( + arkts.Es2pandaModifierFlags.MODIFIER_FLAGS_NONE, + arkts.Es2pandaVariableDeclarationKind.VARIABLE_DECLARATION_KIND_LET, + [arkts.factory.createVariableDeclarator( + arkts.Es2pandaVariableDeclaratorFlag.VARIABLE_DECLARATOR_FLAG_LET, + arkts.factory.createIdentifier(InteroperAbilityNames.ELMTID), + arkts.factory.createCallExpression( + arkts.factory.createMemberExpression( + arkts.factory.createIdentifier('createId'), + arkts.factory.createIdentifier(ESValueMethodNames.INVOKE), + arkts.Es2pandaMemberExpressionKind.MEMBER_EXPRESSION_KIND_PROPERTY_ACCESS, + false, + false + ), + undefined, + undefined + ) + )] + ); + body.push(elmtId); + return body; +} + +/** + * + * @param componentName + * @returns return { + * component: component, + * name: componentName, + * }; + */ +export function createInitReturn(componentName: string): arkts.ReturnStatement { + return arkts.factory.createReturnStatement( + arkts.ObjectExpression.createObjectExpression( + arkts.Es2pandaAstNodeType.AST_NODE_TYPE_OBJECT_EXPRESSION, + [ + arkts.Property.createProperty( + arkts.factory.createIdentifier(InteroperAbilityNames.COMPONENT), + arkts.factory.createIdentifier(InteroperAbilityNames.COMPONENT) + ), + arkts.Property.createProperty( + arkts.factory.createIdentifier('name'), + arkts.factory.createStringLiteral(componentName) + ) + ], + false + ), + ); +} + +/** + * createGlobal + * @returns let global = ESValue.getGlobal(); + */ +export function createGlobal(): arkts.Statement { + return arkts.factory.createVariableDeclaration( + arkts.Es2pandaModifierFlags.MODIFIER_FLAGS_NONE, + arkts.Es2pandaVariableDeclarationKind.VARIABLE_DECLARATION_KIND_LET, + [arkts.factory.createVariableDeclarator( + arkts.Es2pandaVariableDeclaratorFlag.VARIABLE_DECLARATOR_FLAG_LET, + arkts.factory.createIdentifier(InteroperAbilityNames.GLOBAL), + arkts.factory.createCallExpression( + arkts.factory.createMemberExpression( + arkts.factory.createIdentifier(ESValueMethodNames.ESVALUE), + arkts.factory.createIdentifier('getGlobal'), + arkts.Es2pandaMemberExpressionKind.MEMBER_EXPRESSION_KIND_PROPERTY_ACCESS, + false, + false + ), + undefined, + undefined + ) + )] + ); +} diff --git a/koala-wrapper/src/arkts-api/index.ts b/koala-wrapper/src/arkts-api/index.ts index eef8304a59881a93eb1c6b9e7167d5b73492062e..b192306d6bd7f5cca2cb851d487cd2227b54a721 100644 --- a/koala-wrapper/src/arkts-api/index.ts +++ b/koala-wrapper/src/arkts-api/index.ts @@ -63,6 +63,8 @@ export * from '../generated/peers/TSArrayType'; export * from '../generated/peers/ArrayExpression'; export * from '../generated/peers/TryStatement'; export * from '../generated/peers/ETSNullType'; +export * from '../generated/peers/ETSTuple'; +export * from '../generated/peers/ImportDeclaration' export * from './types'; export * from './utilities/private';