Skip to content

Commit

Permalink
Fix: make mustaches allowing empty (refs vuejs/eslint-plugin-vue#398)
Browse files Browse the repository at this point in the history
  • Loading branch information
mysticatea committed Jul 21, 2018
1 parent 7ded104 commit 6906fb1
Show file tree
Hide file tree
Showing 5 changed files with 45 additions and 35 deletions.
1 change: 1 addition & 0 deletions docs/ast.md
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ interface VSlotScopeExpression <: Expression {

- This is mustaches or directive values.
- If syntax errors exist, `VExpressionContainer#expression` is `null`.
- If it's an empty mustache, `VExpressionContainer#expression` is `null`. (e.g., `{{ /* a comment */ }}`)
- `Reference` is objects but not `Node`. Those are external references which are in the expression.
- `Reference#variable` is the variable which is defined by a `VElement`. If a reference uses a global variable or a member of VM, this is `null`.
- `VForExpression` is an expression node like [ForInStatement] but it has an array as `left` property and does not have `body` property. This is the value of [`v-for` directives].
Expand Down
51 changes: 42 additions & 9 deletions src/script/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
traverseNodes,
ESLintArrayPattern,
ESLintBlockStatement,
ESLintCallExpression,
ESLintExpression,
ESLintExpressionStatement,
ESLintExtendedProgram,
Expand All @@ -17,6 +18,7 @@ import {
ESLintFunctionExpression,
ESLintPattern,
ESLintProgram,
ESLintSpreadElement,
ESLintVariableDeclaration,
ESLintUnaryExpression,
Node,
Expand Down Expand Up @@ -169,6 +171,27 @@ function throwEmptyError(
throw err
}

/**
* Throw syntax error for empty.
* @param locationCalculator The location calculator to get line/column.
*/
function throwUnexpectedSpreadElementError(
locationCalculator: LocationCalculator,
node: ESLintSpreadElement,
): never {
const loc = locationCalculator.getLocation(node.start || 0)
const err = new ParseError(
"Unexpected spread element.",
undefined,
0,
loc.line,
loc.column,
)
locationCalculator.fixErrorLocation(err)

throw err
}

/**
* Throw syntax error of outside of code.
* @param locationCalculator The location calculator to get line/column.
Expand Down Expand Up @@ -320,26 +343,36 @@ export function parseExpression(
code: string,
locationCalculator: LocationCalculator,
parserOptions: any,
allowEmpty = false,
): ExpressionParseResult {
debug('[script] parse expression: "(%s)"', code)

if (code.trim() === "") {
return throwEmptyError(locationCalculator, "an expression")
}
debug('[script] parse expression: "0(%s)"', code)

try {
const ast = parseScriptFragment(
`(${code})`,
locationCalculator.getSubCalculatorAfter(-1),
`0(${code})`,
locationCalculator.getSubCalculatorAfter(-2),
parserOptions,
).ast
const references = analyzeExternalReferences(ast, parserOptions)
const expression = (ast.body[0] as ESLintExpressionStatement).expression
const tokens = ast.tokens || []
const comments = ast.comments || []
const references = analyzeExternalReferences(ast, parserOptions)
const statement = ast.body[0] as ESLintExpressionStatement
const callExpression = statement.expression as ESLintCallExpression
const expression = callExpression.arguments[0]

if (!allowEmpty && !expression) {
return throwEmptyError(locationCalculator, "an expression")
}
if (expression && expression.type === "SpreadElement") {
return throwUnexpectedSpreadElementError(
locationCalculator.getSubCalculatorAfter(-2),
expression,
)
}

// Remvoe parens.
tokens.shift()
tokens.shift()
tokens.pop()

return { expression, tokens, comments, references, variables: [] }
Expand Down
3 changes: 2 additions & 1 deletion src/template/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -466,9 +466,10 @@ export function processMustache(
mustache.value,
locationCalculator,
parserOptions,
true,
)

node.expression = ret.expression
node.expression = ret.expression || null
node.references = ret.references
if (ret.expression != null) {
ret.expression.parent = node
Expand Down
24 changes: 0 additions & 24 deletions test/fixtures/ast/error-message-empty/ast.json
Original file line number Diff line number Diff line change
Expand Up @@ -1100,24 +1100,6 @@
},
"value": "{{"
},
{
"type": "HTMLWhitespace",
"range": [
26,
27
],
"loc": {
"start": {
"line": 3,
"column": 6
},
"end": {
"line": 3,
"column": 7
}
},
"value": " "
},
{
"type": "VExpressionEnd",
"range": [
Expand Down Expand Up @@ -2129,12 +2111,6 @@
],
"comments": [],
"errors": [
{
"message": "Expected to be an expression, but got empty.",
"index": 26,
"lineNumber": 3,
"column": 6
},
{
"message": "Expected to be an expression, but got empty.",
"index": 65,
Expand Down
1 change: 0 additions & 1 deletion test/fixtures/ast/error-message-empty/token-ranges.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
"}}",
"\n ",
"{{",
" ",
"}}",
"\n ",
"<div",
Expand Down

0 comments on commit 6906fb1

Please sign in to comment.