diff --git a/compiler/src/compile_info.ts b/compiler/src/compile_info.ts index 01bfccb..42c0532 100644 --- a/compiler/src/compile_info.ts +++ b/compiler/src/compile_info.ts @@ -22,7 +22,6 @@ import { configure, getLogger } from 'log4js'; -import RawSource from 'webpack-sources/lib/RawSource'; import path from 'path'; import fs from 'fs'; import CachedSource from 'webpack-sources/lib/CachedSource'; @@ -47,7 +46,6 @@ import { import { createLanguageService, appComponentCollection, - importModuleCollection, createWatchCompilerHost } from './ets_checker'; import { globalProgram } from '../main'; @@ -376,7 +374,6 @@ export class ResultStates { private validateError(message: string): boolean { const propInfoReg: RegExp = /Cannot find name\s*'(\$?\$?[_a-zA-Z0-9]+)'/; const stateInfoReg: RegExp = /Property\s*'(\$?[_a-zA-Z0-9]+)' does not exist on type/; - const importInfoReg: RegExp = /Cannot find namespace\s*'([_a-zA-Z0-9]+)'\./; if (this.matchMessage(message, props, propInfoReg) || this.matchMessage(message, props, stateInfoReg)) { return false; diff --git a/compiler/src/pre_define.ts b/compiler/src/pre_define.ts index 0270693..fcd08de 100644 --- a/compiler/src/pre_define.ts +++ b/compiler/src/pre_define.ts @@ -94,7 +94,6 @@ export const COMPONENT_RENDER_FUNCTION: string = 'render'; export const COMPONENT_TRANSITION_FUNCTION: string = 'pageTransition'; export const COMPONENT_TRANSITION_NAME: string = 'PageTransition'; -export const COMPONENT_COMMON: string = '__Common__'; export const COMPONENT_BUTTON: string = 'Button'; export const COMPONENT_FOREACH: string = 'ForEach'; export const COMPONENT_LAZYFOREACH: string = 'LazyForEach'; @@ -125,6 +124,7 @@ export const COMPONENT_CREATE_LABEL_FUNCTION: string = 'createWithLabel'; export const COMPONENT_CREATE_CHILD_FUNCTION: string = 'createWithChild'; export const COMPONENT_POP_FUNCTION: string = 'pop'; export const COMPONENT_DEBUGLINE_FUNCTION: string = 'debugLine'; +export const COMPONENT_COMMON: string = '__Common__'; export const COMPONENT_CONSTRUCTOR_UPDATE_PARAMS: string = 'updateWithValueParams'; export const COMPONENT_CONSTRUCTOR_DELETE_PARAMS: string = 'aboutToBeDeleted'; diff --git a/compiler/src/process_component_build.ts b/compiler/src/process_component_build.ts index dd21537..50f39ac 100644 --- a/compiler/src/process_component_build.ts +++ b/compiler/src/process_component_build.ts @@ -236,11 +236,13 @@ export function processComponentChild(node: ts.Block | ts.SourceFile, newStateme case ComponentType.customComponent: if (!newsupplement.isAcceleratePreview) { if (item.expression && ts.isEtsComponentExpression(item.expression) && item.expression.body) { - if (processExpressionStatementChange(item, item.expression.body, log)) { - item = processExpressionStatementChange(item, item.expression.body, log); + const expressionResult: ts.ExpressionStatement = + processExpressionStatementChange(item, item.expression.body, log); + if (expressionResult) { + item = expressionResult; } } - processCustomComponent(item as ts.ExpressionStatement, newStatements, log); + processCustomComponent(item as ts.ExpressionStatement, newStatements, log, name); lastName = name; lastExpression = item; } @@ -295,8 +297,8 @@ function processMixBuilder(lastName: string, name: string, index: number, lastEx isMixExtend = false; } if (lastName) { - if (index && (isMixExtend ? (BUILDER_MIX_EXTEND_RESPECTIVE.get(lastName) && - BUILDER_MIX_EXTEND_RESPECTIVE.get(lastName).has(name)) : true) && + if (index && (isMixExtend ? BUILDER_MIX_EXTEND_RESPECTIVE.get(lastName) && + BUILDER_MIX_EXTEND_RESPECTIVE.get(lastName).has(name) : true) && (getComponentType(lastExpression as ts.ExpressionStatement, log, lastName) === ComponentType.innerComponent || (isMixExtend ? undefined : getComponentType( lastExpression as ts.ExpressionStatement, log, lastName) === ComponentType.customComponent))) { @@ -348,6 +350,7 @@ function processExpressionStatementChange(node: ts.ExpressionStatement, nextNode + `@BuilderParam, and its @BuilderParam expects no parameter.`, pos: node.getStart() }); + return null; } } @@ -368,10 +371,15 @@ function processBlockToExpression(node: ts.ExpressionStatement, nextNode: ts.Blo // @ts-ignore node.expression.arguments[0].properties.concat([newPropertyAssignment]), true)]; } - node = ts.factory.updateExpressionStatement(node, ts.factory.updateCallExpression( + const callNode: ts.CallExpression = ts.factory.updateCallExpression( // @ts-ignore node.expression, node.expression.expression, node.expression.expression.typeArguments, - argumentsArray)); + argumentsArray); + // @ts-ignore + node.expression.expression.parent = callNode; + // @ts-ignore + callNode.parent = node.expression.parent; + node = ts.factory.updateExpressionStatement(node, callNode); return node; } @@ -721,14 +729,16 @@ export function bindComponentAttr(node: ts.ExpressionStatement, identifierNode: flag = true; } if (ts.isPropertyAccessExpression(temp.expression) && - temp.expression.name && ts.isIdentifier(temp.expression.name)) { + temp.expression.name && ts.isIdentifier(temp.expression.name) && + !componentCollection.customComponents.has(temp.expression.name.getText())) { addComponentAttr(temp, temp.expression.name, lastStatement, statements, identifierNode, log, isStylesAttr, isGlobalStyles); temp = temp.expression.expression; flag = true; } else if (ts.isIdentifier(temp.expression)) { if (!INNER_COMPONENT_NAMES.has(temp.expression.getText()) && - !GESTURE_TYPE_NAMES.has(temp.expression.getText())) { + !GESTURE_TYPE_NAMES.has(temp.expression.getText()) && + !componentCollection.customComponents.has(temp.expression.getText())) { addComponentAttr(temp, temp.expression, lastStatement, statements, identifierNode, log, isStylesAttr, isGlobalStyles); } @@ -1253,7 +1263,8 @@ function parseGestureInterface(node: ts.CallExpression, statements: ts.Statement } } -export function getName(node: ts.ExpressionStatement): string { +export function getName(node: ts.ExpressionStatement | ts.Expression): string { + // @ts-ignore let temp: any = node.expression; let name: string; while (temp) { diff --git a/compiler/src/process_component_class.ts b/compiler/src/process_component_class.ts index 7b26a62..fcea374 100644 --- a/compiler/src/process_component_class.ts +++ b/compiler/src/process_component_class.ts @@ -94,11 +94,10 @@ import { export function processComponentClass(node: ts.StructDeclaration, context: ts.TransformationContext, log: LogInfo[], program: ts.Program): ts.ClassDeclaration { - validateInheritClass(node, log); const memberNode: ts.ClassElement[] = processMembers(node.members, node.name, context, log, program, checkPreview(node)); return ts.factory.createClassDeclaration(undefined, node.modifiers, node.name, - node.typeParameters, updateHeritageClauses(node), memberNode); + node.typeParameters, updateHeritageClauses(), memberNode); } function checkPreview(node: ts.ClassDeclaration) { @@ -382,18 +381,13 @@ function getGeometryReaderFunctionBlock(node: ts.ArrowFunction | ts.FunctionExpr return processComponentBlock(blockNode, false, log); } -function updateHeritageClauses(node: ts.StructDeclaration): ts.NodeArray { +function updateHeritageClauses(): ts.NodeArray { const result:ts.HeritageClause[] = []; const heritageClause:ts.HeritageClause = ts.factory.createHeritageClause( ts.SyntaxKind.ExtendsKeyword, [ts.factory.createExpressionWithTypeArguments( ts.factory.createIdentifier(BASE_COMPONENT_NAME), [])]); - - if (node.heritageClauses) { - result.push(...node.heritageClauses); - } result.push(heritageClause); - return ts.factory.createNodeArray(result); } @@ -538,16 +532,6 @@ function validateBuildMethodCount(buildCount: BuildCount, parentComponentName: t } } -function validateInheritClass(node: ts.StructDeclaration, log: LogInfo[]): void { - if (node.heritageClauses) { - log.push({ - type: LogType.ERROR, - message: '@Component should not be inherit other Classes.', - pos: node.heritageClauses.pos - }); - } -} - function validateHasController(componentName: ts.Identifier, checkController: ControllerType, log: LogInfo[]): void { if (!checkController.hasController) { diff --git a/compiler/src/process_component_member.ts b/compiler/src/process_component_member.ts index a2e3e25..3629d32 100644 --- a/compiler/src/process_component_member.ts +++ b/compiler/src/process_component_member.ts @@ -572,26 +572,23 @@ export function createViewCreate(node: ts.NewExpression | ts.Identifier): ts.Cal ts.factory.createIdentifier(COMPONENT_CREATE_FUNCTION), ts.factory.createNodeArray([node])); } -export function createCustomComponentNewExpression(node: ts.CallExpression): ts.NewExpression { +export function createCustomComponentNewExpression(node: ts.CallExpression, name: string) + : ts.NewExpression { const newNode: ts.NewExpression = ts.factory.createNewExpression(node.expression, node.typeArguments, node.arguments.length ? node.arguments : []); - return addCustomComponentId(newNode); + return addCustomComponentId(newNode, name); } -function addCustomComponentId(node: ts.NewExpression): ts.NewExpression { +function addCustomComponentId(node: ts.NewExpression, componentName: string): ts.NewExpression { for (const item of componentCollection.customComponents) { componentInfo.componentNames.add(item); } componentInfo.componentNames.forEach((name: string) => { - const nodeIdentifier: ts.Identifier | ts.PropertyAccessExpression = - node.expression as ts.Identifier | ts.PropertyAccessExpression; let argumentsArray: ts.Expression[]; if (node.arguments && node.arguments.length) { argumentsArray = Array.from(node.arguments); } - if (nodeIdentifier && (ts.isIdentifier(nodeIdentifier) && - nodeIdentifier.escapedText === name || ts.isPropertyAccessExpression(nodeIdentifier) && - ts.isIdentifier(nodeIdentifier.name) && nodeIdentifier.name.escapedText === name)) { + if (componentName === name) { if (!argumentsArray) { argumentsArray = [ts.factory.createObjectLiteralExpression([], true)]; } diff --git a/compiler/src/process_custom_component.ts b/compiler/src/process_custom_component.ts index 039810e..40d05ee 100644 --- a/compiler/src/process_custom_component.ts +++ b/compiler/src/process_custom_component.ts @@ -24,13 +24,15 @@ import { COMPONENT_PROVIDE_DECORATOR, COMPONENT_OBJECT_LINK_DECORATOR, COMPONENT_CREATE_FUNCTION, + COMPONENT_POP_FUNCTION, BASE_COMPONENT_NAME, CUSTOM_COMPONENT_EARLIER_CREATE_CHILD, COMPONENT_CONSTRUCTOR_UPDATE_PARAMS, CUSTOM_COMPONENT_FUNCTION_FIND_CHILD_BY_ID, COMPONENT_CONSTRUCTOR_UNDEFINED, CUSTOM_COMPONENT_NEEDS_UPDATE_FUNCTION, - CUSTOM_COMPONENT_MARK_STATIC_FUNCTION + CUSTOM_COMPONENT_MARK_STATIC_FUNCTION, + COMPONENT_COMMON } from './pre_define'; import { propertyCollection, @@ -56,8 +58,10 @@ import { import { LogType, LogInfo, - componentInfo + componentInfo, + createFunction } from './utils'; +import { bindComponentAttr } from './process_component_build'; const localArray: string[] = [...observedPropertyDecorators, COMPONENT_NON_DECORATOR, COMPONENT_PROP_DECORATOR, COMPONENT_OBJECT_LINK_DECORATOR]; @@ -71,17 +75,20 @@ const decoractorMap: Map>> = new Map( [COMPONENT_OBJECT_LINK_DECORATOR, objectLinkCollection]]); export function processCustomComponent(node: ts.ExpressionStatement, newStatements: ts.Statement[], - log: LogInfo[]): void { - if (ts.isCallExpression(node.expression)) { + log: LogInfo[], name: string): void { + const componentNode: ts.CallExpression = getCustomComponentNode(node); + if (componentNode) { + const hasChainCall: boolean = componentNode.parent && + ts.isPropertyAccessExpression(componentNode.parent); let ischangeNode: boolean = false; let customComponentNewExpression: ts.NewExpression = createCustomComponentNewExpression( - node.expression); + componentNode, name); let argumentsArray: ts.PropertyAssignment[]; - if (isHasChild(node.expression)) { + if (isHasChild(componentNode)) { // @ts-ignore - argumentsArray = node.expression.arguments[0].properties.slice(); + argumentsArray = componentNode.arguments[0].properties.slice(); argumentsArray.forEach((item: ts.PropertyAssignment, index: number) => { - if (isToChange(item, node.expression as ts.CallExpression)) { + if (isToChange(item, name)) { ischangeNode = true; const propertyAssignmentNode: ts.PropertyAssignment = ts.factory.updatePropertyAssignment( item, item.name, changeNodeFromCallToArrow(item.initializer as ts.CallExpression)); @@ -90,23 +97,34 @@ export function processCustomComponent(node: ts.ExpressionStatement, newStatemen }); if (ischangeNode) { const newNode: ts.ExpressionStatement = ts.factory.updateExpressionStatement(node, - ts.factory.createNewExpression(node.expression.expression, node.expression.typeArguments, + ts.factory.createNewExpression(componentNode.expression, componentNode.typeArguments, [ts.factory.createObjectLiteralExpression(argumentsArray, true)])); customComponentNewExpression = createCustomComponentNewExpression( - newNode.expression as ts.CallExpression); + newNode.expression as ts.CallExpression, name); } } - addCustomComponent(node, newStatements, customComponentNewExpression, log); + if (hasChainCall) { + newStatements.push(ts.factory.createExpressionStatement( + createFunction(ts.factory.createIdentifier(COMPONENT_COMMON), + ts.factory.createIdentifier(COMPONENT_CREATE_FUNCTION), null))); + bindComponentAttr(node, ts.factory.createIdentifier(COMPONENT_COMMON), newStatements, log); + } + addCustomComponent(node, newStatements, customComponentNewExpression, log, name, componentNode); + if (hasChainCall) { + newStatements.push(ts.factory.createExpressionStatement( + createFunction(ts.factory.createIdentifier(COMPONENT_COMMON), + ts.factory.createIdentifier(COMPONENT_POP_FUNCTION), null))); + } } } function isHasChild(node: ts.CallExpression): boolean { return node.arguments && node.arguments[0] && ts.isObjectLiteralExpression(node.arguments[0]) && - node.arguments[0].properties && node.arguments[0].properties.length; + node.arguments[0].properties && node.arguments[0].properties.length > 0; } -function isToChange(item: ts.PropertyAssignment, node: ts.CallExpression): boolean { - const builderParamName: Set = builderParamObjectCollection.get(node.expression.getText()); +function isToChange(item: ts.PropertyAssignment, name: string): boolean { + const builderParamName: Set = builderParamObjectCollection.get(name); if (item.initializer && ts.isCallExpression(item.initializer) && builderParamName && builderParamName.has(item.name.getText()) && !/\.(bind|call|apply)/.test(item.initializer.getText())) { @@ -122,12 +140,11 @@ function changeNodeFromCallToArrow(node: ts.CallExpression): ts.ArrowFunction { } function addCustomComponent(node: ts.ExpressionStatement, newStatements: ts.Statement[], - newNode: ts.NewExpression, log: LogInfo[]): void { + newNode: ts.NewExpression, log: LogInfo[], name: string, componentNode: ts.CallExpression): void { if (ts.isNewExpression(newNode)) { - const customComponentName: string = getCustomComponentName(newNode); const propertyArray: ts.ObjectLiteralElementLike[] = []; - validateCustomComponentPrams(node, customComponentName, propertyArray, log); - addCustomComponentStatements(node, newStatements, newNode, customComponentName, propertyArray); + validateCustomComponentPrams(componentNode, name, propertyArray, log); + addCustomComponentStatements(node, newStatements, newNode, name, propertyArray); } } @@ -139,11 +156,10 @@ function addCustomComponentStatements(node: ts.ExpressionStatement, newStatement ts.factory.createObjectLiteralExpression(props, true), name)); } -function validateCustomComponentPrams(node: ts.ExpressionStatement, name: string, +function validateCustomComponentPrams(node: ts.CallExpression, name: string, props: ts.ObjectLiteralElementLike[], log: LogInfo[]): void { const curChildProps: Set = new Set([]); - const nodeExpression: ts.CallExpression = node.expression as ts.CallExpression; - const nodeArguments: ts.NodeArray = nodeExpression.arguments; + const nodeArguments: ts.NodeArray = node.arguments; const propertySet: Set = getCollectionSet(name, propertyCollection); const linkSet: Set = getCollectionSet(name, linkCollection); if (nodeArguments && nodeArguments.length === 1 && @@ -155,7 +171,7 @@ function validateCustomComponentPrams(node: ts.ExpressionStatement, name: string } validateStateManagement(item, name, log); if (isNonThisProperty(item, linkSet)) { - if (isToChange(item as ts.PropertyAssignment, node.expression as ts.CallExpression)) { + if (isToChange(item as ts.PropertyAssignment, name)) { item = ts.factory.updatePropertyAssignment(item as ts.PropertyAssignment, item.name, changeNodeFromCallToArrow(item.initializer)); } @@ -165,14 +181,31 @@ function validateCustomComponentPrams(node: ts.ExpressionStatement, name: string } } -function getCustomComponentName(newNode: ts.NewExpression): string { - let customComponentName: string; - if (ts.isIdentifier(newNode.expression)) { - customComponentName = newNode.expression.escapedText.toString(); - } else if (ts.isPropertyAccessExpression(newNode.expression)) { - customComponentName = newNode.expression.name.escapedText.toString(); +function getCustomComponentNode(node: ts.ExpressionStatement): ts.CallExpression { + let temp: any = node.expression; + let child: any = null; + let componentNode: any = null; + while (temp) { + if (ts.isIdentifier(temp)) { + child = temp; + break; + } + temp = temp.expression; } - return customComponentName; + if (child) { + let parent = child.parent; + while (parent) { + if (ts.isExpressionStatement(parent)) { + break; + } + if (ts.isCallExpression(parent) || ts.isEtsComponentExpression(parent)) { + componentNode = parent; + break; + } + parent = parent.parent; + } + } + return componentNode; } function getCollectionSet(name: string, collection: Map>): Set { diff --git a/compiler/src/process_import.ts b/compiler/src/process_import.ts index f78c1b9..d251a29 100644 --- a/compiler/src/process_import.ts +++ b/compiler/src/process_import.ts @@ -62,7 +62,7 @@ const IMPORT_FILE_ASTCACHE: Map = new Map(); export default function processImport(node: ts.ImportDeclaration | ts.ImportEqualsDeclaration | ts.ExportDeclaration, pagesDir: string, log: LogInfo[], asName: Map = new Map(), - isEntryPage: boolean = true, pathCollection: Set = new Set()): void { +isEntryPage: boolean = true, pathCollection: Set = new Set()): void { let filePath: string; let defaultName: string; if (ts.isImportDeclaration(node) || ts.isExportDeclaration(node)) { diff --git a/compiler/src/process_ui_syntax.ts b/compiler/src/process_ui_syntax.ts index a7184b0..bee2c34 100644 --- a/compiler/src/process_ui_syntax.ts +++ b/compiler/src/process_ui_syntax.ts @@ -57,7 +57,8 @@ import { } from './utils'; import { processComponentBlock, - bindComponentAttr + bindComponentAttr, + getName } from './process_component_build'; import { BUILDIN_STYLE_NAMES, @@ -195,8 +196,10 @@ function createCustomDialogController(parent: ts.Expression, node: ts.NewExpress if (node.arguments && node.arguments.length === 1 && ts.isObjectLiteralExpression(node.arguments[0]) && node.arguments[0].properties) { const newproperties: ts.ObjectLiteralElementLike[] = node.arguments[0].properties.map((item) => { - if (isCustomDialogControllerPropertyAssignment(item, log)) { - item = processCustomDialogControllerPropertyAssignment(parent, item as ts.PropertyAssignment); + const componentName: string = isCustomDialogControllerPropertyAssignment(item, log); + if (componentName !== null) { + item = processCustomDialogControllerPropertyAssignment(parent, + item as ts.PropertyAssignment, componentName); } return item; }); @@ -206,16 +209,19 @@ function createCustomDialogController(parent: ts.Expression, node: ts.NewExpress } function isCustomDialogControllerPropertyAssignment(node: ts.ObjectLiteralElementLike, - log: LogInfo[]): boolean { + log: LogInfo[]): string { if (ts.isPropertyAssignment(node) && ts.isIdentifier(node.name) && node.name.getText() === CUSTOM_DIALOG_CONTROLLER_BUILDER) { - if (ts.isCallExpression(node.initializer) && ts.isIdentifier(node.initializer.expression) && - componentCollection.customDialogs.has(node.initializer.expression.getText())) { - return true; + if (node.initializer) { + const componentName: string = getName(node.initializer); + if (componentCollection.customDialogs.has(componentName)) { + return componentName; + } } else { validateCustomDialogControllerBuilderInit(node, log); } } + return null; } function validateCustomDialogControllerBuilderInit(node: ts.ObjectLiteralElementLike, @@ -228,16 +234,16 @@ function validateCustomDialogControllerBuilderInit(node: ts.ObjectLiteralElement } function processCustomDialogControllerPropertyAssignment(parent: ts.Expression, - node: ts.PropertyAssignment): ts.PropertyAssignment { + node: ts.PropertyAssignment, componentName: string): ts.PropertyAssignment { if (ts.isCallExpression(node.initializer)) { return ts.factory.updatePropertyAssignment(node, node.name, - processCustomDialogControllerBuilder(parent, node.initializer)); + processCustomDialogControllerBuilder(parent, node.initializer, componentName)); } } function processCustomDialogControllerBuilder(parent: ts.Expression, - node: ts.CallExpression): ts.ArrowFunction { - const newExp: ts.Expression = createCustomComponentNewExpression(node); + node: ts.CallExpression, componentName: string): ts.ArrowFunction { + const newExp: ts.Expression = createCustomComponentNewExpression(node, componentName); const jsDialog: ts.Identifier = ts.factory.createIdentifier(JS_DIALOG); return createCustomComponentBuilderArrowFunction(parent, jsDialog, newExp); } diff --git a/compiler/test/ut/import/importAllEts.ts b/compiler/test/ut/import/importAllEts.ts index 17441fd..e71ae69 100644 --- a/compiler/test/ut/import/importAllEts.ts +++ b/compiler/test/ut/import/importAllEts.ts @@ -35,6 +35,15 @@ struct ImportTest { myVar: 100, myVar2: 80 }) + AllComponent.NamespaceComponent1({ + NamespaceComponent1Link1: $myState1, + NamespaceComponent1Link2: $myState2, + NamespaceComponent1Link3: $myState3, + NamespaceComponent1Link4: $myState4, + myVar: 100, + myVar2: 80 + }) + .width(100) AllComponent.default({ NamespaceComponent3Link1: $myState1, NamespaceComponent3Link2: $myState2, @@ -43,6 +52,15 @@ struct ImportTest { myVar: 100, myVar2: 80 }) + AllComponent.default({ + NamespaceComponent3Link1: $myState1, + NamespaceComponent3Link2: $myState2, + NamespaceComponent3Link3: $myState3, + NamespaceComponent3Link4: $myState4, + myVar: 100, + myVar2: 80 + }) + .height(200) } } } @@ -149,13 +167,15 @@ class ImportTest extends View { }); View.create(earlierCreatedChild_2); } + __Common__.create(); + __Common__.width(100); let earlierCreatedChild_3 = this.findChildById("3"); if (earlierCreatedChild_3 == undefined) { - View.create(new AllComponent.default("3", this, { - NamespaceComponent3Link1: this.__myState1, - NamespaceComponent3Link2: this.__myState2, - NamespaceComponent3Link3: this.__myState3, - NamespaceComponent3Link4: this.__myState4, + View.create(new AllComponent.NamespaceComponent1("3", this, { + NamespaceComponent1Link1: this.__myState1, + NamespaceComponent1Link2: this.__myState2, + NamespaceComponent1Link3: this.__myState3, + NamespaceComponent1Link4: this.__myState4, myVar: 100, myVar2: 80 })); @@ -167,6 +187,46 @@ class ImportTest extends View { }); View.create(earlierCreatedChild_3); } + __Common__.pop(); + let earlierCreatedChild_4 = this.findChildById("4"); + if (earlierCreatedChild_4 == undefined) { + View.create(new AllComponent.default("4", this, { + NamespaceComponent3Link1: this.__myState1, + NamespaceComponent3Link2: this.__myState2, + NamespaceComponent3Link3: this.__myState3, + NamespaceComponent3Link4: this.__myState4, + myVar: 100, + myVar2: 80 + })); + } + else { + earlierCreatedChild_4.updateWithValueParams({ + myVar: 100, + myVar2: 80 + }); + View.create(earlierCreatedChild_4); + } + __Common__.create(); + __Common__.height(200); + let earlierCreatedChild_5 = this.findChildById("5"); + if (earlierCreatedChild_5 == undefined) { + View.create(new AllComponent.default("5", this, { + NamespaceComponent3Link1: this.__myState1, + NamespaceComponent3Link2: this.__myState2, + NamespaceComponent3Link3: this.__myState3, + NamespaceComponent3Link4: this.__myState4, + myVar: 100, + myVar2: 80 + })); + } + else { + earlierCreatedChild_5.updateWithValueParams({ + myVar: 100, + myVar2: 80 + }); + View.create(earlierCreatedChild_5); + } + __Common__.pop(); Column.pop(); } } diff --git a/compiler/test/ut/inner_commponent_transform/custom_component/custom_component.ts b/compiler/test/ut/inner_commponent_transform/custom_component/custom_component.ts new file mode 100644 index 0000000..95dc4d0 --- /dev/null +++ b/compiler/test/ut/inner_commponent_transform/custom_component/custom_component.ts @@ -0,0 +1,172 @@ +/* + * Copyright (c) 2022 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 +@Entry +struct MyComponent { + build() { + Column() { + Banner() + Banner() + .width(100) + Banner() + .width(100) + .height(200) + Banner({value: "Hello"}) + Banner({value: "Hello"}) + .width(100) + Banner({value: "Hello"}) + .width(100) + .height(200) + } + } +} + +@Component +struct Banner { + value: string = "Hello" + build() { + Column() { + Text(this.value) + } + } +}` + +exports.expectResult = +`class MyComponent extends View { + 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 Banner("2", this, {})); + } + else { + earlierCreatedChild_2.updateWithValueParams({}); + if (!earlierCreatedChild_2.needsUpdate()) { + earlierCreatedChild_2.markStatic(); + } + View.create(earlierCreatedChild_2); + } + __Common__.create(); + __Common__.width(100); + let earlierCreatedChild_3 = this.findChildById("3"); + if (earlierCreatedChild_3 == undefined) { + View.create(new Banner("3", this, {})); + } + else { + earlierCreatedChild_3.updateWithValueParams({}); + if (!earlierCreatedChild_3.needsUpdate()) { + earlierCreatedChild_3.markStatic(); + } + View.create(earlierCreatedChild_3); + } + __Common__.pop(); + __Common__.create(); + __Common__.width(100); + __Common__.height(200); + let earlierCreatedChild_4 = this.findChildById("4"); + if (earlierCreatedChild_4 == undefined) { + View.create(new Banner("4", this, {})); + } + else { + earlierCreatedChild_4.updateWithValueParams({}); + if (!earlierCreatedChild_4.needsUpdate()) { + earlierCreatedChild_4.markStatic(); + } + View.create(earlierCreatedChild_4); + } + __Common__.pop(); + let earlierCreatedChild_5 = this.findChildById("5"); + if (earlierCreatedChild_5 == undefined) { + View.create(new Banner("5", this, { value: "Hello" })); + } + else { + earlierCreatedChild_5.updateWithValueParams({ + value: "Hello" + }); + if (!earlierCreatedChild_5.needsUpdate()) { + earlierCreatedChild_5.markStatic(); + } + View.create(earlierCreatedChild_5); + } + __Common__.create(); + __Common__.width(100); + let earlierCreatedChild_6 = this.findChildById("6"); + if (earlierCreatedChild_6 == undefined) { + View.create(new Banner("6", this, { value: "Hello" })); + } + else { + earlierCreatedChild_6.updateWithValueParams({ + value: "Hello" + }); + if (!earlierCreatedChild_6.needsUpdate()) { + earlierCreatedChild_6.markStatic(); + } + View.create(earlierCreatedChild_6); + } + __Common__.pop(); + __Common__.create(); + __Common__.width(100); + __Common__.height(200); + let earlierCreatedChild_7 = this.findChildById("7"); + if (earlierCreatedChild_7 == undefined) { + View.create(new Banner("7", this, { value: "Hello" })); + } + else { + earlierCreatedChild_7.updateWithValueParams({ + value: "Hello" + }); + if (!earlierCreatedChild_7.needsUpdate()) { + earlierCreatedChild_7.markStatic(); + } + View.create(earlierCreatedChild_7); + } + __Common__.pop(); + Column.pop(); + } +} +class Banner extends View { + constructor(compilerAssignedUniqueChildId, parent, params) { + super(compilerAssignedUniqueChildId, parent); + this.value = "Hello"; + this.updateWithValueParams(params); + } + updateWithValueParams(params) { + if (params.value !== undefined) { + this.value = params.value; + } + } + aboutToBeDeleted() { + SubscriberManager.Get().delete(this.id()); + } + render() { + Column.create(); + Text.create(this.value); + Text.pop(); + Column.pop(); + } +} +loadDocument(new MyComponent("1", undefined, {})); +` \ No newline at end of file diff --git a/compiler/tsconfig.esm.json b/compiler/tsconfig.esm.json index b37d725..f159b95 100644 --- a/compiler/tsconfig.esm.json +++ b/compiler/tsconfig.esm.json @@ -544,6 +544,7 @@ }, "property": "stateStyles" }, + "customComponent": "CustomComponent", }, "allowJs": true, "allowSyntheticDefaultImports": true, diff --git a/compiler/tsconfig.json b/compiler/tsconfig.json index 09ad1cd..ec8cfec 100644 --- a/compiler/tsconfig.json +++ b/compiler/tsconfig.json @@ -544,6 +544,7 @@ }, "property": "stateStyles" }, + "customComponent": "CustomComponent", }, "allowJs": true, "allowSyntheticDefaultImports": true,