perf(compiler): skip unncessary checks when parsing end tag

This commit is contained in:
Evan You 2021-04-17 22:05:18 -04:00
parent 2c31227e7c
commit 048ac299f3

View File

@ -444,11 +444,21 @@ const isSpecialTemplateDirective = /*#__PURE__*/ makeMap(
/**
* Parse a tag (E.g. `<div id=a>`) with that type (start tag or end tag).
*/
function parseTag(
context: ParserContext,
type: TagType.Start,
parent: ElementNode | undefined
): ElementNode
function parseTag(
context: ParserContext,
type: TagType.End,
parent: ElementNode | undefined
): void
function parseTag(
context: ParserContext,
type: TagType,
parent: ElementNode | undefined
): ElementNode {
): ElementNode | undefined {
__TEST__ && assert(/^<\/?[a-z]/i.test(context.source))
__TEST__ &&
assert(
@ -478,6 +488,7 @@ function parseTag(
// check v-pre
if (
type === TagType.Start &&
!context.inVPre &&
props.some(p => p.type === NodeTypes.DIRECTIVE && p.name === 'pre')
) {
@ -489,6 +500,22 @@ function parseTag(
props = parseAttributes(context, type).filter(p => p.name !== 'v-pre')
}
// Tag close.
let isSelfClosing = false
if (context.source.length === 0) {
emitError(context, ErrorCodes.EOF_IN_TAG)
} else {
isSelfClosing = startsWith(context.source, '/>')
if (type === TagType.End && isSelfClosing) {
emitError(context, ErrorCodes.END_TAG_WITH_TRAILING_SOLIDUS)
}
advanceBy(context, isSelfClosing ? 2 : 1)
}
if (type === TagType.End) {
return
}
// warn v-if/v-for usage on the same element
if (__COMPAT__ && __DEV__ && !__TEST__) {
let hasIf = false
@ -512,18 +539,6 @@ function parseTag(
}
}
// Tag close.
let isSelfClosing = false
if (context.source.length === 0) {
emitError(context, ErrorCodes.EOF_IN_TAG)
} else {
isSelfClosing = startsWith(context.source, '/>')
if (type === TagType.End && isSelfClosing) {
emitError(context, ErrorCodes.END_TAG_WITH_TRAILING_SOLIDUS)
}
advanceBy(context, isSelfClosing ? 2 : 1)
}
let tagType = ElementTypes.ELEMENT
const options = context.options
if (!context.inVPre && !options.isCustomElement(tag)) {
@ -565,11 +580,10 @@ function parseTag(
tagType = ElementTypes.SLOT
} else if (
tag === 'template' &&
props.some(p => {
return (
props.some(
p =>
p.type === NodeTypes.DIRECTIVE && isSpecialTemplateDirective(p.name)
)
})
) {
tagType = ElementTypes.TEMPLATE
}