From 702330bcad967af0b5ef70694d2fc058f80cc5ae Mon Sep 17 00:00:00 2001 From: songbeibei <3409533354@qq.com> Date: Wed, 12 Jan 2022 21:15:44 +0800 Subject: [PATCH 1/8] puyajun@huawei.com Signed-off-by: songbeibei <3409533354@qq.com> --- compiler/src/pre_define.ts | 3 +- compiler/src/process_component_build.ts | 46 ++++++++++++++++++++++-- compiler/src/process_component_class.ts | 3 +- compiler/src/process_component_member.ts | 21 +++++++++-- compiler/src/process_custom_component.ts | 9 +++-- 5 files changed, 72 insertions(+), 10 deletions(-) diff --git a/compiler/src/pre_define.ts b/compiler/src/pre_define.ts index a0a1f741c..8efee8a17 100644 --- a/compiler/src/pre_define.ts +++ b/compiler/src/pre_define.ts @@ -35,13 +35,14 @@ export const COMPONENT_PROVIDE_DECORATOR: string = '@Provide'; export const COMPONENT_CONSUME_DECORATOR: string = '@Consume'; export const COMPONENT_OBJECT_LINK_DECORATOR: string = '@ObjectLink'; export const COMPONENT_WATCH_DECORATOR: string = '@Watch'; +export const COMPONENT_BUILDERPARAM_DECORATOR: string = '@BuilderParam'; export const INNER_COMPONENT_DECORATORS: Set = new Set([COMPONENT_DECORATOR_ENTRY, COMPONENT_DECORATOR_PREVIEW, COMPONENT_DECORATOR_COMPONENT, COMPONENT_DECORATOR_CUSTOM_DIALOG]); export const INNER_COMPONENT_MEMBER_DECORATORS: Set = new Set([COMPONENT_STATE_DECORATOR, COMPONENT_PROP_DECORATOR, COMPONENT_LINK_DECORATOR, COMPONENT_STORAGE_PROP_DECORATOR, COMPONENT_STORAGE_LINK_DECORATOR, COMPONENT_PROVIDE_DECORATOR, COMPONENT_CONSUME_DECORATOR, - COMPONENT_OBJECT_LINK_DECORATOR, COMPONENT_WATCH_DECORATOR]); + COMPONENT_OBJECT_LINK_DECORATOR, COMPONENT_WATCH_DECORATOR, COMPONENT_BUILDERPARAM_DECORATOR]); export const COMPONENT_OBSERVED_DECORATOR: string = '@Observed'; export const COMPONENT_BUILDER_DECORATOR: string = '@Builder'; diff --git a/compiler/src/process_component_build.ts b/compiler/src/process_component_build.ts index a2d4acc69..5c46d1190 100644 --- a/compiler/src/process_component_build.ts +++ b/compiler/src/process_component_build.ts @@ -76,6 +76,7 @@ import { componentInfo, createFunction } from './utils'; +import { builderParamObjectCollection } from './process_component_member'; import { projectConfig } from '../main'; import { transformLog } from './process_ui_syntax'; import { props } from './compile_info'; @@ -157,7 +158,7 @@ function validateRootNode(node: ts.MethodDeclaration, log: LogInfo[]): boolean { export function processComponentChild(node: ts.Block | ts.SourceFile, newStatements: ts.Statement[], log: LogInfo[]): void { if (node.statements.length) { - node.statements.forEach((item, index) => { + node.statements.forEach((item, index, array) => { if (ts.isExpressionStatement(item)) { const name: string = getName(item); switch (getComponentType(item, log, name)) { @@ -165,6 +166,12 @@ export function processComponentChild(node: ts.Block | ts.SourceFile, newStateme processInnerComponent(item, index, Array.from(node.statements), newStatements, log, name); break; case ComponentType.customComponent: + if (index + 1 < array.length && ts.isBlock(array[index + 1])) { + // @ts-ignore + const nextNode:ts.Block = array[index + 1] + item = processBlockNode(item, nextNode, log) + } + // @ts-ignore processCustomComponent(item, newStatements, log); break; case ComponentType.forEachComponent: @@ -173,10 +180,13 @@ export function processComponentChild(node: ts.Block | ts.SourceFile, newStateme case ComponentType.customBuilderMethod: newStatements.push(item); break; + case ComponentType.builderParamMethod: + processExpressionStatement(item, newStatements, log); + break; } } else if (ts.isIfStatement(item)) { appComponentCollection.add(COMPONENT_IF); - processIfStatement(item, newStatements, log); + processCustomBuilderComponent(item, newStatements, log); } else if (!ts.isBlock(item)) { log.push({ type: LogType.ERROR, @@ -188,6 +198,32 @@ export function processComponentChild(node: ts.Block | ts.SourceFile, newStateme } } +function processExpressionStatement(node: ts.ExpressionStatement, nextNode: ts.Block, + log: LogInfo[]): ts.block { + // @ts-ignore + const newBlock:ts.Block = processComponentBlock(nextNode, false, log) + const arrowNode = ts.factory.createArrowFunction(undefined, undefined, [], undefined, + ts.factory.createToken(ts.SyntaxKind.EqualsGreaterThanToken), newBlock); + const newPropertyAssignment:ts.PropertyAssignment = ts.factory.createPropertyAssignment( + ts.factory.createIdentifier('child'), arrowNode) + // @ts-ignore + let argumentsArray: Array = node.express.arguments; + if (arguments && arguments.length < 1) { + argumentsArray = [ts.factory.createObjectLiteralExpression([], false)] + } + // @ts-ignore + argumentsArray[0].properties.push(newPropertyAssignment); + // @ts-ignore + node = ts.factory.updateExpressionStatement(node, ts.factory.updateCallExpression( + node.expression, node.expression.expression, [], argumentsArray)) + return node; +} + +function processCustomBuilderComponent(node: ts.ExpressionStatement, newStatements: ts.Statement[], + log: LogInfo[]): void { + newStatements.push(node); +} + function processInnerComponent(node: ts.ExpressionStatement, index: number, arr: ts.Statement[], newStatements: ts.Statement[], log: LogInfo[], name: string): void { const res: CreateResult = createComponent(node, COMPONENT_CREATE_FUNCTION); @@ -802,7 +838,8 @@ enum ComponentType { innerComponent, customComponent, forEachComponent, - customBuilderMethod + customBuilderMethod, + builderParamMethod } function getComponentType(node: ts.ExpressionStatement, log: LogInfo[], @@ -816,6 +853,9 @@ function getComponentType(node: ts.ExpressionStatement, log: LogInfo[], return ComponentType.forEachComponent; } else if (CUSTOM_BUILDER_METHOD.has(name)) { return ComponentType.customBuilderMethod; + } else if (builderParamObjectCollection.get(componentCollection.currentClassName) && + builderParamObjectCollection.get(componentCollection.currentClassName).has(name)) { + return ComponentType.builderParamMethod; } else if (!isAttributeNode(node)) { log.push({ type: LogType.ERROR, diff --git a/compiler/src/process_component_class.ts b/compiler/src/process_component_class.ts index 1ac7be84b..e4660f848 100644 --- a/compiler/src/process_component_class.ts +++ b/compiler/src/process_component_class.ts @@ -238,7 +238,8 @@ function validateBuilderFunctionNode(node: ts.PropertyAccessExpression | ts.Iden ts.isIdentifier(node) && CUSTOM_BUILDER_METHOD.has(node.escapedText.toString())) && !((ts.isPropertyAccessExpression(node) && validateBuilderParam(node)) || (ts.isIdentifier(node) && node.parent && ts.isPropertyAccessExpression(node.parent) && - validateBuilderParam(node.parent)))) { + validateBuilderParam(node.parent))) && + (node.paren.argument || (node.paren.argument && node.paren.argument.length < 0))) { return true; } else { return false; diff --git a/compiler/src/process_component_member.ts b/compiler/src/process_component_member.ts index 4799fe32d..11f43d34c 100644 --- a/compiler/src/process_component_member.ts +++ b/compiler/src/process_component_member.ts @@ -51,7 +51,8 @@ import { JS_DIALOG, CUSTOM_DIALOG_CONTROLLER_BUILDER, BASE_COMPONENT_NAME, - COMPONENT_CREATE_FUNCTION + COMPONENT_CREATE_FUNCTION, + COMPONENT_BUILDERPARAM_DECORATOR } from './pre_define'; import { forbiddenUseStateType, @@ -98,7 +99,9 @@ export const mandatoryToInitViaParamDecorators: Set = new Set([...propAndLinkDecorators, COMPONENT_OBJECT_LINK_DECORATOR]); export const setUpdateParamsDecorators: Set = - new Set([...observedPropertyDecorators, COMPONENT_PROP_DECORATOR, COMPONENT_OBJECT_LINK_DECORATOR]); + new Set([...observedPropertyDecorators, COMPONENT_PROP_DECORATOR, COMPONENT_OBJECT_LINK_DECORATOR, + COMPONENT_BUILDERPARAM_DECORATOR + ]); export const immutableDecorators: Set = new Set([COMPONENT_STORAGE_PROP_DECORATOR, COMPONENT_OBJECT_LINK_DECORATOR]); @@ -110,6 +113,8 @@ export const decoratorParamSet: Set = new Set(); export const stateObjectCollection: Set = new Set(); +export const builderParamObjectCollection: Map> = new Map(); + export class UpdateResult { private itemUpdate: boolean = false; private ctorUpdate: boolean = false; @@ -263,7 +268,7 @@ function processPropertyNodeDecorator(parentName: ts.Identifier, node: ts.Proper if (node.questionToken && mandatoryToInitViaParamDecorators.has(decoratorName)) { validateHasIllegalQuestionToken(name, decoratorName, log); } - if (!isSimpleType(node.type, program)) { + if (!isSimpleType(node.type, program) && decoratorName !== COMPONENT_BUILDERPARAM_DECORATOR) { stateObjectCollection.add(name.escapedText.toString()); } if (decoratorName === COMPONENT_WATCH_DECORATOR && @@ -405,6 +410,16 @@ function createUpdateParams(name: ts.Identifier, decorator: string): ts.Statemen case COMPONENT_OBJECT_LINK_DECORATOR: updateParamsNode = createUpdateParamsWithSet(name); break; + case COMPONENT_BUILDERPARAM_DECORATOR: + if (decorator === COMPONENT_BUILDERPARAM_DECORATOR) { + if (!builderParamObjectCollection.get(componentCollection.currentClassName)) { + builderParamObjectCollection.set(componentCollection.currentClassName, new Set([])); + } + builderParamObjectCollection.get(componentCollection.currentClassName) + .add(name.escapedText.toString()) + } + updateParamsNode = createUpdateParamsWithoutIf(name); + break; } return updateParamsNode; } diff --git a/compiler/src/process_custom_component.ts b/compiler/src/process_custom_component.ts index 163e8cbb3..ee7eff8dc 100644 --- a/compiler/src/process_custom_component.ts +++ b/compiler/src/process_custom_component.ts @@ -105,7 +105,9 @@ function validateCustomComponentPrams(node: ts.ExpressionStatement, name: string ts.isObjectLiteralExpression(nodeArguments[0])) { const nodeArgument: ts.ObjectLiteralExpression = nodeArguments[0] as ts.ObjectLiteralExpression; nodeArgument.properties.forEach(item => { - curChildProps.add(item.name.getText()); + if (item.name && item.initializer && item.initializer.text) { + curChildProps.add(item.name.getText()); + } if (isThisProperty(item, propertySet)) { validateStateManagement(item, name, log); if (isNonThisProperty(item, linkSet)) { @@ -157,7 +159,10 @@ function validateStateManagement(node: ts.ObjectLiteralElementLike, customCompon function checkFromParentToChild(node: ts.ObjectLiteralElementLike, customComponentName: string, log: LogInfo[]): void { - const propertyName: string = node.name.getText(); + let propertyName: string; + if (node.name && node.initializer && node.initializer.text) { + propertyName = node.name.getText(); + } const curPropertyKind: string = getPropertyDecoratorKind(propertyName, customComponentName); if (curPropertyKind) { if (isInitFromParent(node)) { -- Gitee From 226b257d470a09904a43c359d55fc37d396f6a5f Mon Sep 17 00:00:00 2001 From: songbeibei <3409533354@qq.com> Date: Thu, 13 Jan 2022 11:39:20 +0800 Subject: [PATCH 2/8] puyajun@huawei.com Signed-off-by: songbeibei <3409533354@qq.com> --- compiler/src/process_component_build.ts | 7 +++++-- compiler/src/process_component_class.ts | 1 + compiler/src/process_custom_component.ts | 10 ++++++---- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/compiler/src/process_component_build.ts b/compiler/src/process_component_build.ts index 5c46d1190..028a47836 100644 --- a/compiler/src/process_component_build.ts +++ b/compiler/src/process_component_build.ts @@ -211,10 +211,13 @@ function processExpressionStatement(node: ts.ExpressionStatement, nextNode: ts.B if (arguments && arguments.length < 1) { argumentsArray = [ts.factory.createObjectLiteralExpression([], false)] } - // @ts-ignore - argumentsArray[0].properties.push(newPropertyAssignment); + if (ts.isObjectLiteralExpression(argumentsArray[0])) { + // @ts-ignore + argumentsArray[0].properties.push(newPropertyAssignment); + } // @ts-ignore node = ts.factory.updateExpressionStatement(node, ts.factory.updateCallExpression( + // @ts-ignore node.expression, node.expression.expression, [], argumentsArray)) return node; } diff --git a/compiler/src/process_component_class.ts b/compiler/src/process_component_class.ts index e4660f848..4208741b2 100644 --- a/compiler/src/process_component_class.ts +++ b/compiler/src/process_component_class.ts @@ -239,6 +239,7 @@ function validateBuilderFunctionNode(node: ts.PropertyAccessExpression | ts.Iden !((ts.isPropertyAccessExpression(node) && validateBuilderParam(node)) || (ts.isIdentifier(node) && node.parent && ts.isPropertyAccessExpression(node.parent) && validateBuilderParam(node.parent))) && + // @ts-ignore (node.paren.argument || (node.paren.argument && node.paren.argument.length < 0))) { return true; } else { diff --git a/compiler/src/process_custom_component.ts b/compiler/src/process_custom_component.ts index ee7eff8dc..69bcf846d 100644 --- a/compiler/src/process_custom_component.ts +++ b/compiler/src/process_custom_component.ts @@ -105,8 +105,9 @@ function validateCustomComponentPrams(node: ts.ExpressionStatement, name: string ts.isObjectLiteralExpression(nodeArguments[0])) { const nodeArgument: ts.ObjectLiteralExpression = nodeArguments[0] as ts.ObjectLiteralExpression; nodeArgument.properties.forEach(item => { - if (item.name && item.initializer && item.initializer.text) { - curChildProps.add(item.name.getText()); + if (item.name) { + // @ts-ignore + curChildProps.add(node.name.escapedText); } if (isThisProperty(item, propertySet)) { validateStateManagement(item, name, log); @@ -160,8 +161,9 @@ function validateStateManagement(node: ts.ObjectLiteralElementLike, customCompon function checkFromParentToChild(node: ts.ObjectLiteralElementLike, customComponentName: string, log: LogInfo[]): void { let propertyName: string; - if (node.name && node.initializer && node.initializer.text) { - propertyName = node.name.getText(); + if (node.name) { + // @ts-ignore + propertyName = node.name.escapedText; } const curPropertyKind: string = getPropertyDecoratorKind(propertyName, customComponentName); if (curPropertyKind) { -- Gitee From 80041973664cb505d3f77943e633ef51e8083085 Mon Sep 17 00:00:00 2001 From: songbeibei <3409533354@qq.com> Date: Thu, 13 Jan 2022 13:08:08 +0800 Subject: [PATCH 3/8] puyajun@huawei.com Signed-off-by: songbeibei <3409533354@qq.com> --- compiler/src/process_component_build.ts | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/compiler/src/process_component_build.ts b/compiler/src/process_component_build.ts index 028a47836..73eae5285 100644 --- a/compiler/src/process_component_build.ts +++ b/compiler/src/process_component_build.ts @@ -209,11 +209,12 @@ function processExpressionStatement(node: ts.ExpressionStatement, nextNode: ts.B // @ts-ignore let argumentsArray: Array = node.express.arguments; if (arguments && arguments.length < 1) { - argumentsArray = [ts.factory.createObjectLiteralExpression([], false)] - } - if (ts.isObjectLiteralExpression(argumentsArray[0])) { + argumentsArray = [ts.factory.createObjectLiteralExpression([newPropertyAssignment], false)] + } else { + // @ts-ignore + node.express.arguments[0].properties.push(newPropertyAssignment); // @ts-ignore - argumentsArray[0].properties.push(newPropertyAssignment); + argumentsArray = node.express.arguments; } // @ts-ignore node = ts.factory.updateExpressionStatement(node, ts.factory.updateCallExpression( -- Gitee From 23816aebb8802fbf563ec54289d48ea41a87d2c5 Mon Sep 17 00:00:00 2001 From: songbeibei <3409533354@qq.com> Date: Thu, 13 Jan 2022 15:36:04 +0800 Subject: [PATCH 4/8] puyajun@huawei.com Signed-off-by: songbeibei <3409533354@qq.com> --- compiler/src/process_component_build.ts | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/compiler/src/process_component_build.ts b/compiler/src/process_component_build.ts index 73eae5285..f372f02c5 100644 --- a/compiler/src/process_component_build.ts +++ b/compiler/src/process_component_build.ts @@ -209,12 +209,11 @@ function processExpressionStatement(node: ts.ExpressionStatement, nextNode: ts.B // @ts-ignore let argumentsArray: Array = node.express.arguments; if (arguments && arguments.length < 1) { - argumentsArray = [ts.factory.createObjectLiteralExpression([newPropertyAssignment], false)] + argumentsArray = [ts.factory.createObjectLiteralExpression([newPropertyAssignment], true)] } else { // @ts-ignore - node.express.arguments[0].properties.push(newPropertyAssignment); - // @ts-ignore - argumentsArray = node.express.arguments; + argumentsArray = [ts.factory.createObjectLiteralExpression(node.express.arguments[0].properties.concat( + [newPropertyAssignment]), true)] } // @ts-ignore node = ts.factory.updateExpressionStatement(node, ts.factory.updateCallExpression( -- Gitee From b82906179aa2323ccacfb7047de9439e9d45c1a9 Mon Sep 17 00:00:00 2001 From: songbeibei <3409533354@qq.com> Date: Fri, 14 Jan 2022 11:02:01 +0800 Subject: [PATCH 5/8] puyajun@huawei.com Signed-off-by: songbeibei <3409533354@qq.com> --- compiler/src/process_component_build.ts | 18 ++++++------------ compiler/src/process_component_class.ts | 2 +- 2 files changed, 7 insertions(+), 13 deletions(-) diff --git a/compiler/src/process_component_build.ts b/compiler/src/process_component_build.ts index f372f02c5..11c88d82f 100644 --- a/compiler/src/process_component_build.ts +++ b/compiler/src/process_component_build.ts @@ -163,16 +163,15 @@ export function processComponentChild(node: ts.Block | ts.SourceFile, newStateme const name: string = getName(item); switch (getComponentType(item, log, name)) { case ComponentType.innerComponent: - processInnerComponent(item, index, Array.from(node.statements), newStatements, log, name); + processInnerComponent(item, index, Array.from(node.statements), + newStatements, log, name); break; case ComponentType.customComponent: if (index + 1 < array.length && ts.isBlock(array[index + 1])) { - // @ts-ignore - const nextNode:ts.Block = array[index + 1] - item = processBlockNode(item, nextNode, log) + item = processExpressionStatement(item, + array[index + 1] as ts.Block, log) } - // @ts-ignore - processCustomComponent(item, newStatements, log); + processCustomComponent(item as ts.ExpressionStatement, newStatements, log); break; case ComponentType.forEachComponent: processForEachComponent(item, newStatements, log); @@ -186,7 +185,7 @@ export function processComponentChild(node: ts.Block | ts.SourceFile, newStateme } } else if (ts.isIfStatement(item)) { appComponentCollection.add(COMPONENT_IF); - processCustomBuilderComponent(item, newStatements, log); + newStatements.push(node); } else if (!ts.isBlock(item)) { log.push({ type: LogType.ERROR, @@ -222,11 +221,6 @@ function processExpressionStatement(node: ts.ExpressionStatement, nextNode: ts.B return node; } -function processCustomBuilderComponent(node: ts.ExpressionStatement, newStatements: ts.Statement[], - log: LogInfo[]): void { - newStatements.push(node); -} - function processInnerComponent(node: ts.ExpressionStatement, index: number, arr: ts.Statement[], newStatements: ts.Statement[], log: LogInfo[], name: string): void { const res: CreateResult = createComponent(node, COMPONENT_CREATE_FUNCTION); diff --git a/compiler/src/process_component_class.ts b/compiler/src/process_component_class.ts index 4208741b2..5d6a33a70 100644 --- a/compiler/src/process_component_class.ts +++ b/compiler/src/process_component_class.ts @@ -240,7 +240,7 @@ function validateBuilderFunctionNode(node: ts.PropertyAccessExpression | ts.Iden (ts.isIdentifier(node) && node.parent && ts.isPropertyAccessExpression(node.parent) && validateBuilderParam(node.parent))) && // @ts-ignore - (node.paren.argument || (node.paren.argument && node.paren.argument.length < 0))) { + (!node.paren.argument || (node.paren.argument && !node.paren.argument.length))) { return true; } else { return false; -- Gitee From f7ea9f3410f00ac4105896e1ca1f0054d2a6404b Mon Sep 17 00:00:00 2001 From: songbeibei <3409533354@qq.com> Date: Fri, 14 Jan 2022 17:41:46 +0800 Subject: [PATCH 6/8] 1972617324@qq.com --- compiler/src/pre_define.ts | 1 + compiler/src/process_component_build.ts | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/compiler/src/pre_define.ts b/compiler/src/pre_define.ts index 8efee8a17..33f4f2115 100644 --- a/compiler/src/pre_define.ts +++ b/compiler/src/pre_define.ts @@ -182,6 +182,7 @@ export const GEOMETRY_VIEW: string = 'GeometryView'; export const MODULE_SHARE_PATH: string = 'src' + path.sep + 'ets' + path.sep + 'share'; export const BUILD_SHARE_PATH: string = '../share'; +export const CHILD: string = 'child'; export const THIS: string = 'this'; export const STYLES: string = 'Styles'; export const VISUAL_STATE: string = 'visualState'; diff --git a/compiler/src/process_component_build.ts b/compiler/src/process_component_build.ts index 11c88d82f..20f010707 100644 --- a/compiler/src/process_component_build.ts +++ b/compiler/src/process_component_build.ts @@ -45,6 +45,7 @@ import { COMPONENT_TRANSITION_NAME, COMPONENT_DEBUGLINE_FUNCTION, ATTRIBUTE_STATESTYLES, + CHILD, THIS, VISUAL_STATE, VIEW_STACK_PROCESSOR, @@ -204,7 +205,7 @@ function processExpressionStatement(node: ts.ExpressionStatement, nextNode: ts.B const arrowNode = ts.factory.createArrowFunction(undefined, undefined, [], undefined, ts.factory.createToken(ts.SyntaxKind.EqualsGreaterThanToken), newBlock); const newPropertyAssignment:ts.PropertyAssignment = ts.factory.createPropertyAssignment( - ts.factory.createIdentifier('child'), arrowNode) + ts.factory.createIdentifier(CHILD), arrowNode) // @ts-ignore let argumentsArray: Array = node.express.arguments; if (arguments && arguments.length < 1) { -- Gitee From 136eda4ad59de889409efb13922b76938cf5750d Mon Sep 17 00:00:00 2001 From: songbeibei <3409533354@qq.com> Date: Fri, 14 Jan 2022 17:52:05 +0800 Subject: [PATCH 7/8] puyajun@huawei.com Signed-off-by: songbeibei <3409533354@qq.com> --- compiler/src/process_component_build.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/src/process_component_build.ts b/compiler/src/process_component_build.ts index 20f010707..713d8ae74 100644 --- a/compiler/src/process_component_build.ts +++ b/compiler/src/process_component_build.ts @@ -181,7 +181,7 @@ export function processComponentChild(node: ts.Block | ts.SourceFile, newStateme newStatements.push(item); break; case ComponentType.builderParamMethod: - processExpressionStatement(item, newStatements, log); + processBlockChange(item, newStatements, log); break; } } else if (ts.isIfStatement(item)) { @@ -198,7 +198,7 @@ export function processComponentChild(node: ts.Block | ts.SourceFile, newStateme } } -function processExpressionStatement(node: ts.ExpressionStatement, nextNode: ts.Block, +function processBlockChange(node: ts.ExpressionStatement, nextNode: ts.Block, log: LogInfo[]): ts.block { // @ts-ignore const newBlock:ts.Block = processComponentBlock(nextNode, false, log) -- Gitee From d36f1d01f077827067fc3ad7cb42028b05d205e6 Mon Sep 17 00:00:00 2001 From: songbeibei <3409533354@qq.com> Date: Mon, 17 Jan 2022 16:00:05 +0800 Subject: [PATCH 8/8] puyajun@huawei.com Signed-off-by: songbeibei <3409533354@qq.com> --- compiler/src/process_component_class.ts | 2 +- compiler/src/process_component_member.ts | 12 +- compiler/test/ut/builder/builderLambda.ts | 149 +++++++++++++++++++ compiler/test/ut/builder/builderParam.ts | 166 ++++++++++++++++++++++ 4 files changed, 325 insertions(+), 4 deletions(-) create mode 100644 compiler/test/ut/builder/builderLambda.ts create mode 100644 compiler/test/ut/builder/builderParam.ts diff --git a/compiler/src/process_component_class.ts b/compiler/src/process_component_class.ts index 5d6a33a70..a220716b1 100644 --- a/compiler/src/process_component_class.ts +++ b/compiler/src/process_component_class.ts @@ -240,7 +240,7 @@ function validateBuilderFunctionNode(node: ts.PropertyAccessExpression | ts.Iden (ts.isIdentifier(node) && node.parent && ts.isPropertyAccessExpression(node.parent) && validateBuilderParam(node.parent))) && // @ts-ignore - (!node.paren.argument || (node.paren.argument && !node.paren.argument.length))) { + (!node.parent.arguments || (node.parent.arguments && !node.parent.arguments.length))) { return true; } else { return false; diff --git a/compiler/src/process_component_member.ts b/compiler/src/process_component_member.ts index 11f43d34c..5b0ad6ab8 100644 --- a/compiler/src/process_component_member.ts +++ b/compiler/src/process_component_member.ts @@ -418,7 +418,7 @@ function createUpdateParams(name: ts.Identifier, decorator: string): ts.Statemen builderParamObjectCollection.get(componentCollection.currentClassName) .add(name.escapedText.toString()) } - updateParamsNode = createUpdateParamsWithoutIf(name); + updateParamsNode = createUpdateParamsWithoutIf(name, 1); break; } return updateParamsNode; @@ -434,9 +434,15 @@ function createUpdateParamsWithIf(name: ts.Identifier): ts.IfStatement { createUpdateParamsWithoutIf(name)], true), undefined); } -function createUpdateParamsWithoutIf(name: ts.Identifier): ts.ExpressionStatement { +function createUpdateParamsWithoutIf(name: ts.Identifier, isAdd: number = 0): ts.ExpressionStatement { + let escapedTextName: string; + if (isAdd) { + escapedTextName = `__${name.getText()}`; + } else { + escapedTextName = name.getText(); + } return ts.factory.createExpressionStatement(ts.factory.createBinaryExpression( - createPropertyAccessExpressionWithThis(name.getText()), + createPropertyAccessExpressionWithThis(escapedTextName), ts.factory.createToken(ts.SyntaxKind.EqualsToken), createPropertyAccessExpressionWithParams(name.getText()))); } diff --git a/compiler/test/ut/builder/builderLambda.ts b/compiler/test/ut/builder/builderLambda.ts new file mode 100644 index 000000000..c19735078 --- /dev/null +++ b/compiler/test/ut/builder/builderLambda.ts @@ -0,0 +1,149 @@ +/* + * Copyright (c) 2021 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. + */ + +exports.source = ` +@Component +struct CustomContainer { + header: string = ""; + footer: string = ""; + @BuilderParam child: () => any; + + build() { + Column() { + Text(this.header) + this.child() + Text(this.footer) + } + } +} + +@Builder function specificParam(label1: string, label2: string) { + Column() { + Text(label1) + Text(label2) + } +} + +@Entry +@Component +struct CustomContainerUser { + build() { + Column() { + CustomContainer({header: "Header", footer: "Footer"}){ + Column() { + Text("content1") + .width(50) + Text("content2") + } + specificParam("content3", "content4") + } + } + } +} +` +exports.expectResult = +`class CustomContainer extends View { + constructor(compilerAssignedUniqueChildId, parent, params) { + super(compilerAssignedUniqueChildId, parent); + this.header = "" + this.footer = "" + this.updateWithValueParams(params); + } + updateWithValueParams(params) { + if (params.header !== undefined) { + this.header = params.header; + } + if (params.footer !== undefined) { + this.footer = params.footer; + } + this.__child = params.child; + } + aboutToBeDeleted() { + this.__child.aboutToBeDeleted(); + SubscriberManager.Get().delete(this.id()); + } + get child(){ + return this.__child.get(); + } + set child(newValue) { + this.__child.set(newValue) + } + render() { + Column.create(); + Text.create(this.header); + Text.pop(); + this.child(); + Text.create(this.footer); + Text.pop(); + Column.pop(); + } +} +function specificParam(label1, label2) { + Column.create(); + Text.create(label1); + Text.pop(); + Text.create(label1); + Text.pop(); + Column.pop(); +} +class CustomContainerUser { + constructor(compilerAssignedUniqueChildId, parent, params) { + super(compilerAssignedUniqueChildId, parent); + this.updateWithValueParams(params); + } + updateWithValueParams(params) { + } + aboutToBeDeleted() { + SubscriberManager.Get().delete(this.id()); + } + render() { + Column.create(); + let earlierCreatedChild_2 = this.findChildById("2"); + if (earlierCreatedChild_2 == undefined) { + View.create(new CustomContainer("2", this, { + header: "Header", footer: "Footer", + child: () => { + Column.create(); + Text.create("content1"); + Text.width(50) + Text.pop(); + Text.create("content2"); + Text.pop(); + Column.pop(); + specificParam("content3", "content4) + } + })); + } + else { + earlierCreatedChild_2.updateWithValueParams({ + header: "Header", footer: "Footer", + child: () => { + Column.create(); + Text.create("content1"); + Text.width(50) + Text.pop(); + Text.create("content2"); + Text.pop(); + Column.pop(); + specificParam("content3", "content4) + }} + }); + View.create(earlierCreatedChild_2); + } + Column.pop(); + } +} +loadDocument(new MyComponent("1", undefined, {})); +` diff --git a/compiler/test/ut/builder/builderParam.ts b/compiler/test/ut/builder/builderParam.ts new file mode 100644 index 000000000..e3c8083e1 --- /dev/null +++ b/compiler/test/ut/builder/builderParam.ts @@ -0,0 +1,166 @@ +/* + * Copyright (c) 2021 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. + */ + +exports.source = ` +@Component +struct CustomContainer { + header: string = ""; + footer: string = ""; + @BuilderParam child: () => any; + + build() { + Column() { + Text(this.header) + this.child() + Text(this.footer) + } + } +} + +@Builder function specificParam(label1: string, label2: string) { + Column() { + Text(label1) + Text(label2) + } +} + +@Entry +@Component +struct CustomContainerUser { + @Builder specificChild() { + Column() { + Text("My content1") + Text("My content1") + } + } + + build() { + Column() { + CustomContainer({ + header: "Header", + footer: "Footer", + child: this.specificChild + }) + CustomContainer({ + header: "Header", + footer: "Footer", + child: specificParam("content3", "content4") + }) + } + } +} +` +exports.expectResult = +`class CustomContainer extends View { + constructor(compilerAssignedUniqueChildId, parent, params) { + super(compilerAssignedUniqueChildId, parent); + this.header = "" + this.footer = "" + this.updateWithValueParams(params); + } + updateWithValueParams(params) { + if (params.header !== undefined) { + this.header = params.header; + } + if (params.footer !== undefined) { + this.footer = params.footer; + } + this.__child = params.child; + } + aboutToBeDeleted() { + this.__child.aboutToBeDeleted(); + SubscriberManager.Get().delete(this.id()); + } + get child(){ + return this.__child.get(); + } + set child(newValue) { + this.__child.set(newValue) + } + render() { + Column.create(); + Text.create(this.header); + Text.pop(); + this.child(); + Text.create(this.footer); + Text.pop(); + Column.pop(); + } +} +function specificParam(label1, label2) { + Column.create(); + Text.create(label1); + Text.pop(); + Text.create(label1); + Text.pop(); + Column.pop(); +} +class CustomContainerUser { + constructor(compilerAssignedUniqueChildId, parent, params) { + super(compilerAssignedUniqueChildId, parent); + this.updateWithValueParams(params); + } + updateWithValueParams(params) { + } + aboutToBeDeleted() { + SubscriberManager.Get().delete(this.id()); + } + specificChild() { + Column.create(); + Text.create("My content1"); + Text.pop(); + Text.create("My content2"); + Text.pop(); + Column.pop(); + } + render() { + Column.create(); + let earlierCreatedChild_2 = this.findChildById("2"); + if (earlierCreatedChild_2 == undefined) { + View.create(new CustomContainer("2", this, { + header: "Header", + footer: "Footer", + child: {build:this.specificChild.bind(this)} + })); + } + else { + earlierCreatedChild_2.updateWithValueParams({ + header: "Header", + footer: "Footer", + child: {build:this.specificChild.bind(this)} + }); + View.create(earlierCreatedChild_2); + } + let earlierCreatedChild_3 = this.findChildById("3"); + if (earlierCreatedChild_3 == undefined) { + View.create(new CustomContainer("3", this, { + header: "Header", + footer: "Footer", + child: specificParam("content3", "content4") + })); + } + else { + earlierCreatedChild_3.updateWithValueParams({ + header: "Header", + footer: "Footer", + child: specificParam("content3", "content4") + }); + View.create(earlierCreatedChild_3); + } + Column.pop(); + } +} +loadDocument(new MyComponent("1", undefined, {})); +` -- Gitee