diff --git a/compiler/src/component_map.ts b/compiler/src/component_map.ts index fe9f600..c92226c 100644 --- a/compiler/src/component_map.ts +++ b/compiler/src/component_map.ts @@ -47,6 +47,8 @@ export const GESTURE_ATTRS: Set = new Set([ 'gesture', 'parallelGesture', 'priorityGesture' ]); +export const ID_ATTRS: Map> = new Map(); + export const forbiddenUseStateType: Set = new Set(['Scroller', 'SwiperScroller', 'VideoController', 'WebController', 'CustomDialogController', 'SwiperController', 'TabsController', 'CalendarController', 'AbilityController', 'XComponentController', diff --git a/compiler/src/pre_define.ts b/compiler/src/pre_define.ts index 20dfabd..f4b4656 100644 --- a/compiler/src/pre_define.ts +++ b/compiler/src/pre_define.ts @@ -111,6 +111,7 @@ export const GLOBAL_CONTEXT: string = 'Context'; export const ATTRIBUTE_ANIMATION: string = 'animation'; export const ATTRIBUTE_ANIMATETO: string = 'animateTo'; export const ATTRIBUTE_STATESTYLES: string = 'stateStyles'; +export const ATTRIBUTE_ID: string = 'id'; export const COMPONENT_CONSTRUCTOR_ID: string = 'compilerAssignedUniqueChildId'; export const COMPONENT_CONSTRUCTOR_PARENT: string = 'parent'; diff --git a/compiler/src/process_component_build.ts b/compiler/src/process_component_build.ts index 9b30e31..f5f3858 100644 --- a/compiler/src/process_component_build.ts +++ b/compiler/src/process_component_build.ts @@ -59,7 +59,8 @@ import { BIND_DRAG_SET, BIND_POPUP_SET, $$, - PROPERTIES_ADD_DOUBLE_DOLLAR + PROPERTIES_ADD_DOUBLE_DOLLAR, + ATTRIBUTE_ID } from './pre_define'; import { INNER_COMPONENT_NAMES, @@ -74,7 +75,8 @@ import { INNER_STYLE_FUNCTION, GLOBAL_STYLE_FUNCTION, COMMON_ATTRS, - CUSTOM_BUILDER_PROPERTIES + CUSTOM_BUILDER_PROPERTIES, + ID_ATTRS } from './component_map'; import { componentCollection, @@ -905,10 +907,36 @@ function updateArgumentFor$$(argument: any): ts.Expression { } } +function verifyComponentId(temp: any, node: ts.Identifier, propName: string, + log: LogInfo[]): void { + if (!newsupplement.isAcceleratePreview && propName === ATTRIBUTE_ID) { + const literalString: string = temp.arguments[0].text; + if (ID_ATTRS.has(literalString)) { + const errInfo: Map = ID_ATTRS.get(literalString); + log.push({ + type: LogType.ERROR, + message: `The current component id "${literalString}" is duplicate with ` + + `${errInfo.get('path')}:${errInfo.get('line')}:${errInfo.get('col')}.`, + pos: node.pos + }); + } else { + const posOfNode: ts.LineAndCharacter = transformLog.sourceFile + .getLineAndCharacterOfPosition(getRealNodePos(node)); + const curFileName: string = transformLog.sourceFile.fileName.replace(/\.ts$/, ''); + const rPath: string = path.resolve(projectConfig.projectPath, curFileName) + .replace(/\\+/g, '/'); + ID_ATTRS.set(literalString, new Map().set('path', rPath) + .set('line', posOfNode.line + 1) + .set('col', posOfNode.character + 1)); + } + } +} + function addComponentAttr(temp: any, node: ts.Identifier, lastStatement: any, statements: ts.Statement[], identifierNode: ts.Identifier, log: LogInfo[], isStylesAttr: boolean, isGlobalStyles: boolean): void { const propName: string = node.getText(); + verifyComponentId(temp, node, propName, log); if (propName === ATTRIBUTE_ANIMATION) { if (!lastStatement.statement) { if (!(temp.arguments.length === 1 &&