55 */
66import first from "lodash/first"
77import last from "lodash/last"
8+ import sortedIndexBy from "lodash/sortedIndexBy"
89import {
910 traverseNodes ,
1011 ESLintArrayPattern ,
@@ -18,7 +19,6 @@ import {
1819 ESLintFunctionExpression ,
1920 ESLintPattern ,
2021 ESLintProgram ,
21- ESLintSpreadElement ,
2222 ESLintVariableDeclaration ,
2323 ESLintUnaryExpression ,
2424 Node ,
@@ -150,6 +150,30 @@ function removeByName(references: Reference[], name: string): void {
150150 }
151151}
152152
153+ /**
154+ * Get the comma token before a given node.
155+ * @param tokens The token list.
156+ * @param node The node to get the comma before this node.
157+ * @returns The comma token.
158+ */
159+ function getCommaTokenBeforeNode ( tokens : Token [ ] , node : Node ) : Token | null {
160+ let tokenIndex = sortedIndexBy (
161+ tokens ,
162+ { range : node . range } ,
163+ t => t . range [ 0 ] ,
164+ )
165+
166+ while ( tokenIndex >= 0 ) {
167+ const token = tokens [ tokenIndex ]
168+ if ( token . type === "Punctuator" && token . value === "," ) {
169+ return token
170+ }
171+ tokenIndex -= 1
172+ }
173+
174+ return null
175+ }
176+
153177/**
154178 * Throw syntax error for empty.
155179 * @param locationCalculator The location calculator to get line/column.
@@ -172,22 +196,19 @@ function throwEmptyError(
172196}
173197
174198/**
175- * Throw syntax error for empty .
199+ * Throw syntax error for unexpected token .
176200 * @param locationCalculator The location calculator to get line/column.
201+ * @param name The token name.
202+ * @param token The token object to get that location.
177203 */
178- function throwUnexpectedSpreadElementError (
179- locationCalculator : LocationCalculator ,
180- node : ESLintSpreadElement ,
181- ) : never {
182- const loc = locationCalculator . getLocation ( node . start || 0 )
204+ function throwUnexpectedTokenError ( name : string , token : Node | Token ) : never {
183205 const err = new ParseError (
184- " Unexpected spread element." ,
206+ ` Unexpected token ' ${ name } '.` ,
185207 undefined ,
186- 0 ,
187- loc . line ,
188- loc . column ,
208+ token . range [ 0 ] ,
209+ token . loc . start . line ,
210+ token . loc . start . column ,
189211 )
190- locationCalculator . fixErrorLocation ( err )
191212
192213 throw err
193214}
@@ -364,13 +385,17 @@ export function parseExpression(
364385 return throwEmptyError ( locationCalculator , "an expression" )
365386 }
366387 if ( expression && expression . type === "SpreadElement" ) {
367- return throwUnexpectedSpreadElementError (
368- locationCalculator . getSubCalculatorAfter ( - 2 ) ,
369- expression ,
388+ return throwUnexpectedTokenError ( "..." , expression )
389+ }
390+ if ( callExpression . arguments [ 1 ] ) {
391+ const node = callExpression . arguments [ 1 ]
392+ return throwUnexpectedTokenError (
393+ "," ,
394+ getCommaTokenBeforeNode ( tokens , node ) || node ,
370395 )
371396 }
372397
373- // Remvoe parens.
398+ // Remove parens.
374399 tokens . shift ( )
375400 tokens . shift ( )
376401 tokens . pop ( )
0 commit comments