修复多级自定义组件传递@Builder this绑定错误

Signed-off-by: houhaoyu <houhaoyu@huawei.com>
Change-Id: I4d0b12c80fba96991a849e2f346078de5fa73e0f
This commit is contained in:
houhaoyu
2022-07-09 20:51:04 +08:00
parent 464087ecf1
commit 3964f37e30
3 changed files with 44 additions and 15 deletions
+24 -5
View File
@@ -94,6 +94,7 @@ import {
import { projectConfig } from '../main';
import { transformLog, contextGlobal } from './process_ui_syntax';
import { props } from './compile_info';
import { INNER_CUSTOM_BUILDER_METHOD } from './process_component_class';
export function processComponentBuild(node: ts.MethodDeclaration,
log: LogInfo[]): ts.MethodDeclaration {
@@ -113,9 +114,9 @@ export function processComponentBuild(node: ts.MethodDeclaration,
}
export function processComponentBlock(node: ts.Block, isLazy: boolean, log: LogInfo[],
isTransition: boolean = false): ts.Block {
isTransition: boolean = false, isInnerBuilder: boolean = false): ts.Block {
const newStatements: ts.Statement[] = [];
processComponentChild(node, newStatements, log);
processComponentChild(node, newStatements, log, {isAcceleratePreview: false, line: 0, column: 0, fileName: ''}, isInnerBuilder);
if (isLazy) {
newStatements.unshift(createRenderingInProgress(true));
}
@@ -221,7 +222,7 @@ function validateEtsComponentNode(node: ts.CallExpression | ts.EtsComponentExpre
let sourceNode: ts.SourceFile;
export function processComponentChild(node: ts.Block | ts.SourceFile, newStatements: ts.Statement[], log: LogInfo[],
supplement: supplementType = {isAcceleratePreview: false, line: 0, column: 0, fileName: ''}): void {
supplement: supplementType = {isAcceleratePreview: false, line: 0, column: 0, fileName: ''}, isInnerBuilder: boolean = false): void {
if (supplement.isAcceleratePreview) {
newsupplement = supplement;
const compilerOptions = ts.readConfigFile(
@@ -253,7 +254,7 @@ export function processComponentChild(node: ts.Block | ts.SourceFile, newStateme
item = expressionResult;
}
}
processCustomComponent(item as ts.ExpressionStatement, newStatements, log, name);
processCustomComponent(item as ts.ExpressionStatement, newStatements, log, name, isInnerBuilder);
lastName = name;
lastExpression = item;
}
@@ -264,8 +265,16 @@ export function processComponentChild(node: ts.Block | ts.SourceFile, newStateme
lastExpression = item;
break;
case ComponentType.customBuilderMethod:
if (INNER_CUSTOM_BUILDER_METHOD.has(name)) {
newStatements.push(addInnerBuilderParameter(item));
} else {
newStatements.push(item);
}
lastName = name;
lastExpression = item;
break;
case ComponentType.builderParamMethod:
newStatements.push(item);
newStatements.push(addInnerBuilderParameter(item));
lastName = name;
lastExpression = item;
break;
@@ -299,6 +308,16 @@ export function processComponentChild(node: ts.Block | ts.SourceFile, newStateme
};
}
function addInnerBuilderParameter(node: ts.ExpressionStatement): ts.ExpressionStatement {
if (node.expression && ts.isCallExpression(node.expression) && node.expression.arguments) {
node.expression.arguments.push(ts.factory.createThis());
return ts.factory.createExpressionStatement(ts.factory.updateCallExpression(node.expression,
node.expression.expression, node.expression.typeArguments, node.expression.arguments));
} else {
return node;
}
}
function processMixBuilder(lastName: string, name: string, index: number, lastExpression: ts.Statement, log: LogInfo[],
newStatements: ts.Statement[], item: ts.Statement, type: ComponentType): void {
let isMixExtend: boolean;
+12 -2
View File
@@ -276,7 +276,7 @@ function createLocalStroageCallExpression(node: ts.PropertyDeclaration, name: st
]
);
}
export const INNER_CUSTOM_BUILDER_METHOD: Set<string> = new Set();
function processComponentMethod(node: ts.MethodDeclaration, parentComponentName: ts.Identifier,
context: ts.TransformationContext, log: LogInfo[], buildCount: BuildCount): ts.MethodDeclaration {
let updateItem: ts.MethodDeclaration = node;
@@ -300,9 +300,19 @@ function processComponentMethod(node: ts.MethodDeclaration, parentComponentName:
node.type, processComponentBlock(node.body, false, log, true));
} else if (hasDecorator(node, COMPONENT_BUILDER_DECORATOR)) {
CUSTOM_BUILDER_METHOD.add(name);
INNER_CUSTOM_BUILDER_METHOD.add(name)
node.parameters.push(ts.factory.createParameterDeclaration(
undefined,
undefined,
undefined,
ts.factory.createIdentifier("parent"),
undefined,
undefined,
undefined
))
const builderNode: ts.MethodDeclaration = ts.factory.updateMethodDeclaration(node, undefined, node.modifiers,
node.asteriskToken, node.name, node.questionToken, node.typeParameters, node.parameters,
node.type, processComponentBlock(node.body, false, log));
node.type, processComponentBlock(node.body, false, log, false, true));
updateItem = processBuildMember(builderNode, context, log);
} else if (hasDecorator(node, COMPONENT_STYLES_DECORATOR)) {
if (node.parameters && node.parameters.length === 0) {
+8 -8
View File
@@ -75,7 +75,7 @@ const decoractorMap: Map<string, Map<string, Set<string>>> = new Map(
[COMPONENT_OBJECT_LINK_DECORATOR, objectLinkCollection]]);
export function processCustomComponent(node: ts.ExpressionStatement, newStatements: ts.Statement[],
log: LogInfo[], name: string): void {
log: LogInfo[], name: string, isInnerBuilder: boolean = false): void {
const componentNode: ts.CallExpression = getCustomComponentNode(node);
if (componentNode) {
const hasChainCall: boolean = componentNode.parent &&
@@ -109,7 +109,7 @@ export function processCustomComponent(node: ts.ExpressionStatement, newStatemen
ts.factory.createIdentifier(COMPONENT_CREATE_FUNCTION), null)));
bindComponentAttr(node, ts.factory.createIdentifier(COMPONENT_COMMON), newStatements, log);
}
addCustomComponent(node, newStatements, customComponentNewExpression, log, name, componentNode);
addCustomComponent(node, newStatements, customComponentNewExpression, log, name, componentNode, isInnerBuilder);
if (hasChainCall) {
newStatements.push(ts.factory.createExpressionStatement(
createFunction(ts.factory.createIdentifier(COMPONENT_COMMON),
@@ -140,18 +140,18 @@ function changeNodeFromCallToArrow(node: ts.CallExpression): ts.ArrowFunction {
}
function addCustomComponent(node: ts.ExpressionStatement, newStatements: ts.Statement[],
newNode: ts.NewExpression, log: LogInfo[], name: string, componentNode: ts.CallExpression): void {
newNode: ts.NewExpression, log: LogInfo[], name: string, componentNode: ts.CallExpression, isInnerBuilder: boolean = false): void {
if (ts.isNewExpression(newNode)) {
const propertyArray: ts.ObjectLiteralElementLike[] = [];
validateCustomComponentPrams(componentNode, name, propertyArray, log);
addCustomComponentStatements(node, newStatements, newNode, name, propertyArray);
addCustomComponentStatements(node, newStatements, newNode, name, propertyArray, isInnerBuilder);
}
}
function addCustomComponentStatements(node: ts.ExpressionStatement, newStatements: ts.Statement[],
newNode: ts.NewExpression, name: string, props: ts.ObjectLiteralElementLike[]): void {
newNode: ts.NewExpression, name: string, props: ts.ObjectLiteralElementLike[], isInnerBuilder: boolean = false): void {
const id: string = componentInfo.id.toString();
newStatements.push(createFindChildById(id, name), createCustomComponentIfStatement(id,
newStatements.push(createFindChildById(id, name, isInnerBuilder), createCustomComponentIfStatement(id,
ts.factory.updateExpressionStatement(node, createViewCreate(newNode)),
ts.factory.createObjectLiteralExpression(props, true), name));
}
@@ -355,12 +355,12 @@ function getPropertyDecoratorKind(propertyName: string, customComponentName: str
}
}
function createFindChildById(id: string, name: string): ts.VariableStatement {
function createFindChildById(id: string, name: string, isInnerBuilder: boolean = false): ts.VariableStatement {
return ts.factory.createVariableStatement(undefined, ts.factory.createVariableDeclarationList(
[ts.factory.createVariableDeclaration(ts.factory.createIdentifier(
`${CUSTOM_COMPONENT_EARLIER_CREATE_CHILD}${id}`), undefined, ts.factory.createTypeReferenceNode(
ts.factory.createIdentifier(name)), ts.factory.createAsExpression(ts.factory.createCallExpression(
ts.factory.createPropertyAccessExpression(ts.factory.createThis(), ts.factory.createIdentifier(
ts.factory.createPropertyAccessExpression(isInnerBuilder ? ts.factory.createIdentifier('parent') : ts.factory.createThis(), ts.factory.createIdentifier(
`${CUSTOM_COMPONENT_FUNCTION_FIND_CHILD_BY_ID}`)), undefined, [ts.factory.createStringLiteral(id)]),
ts.factory.createTypeReferenceNode(ts.factory.createIdentifier(name))))], ts.NodeFlags.Let));
}