|
|
@@ -0,0 +1,60 @@
|
|
|
+// these keywords should not appear inside expressions, but operators like
|
|
|
+
|
|
|
+import { SimpleExpressionNode } from './ast'
|
|
|
+import { TransformContext } from './transform'
|
|
|
+import { createCompilerError, ErrorCodes } from './errors'
|
|
|
+
|
|
|
+// typeof, instanceof and in are allowed
|
|
|
+const prohibitedKeywordRE = new RegExp(
|
|
|
+ '\\b' +
|
|
|
+ (
|
|
|
+ 'do,if,for,let,new,try,var,case,else,with,await,break,catch,class,const,' +
|
|
|
+ 'super,throw,while,yield,delete,export,import,return,switch,default,' +
|
|
|
+ 'extends,finally,continue,debugger,function,arguments,typeof,void'
|
|
|
+ )
|
|
|
+ .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
|
|
|
+ try {
|
|
|
+ new Function(
|
|
|
+ asRawStatements
|
|
|
+ ? ` ${exp} `
|
|
|
+ : `return ${asParams ? `(${exp}) => {}` : `(${exp})`}`
|
|
|
+ )
|
|
|
+ } catch (e) {
|
|
|
+ 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
|
|
|
+ )
|
|
|
+ )
|
|
|
+ }
|
|
|
+}
|