fix(compiler-core): more robust member expression check when running in node

fix #4640
This commit is contained in:
Evan You
2021-09-21 12:19:27 -04:00
parent 7c3c28eb03
commit d23fde3d3b
4 changed files with 98 additions and 36 deletions

View File

@@ -42,8 +42,16 @@ import {
WITH_MEMO,
OPEN_BLOCK
} from './runtimeHelpers'
import { isString, isObject, hyphenate, extend } from '@vue/shared'
import {
isString,
isObject,
hyphenate,
extend,
babelParserDefaultPlugins
} from '@vue/shared'
import { PropsExpression } from './transforms/transformElement'
import { parseExpression } from '@babel/parser'
import { Expression } from '@babel/types'
export const isStaticExp = (p: JSChildNode): p is SimpleExpressionNode =>
p.type === NodeTypes.SIMPLE_EXPRESSION && p.isStatic
@@ -84,7 +92,7 @@ const whitespaceRE = /\s+[.[]\s*|\s*[.[]\s+/g
* inside square brackets), but it's ok since these are only used on template
* expressions and false positives are invalid expressions in the first place.
*/
export const isMemberExpression = (path: string): boolean => {
export const isMemberExpressionBrowser = (path: string): boolean => {
// remove whitespaces around . or [ first
path = path.trim().replace(whitespaceRE, s => s.trim())
@@ -153,6 +161,35 @@ export const isMemberExpression = (path: string): boolean => {
return !currentOpenBracketCount && !currentOpenParensCount
}
export const isMemberExpressionNode = (
path: string,
context: TransformContext
): boolean => {
path = path.trim()
if (!validFirstIdentCharRE.test(path[0])) {
return false
}
try {
let ret: Expression = parseExpression(path, {
plugins: [...context.expressionPlugins, ...babelParserDefaultPlugins]
})
if (ret.type === 'TSAsExpression' || ret.type === 'TSTypeAssertion') {
ret = ret.expression
}
return (
ret.type === 'MemberExpression' ||
ret.type === 'OptionalMemberExpression' ||
ret.type === 'Identifier'
)
} catch (e) {
return false
}
}
export const isMemberExpression = __BROWSER__
? isMemberExpressionBrowser
: isMemberExpressionNode
export function getInnerRange(
loc: SourceLocation,
offset: number,