From d4a1639dc92ab7905bbd58861d53d5f6a24332b3 Mon Sep 17 00:00:00 2001 From: Yenan Date: Mon, 1 Sep 2025 15:38:33 +0800 Subject: [PATCH] =?UTF-8?q?=E5=B7=A5=E5=85=B7=E9=93=BE=E6=94=AF=E6=8C=81mu?= =?UTF-8?q?tableBuilder?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Yenan --- compiler/src/pre_define.ts | 4 + compiler/src/process_component_build.ts | 117 +++++++++++++++++++++++- 2 files changed, 119 insertions(+), 2 deletions(-) diff --git a/compiler/src/pre_define.ts b/compiler/src/pre_define.ts index 17a174368..fd06d674b 100644 --- a/compiler/src/pre_define.ts +++ b/compiler/src/pre_define.ts @@ -305,6 +305,8 @@ export const CUSTOM_DIALOG_CONTROLLER_BUILDER: string = 'builder'; export const BUILDER_ATTR_NAME: string = 'builder'; export const BUILDER_ATTR_BIND: string = 'bind'; +export const MUTABLEBUILDER_DISPATCHBUILDER: string = '_dispatchBuilder'; + export const GEOMETRY_VIEW: string = 'GeometryView'; export const MODULE_SHARE_PATH: string = 'src' + path.sep + 'main' + path.sep + 'ets' + path.sep + 'share'; @@ -648,7 +650,9 @@ export const USER_DEFINE_MOCK_CONFIG: string = 'mock-config.json5'; export const WRAPBUILDER_FUNCTION: string = 'wrapBuilder'; export const WRAPPEDBUILDER_CLASS: string = 'WrappedBuilder'; +export const MUTABLEBUILDER_CLASS: string = 'MutableBuilder'; export const WRAPBUILDER_BUILDERPROP: string = 'builder'; +export const MUTABLEBUILDER_BUILDERPROP: string = 'builder'; export const LENGTH: string = 'length'; export const PREVIEW: string = 'preview'; diff --git a/compiler/src/process_component_build.ts b/compiler/src/process_component_build.ts index b6d2888b4..70a5763f9 100644 --- a/compiler/src/process_component_build.ts +++ b/compiler/src/process_component_build.ts @@ -139,7 +139,10 @@ import { CREATE_ROUTER_COMPONENT_COLLECT, NAV_PATH_STACK, IS_USER_CREATE_STACK, - REUSE_ATTRIBUTE + REUSE_ATTRIBUTE, + MUTABLEBUILDER_BUILDERPROP, + MUTABLEBUILDER_CLASS, + MUTABLEBUILDER_DISPATCHBUILDER } from './pre_define'; import { INNER_COMPONENT_NAMES, @@ -534,6 +537,12 @@ export function processComponentChild(node: ts.Block | ts.SourceFile, newStateme newStatements.push(addInnerBuilderParameter(item, isGlobalBuilder)); } break; + case ComponentType.mutableBuilderMethod: + parent = undefined; + if (partialUpdateConfig.partialUpdateMode) { + newStatements.push(transferMutableBuilderCall(item, name)); + } + break; case ComponentType.builderParamMethod: parent = undefined; if (partialUpdateConfig.partialUpdateMode) { @@ -3329,7 +3338,8 @@ enum ComponentType { builderParamMethod, function, builderTypeFunction, - repeatComponent + repeatComponent, + mutableBuilderMethod } function isEtsComponent(node: ts.ExpressionStatement): boolean { @@ -3381,6 +3391,8 @@ function getComponentType(node: ts.ExpressionStatement, log: LogInfo[], name: st } else if (isLocalBuilderOrBuilderMethod(CUSTOM_BUILDER_METHOD, isBuilderName, name) || isWrappedBuilderExpression(node) || isLocalBuilderOrBuilderMethod(INNER_CUSTOM_LOCALBUILDER_METHOD, isLocalBuilderName, name)) { return ComponentType.customBuilderMethod; + } else if (isMutableBuilderExpression(node)) { + return ComponentType.mutableBuilderMethod; } else if (builderParamObjectCollection.get(componentCollection.currentClassName) && builderParamObjectCollection.get(componentCollection.currentClassName).has(name)) { return ComponentType.builderParamMethod; @@ -3739,4 +3751,105 @@ function equalToHiddenNav(componentName: string): boolean { function equalToHiddenNavDes(componentName: string): boolean { return (EXT_WHITE_LIST.length >= 2) && (componentName === EXT_WHITE_LIST[1]); +} + +export function transferMutableBuilderCall(node: ts.ExpressionStatement, name: string): ts.ExpressionStatement { + if (node.expression && ts.isCallExpression(node.expression)) { + let newNode: ts.Expression = mutableBuilderCallNode(node.expression); + // 按引用传递 + if (node.expression.arguments && node.expression.arguments.length === 1 && ts.isObjectLiteralExpression(node.expression.arguments[0]) && + ts.isPropertyAccessExpression(node.expression.expression)) { + return ts.factory.createExpressionStatement(ts.factory.updateCallExpression( + node.expression, + newNode, + undefined, + [ts.factory.createArrowFunction(undefined, + undefined, + [], + undefined, + ts.factory.createToken(ts.SyntaxKind.EqualsGreaterThanToken), + node.expression.expression.expression), + ts.factory.createCallExpression( + ts.factory.createIdentifier(BUILDER_PARAM_PROXY), + undefined, + [ + ts.factory.createStringLiteral(name), + traverseBuilderParams(node.expression.arguments[0], true) + ] + )] + )); + } else if (ts.isPropertyAccessExpression(node.expression.expression)) { + return ts.factory.createExpressionStatement(ts.factory.updateCallExpression( + node.expression, + newNode, + undefined, + !(projectConfig.optLazyForEach && (storedFileInfo.processLazyForEach && + storedFileInfo.lazyForEachInfo.forEachParameters || true)) ? + [ts.factory.createArrowFunction(undefined, + undefined, + [], + undefined, + ts.factory.createToken(ts.SyntaxKind.EqualsGreaterThanToken), + node.expression.expression.expression), + ...node.expression.arguments] : + [...node.expression.arguments, ts.factory.createNull(), ts.factory.createIdentifier(MY_IDS)] + )); + } + } + return undefined; +} + +function mutableBuilderCallNode(node: ts.CallExpression): ts.Expression { + let newNode: ts.Expression; + if (node.expression && ts.isPropertyAccessExpression(node.expression)) { + newNode = ts.factory.createCallExpression( + ts.factory.createPropertyAccessExpression( + ts.factory.createPropertyAccessExpression( + node.expression.expression, + ts.factory.createIdentifier(MUTABLEBUILDER_DISPATCHBUILDER) + ), + ts.factory.createIdentifier(BUILDER_ATTR_BIND) + ), + undefined, + [ts.factory.createThis()] + ); + } + return newNode; +} + +export function isMutableBuilder(node: ts.PropertyAccessExpression): boolean { + if (!( + projectConfig.minAPIVersion >= 11 && + ts.isPropertyAccessExpression(node) && + node.name && ts.isIdentifier(node.name) && + node.name.escapedText.toString() === MUTABLEBUILDER_BUILDERPROP + )) { + return false; + } + const checker: ts.TypeChecker | undefined = CurrentProcessFile.getChecker(); + if (checker) { + const type: ts.Type | ts.Type[] = + findNonNullType(checker.getTypeAtLocation(node.expression)); + if (Array.isArray(type)) { + return false; + } + return type.symbol && type.symbol.escapedName === MUTABLEBUILDER_CLASS; + } + return false; +} + +function isMutableBuilderCallExpression(node: ts.CallExpression): boolean { + if (projectConfig.minAPIVersion >= 11 && ts.isCallExpression(node) && node.expression && + isMutableBuilder(node.expression as ts.PropertyAccessExpression)) { + return true; + } + return false; +} + +function isMutableBuilderExpression(node: ts.ExpressionStatement): boolean { + if (projectConfig.minAPIVersion >= 11 && node.expression && + isMutableBuilderCallExpression(node.expression as ts.CallExpression)) { + return true; + } + return false; } \ No newline at end of file -- Gitee