From 6281524d49fcf89cb366be4d302ff6f9543797d4 Mon Sep 17 00:00:00 2001 From: l00913061 Date: Wed, 3 Sep 2025 14:44:41 +0800 Subject: [PATCH 1/2] builderparamupdate Signed-off-by: l00913061 --- compiler/src/interop/src/pre_define.ts | 1 + .../interop/src/process_component_build.ts | 48 +++++----- .../interop/src/process_interop_builder.ts | 90 +++++++++++++++++++ 3 files changed, 117 insertions(+), 22 deletions(-) create mode 100644 compiler/src/interop/src/process_interop_builder.ts diff --git a/compiler/src/interop/src/pre_define.ts b/compiler/src/interop/src/pre_define.ts index a044b786c..ba0fc530a 100644 --- a/compiler/src/interop/src/pre_define.ts +++ b/compiler/src/interop/src/pre_define.ts @@ -623,6 +623,7 @@ export const RESERT = 'reset'; export const TS_NOCHECK: string = '// @ts-nocheck'; export const BUILDER_PARAM_PROXY: string = 'makeBuilderParameterProxy'; +export const BUILDER_PARAM_PROXY_INTEROP: string = 'makeBuilderParameterProxyInterop'; export const BUILDER_TYPE: string = 'BuilderType'; export const FUNCTION: string = 'function'; diff --git a/compiler/src/interop/src/process_component_build.ts b/compiler/src/interop/src/process_component_build.ts index 037efb0b8..6e233e89e 100644 --- a/compiler/src/interop/src/process_component_build.ts +++ b/compiler/src/interop/src/process_component_build.ts @@ -203,6 +203,7 @@ import { concatenateEtsOptions, getExternalComponentPaths } from './external_component_map'; +import { updateInteropObjectLiteralxpression } from './process_interop_builder'; export function processComponentBuild(node: ts.MethodDeclaration, log: LogInfo[]): ts.MethodDeclaration { @@ -612,30 +613,33 @@ export function transferBuilderCall(node: ts.ExpressionStatement, name: string, if (node.expression && ts.isCallExpression(node.expression)) { let newNode: ts.Expression = builderCallNode(node.expression); newNode.expression.questionDotToken = node.expression.questionDotToken; - if (node.expression.arguments && node.expression.arguments.length === 1 && ts.isObjectLiteralExpression(node.expression.arguments[0])) { - return ts.factory.createExpressionStatement(ts.factory.updateCallExpression( - node.expression, - newNode, - undefined, - [ts.factory.createCallExpression( - ts.factory.createIdentifier(BUILDER_PARAM_PROXY), + if (node.expression.arguments && node.expression.arguments.length === 1) { + if (ts.isObjectLiteralExpression(node.expression.arguments[0])) { + return ts.factory.createExpressionStatement(ts.factory.updateCallExpression( + node.expression, + newNode, undefined, - [ - ts.factory.createStringLiteral(name), - traverseBuilderParams(node.expression.arguments[0], isBuilder) - ] - )] - )); - } else { - return ts.factory.createExpressionStatement(ts.factory.updateCallExpression( - node.expression, - newNode, - undefined, - !(projectConfig.optLazyForEach && (storedFileInfo.processLazyForEach && - storedFileInfo.lazyForEachInfo.forEachParameters || isBuilder)) ? node.expression.arguments : - [...node.expression.arguments, ts.factory.createNull(), ts.factory.createIdentifier(MY_IDS)] - )); + [ts.factory.createCallExpression( + ts.factory.createIdentifier(BUILDER_PARAM_PROXY), + undefined, + [ + ts.factory.createStringLiteral(name), + traverseBuilderParams(node.expression.arguments[0], isBuilder) + ] + )] + )); + } else if (ts.isParenthesizedExpression(node.expression.arguments[0]) && ts.isCommaListExpression(node.expression.arguments[0].expression)) { + return updateInteropObjectLiteralxpression(node.expression, newNode, name); + } } + return ts.factory.createExpressionStatement(ts.factory.updateCallExpression( + node.expression, + newNode, + undefined, + !(projectConfig.optLazyForEach && (storedFileInfo.processLazyForEach && + storedFileInfo.lazyForEachInfo.forEachParameters || isBuilder)) ? node.expression.arguments : + [...node.expression.arguments, ts.factory.createNull(), ts.factory.createIdentifier(MY_IDS)] + )); } return undefined; } diff --git a/compiler/src/interop/src/process_interop_builder.ts b/compiler/src/interop/src/process_interop_builder.ts new file mode 100644 index 000000000..abdf7301f --- /dev/null +++ b/compiler/src/interop/src/process_interop_builder.ts @@ -0,0 +1,90 @@ +/* + * 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 ts from 'typescript'; +import { BUILDER_PARAM_PROXY_INTEROP } from './pre_define'; + +function processObjectLiteral(properties: ts.ObjectLiteralElementLike[], node: ts.ParenthesizedExpression): void { + const list = (node.expression as ts.CommaListExpression).elements; + list.forEach(node => { + if (ts.isBinaryExpression(node) && ts.isPropertyAccessExpression(node.left)) { + const keyName = node.left.name.text; + if (ts.isPropertyAccessExpression(node.right) && node.right.expression.kind === ts.SyntaxKind.ThisKeyword) { + const name = node.right.name.text; + properties.push(ts.factory.createPropertyAssignment( + keyName, + ts.factory.createArrowFunction( + undefined, + undefined, + [], + undefined, + ts.factory.createToken(ts.SyntaxKind.EqualsGreaterThanToken), + ts.factory.createParenthesizedExpression(ts.factory.createConditionalExpression( + ts.factory.createElementAccessExpression( + ts.factory.createThis(), + ts.factory.createStringLiteral('__' + name) + ), + ts.factory.createToken(ts.SyntaxKind.QuestionToken), + ts.factory.createElementAccessExpression( + ts.factory.createThis(), + ts.factory.createStringLiteral('__' + name) + ), + ts.factory.createToken(ts.SyntaxKind.ColonToken), + ts.factory.createElementAccessExpression( + ts.factory.createThis(), + ts.factory.createStringLiteral(name) + ) + )) + ) + )); + } else { + properties.push(ts.factory.createPropertyAssignment( + keyName, + node.right + )); + } + } + }); +} + +export function updateInteropObjectLiteralxpression(origin: ts.CallExpression, newNode:ts.Expression, name: string): ts.ExpressionStatement { + const properties: ts.ObjectLiteralElementLike[] = []; + processObjectLiteral(properties, origin.arguments[0] as ts.ParenthesizedExpression); + return ts.factory.createExpressionStatement(ts.factory.updateCallExpression( + origin, + newNode, + undefined, + [ts.factory.createCallExpression( + ts.factory.createIdentifier(BUILDER_PARAM_PROXY_INTEROP), + undefined, + [ + ts.factory.createStringLiteral(name), + ts.factory.createObjectLiteralExpression(properties), + makeArrow(origin.arguments[0] as ts.ParenthesizedExpression) + ] + )] + )); +} + +function makeArrow(node: ts.ParenthesizedExpression): ts.ArrowFunction { + return ts.factory.createArrowFunction( + undefined, + undefined, + [], + undefined, + ts.factory.createToken(ts.SyntaxKind.EqualsGreaterThanToken), + node + ); +} \ No newline at end of file -- Gitee From 2e6d93ecac22a3c239e08b014752217799ef75e0 Mon Sep 17 00:00:00 2001 From: l00913061 Date: Thu, 4 Sep 2025 19:30:58 +0800 Subject: [PATCH 2/2] builderupdate Signed-off-by: l00913061 --- .../ui-plugins/interop/initstatevar.ts | 57 +++++++++++++++++++ arkui-plugins/ui-plugins/interop/interop.ts | 2 + .../ui-plugins/interop/predefines.ts | 1 + compiler/src/interop/src/pre_define.ts | 2 +- .../interop/src/process_component_build.ts | 4 +- .../interop/src/process_interop_builder.ts | 44 ++++++-------- .../src/interop/src/process_interop_ui.ts | 3 +- 7 files changed, 81 insertions(+), 32 deletions(-) diff --git a/arkui-plugins/ui-plugins/interop/initstatevar.ts b/arkui-plugins/ui-plugins/interop/initstatevar.ts index 14225718e..1f43c179e 100644 --- a/arkui-plugins/ui-plugins/interop/initstatevar.ts +++ b/arkui-plugins/ui-plugins/interop/initstatevar.ts @@ -231,7 +231,9 @@ export function processNormal(keyName: string, value: arkts.AstNode): arkts.Stat */ export function processBuilderParam(keyName: string, value: arkts.AstNode): arkts.Statement[] { const result: arkts.Statement[] = []; + const needUpdate: boolean = checkUpdatable(value); const newValue = arkts.factory.createCallExpression( + needUpdate ? arkts.factory.createIdentifier(BuilderMethodNames.TRANSFERCOMPATIBLEUPDATABLEBUILDER) : arkts.factory.createIdentifier(BuilderMethodNames.TRANSFERCOMPATIBLEBUILDER), undefined, [ @@ -245,4 +247,59 @@ export function processBuilderParam(keyName: string, value: arkts.AstNode): arkt ); result.push(setProperty); return result; +} + +function getIdentifier(value: arkts.AstNode): arkts.identifier | undefined { + if (arkts.isIdentifier(value)) { + return value; + } else if (arkts.isMemberExpression(value) && arkts.isThisExpression(value.object) && arkts.isIdentifier(value.property)) { + return value.property; + } else { + return undefined; + } +} + +function checkUpdatable(value: arkts.AstNode): boolean { + const ident = getIdentifier(value); + if (ident === undefined) { + return false; + } + const decl = arkts.getDecl(ident) as arkts.MethodDefinition; + const script = decl.scriptFunction; + const params = script.params; + if (params.length === 1 && arkts.isEtsParameterExpression(params[0])) { + const type = params[0].type; + if (type === undefined) { + return false; + } + if (arkts.isETSUnionType(type)) { + for (const element of type.types) { + if (isNonBuiltinType(element)) { + return true; + } + } + } else if (isNonBuiltinType(type)) { + return true; + } + } + return false; +} + +function isNonBuiltinType(type: arkts.AstNode): boolean { + if (!arkts.isETSTypeReference(type)) { + return false; + } + const ident = type.part?.name; + if (ident && arkts.isIdentifier(ident)) { + const decl = arkts.getDecl(ident); + if (!decl) { + return false; + } + const moduleName = arkts.getProgramFromAstNode(decl).moduleName; + if (moduleName === 'escompat') { + return false; + } + return true; + } + return false; } \ 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 8da4bc6d5..554444410 100644 --- a/arkui-plugins/ui-plugins/interop/interop.ts +++ b/arkui-plugins/ui-plugins/interop/interop.ts @@ -402,6 +402,8 @@ export function isArkUICompatible(node: arkts.AstNode): boolean { ImportCollector.getInstance().collectImport(InteroperAbilityNames.GETCOMPATIBLESTATE); ImportCollector.getInstance().collectSource(BuilderMethodNames.TRANSFERCOMPATIBLEBUILDER, InteroperAbilityNames.INTEROP); ImportCollector.getInstance().collectImport(BuilderMethodNames.TRANSFERCOMPATIBLEBUILDER); + ImportCollector.getInstance().collectSource(BuilderMethodNames.TRANSFERCOMPATIBLEUPDATABLEBUILDER, InteroperAbilityNames.INTEROP); + ImportCollector.getInstance().collectImport(BuilderMethodNames.TRANSFERCOMPATIBLEUPDATABLEBUILDER); return true; } return false; diff --git a/arkui-plugins/ui-plugins/interop/predefines.ts b/arkui-plugins/ui-plugins/interop/predefines.ts index 1a8f5deab..5eec3bffe 100644 --- a/arkui-plugins/ui-plugins/interop/predefines.ts +++ b/arkui-plugins/ui-plugins/interop/predefines.ts @@ -65,6 +65,7 @@ export enum BuilderMethodNames { RUNPENDINGJOBS = 'runPendingJobs', CREATECOMPATIBLENODE = 'createCompatibleNode', TRANSFERCOMPATIBLEBUILDER = 'transferCompatibleBuilder', + TRANSFERCOMPATIBLEUPDATABLEBUILDER = 'transferCompatibleUpdatableBuilder', } export enum BuilderParams { diff --git a/compiler/src/interop/src/pre_define.ts b/compiler/src/interop/src/pre_define.ts index ba0fc530a..6605153d6 100644 --- a/compiler/src/interop/src/pre_define.ts +++ b/compiler/src/interop/src/pre_define.ts @@ -623,7 +623,7 @@ export const RESERT = 'reset'; export const TS_NOCHECK: string = '// @ts-nocheck'; export const BUILDER_PARAM_PROXY: string = 'makeBuilderParameterProxy'; -export const BUILDER_PARAM_PROXY_INTEROP: string = 'makeBuilderParameterProxyInterop'; +export const BUILDER_PARAM_PROXY_INTEROP: string = '__makeBuilderParameterStaticProxy_Interop_Internal'; export const BUILDER_TYPE: string = 'BuilderType'; export const FUNCTION: string = 'function'; diff --git a/compiler/src/interop/src/process_component_build.ts b/compiler/src/interop/src/process_component_build.ts index 6e233e89e..4956abd64 100644 --- a/compiler/src/interop/src/process_component_build.ts +++ b/compiler/src/interop/src/process_component_build.ts @@ -203,7 +203,7 @@ import { concatenateEtsOptions, getExternalComponentPaths } from './external_component_map'; -import { updateInteropObjectLiteralxpression } from './process_interop_builder'; +import { isStaticObjectLiteral, updateInteropObjectLiteralxpression } from './process_interop_builder'; export function processComponentBuild(node: ts.MethodDeclaration, log: LogInfo[]): ts.MethodDeclaration { @@ -628,7 +628,7 @@ export function transferBuilderCall(node: ts.ExpressionStatement, name: string, ] )] )); - } else if (ts.isParenthesizedExpression(node.expression.arguments[0]) && ts.isCommaListExpression(node.expression.arguments[0].expression)) { + } else if (isStaticObjectLiteral(node.expression.arguments[0])) { return updateInteropObjectLiteralxpression(node.expression, newNode, name); } } diff --git a/compiler/src/interop/src/process_interop_builder.ts b/compiler/src/interop/src/process_interop_builder.ts index abdf7301f..0f83f99b9 100644 --- a/compiler/src/interop/src/process_interop_builder.ts +++ b/compiler/src/interop/src/process_interop_builder.ts @@ -16,6 +16,17 @@ import ts from 'typescript'; import { BUILDER_PARAM_PROXY_INTEROP } from './pre_define'; +export function isStaticObjectLiteral(node: ts.Expression): boolean { + if (ts.isParenthesizedExpression(node) && ts.isCommaListExpression(node.expression)) { + const list = node.expression.elements; + const lastNode = list[list.length - 1]; + if (ts.isIdentifier(lastNode) && lastNode.text.startsWith('tmpObj')) { + return true; + } + } + return false; +} + function processObjectLiteral(properties: ts.ObjectLiteralElementLike[], node: ts.ParenthesizedExpression): void { const list = (node.expression as ts.CommaListExpression).elements; list.forEach(node => { @@ -31,22 +42,10 @@ function processObjectLiteral(properties: ts.ObjectLiteralElementLike[], node: t [], undefined, ts.factory.createToken(ts.SyntaxKind.EqualsGreaterThanToken), - ts.factory.createParenthesizedExpression(ts.factory.createConditionalExpression( - ts.factory.createElementAccessExpression( - ts.factory.createThis(), - ts.factory.createStringLiteral('__' + name) - ), - ts.factory.createToken(ts.SyntaxKind.QuestionToken), - ts.factory.createElementAccessExpression( - ts.factory.createThis(), - ts.factory.createStringLiteral('__' + name) - ), - ts.factory.createToken(ts.SyntaxKind.ColonToken), - ts.factory.createElementAccessExpression( - ts.factory.createThis(), - ts.factory.createStringLiteral(name) - ) - )) + ts.factory.createElementAccessExpression( + ts.factory.createThis(), + ts.factory.createStringLiteral(name) + ) ) )); } else { @@ -71,20 +70,9 @@ export function updateInteropObjectLiteralxpression(origin: ts.CallExpression, n undefined, [ ts.factory.createStringLiteral(name), + origin.arguments[0], ts.factory.createObjectLiteralExpression(properties), - makeArrow(origin.arguments[0] as ts.ParenthesizedExpression) ] )] )); } - -function makeArrow(node: ts.ParenthesizedExpression): ts.ArrowFunction { - return ts.factory.createArrowFunction( - undefined, - undefined, - [], - undefined, - ts.factory.createToken(ts.SyntaxKind.EqualsGreaterThanToken), - node - ); -} \ No newline at end of file diff --git a/compiler/src/interop/src/process_interop_ui.ts b/compiler/src/interop/src/process_interop_ui.ts index 4907c40ae..cad3fcdde 100644 --- a/compiler/src/interop/src/process_interop_ui.ts +++ b/compiler/src/interop/src/process_interop_ui.ts @@ -168,7 +168,8 @@ class HandleUIImports { const interopImportName = [ 'compatibleComponent', 'getCompatibleState', - 'transferCompatibleBuilder' + 'transferCompatibleBuilder', + 'transferCompatibleUpdatableBuilder' ]; const interopImportSpecifiers: ts.ImportSpecifier[] = []; interopImportName.forEach((interopName) => { -- Gitee