perf(compiler): should only perform assertions during tests
Compiler assertions are made to ensure implementation correctness, but they have performance costs that should not affect users during development.
This commit is contained in:
parent
51d57b4566
commit
353b06df77
@ -141,7 +141,7 @@ function parseChildren(
|
|||||||
const nodes: TemplateChildNode[] = []
|
const nodes: TemplateChildNode[] = []
|
||||||
|
|
||||||
while (!isEnd(context, mode, ancestors)) {
|
while (!isEnd(context, mode, ancestors)) {
|
||||||
__DEV__ && assert(context.source.length > 0)
|
__TEST__ && assert(context.source.length > 0)
|
||||||
const s = context.source
|
const s = context.source
|
||||||
let node: TemplateChildNode | TemplateChildNode[] | undefined = undefined
|
let node: TemplateChildNode | TemplateChildNode[] | undefined = undefined
|
||||||
|
|
||||||
@ -286,16 +286,16 @@ function parseCDATA(
|
|||||||
context: ParserContext,
|
context: ParserContext,
|
||||||
ancestors: ElementNode[]
|
ancestors: ElementNode[]
|
||||||
): TemplateChildNode[] {
|
): TemplateChildNode[] {
|
||||||
__DEV__ &&
|
__TEST__ &&
|
||||||
assert(last(ancestors) == null || last(ancestors)!.ns !== Namespaces.HTML)
|
assert(last(ancestors) == null || last(ancestors)!.ns !== Namespaces.HTML)
|
||||||
__DEV__ && assert(startsWith(context.source, '<![CDATA['))
|
__TEST__ && assert(startsWith(context.source, '<![CDATA['))
|
||||||
|
|
||||||
advanceBy(context, 9)
|
advanceBy(context, 9)
|
||||||
const nodes = parseChildren(context, TextModes.CDATA, ancestors)
|
const nodes = parseChildren(context, TextModes.CDATA, ancestors)
|
||||||
if (context.source.length === 0) {
|
if (context.source.length === 0) {
|
||||||
emitError(context, ErrorCodes.EOF_IN_CDATA)
|
emitError(context, ErrorCodes.EOF_IN_CDATA)
|
||||||
} else {
|
} else {
|
||||||
__DEV__ && assert(startsWith(context.source, ']]>'))
|
__TEST__ && assert(startsWith(context.source, ']]>'))
|
||||||
advanceBy(context, 3)
|
advanceBy(context, 3)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -303,7 +303,7 @@ function parseCDATA(
|
|||||||
}
|
}
|
||||||
|
|
||||||
function parseComment(context: ParserContext): CommentNode {
|
function parseComment(context: ParserContext): CommentNode {
|
||||||
__DEV__ && assert(startsWith(context.source, '<!--'))
|
__TEST__ && assert(startsWith(context.source, '<!--'))
|
||||||
|
|
||||||
const start = getCursor(context)
|
const start = getCursor(context)
|
||||||
let content: string
|
let content: string
|
||||||
@ -345,7 +345,7 @@ function parseComment(context: ParserContext): CommentNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function parseBogusComment(context: ParserContext): CommentNode | undefined {
|
function parseBogusComment(context: ParserContext): CommentNode | undefined {
|
||||||
__DEV__ && assert(/^<(?:[\!\?]|\/[^a-z>])/i.test(context.source))
|
__TEST__ && assert(/^<(?:[\!\?]|\/[^a-z>])/i.test(context.source))
|
||||||
|
|
||||||
const start = getCursor(context)
|
const start = getCursor(context)
|
||||||
const contentStart = context.source[1] === '?' ? 1 : 2
|
const contentStart = context.source[1] === '?' ? 1 : 2
|
||||||
@ -371,7 +371,7 @@ function parseElement(
|
|||||||
context: ParserContext,
|
context: ParserContext,
|
||||||
ancestors: ElementNode[]
|
ancestors: ElementNode[]
|
||||||
): ElementNode | undefined {
|
): ElementNode | undefined {
|
||||||
__DEV__ && assert(/^<[a-z]/i.test(context.source))
|
__TEST__ && assert(/^<[a-z]/i.test(context.source))
|
||||||
|
|
||||||
// Start tag.
|
// Start tag.
|
||||||
const wasInPre = context.inPre
|
const wasInPre = context.inPre
|
||||||
@ -425,8 +425,8 @@ function parseTag(
|
|||||||
type: TagType,
|
type: TagType,
|
||||||
parent: ElementNode | undefined
|
parent: ElementNode | undefined
|
||||||
): ElementNode {
|
): ElementNode {
|
||||||
__DEV__ && assert(/^<\/?[a-z]/i.test(context.source))
|
__TEST__ && assert(/^<\/?[a-z]/i.test(context.source))
|
||||||
__DEV__ &&
|
__TEST__ &&
|
||||||
assert(
|
assert(
|
||||||
type === (startsWith(context.source, '</') ? TagType.End : TagType.Start)
|
type === (startsWith(context.source, '</') ? TagType.End : TagType.Start)
|
||||||
)
|
)
|
||||||
@ -538,7 +538,7 @@ function parseAttribute(
|
|||||||
context: ParserContext,
|
context: ParserContext,
|
||||||
nameSet: Set<string>
|
nameSet: Set<string>
|
||||||
): AttributeNode | DirectiveNode {
|
): AttributeNode | DirectiveNode {
|
||||||
__DEV__ && assert(/^[^\t\r\n\f />]/.test(context.source))
|
__TEST__ && assert(/^[^\t\r\n\f />]/.test(context.source))
|
||||||
|
|
||||||
// Name.
|
// Name.
|
||||||
const start = getCursor(context)
|
const start = getCursor(context)
|
||||||
@ -725,7 +725,7 @@ function parseInterpolation(
|
|||||||
mode: TextModes
|
mode: TextModes
|
||||||
): InterpolationNode | undefined {
|
): InterpolationNode | undefined {
|
||||||
const [open, close] = context.options.delimiters
|
const [open, close] = context.options.delimiters
|
||||||
__DEV__ && assert(startsWith(context.source, open))
|
__TEST__ && assert(startsWith(context.source, open))
|
||||||
|
|
||||||
const closeIndex = context.source.indexOf(close, open.length)
|
const closeIndex = context.source.indexOf(close, open.length)
|
||||||
if (closeIndex === -1) {
|
if (closeIndex === -1) {
|
||||||
@ -765,7 +765,7 @@ function parseInterpolation(
|
|||||||
}
|
}
|
||||||
|
|
||||||
function parseText(context: ParserContext, mode: TextModes): TextNode {
|
function parseText(context: ParserContext, mode: TextModes): TextNode {
|
||||||
__DEV__ && assert(context.source.length > 0)
|
__TEST__ && assert(context.source.length > 0)
|
||||||
|
|
||||||
const [open] = context.options.delimiters
|
const [open] = context.options.delimiters
|
||||||
// TODO could probably use some perf optimization
|
// TODO could probably use some perf optimization
|
||||||
@ -777,7 +777,7 @@ function parseText(context: ParserContext, mode: TextModes): TextNode {
|
|||||||
context.source.length
|
context.source.length
|
||||||
].filter(n => n !== -1)
|
].filter(n => n !== -1)
|
||||||
)
|
)
|
||||||
__DEV__ && assert(endIndex > 0)
|
__TEST__ && assert(endIndex > 0)
|
||||||
|
|
||||||
const start = getCursor(context)
|
const start = getCursor(context)
|
||||||
const content = parseTextData(context, endIndex, mode)
|
const content = parseTextData(context, endIndex, mode)
|
||||||
@ -951,7 +951,7 @@ function startsWith(source: string, searchString: string): boolean {
|
|||||||
|
|
||||||
function advanceBy(context: ParserContext, numberOfCharacters: number): void {
|
function advanceBy(context: ParserContext, numberOfCharacters: number): void {
|
||||||
const { source } = context
|
const { source } = context
|
||||||
__DEV__ && assert(numberOfCharacters <= source.length)
|
__TEST__ && assert(numberOfCharacters <= source.length)
|
||||||
advancePositionWithMutation(context, source, numberOfCharacters)
|
advancePositionWithMutation(context, source, numberOfCharacters)
|
||||||
context.source = source.slice(numberOfCharacters)
|
context.source = source.slice(numberOfCharacters)
|
||||||
}
|
}
|
||||||
|
@ -51,7 +51,7 @@ export const transformElement: NodeTransform = (node, context) => {
|
|||||||
}
|
}
|
||||||
// perform the work on exit, after all child expressions have been
|
// perform the work on exit, after all child expressions have been
|
||||||
// processed and merged.
|
// processed and merged.
|
||||||
return () => {
|
return function postTransformElement() {
|
||||||
const { tag, tagType, props } = node
|
const { tag, tagType, props } = node
|
||||||
const isPortal = tag === 'portal' || tag === 'Portal'
|
const isPortal = tag === 'portal' || tag === 'Portal'
|
||||||
const isSuspense = tag === 'suspense' || tag === 'Suspense'
|
const isSuspense = tag === 'suspense' || tag === 'Suspense'
|
||||||
@ -113,7 +113,7 @@ export const transformElement: NodeTransform = (node, context) => {
|
|||||||
node,
|
node,
|
||||||
context,
|
context,
|
||||||
// skip reserved "is" prop <component is>
|
// skip reserved "is" prop <component is>
|
||||||
node.props.filter(p => p !== isProp)
|
isProp ? node.props.filter(p => p !== isProp) : node.props
|
||||||
)
|
)
|
||||||
patchFlag = propsBuildResult.patchFlag
|
patchFlag = propsBuildResult.patchFlag
|
||||||
dynamicPropNames = propsBuildResult.dynamicPropNames
|
dynamicPropNames = propsBuildResult.dynamicPropNames
|
||||||
@ -177,9 +177,7 @@ export const transformElement: NodeTransform = (node, context) => {
|
|||||||
args.push(patchFlag + '')
|
args.push(patchFlag + '')
|
||||||
}
|
}
|
||||||
if (dynamicPropNames && dynamicPropNames.length) {
|
if (dynamicPropNames && dynamicPropNames.length) {
|
||||||
args.push(
|
args.push(stringifyDynamicPropNames(dynamicPropNames))
|
||||||
`[${dynamicPropNames.map(n => JSON.stringify(n)).join(`, `)}]`
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -204,6 +202,15 @@ export const transformElement: NodeTransform = (node, context) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function stringifyDynamicPropNames(props: string[]): string {
|
||||||
|
let propsNamesString = `[`
|
||||||
|
for (let i = 0, l = props.length; i < l; i++) {
|
||||||
|
propsNamesString += JSON.stringify(props[i])
|
||||||
|
if (i < l - 1) propsNamesString += ', '
|
||||||
|
}
|
||||||
|
return propsNamesString + `]`
|
||||||
|
}
|
||||||
|
|
||||||
export type PropsExpression = ObjectExpression | CallExpression | ExpressionNode
|
export type PropsExpression = ObjectExpression | CallExpression | ExpressionNode
|
||||||
|
|
||||||
export function buildProps(
|
export function buildProps(
|
||||||
@ -410,7 +417,7 @@ export function buildProps(
|
|||||||
// - onXXX handlers / style: merge into array
|
// - onXXX handlers / style: merge into array
|
||||||
// - class: merge into single expression with concatenation
|
// - class: merge into single expression with concatenation
|
||||||
function dedupeProperties(properties: Property[]): Property[] {
|
function dedupeProperties(properties: Property[]): Property[] {
|
||||||
const knownProps: Record<string, Property> = {}
|
const knownProps: Map<string, Property> = new Map()
|
||||||
const deduped: Property[] = []
|
const deduped: Property[] = []
|
||||||
for (let i = 0; i < properties.length; i++) {
|
for (let i = 0; i < properties.length; i++) {
|
||||||
const prop = properties[i]
|
const prop = properties[i]
|
||||||
@ -420,7 +427,7 @@ function dedupeProperties(properties: Property[]): Property[] {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
const name = prop.key.content
|
const name = prop.key.content
|
||||||
const existing = knownProps[name]
|
const existing = knownProps.get(name)
|
||||||
if (existing) {
|
if (existing) {
|
||||||
if (
|
if (
|
||||||
name === 'style' ||
|
name === 'style' ||
|
||||||
@ -432,7 +439,7 @@ function dedupeProperties(properties: Property[]): Property[] {
|
|||||||
}
|
}
|
||||||
// unexpected duplicate, should have emitted error during parse
|
// unexpected duplicate, should have emitted error during parse
|
||||||
} else {
|
} else {
|
||||||
knownProps[name] = prop
|
knownProps.set(name, prop)
|
||||||
deduped.push(prop)
|
deduped.push(prop)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -208,7 +208,7 @@ export function buildSlots(
|
|||||||
// remove node
|
// remove node
|
||||||
children.splice(i, 1)
|
children.splice(i, 1)
|
||||||
i--
|
i--
|
||||||
__DEV__ && assert(dynamicSlots.length > 0)
|
__TEST__ && assert(dynamicSlots.length > 0)
|
||||||
// attach this slot to previous conditional
|
// attach this slot to previous conditional
|
||||||
let conditional = dynamicSlots[
|
let conditional = dynamicSlots[
|
||||||
dynamicSlots.length - 1
|
dynamicSlots.length - 1
|
||||||
|
@ -77,7 +77,7 @@ export function getInnerRange(
|
|||||||
offset: number,
|
offset: number,
|
||||||
length?: number
|
length?: number
|
||||||
): SourceLocation {
|
): SourceLocation {
|
||||||
__DEV__ && assert(offset <= loc.source.length)
|
__TEST__ && assert(offset <= loc.source.length)
|
||||||
const source = loc.source.substr(offset, length)
|
const source = loc.source.substr(offset, length)
|
||||||
const newLoc: SourceLocation = {
|
const newLoc: SourceLocation = {
|
||||||
source,
|
source,
|
||||||
@ -86,7 +86,7 @@ export function getInnerRange(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (length != null) {
|
if (length != null) {
|
||||||
__DEV__ && assert(offset + length <= loc.source.length)
|
__TEST__ && assert(offset + length <= loc.source.length)
|
||||||
newLoc.end = advancePositionWithClone(
|
newLoc.end = advancePositionWithClone(
|
||||||
loc.start,
|
loc.start,
|
||||||
loc.source,
|
loc.source,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user