Unify reserved word checking and update error messages (#9402)

* Unify reserved word checking and update error messages

* Fix test
This commit is contained in:
Daniel Tschinder 2019-01-31 19:02:32 -08:00 committed by GitHub
parent 7e9029e337
commit 9eb010da50
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
172 changed files with 347 additions and 331 deletions

View File

@ -1,8 +1,6 @@
// @flow // @flow
import type { Options } from "../options"; import type { Options } from "../options";
import { isES2015ReservedWord } from "../util/identifier";
import type State from "../tokenizer/state"; import type State from "../tokenizer/state";
import type { PluginsMap } from "./index"; import type { PluginsMap } from "./index";
@ -17,14 +15,6 @@ export default class BaseParser {
// Initialized by Tokenizer // Initialized by Tokenizer
state: State; state: State;
isReservedWord(word: string): boolean {
if (word === "await") {
return this.inModule;
} else {
return isES2015ReservedWord(word);
}
}
hasPlugin(name: string): boolean { hasPlugin(name: string): boolean {
return this.plugins.has(name); return this.plugins.has(name);
} }

View File

@ -22,9 +22,10 @@ import { types as tt, type TokenType } from "../tokenizer/types";
import * as N from "../types"; import * as N from "../types";
import LValParser from "./lval"; import LValParser from "./lval";
import { import {
isKeyword,
isReservedWord,
isStrictReservedWord, isStrictReservedWord,
isStrictBindReservedWord, isStrictBindReservedWord,
isKeyword,
} from "../util/identifier"; } from "../util/identifier";
import type { Pos, Position } from "../util/location"; import type { Pos, Position } from "../util/location";
import * as charCodes from "charcodes"; import * as charCodes from "charcodes";
@ -1988,43 +1989,45 @@ export default class ExpressionParser extends LValParser {
checkKeywords: boolean, checkKeywords: boolean,
isBinding: boolean, isBinding: boolean,
): void { ): void {
if (this.state.inGenerator && word === "yield") { const state = this.state;
if (state.inGenerator && word === "yield") {
this.raise( this.raise(
startLoc, startLoc,
"Can not use 'yield' as identifier inside a generator", "Can not use 'yield' as identifier inside a generator",
); );
} }
if (this.state.inAsync && word === "await") { if (state.inAsync && word === "await") {
this.raise( this.raise(
startLoc, startLoc,
"Can not use 'await' as identifier inside an async function", "Can not use 'await' as identifier inside an async function",
); );
} }
if (this.state.inClassProperty && word === "arguments") { if (state.inClassProperty && word === "arguments") {
this.raise( this.raise(
startLoc, startLoc,
"'arguments' is not allowed in class field initializer", "'arguments' is not allowed in class field initializer",
); );
} }
if (checkKeywords && isKeyword(word)) {
this.raise(startLoc, `Unexpected keyword '${word}'`);
}
if (this.isReservedWord(word) || (checkKeywords && isKeyword(word))) { const reservedTest = !state.strict
if (!this.state.inAsync && word === "await") { ? isReservedWord
: isBinding
? isStrictBindReservedWord
: isStrictReservedWord;
if (reservedTest(word, this.inModule)) {
if (!state.inAsync && word === "await") {
this.raise( this.raise(
startLoc, startLoc,
"Can not use keyword 'await' outside an async function", "Can not use keyword 'await' outside an async function",
); );
} }
this.raise(startLoc, word + " is a reserved word"); this.raise(startLoc, `Unexpected reserved word '${word}'`);
}
if (
this.state.strict &&
(isStrictReservedWord(word) ||
(isBinding && isStrictBindReservedWord(word)))
) {
this.raise(startLoc, word + " is a reserved word in strict mode");
} }
} }

View File

@ -14,10 +14,7 @@ import type {
SpreadElement, SpreadElement,
} from "../types"; } from "../types";
import type { Pos, Position } from "../util/location"; import type { Pos, Position } from "../util/location";
import { import { isStrictBindReservedWord } from "../util/identifier";
isStrictReservedWord,
isStrictBindReservedWord,
} from "../util/identifier";
import { NodeUtils } from "./node"; import { NodeUtils } from "./node";
export default class LValParser extends NodeUtils { export default class LValParser extends NodeUtils {
@ -336,12 +333,13 @@ export default class LValParser extends NodeUtils {
case "Identifier": case "Identifier":
if ( if (
this.state.strict && this.state.strict &&
(isStrictReservedWord(expr.name) || isStrictBindReservedWord(expr.name, this.inModule)
isStrictBindReservedWord(expr.name))
) { ) {
this.raise( this.raise(
expr.start, expr.start,
expr.name + " is a reserved word in strict mode", `${isBinding ? "Binding" : "Assigning to"} '${
expr.name
}' in strict mode`,
); );
} }

View File

@ -4,27 +4,52 @@
import * as charCodes from "charcodes"; import * as charCodes from "charcodes";
export const isES2015ReservedWord = (word: string): boolean => { const reservedWords = {
return word === "enum" || word === "await"; strict: [
"implements",
"interface",
"let",
"package",
"private",
"protected",
"public",
"static",
"yield",
],
strictBind: ["eval", "arguments"],
}; };
const reservedWordsStrict = new Set([ const reservedWordsStrictSet = new Set(reservedWords.strict);
"implements", const reservedWordsStrictBindSet = new Set(
"interface", reservedWords.strict.concat(reservedWords.strictBind),
"let", );
"package",
"private", /**
"protected", * Checks if word is a reserved word in non-strict mode
"public", */
"static", export const isReservedWord = (word: string, inModule: boolean): boolean => {
"yield", return (inModule && word === "await") || word === "enum";
]); };
export function isStrictReservedWord(word: string): boolean {
return reservedWordsStrict.has(word); /**
* Checks if word is a reserved word in non-binding strict mode
*
* Includes non-strict reserved words
*/
export function isStrictReservedWord(word: string, inModule: boolean): boolean {
return isReservedWord(word, inModule) || reservedWordsStrictSet.has(word);
} }
export function isStrictBindReservedWord(word: string): boolean { /**
return word === "eval" || word === "arguments"; * Checks if word is a reserved word in binding strict mode
*
* Includes non-strict reserved words and non-binding strict reserved words
*/
export function isStrictBindReservedWord(
word: string,
inModule: boolean,
): boolean {
return isReservedWord(word, inModule) || reservedWordsStrictBindSet.has(word);
} }
const keywords = new Set([ const keywords = new Set([

View File

@ -1,4 +1,4 @@
{ {
"strictMode": true, "strictMode": true,
"throws": "public is a reserved word in strict mode (2:0)" "throws": "Unexpected reserved word 'public' (2:0)"
} }

View File

@ -1,3 +1,3 @@
{ {
"throws": "eval is a reserved word in strict mode (1:36)" "throws": "Binding 'eval' in strict mode (1:36)"
} }

View File

@ -1,3 +1,3 @@
{ {
"throws": "arguments is a reserved word in strict mode (1:36)" "throws": "Binding 'arguments' in strict mode (1:36)"
} }

View File

@ -1,3 +1,3 @@
{ {
"throws": "eval is a reserved word in strict mode (1:47)" "throws": "Binding 'eval' in strict mode (1:47)"
} }

View File

@ -1,3 +1,3 @@
{ {
"throws": "arguments is a reserved word in strict mode (1:47)" "throws": "Binding 'arguments' in strict mode (1:47)"
} }

View File

@ -1,3 +1,3 @@
{ {
"throws": "eval is a reserved word in strict mode (1:32)" "throws": "Assigning to 'eval' in strict mode (1:32)"
} }

View File

@ -1,3 +1,3 @@
{ {
"throws": "arguments is a reserved word in strict mode (1:32)" "throws": "Assigning to 'arguments' in strict mode (1:32)"
} }

View File

@ -1,3 +1,3 @@
{ {
"throws": "eval is a reserved word in strict mode (1:34)" "throws": "Assigning to 'eval' in strict mode (1:34)"
} }

View File

@ -1,3 +1,3 @@
{ {
"throws": "eval is a reserved word in strict mode (1:34)" "throws": "Assigning to 'eval' in strict mode (1:34)"
} }

View File

@ -1,3 +1,3 @@
{ {
"throws": "arguments is a reserved word in strict mode (1:34)" "throws": "Assigning to 'arguments' in strict mode (1:34)"
} }

View File

@ -1,3 +1,3 @@
{ {
"throws": "arguments is a reserved word in strict mode (1:34)" "throws": "Assigning to 'arguments' in strict mode (1:34)"
} }

View File

@ -1,3 +1,3 @@
{ {
"throws": "eval is a reserved word in strict mode (1:32)" "throws": "Assigning to 'eval' in strict mode (1:32)"
} }

View File

@ -1,3 +1,3 @@
{ {
"throws": "eval is a reserved word in strict mode (1:32)" "throws": "Assigning to 'eval' in strict mode (1:32)"
} }

View File

@ -1,3 +1,3 @@
{ {
"throws": "arguments is a reserved word in strict mode (1:32)" "throws": "Assigning to 'arguments' in strict mode (1:32)"
} }

View File

@ -1,3 +1,3 @@
{ {
"throws": "arguments is a reserved word in strict mode (1:32)" "throws": "Assigning to 'arguments' in strict mode (1:32)"
} }

View File

@ -1,3 +1,3 @@
{ {
"throws": "eval is a reserved word in strict mode (1:41)" "throws": "Binding 'eval' in strict mode (1:41)"
} }

View File

@ -1,3 +1,3 @@
{ {
"throws": "arguments is a reserved word in strict mode (1:41)" "throws": "Binding 'arguments' in strict mode (1:41)"
} }

View File

@ -1,3 +1,3 @@
{ {
"throws": "eval is a reserved word in strict mode (1:9)" "throws": "Binding 'eval' in strict mode (1:9)"
} }

View File

@ -1,3 +1,3 @@
{ {
"throws": "arguments is a reserved word in strict mode (1:9)" "throws": "Binding 'arguments' in strict mode (1:9)"
} }

View File

@ -1,3 +1,3 @@
{ {
"throws": "eval is a reserved word in strict mode (1:42)" "throws": "Binding 'eval' in strict mode (1:42)"
} }

View File

@ -1,3 +1,3 @@
{ {
"throws": "arguments is a reserved word in strict mode (1:42)" "throws": "Binding 'arguments' in strict mode (1:42)"
} }

View File

@ -1,3 +1,3 @@
{ {
"throws": "eval is a reserved word in strict mode (1:10)" "throws": "Binding 'eval' in strict mode (1:10)"
} }

View File

@ -1,3 +1,3 @@
{ {
"throws": "arguments is a reserved word in strict mode (1:10)" "throws": "Binding 'arguments' in strict mode (1:10)"
} }

View File

@ -1,3 +1,3 @@
{ {
"throws": "eval is a reserved word in strict mode (1:47)" "throws": "Binding 'eval' in strict mode (1:47)"
} }

View File

@ -1,3 +1,3 @@
{ {
"throws": "package is a reserved word in strict mode (1:10)" "throws": "Binding 'package' in strict mode (1:10)"
} }

View File

@ -1,3 +1,3 @@
{ {
"throws": "eval is a reserved word in strict mode (1:48)" "throws": "Binding 'eval' in strict mode (1:48)"
} }

View File

@ -1,3 +1,3 @@
{ {
"throws": "eval is a reserved word in strict mode (1:41)" "throws": "Binding 'eval' in strict mode (1:41)"
} }

View File

@ -1,3 +1,3 @@
{ {
"throws": "eval is a reserved word in strict mode (1:49)" "throws": "Binding 'eval' in strict mode (1:49)"
} }

View File

@ -1,3 +1,3 @@
{ {
"throws": "eval is a reserved word in strict mode (1:15)" "throws": "Binding 'eval' in strict mode (1:15)"
} }

View File

@ -1,3 +1,3 @@
{ {
"throws": "arguments is a reserved word in strict mode (1:15)" "throws": "Binding 'arguments' in strict mode (1:15)"
} }

View File

@ -1,3 +1,3 @@
{ {
"throws": "eval is a reserved word in strict mode (1:48)" "throws": "Binding 'eval' in strict mode (1:48)"
} }

View File

@ -1,3 +1,3 @@
{ {
"throws": "arguments is a reserved word in strict mode (1:48)" "throws": "Binding 'arguments' in strict mode (1:48)"
} }

View File

@ -1,3 +1,3 @@
{ {
"throws": "implements is a reserved word in strict mode (1:37)" "throws": "Unexpected reserved word 'implements' (1:37)"
} }

View File

@ -1,3 +1,3 @@
{ {
"throws": "interface is a reserved word in strict mode (1:37)" "throws": "Unexpected reserved word 'interface' (1:37)"
} }

View File

@ -1,3 +1,3 @@
{ {
"throws": "package is a reserved word in strict mode (1:37)" "throws": "Unexpected reserved word 'package' (1:37)"
} }

View File

@ -1,3 +1,3 @@
{ {
"throws": "private is a reserved word in strict mode (1:37)" "throws": "Unexpected reserved word 'private' (1:37)"
} }

View File

@ -1,3 +1,3 @@
{ {
"throws": "protected is a reserved word in strict mode (1:37)" "throws": "Unexpected reserved word 'protected' (1:37)"
} }

View File

@ -1,3 +1,3 @@
{ {
"throws": "public is a reserved word in strict mode (1:37)" "throws": "Unexpected reserved word 'public' (1:37)"
} }

View File

@ -1,3 +1,3 @@
{ {
"throws": "static is a reserved word in strict mode (1:37)" "throws": "Unexpected reserved word 'static' (1:37)"
} }

View File

@ -1,3 +1,3 @@
{ {
"throws": "static is a reserved word in strict mode (1:15)" "throws": "Binding 'static' in strict mode (1:15)"
} }

View File

@ -1,3 +1,3 @@
{ {
"throws": "static is a reserved word in strict mode (1:9)" "throws": "Binding 'static' in strict mode (1:9)"
} }

View File

@ -1,3 +1,3 @@
{ {
"throws": "static is a reserved word in strict mode (1:23)" "throws": "Unexpected reserved word 'static' (1:23)"
} }

View File

@ -1,3 +1,3 @@
{ {
"throws": "eval is a reserved word in strict mode (1:11)" "throws": "Binding 'eval' in strict mode (1:11)"
} }

View File

@ -1,3 +1,3 @@
{ {
"throws": "package is a reserved word in strict mode (1:11)" "throws": "Binding 'package' in strict mode (1:11)"
} }

View File

@ -1,3 +1,3 @@
{ {
"throws": "eval is a reserved word in strict mode (1:12)" "throws": "Binding 'eval' in strict mode (1:12)"
} }

View File

@ -1,3 +1,3 @@
{ {
"throws": "package is a reserved word in strict mode (1:12)" "throws": "Binding 'package' in strict mode (1:12)"
} }

View File

@ -1,3 +1,3 @@
{ {
"throws": "public is a reserved word in strict mode (2:8)" "throws": "Unexpected reserved word 'public' (2:8)"
} }

View File

@ -1,4 +1,4 @@
{ {
"sourceType": "module", "sourceType": "module",
"throws": "public is a reserved word in strict mode (1:8)" "throws": "Unexpected reserved word 'public' (1:8)"
} }

View File

@ -1,3 +1,3 @@
{ {
"throws": "arguments is a reserved word in strict mode (2:8)" "throws": "Unexpected reserved word 'arguments' (2:8)"
} }

View File

@ -1,4 +1,4 @@
{ {
"sourceType": "module", "sourceType": "module",
"throws": "arguments is a reserved word in strict mode (1:8)" "throws": "Unexpected reserved word 'arguments' (1:8)"
} }

View File

@ -1,3 +1,3 @@
{ {
"throws": "this is a reserved word (1:6)" "throws": "Unexpected keyword 'this' (1:6)"
} }

View File

@ -1,3 +1,3 @@
{ {
"throws": "let is a reserved word in strict mode (2:0)" "throws": "Unexpected reserved word 'let' (2:0)"
} }

View File

@ -1,4 +1,4 @@
{ {
"plugins": ["flow"], "plugins": ["flow"],
"throws": "default is a reserved word (1:9)" "throws": "Unexpected keyword 'default' (1:9)"
} }

View File

@ -1,4 +1,4 @@
{ {
"plugins": ["flow"], "plugins": ["flow"],
"throws": "typeof is a reserved word (1:9)" "throws": "Unexpected keyword 'typeof' (1:9)"
} }

View File

@ -1,3 +1,3 @@
{ {
"throws": "typeof is a reserved word (1:9)" "throws": "Unexpected keyword 'typeof' (1:9)"
} }

View File

@ -1,3 +1,3 @@
{ {
"throws": "debugger is a reserved word (1:9)" "throws": "Unexpected keyword 'debugger' (1:9)"
} }

View File

@ -1,3 +1,3 @@
{ {
"throws": "const is a reserved word (1:11)" "throws": "Unexpected keyword 'const' (1:11)"
} }

View File

@ -1,3 +1,3 @@
{ {
"throws": "this is a reserved word (1:8)" "throws": "Unexpected keyword 'this' (1:8)"
} }

View File

@ -1,3 +1,3 @@
{ {
"throws": "eval is a reserved word in strict mode (1:44)" "throws": "Binding 'eval' in strict mode (1:44)"
} }

View File

@ -1,3 +1,3 @@
{ {
"throws": "eval is a reserved word in strict mode (1:20)" "throws": "Assigning to 'eval' in strict mode (1:20)"
} }

View File

@ -1,3 +1,3 @@
{ {
"throws": "arguments is a reserved word in strict mode (1:20)" "throws": "Assigning to 'arguments' in strict mode (1:20)"
} }

View File

@ -1,3 +1,3 @@
{ {
"throws": "eval is a reserved word in strict mode (1:15)" "throws": "Assigning to 'eval' in strict mode (1:15)"
} }

View File

@ -1,3 +1,3 @@
{ {
"throws": "eval is a reserved word in strict mode (1:14)" "throws": "Binding 'eval' in strict mode (1:14)"
} }

View File

@ -1,3 +1,3 @@
{ {
"throws": "arguments is a reserved word in strict mode (1:14)" "throws": "Binding 'arguments' in strict mode (1:14)"
} }

View File

@ -1,3 +1,3 @@
{ {
"throws": "eval is a reserved word in strict mode (1:15)" "throws": "Binding 'eval' in strict mode (1:15)"
} }

View File

@ -1,3 +1,3 @@
{ {
"throws": "arguments is a reserved word in strict mode (1:15)" "throws": "Binding 'arguments' in strict mode (1:15)"
} }

View File

@ -1,3 +1,3 @@
{ {
"throws": "eval is a reserved word in strict mode (1:15)" "throws": "Binding 'eval' in strict mode (1:15)"
} }

View File

@ -1,3 +1,3 @@
{ {
"throws": "eval is a reserved word in strict mode (1:5)" "throws": "Binding 'eval' in strict mode (1:5)"
} }

View File

@ -1,3 +1,3 @@
{ {
"throws": "eval is a reserved word in strict mode (1:15)" "throws": "Binding 'eval' in strict mode (1:15)"
} }

View File

@ -1,3 +1,3 @@
{ {
"throws": "eval is a reserved word in strict mode (1:1)" "throws": "Binding 'eval' in strict mode (1:1)"
} }

View File

@ -1,3 +1,3 @@
{ {
"throws": "eval is a reserved word in strict mode (1:18)" "throws": "Assigning to 'eval' in strict mode (1:18)"
} }

View File

@ -1,3 +1,3 @@
{ {
"throws": "eval is a reserved word in strict mode (1:16)" "throws": "Unexpected reserved word 'eval' (1:16)"
} }

View File

@ -1,4 +1,4 @@
{ {
"sourceType": "module", "sourceType": "module",
"throws": "eval is a reserved word in strict mode (1:4)" "throws": "Assigning to 'eval' in strict mode (1:4)"
} }

View File

@ -1,4 +1,4 @@
{ {
"sourceType": "script", "sourceType": "script",
"throws": "enum is a reserved word (1:0)" "throws": "Unexpected reserved word 'enum' (1:0)"
} }

View File

@ -1,4 +1,4 @@
{ {
"sourceType": "module", "sourceType": "module",
"throws": "enum is a reserved word (1:0)" "throws": "Unexpected reserved word 'enum' (1:0)"
} }

View File

@ -1,4 +1,4 @@
{ {
"sourceType": "script", "sourceType": "script",
"throws": "enum is a reserved word (1:6)" "throws": "Unexpected reserved word 'enum' (1:6)"
} }

View File

@ -1,4 +1,4 @@
{ {
"sourceType": "module", "sourceType": "module",
"throws": "enum is a reserved word (1:6)" "throws": "Unexpected reserved word 'enum' (1:6)"
} }

View File

@ -1,4 +1,4 @@
{ {
"sourceType": "script", "sourceType": "script",
"throws": "enum is a reserved word (1:8)" "throws": "Unexpected reserved word 'enum' (1:8)"
} }

View File

@ -1,4 +1,4 @@
{ {
"sourceType": "module", "sourceType": "module",
"throws": "enum is a reserved word (1:8)" "throws": "Unexpected reserved word 'enum' (1:8)"
} }

View File

@ -1,4 +1,4 @@
{ {
"sourceType": "script", "sourceType": "script",
"throws": "enum is a reserved word (1:15)" "throws": "Unexpected reserved word 'enum' (1:15)"
} }

View File

@ -1,4 +1,4 @@
{ {
"sourceType": "module", "sourceType": "module",
"throws": "enum is a reserved word (1:15)" "throws": "Unexpected reserved word 'enum' (1:15)"
} }

View File

@ -1,4 +1,4 @@
{ {
"sourceType": "script", "sourceType": "script",
"throws": "enum is a reserved word (1:9)" "throws": "Unexpected reserved word 'enum' (1:9)"
} }

View File

@ -1,4 +1,4 @@
{ {
"sourceType": "module", "sourceType": "module",
"throws": "enum is a reserved word (1:9)" "throws": "Unexpected reserved word 'enum' (1:9)"
} }

View File

@ -1,4 +1,4 @@
{ {
"sourceType": "script", "sourceType": "script",
"throws": "enum is a reserved word (1:6)" "throws": "Unexpected reserved word 'enum' (1:6)"
} }

View File

@ -1,4 +1,4 @@
{ {
"sourceType": "module", "sourceType": "module",
"throws": "enum is a reserved word (1:6)" "throws": "Unexpected reserved word 'enum' (1:6)"
} }

View File

@ -1,3 +1,3 @@
{ {
"throws": "yield is a reserved word in strict mode (1:9)" "throws": "Binding 'yield' in strict mode (1:9)"
} }

View File

@ -1,3 +1,3 @@
{ {
"throws": "yield is a reserved word in strict mode (2:9)" "throws": "Unexpected reserved word 'yield' (2:9)"
} }

View File

@ -1,3 +1,3 @@
{ {
"throws": "yield is a reserved word in strict mode (1:16)" "throws": "Unexpected reserved word 'yield' (1:16)"
} }

View File

@ -1,3 +1,3 @@
{ {
"throws": "yield is a reserved word in strict mode (2:16)" "throws": "Unexpected reserved word 'yield' (2:16)"
} }

View File

@ -1,3 +1,3 @@
{ {
"throws": "yield is a reserved word in strict mode (1:12)" "throws": "Binding 'yield' in strict mode (1:12)"
} }

View File

@ -1,3 +1,3 @@
{ {
"throws": "yield is a reserved word in strict mode (2:12)" "throws": "Unexpected reserved word 'yield' (2:12)"
} }

View File

@ -1,3 +1,3 @@
{ {
"throws": "eval is a reserved word in strict mode (1:0)" "throws": "Binding 'eval' in strict mode (1:0)"
} }

View File

@ -1,4 +1,4 @@
{ {
"sourceType": "module", "sourceType": "module",
"throws": "yield is a reserved word in strict mode (1:25)" "throws": "Unexpected reserved word 'yield' (1:25)"
} }

View File

@ -1,3 +1,3 @@
{ {
"throws": "yield is a reserved word in strict mode (1:46)" "throws": "Unexpected reserved word 'yield' (1:46)"
} }

View File

@ -1,3 +1,3 @@
{ {
"throws": "yield is a reserved word in strict mode (1:47)" "throws": "Unexpected reserved word 'yield' (1:47)"
} }

View File

@ -1,3 +1,3 @@
{ {
"throws": "yield is a reserved word in strict mode (1:16)" "throws": "Unexpected reserved word 'yield' (1:16)"
} }

Some files were not shown because too many files have changed in this diff Show More