diff --git a/compiler/src/component_map.ts b/compiler/src/component_map.ts index c92226c..a7a0f5b 100644 --- a/compiler/src/component_map.ts +++ b/compiler/src/component_map.ts @@ -82,6 +82,8 @@ export const STYLES_ATTRIBUTE: Set = new Set(); export const INTERFACE_NODE_SET: Set = new Set(); +export const INNER_CUSTOM_BUILDER_METHOD: Set = new Set(); + export const JS_BIND_COMPONENTS: Set = new Set([ 'ForEach', 'LazyForEach', ...GESTURE_TYPE_NAMES, 'Gesture', 'PanGestureOption', 'CustomDialogController', 'Storage', 'Scroller', 'SwiperController', diff --git a/compiler/src/pre_define.ts b/compiler/src/pre_define.ts index 22c1768..c7ec9ae 100644 --- a/compiler/src/pre_define.ts +++ b/compiler/src/pre_define.ts @@ -260,3 +260,6 @@ export const EXTNAME_ABC: string = '.abc'; export const SUCCESS: number = 0; export const FAIL: number = 1; + +export const GENERATE_ID = 'generateId'; +export const _GENERATE_ID = '__generate__Id'; diff --git a/compiler/src/process_component_build.ts b/compiler/src/process_component_build.ts index 4c50b0a..aa51f7f 100644 --- a/compiler/src/process_component_build.ts +++ b/compiler/src/process_component_build.ts @@ -76,6 +76,7 @@ import { GLOBAL_STYLE_FUNCTION, COMMON_ATTRS, CUSTOM_BUILDER_PROPERTIES, + INNER_CUSTOM_BUILDER_METHOD, ID_ATTRS } from './component_map'; import { @@ -112,9 +113,10 @@ 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)); } @@ -210,8 +212,9 @@ 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 { +export function processComponentChild(node: ts.Block | ts.SourceFile, newStatements: ts.Statement[], + log: LogInfo[], supplement: supplementType = {isAcceleratePreview: false, line: 0, column: 0, fileName: ''}, + isInnerBuilder: boolean = false): void { if (supplement.isAcceleratePreview) { newsupplement = supplement; const compilerOptions = ts.readConfigFile( @@ -239,19 +242,25 @@ 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); } break; case ComponentType.forEachComponent: - processForEachComponent(item, newStatements, log); + processForEachComponent(item, newStatements, log, isInnerBuilder); break; case ComponentType.customBuilderMethod: + if (CUSTOM_BUILDER_METHOD.has(name)) { + newStatements.push(addInnerBuilderParameter(item)); + } else { + newStatements.push(item); + } + break; case ComponentType.builderParamMethod: - newStatements.push(item); + newStatements.push(addInnerBuilderParameter(item)); break; } } else if (ts.isIfStatement(item)) { - processIfStatement(item, newStatements, log); + processIfStatement(item, newStatements, log, isInnerBuilder); } else if (!ts.isBlock(item)) { log.push({ type: LogType.ERROR, @@ -269,6 +278,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 processExpressionStatementChange(node: ts.ExpressionStatement, nextNode: ts.Block, log: LogInfo[]): ts.ExpressionStatement { let name: string; @@ -409,7 +428,7 @@ function getRealNodePos(node: ts.Node): number { } function processForEachComponent(node: ts.ExpressionStatement, newStatements: ts.Statement[], - log: LogInfo[]): void { + log: LogInfo[], isInnerBuilder: boolean = false): void { const popNode: ts.ExpressionStatement = ts.factory.createExpressionStatement(createFunction( // @ts-ignore node.expression.expression as ts.Identifier, @@ -427,7 +446,7 @@ function processForEachComponent(node: ts.ExpressionStatement, newStatements: ts ts.factory.createIdentifier(FOREACH_GET_RAW_OBJECT)), undefined, [argumentsArray[0]]); } argumentsArray.splice(0, 1, arrayObserveredObject); - const newArrowNode: ts.ArrowFunction = processForEachBlock(node.expression, log); + const newArrowNode: ts.ArrowFunction = processForEachBlock(node.expression, log, isInnerBuilder); if (newArrowNode) { argumentsArray.splice(1, 1, newArrowNode); } @@ -445,7 +464,8 @@ function addForEachId(node: ts.ExpressionStatement): ts.ExpressionStatement { ...forEachComponent.arguments])); } -function processForEachBlock(node: ts.CallExpression, log: LogInfo[]): ts.ArrowFunction { +function processForEachBlock(node: ts.CallExpression, log: LogInfo[], + isInnerBuilder: boolean = false): ts.ArrowFunction { if (node.arguments.length > 1 && ts.isArrowFunction(node.arguments[1])) { const isLazy: boolean = node.expression.getText() === COMPONENT_LAZYFOREACH; const arrowNode: ts.ArrowFunction = node.arguments[1] as ts.ArrowFunction; @@ -467,7 +487,8 @@ function processForEachBlock(node: ts.CallExpression, log: LogInfo[]): ts.ArrowF } else { return ts.factory.updateArrowFunction( arrowNode, arrowNode.modifiers, arrowNode.typeParameters, arrowNode.parameters, - arrowNode.type, arrowNode.equalsGreaterThanToken, processComponentBlock(body, isLazy, log)); + arrowNode.type, arrowNode.equalsGreaterThanToken, + processComponentBlock(body, isLazy, log, false, isInnerBuilder)); } } return null; @@ -485,14 +506,15 @@ function createRenderingInProgress(isTrue: boolean): ts.ExpressionStatement { } function processIfStatement(node: ts.IfStatement, newStatements: ts.Statement[], - log: LogInfo[]): void { + log: LogInfo[], isInnerBuilder: boolean = false): void { const ifCreate: ts.ExpressionStatement = createIfCreate(); - const newIfNode: ts.IfStatement = processInnerIfStatement(node, 0, log); + const newIfNode: ts.IfStatement = processInnerIfStatement(node, 0, log, isInnerBuilder); const ifPop: ts.ExpressionStatement = createIfPop(); newStatements.push(ifCreate, newIfNode, ifPop); } -function processInnerIfStatement(node: ts.IfStatement, id: number, log: LogInfo[]): ts.IfStatement { +function processInnerIfStatement(node: ts.IfStatement, id: number, log: LogInfo[], + isInnerBuilder: boolean = false): ts.IfStatement { if (ts.isIdentifier(node.expression) && node.expression.originalKeywordKind === undefined && !node.expression.escapedText) { log.push({ @@ -503,15 +525,15 @@ function processInnerIfStatement(node: ts.IfStatement, id: number, log: LogInfo[ node = ts.factory.updateIfStatement(node, ts.factory.createIdentifier(COMPONENT_IF_UNDEFINED), node.thenStatement, node.elseStatement); } - const newThenStatement: ts.Statement = processThenStatement(node.thenStatement, id, log); - const newElseStatement: ts.Statement = processElseStatement(node.elseStatement, id, log); + const newThenStatement: ts.Statement = processThenStatement(node.thenStatement, id, log, isInnerBuilder); + const newElseStatement: ts.Statement = processElseStatement(node.elseStatement, id, log, isInnerBuilder); const newIfNode: ts.IfStatement = ts.factory.updateIfStatement( node, node.expression, newThenStatement, newElseStatement); return newIfNode; } function processThenStatement(thenStatement: ts.Statement, id: number, - log: LogInfo[]): ts.Statement { + log: LogInfo[], isInnerBuilder: boolean = false): ts.Statement { if (ts.isExpressionStatement(thenStatement) && ts.isIdentifier(thenStatement.expression) && thenStatement.expression.originalKeywordKind === undefined && !thenStatement.expression.escapedText) { @@ -523,36 +545,36 @@ function processThenStatement(thenStatement: ts.Statement, id: number, } if (thenStatement) { if (ts.isBlock(thenStatement)) { - thenStatement = processIfBlock(thenStatement, id, log); + thenStatement = processIfBlock(thenStatement, id, log, isInnerBuilder); } else if (ts.isIfStatement(thenStatement)) { - thenStatement = processInnerIfStatement(thenStatement, 0, log); + thenStatement = processInnerIfStatement(thenStatement, 0, log, isInnerBuilder); thenStatement = ts.factory.createBlock( [createIfCreate(), createIfBranchId(id), thenStatement, createIfPop()], true); } else { thenStatement = ts.factory.createBlock([thenStatement], true); - thenStatement = processIfBlock(thenStatement as ts.Block, id, log); + thenStatement = processIfBlock(thenStatement as ts.Block, id, log, isInnerBuilder); } } return thenStatement; } function processElseStatement(elseStatement: ts.Statement, id: number, - log: LogInfo[]): ts.Statement { + log: LogInfo[], isInnerBuilder: boolean = false): ts.Statement { if (elseStatement) { if (ts.isBlock(elseStatement)) { elseStatement = processIfBlock(elseStatement, id + 1, log); } else if (ts.isIfStatement(elseStatement)) { - elseStatement = processInnerIfStatement(elseStatement, id + 1, log); + elseStatement = processInnerIfStatement(elseStatement, id + 1, log, isInnerBuilder); } else { elseStatement = ts.factory.createBlock([elseStatement], true); - elseStatement = processIfBlock(elseStatement as ts.Block, id + 1, log); + elseStatement = processIfBlock(elseStatement as ts.Block, id + 1, log, isInnerBuilder); } } return elseStatement; } -function processIfBlock(block: ts.Block, id: number, log: LogInfo[]): ts.Block { - return addIfBranchId(id, processComponentBlock(block, false, log)); +function processIfBlock(block: ts.Block, id: number, log: LogInfo[], isInnerBuilder: boolean = false): ts.Block { + return addIfBranchId(id, processComponentBlock(block, false, log, false, isInnerBuilder)); } function addIfBranchId(id: number, container: ts.Block): ts.Block { diff --git a/compiler/src/process_component_class.ts b/compiler/src/process_component_class.ts index f1b6087..f5c7234 100644 --- a/compiler/src/process_component_class.ts +++ b/compiler/src/process_component_class.ts @@ -55,14 +55,17 @@ import { COMPONENT_SET_AND_LINK, COMPONENT_SET_AND_PROP, COMPONENT_CONSTRUCTOR_UNDEFINED, - CUSTOM_COMPONENT + CUSTOM_COMPONENT, + COMPONENT_CONSTRUCTOR_PARENT, + COMPONENT_IF_UNDEFINED } from './pre_define'; import { BUILDIN_STYLE_NAMES, CUSTOM_BUILDER_METHOD, INNER_STYLE_FUNCTION, INTERFACE_NODE_SET, - STYLES_ATTRIBUTE + STYLES_ATTRIBUTE, + INNER_CUSTOM_BUILDER_METHOD } from './component_map'; import { componentCollection, @@ -300,9 +303,11 @@ 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); - 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)); + INNER_CUSTOM_BUILDER_METHOD.add(name); + node.parameters.push(createParentParameter()); + 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, false, true)); updateItem = processBuildMember(builderNode, context, log); } else if (hasDecorator(node, COMPONENT_STYLES_DECORATOR)) { if (node.parameters && node.parameters.length === 0) { @@ -323,6 +328,12 @@ function processComponentMethod(node: ts.MethodDeclaration, parentComponentName: return updateItem; } +export function createParentParameter(): ts.ParameterDeclaration { + return ts.factory.createParameterDeclaration(undefined, undefined, undefined, + ts.factory.createIdentifier(COMPONENT_CONSTRUCTOR_PARENT), undefined, undefined, + ts.factory.createIdentifier(COMPONENT_IF_UNDEFINED)); +} + function processBuildMember(node: ts.MethodDeclaration, context: ts.TransformationContext, log: LogInfo[]): ts.MethodDeclaration { return ts.visitNode(node, visitBuild); diff --git a/compiler/src/process_component_member.ts b/compiler/src/process_component_member.ts index d1c36be..1ae00a1 100644 --- a/compiler/src/process_component_member.ts +++ b/compiler/src/process_component_member.ts @@ -14,6 +14,7 @@ */ import ts from 'typescript'; +const path = require('path'); import { INNER_COMPONENT_MEMBER_DECORATORS, @@ -51,7 +52,10 @@ import { COMPONENT_CREATE_FUNCTION, COMPONENT_BUILDERPARAM_DECORATOR, COMPONENT_LOCAL_STORAGE_LINK_DECORATOR, - COMPONENT_LOCAL_STORAGE_PROP_DECORATOR + COMPONENT_LOCAL_STORAGE_PROP_DECORATOR, + COMPONENT_CONSTRUCTOR_PARENT, + EXTNAME_ETS, + _GENERATE_ID } from './pre_define'; import { forbiddenUseStateType, @@ -74,6 +78,7 @@ import { createReference, isProperty } from './process_component_class'; +import { transformLog } from './process_ui_syntax'; import { globalProgram, projectConfig } from '../main'; export type ControllerType = { @@ -569,14 +574,15 @@ 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, name: string) - : ts.NewExpression { +export function createCustomComponentNewExpression(node: ts.CallExpression, name: string, + isInnerBuilder: boolean = false): ts.NewExpression { const newNode: ts.NewExpression = ts.factory.createNewExpression(node.expression, node.typeArguments, node.arguments.length ? node.arguments : []); - return addCustomComponentId(newNode, name); + return addCustomComponentId(newNode, name, isInnerBuilder); } -function addCustomComponentId(node: ts.NewExpression, componentName: string): ts.NewExpression { +function addCustomComponentId(node: ts.NewExpression, componentName: string, + isInnerBuilder: boolean = false): ts.NewExpression { for (const item of componentCollection.customComponents) { componentInfo.componentNames.add(item); } @@ -589,8 +595,17 @@ function addCustomComponentId(node: ts.NewExpression, componentName: string): ts if (!argumentsArray) { argumentsArray = [ts.factory.createObjectLiteralExpression([], true)]; } - argumentsArray.unshift(ts.factory.createStringLiteral((++componentInfo.id).toString()), - ts.factory.createThis()); + ++componentInfo.id; + argumentsArray.unshift(isInnerBuilder ? ts.factory.createBinaryExpression( + ts.factory.createStringLiteral(path.basename(transformLog.sourceFile.fileName, EXTNAME_ETS) + '_'), + ts.factory.createToken(ts.SyntaxKind.PlusToken), ts.factory.createIdentifier(_GENERATE_ID)) : + ts.factory.createStringLiteral(componentInfo.id.toString()), + isInnerBuilder ? ts.factory.createConditionalExpression( + ts.factory.createIdentifier(COMPONENT_CONSTRUCTOR_PARENT), + ts.factory.createToken(ts.SyntaxKind.QuestionToken), + ts.factory.createIdentifier(COMPONENT_CONSTRUCTOR_PARENT), + ts.factory.createToken(ts.SyntaxKind.ColonToken), ts.factory.createThis() + ) : ts.factory.createThis()); node = ts.factory.updateNewExpression(node, node.expression, node.typeArguments, argumentsArray); } else if (argumentsArray) { diff --git a/compiler/src/process_custom_component.ts b/compiler/src/process_custom_component.ts index 40d05ee..6c69be9 100644 --- a/compiler/src/process_custom_component.ts +++ b/compiler/src/process_custom_component.ts @@ -32,7 +32,9 @@ import { COMPONENT_CONSTRUCTOR_UNDEFINED, CUSTOM_COMPONENT_NEEDS_UPDATE_FUNCTION, CUSTOM_COMPONENT_MARK_STATIC_FUNCTION, - COMPONENT_COMMON + COMPONENT_COMMON, + COMPONENT_CONSTRUCTOR_PARENT, + GENERATE_ID } from './pre_define'; import { propertyCollection, @@ -75,14 +77,14 @@ const decoractorMap: Map>> = 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 && ts.isPropertyAccessExpression(componentNode.parent); let ischangeNode: boolean = false; let customComponentNewExpression: ts.NewExpression = createCustomComponentNewExpression( - componentNode, name); + componentNode, name, isInnerBuilder); let argumentsArray: ts.PropertyAssignment[]; if (isHasChild(componentNode)) { // @ts-ignore @@ -100,7 +102,7 @@ export function processCustomComponent(node: ts.ExpressionStatement, newStatemen ts.factory.createNewExpression(componentNode.expression, componentNode.typeArguments, [ts.factory.createObjectLiteralExpression(argumentsArray, true)])); customComponentNewExpression = createCustomComponentNewExpression( - newNode.expression as ts.CallExpression, name); + newNode.expression as ts.CallExpression, name, isInnerBuilder); } } if (hasChainCall) { @@ -109,7 +111,8 @@ 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 +143,20 @@ 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,14 +360,35 @@ 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( - `${CUSTOM_COMPONENT_FUNCTION_FIND_CHILD_BY_ID}`)), undefined, [ts.factory.createStringLiteral(id)]), - ts.factory.createTypeReferenceNode(ts.factory.createIdentifier(name))))], ts.NodeFlags.Let)); + ts.factory.createIdentifier(name)), + ts.factory.createConditionalExpression( + ts.factory.createParenthesizedExpression( + ts.factory.createBinaryExpression( + createConditionParent(isInnerBuilder), + ts.factory.createToken(ts.SyntaxKind.AmpersandAmpersandToken), + ts.factory.createPropertyAccessExpression( + createConditionParent(isInnerBuilder), + ts.factory.createIdentifier(CUSTOM_COMPONENT_FUNCTION_FIND_CHILD_BY_ID) + ))), ts.factory.createToken(ts.SyntaxKind.QuestionToken), + ts.factory.createAsExpression(ts.factory.createCallExpression( + ts.factory.createPropertyAccessExpression(createConditionParent(isInnerBuilder), + ts.factory.createIdentifier(`${CUSTOM_COMPONENT_FUNCTION_FIND_CHILD_BY_ID}`)), undefined, + [isInnerBuilder ? ts.factory.createCallExpression(ts.factory.createIdentifier(GENERATE_ID), + undefined, []) : ts.factory.createStringLiteral(id)]), + ts.factory.createTypeReferenceNode(ts.factory.createIdentifier(name))), + ts.factory.createToken(ts.SyntaxKind.ColonToken), + ts.factory.createIdentifier('undefined')))], ts.NodeFlags.Let)); +} + +function createConditionParent(isInnerBuilder: boolean): ts.ParenthesizedExpression | ts.ThisExpression { + return isInnerBuilder ? ts.factory.createParenthesizedExpression(ts.factory.createConditionalExpression( + ts.factory.createIdentifier(COMPONENT_CONSTRUCTOR_PARENT), ts.factory.createToken(ts.SyntaxKind.QuestionToken), + ts.factory.createIdentifier(COMPONENT_CONSTRUCTOR_PARENT), ts.factory.createToken(ts.SyntaxKind.ColonToken), + ts.factory.createThis())) : ts.factory.createThis(); } function createCustomComponentIfStatement(id: string, node: ts.ExpressionStatement, diff --git a/compiler/src/process_ui_syntax.ts b/compiler/src/process_ui_syntax.ts index 276bd0d..2bf12ff 100644 --- a/compiler/src/process_ui_syntax.ts +++ b/compiler/src/process_ui_syntax.ts @@ -17,7 +17,10 @@ import ts from 'typescript'; import path from 'path'; import { componentCollection } from './validate_ui_syntax'; -import { processComponentClass } from './process_component_class'; +import { + processComponentClass, + createParentParameter +} from './process_component_class'; import processImport from './process_import'; import { PAGE_ENTRY_FUNCTION_NAME, @@ -48,7 +51,10 @@ import { CUSTOM_DIALOG_CONTROLLER_BUILDER, ESMODULE, ARK, - COMPONENT_COMMON + COMPONENT_COMMON, + EXTNAME_ETS, + GENERATE_ID, + _GENERATE_ID } from './pre_define'; import { componentInfo, @@ -109,6 +115,7 @@ export function processUISyntax(program: ts.Program, ut = false): Function { }); GLOBAL_STYLE_FUNCTION.clear(); const statements: ts.Statement[] = Array.from(node.statements); + generateId(statements, node); INTERFACE_NODE_SET.forEach(item => { statements.unshift(item); }); @@ -141,9 +148,10 @@ export function processUISyntax(program: ts.Program, ut = false): Function { } else if (hasDecorator(node, COMPONENT_BUILDER_DECORATOR) && node.name && node.body && ts.isBlock(node.body)) { CUSTOM_BUILDER_METHOD.add(node.name.getText()); + node.parameters.push(createParentParameter()); node = ts.factory.updateFunctionDeclaration(node, undefined, node.modifiers, node.asteriskToken, node.name, node.typeParameters, node.parameters, node.type, - processComponentBlock(node.body, false, transformLog.errors)); + processComponentBlock(node.body, false, transformLog.errors, false, true)); } else if (hasDecorator(node, COMPONENT_STYLES_DECORATOR)) { if (node.parameters.length === 0) { node = undefined; @@ -175,6 +183,41 @@ export function processUISyntax(program: ts.Program, ut = false): Function { }; } +function generateId(statements: ts.Statement[], node: ts.SourceFile): void { + statements.unshift( + ts.factory.createVariableStatement( + undefined, + ts.factory.createVariableDeclarationList( + [ts.factory.createVariableDeclaration( + ts.factory.createIdentifier(_GENERATE_ID), + undefined, + ts.factory.createKeywordTypeNode(ts.SyntaxKind.NumberKeyword), + ts.factory.createNumericLiteral("0") + )], + ts.NodeFlags.Let + ) + ), + ts.factory.createFunctionDeclaration( + undefined, + undefined, + undefined, + ts.factory.createIdentifier(GENERATE_ID), + undefined, + [], + ts.factory.createKeywordTypeNode(ts.SyntaxKind.StringKeyword), + ts.factory.createBlock( + [ts.factory.createReturnStatement(ts.factory.createBinaryExpression( + ts.factory.createStringLiteral(path.basename(node.fileName, EXTNAME_ETS)+'_'), + ts.factory.createToken(ts.SyntaxKind.PlusToken),ts.factory.createPrefixUnaryExpression( + ts.SyntaxKind.PlusPlusToken, + ts.factory.createIdentifier(_GENERATE_ID) + )))], + true + ) + ) + ) +} + function preprocessIdAttrs(fileName: string): void { for (const [id, idInfo] of ID_ATTRS) { if (fileName === idInfo.get('path')) { @@ -341,7 +384,7 @@ function getResourceDataNode(node: ts.CallExpression): ts.Node { function createResourceParam(resourceValue: number, resourceType: number, argsArr: ts.Expression[]): ts.ObjectLiteralExpression { - const propertyArray: Array[ts.PropertyAssignment] = [ + const propertyArray: Array = [ ts.factory.createPropertyAssignment( ts.factory.createStringLiteral(RESOURCE_NAME_ID), ts.factory.createNumericLiteral(resourceValue)