diff --git a/packages/compiler-core/src/ast.ts b/packages/compiler-core/src/ast.ts index 2d6df9d9010..69a89ffcbf8 100644 --- a/packages/compiler-core/src/ast.ts +++ b/packages/compiler-core/src/ast.ts @@ -130,6 +130,8 @@ export interface BaseElementNode extends Node { type: NodeTypes.ELEMENT ns: Namespace tag: string + openTagLoc?: SourceLocation + closeTagLoc?: SourceLocation tagType: ElementTypes props: Array children: TemplateChildNode[] diff --git a/packages/compiler-core/src/options.ts b/packages/compiler-core/src/options.ts index 1de865f42eb..59d1340c3f7 100644 --- a/packages/compiler-core/src/options.ts +++ b/packages/compiler-core/src/options.ts @@ -97,6 +97,11 @@ export interface ParserOptions * @default false */ prefixIdentifiers?: boolean + /** + * Whether to calculate the location of open tag and close tag of each node. + * @default false + */ + tagLocations?: boolean /** * A list of parser plugins to enable for `@babel/parser`, which is used to * parse expressions in bindings and interpolations. diff --git a/packages/compiler-core/src/parser.ts b/packages/compiler-core/src/parser.ts index 95c5e129f25..43872768100 100644 --- a/packages/compiler-core/src/parser.ts +++ b/packages/compiler-core/src/parser.ts @@ -78,6 +78,7 @@ export const defaultParserOptions: MergedParserOptions = { onWarn: defaultOnWarn, comments: __DEV__, prefixIdentifiers: false, + tagLocations: false, } let currentOptions: MergedParserOptions = defaultParserOptions @@ -146,6 +147,9 @@ const tokenizer = new Tokenizer(stack, { loc: getLoc(start - 1, end), codegenNode: undefined, } + if (currentOptions.tagLocations) { + currentOpenTag.openTagLoc = getLoc(start, end) + } }, onopentagend(end) { @@ -165,6 +169,9 @@ const tokenizer = new Tokenizer(stack, { } for (let j = 0; j <= i; j++) { const el = stack.shift()! + if (j === i && currentOptions.tagLocations) { + el.closeTagLoc = getLoc(start, end) + } onCloseTag(el, end, j < i) } break