| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465 |
- import type { SimpleExpressionNode } from './ast'
- import type { TransformContext } from './transform'
- import { ErrorCodes, createCompilerError } from './errors'
- // these keywords should not appear inside expressions, but operators like
- // 'typeof', 'instanceof', and 'in' are allowed
- const prohibitedKeywordRE = new RegExp(
- '\\b' +
- (
- 'arguments,await,break,case,catch,class,const,continue,debugger,default,' +
- 'delete,do,else,export,extends,finally,for,function,if,import,let,new,' +
- 'return,super,switch,throw,try,var,void,while,with,yield'
- )
- .split(',')
- .join('\\b|\\b') +
- '\\b',
- )
- // strip strings in expressions
- const stripStringRE =
- /'(?:[^'\\]|\\.)*'|"(?:[^"\\]|\\.)*"|`(?:[^`\\]|\\.)*\$\{|\}(?:[^`\\]|\\.)*`|`(?:[^`\\]|\\.)*`/g
- /**
- * Validate a non-prefixed expression.
- * This is only called when using the in-browser runtime compiler since it
- * doesn't prefix expressions.
- */
- export function validateBrowserExpression(
- node: SimpleExpressionNode,
- context: TransformContext,
- asParams = false,
- asRawStatements = false,
- ) {
- const exp = node.content
- // empty expressions are validated per-directive since some directives
- // do allow empty expressions.
- if (!exp.trim()) {
- return
- }
- try {
- new Function(
- asRawStatements
- ? ` ${exp} `
- : `return ${asParams ? `(${exp}) => {}` : `(${exp})`}`,
- )
- } catch (e: any) {
- let message = e.message
- const keywordMatch = exp
- .replace(stripStringRE, '')
- .match(prohibitedKeywordRE)
- if (keywordMatch) {
- message = `avoid using JavaScript keyword as property name: "${keywordMatch[0]}"`
- }
- context.onError(
- createCompilerError(
- ErrorCodes.X_INVALID_EXPRESSION,
- node.loc,
- undefined,
- message,
- ),
- )
- }
- }
|