mirror of https://github.com/vuejs/core.git
refactor: preserve source location convention in sfc mode for base parser
For compatibility w/ usage like https://github.com/vue-macros/vue-macros/blob/main/packages/setup-block/src/core/index.ts
This commit is contained in:
parent
be6cae7dac
commit
08f0baa2ad
|
|
@ -130,6 +130,7 @@ export interface BaseElementNode extends Node {
|
|||
tagType: ElementTypes
|
||||
props: Array<AttributeNode | DirectiveNode>
|
||||
children: TemplateChildNode[]
|
||||
innerLoc?: SourceLocation // only for SFC root level elements
|
||||
}
|
||||
|
||||
export interface PlainElementNode extends BaseElementNode {
|
||||
|
|
|
|||
|
|
@ -123,10 +123,6 @@ const tokenizer = new Tokenizer(stack, {
|
|||
|
||||
onopentagname(start, end) {
|
||||
const name = getSlice(start, end)
|
||||
// in SFC mode, root-level tags locations are for its inner content.
|
||||
const startIndex = tokenizer.inSFCRoot
|
||||
? end + fastForward(end, CharCodes.Gt) + 1
|
||||
: start - 1
|
||||
currentOpenTag = {
|
||||
type: NodeTypes.ELEMENT,
|
||||
tag: name,
|
||||
|
|
@ -134,9 +130,16 @@ const tokenizer = new Tokenizer(stack, {
|
|||
tagType: ElementTypes.ELEMENT, // will be refined on tag close
|
||||
props: [],
|
||||
children: [],
|
||||
loc: getLoc(startIndex, end),
|
||||
loc: getLoc(start - 1, end),
|
||||
codegenNode: undefined
|
||||
}
|
||||
if (tokenizer.inSFCRoot) {
|
||||
// in SFC mode, generate locations for root-level tags' inner content.
|
||||
currentOpenTag.innerLoc = getLoc(
|
||||
end + fastForward(end, CharCodes.Gt) + 1,
|
||||
end
|
||||
)
|
||||
}
|
||||
},
|
||||
|
||||
onopentagend(end) {
|
||||
|
|
@ -571,20 +574,22 @@ function onText(content: string, start: number, end: number) {
|
|||
|
||||
function onCloseTag(el: ElementNode, end: number, isImplied = false) {
|
||||
// attach end position
|
||||
if (tokenizer.inSFCRoot) {
|
||||
// SFC root tag, end position should be inner end
|
||||
if (el.children.length) {
|
||||
el.loc.end = extend({}, el.children[el.children.length - 1].loc.end)
|
||||
} else {
|
||||
el.loc.end = extend({}, el.loc.start)
|
||||
}
|
||||
} else if (isImplied) {
|
||||
if (isImplied) {
|
||||
// implied close, end should be backtracked to close
|
||||
el.loc.end = tokenizer.getPos(backTrack(end, CharCodes.Lt))
|
||||
} else {
|
||||
el.loc.end = tokenizer.getPos(end + fastForward(end, CharCodes.Gt) + 1)
|
||||
}
|
||||
|
||||
if (tokenizer.inSFCRoot) {
|
||||
// SFC root tag, resolve inner end
|
||||
if (el.children.length) {
|
||||
el.innerLoc!.end = extend({}, el.children[el.children.length - 1].loc.end)
|
||||
} else {
|
||||
el.innerLoc!.end = extend({}, el.innerLoc!.start)
|
||||
}
|
||||
}
|
||||
|
||||
// refine element type
|
||||
const { tag, ns } = el
|
||||
if (!inVPre) {
|
||||
|
|
|
|||
|
|
@ -290,11 +290,12 @@ function createBlock(
|
|||
pad: SFCParseOptions['pad']
|
||||
): SFCBlock {
|
||||
const type = node.tag
|
||||
const loc = node.innerLoc!
|
||||
const attrs: Record<string, string | true> = {}
|
||||
const block: SFCBlock = {
|
||||
type,
|
||||
content: source.slice(node.loc.start.offset, node.loc.end.offset),
|
||||
loc: node.loc,
|
||||
content: source.slice(loc.start.offset, loc.end.offset),
|
||||
loc,
|
||||
attrs
|
||||
}
|
||||
if (pad) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue