perf: Use === or Set.has instead of array.indexOf for keyword checks

This commit is contained in:
Daniel Tschinder 2019-01-17 00:46:43 -08:00
parent f12905b531
commit b66d921053
4 changed files with 89 additions and 24 deletions

View File

@ -1,7 +1,7 @@
// @flow // @flow
import type { Options } from "../options"; import type { Options } from "../options";
import { reservedWords } from "../util/identifier"; 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";
@ -21,7 +21,7 @@ export default class BaseParser {
if (word === "await") { if (word === "await") {
return this.inModule; return this.inModule;
} else { } else {
return reservedWords[6](word); return isES2015ReservedWord(word);
} }
} }

View File

@ -21,7 +21,10 @@
import { types as tt, type TokenType } from "../tokenizer/types"; 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 { reservedWords } from "../util/identifier"; import {
isStrictReservedWord,
isStrictBindReservedWord,
} 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";
@ -1997,8 +2000,8 @@ export default class ExpressionParser extends LValParser {
): void { ): void {
if ( if (
this.state.strict && this.state.strict &&
(reservedWords.strict(word) || (isStrictReservedWord(word) ||
(isBinding && reservedWords.strictBind(word))) (isBinding && isStrictBindReservedWord(word)))
) { ) {
this.raise(startLoc, word + " is a reserved word in strict mode"); this.raise(startLoc, word + " is a reserved word in strict mode");
} }

View File

@ -4,28 +4,72 @@
import * as charCodes from "charcodes"; import * as charCodes from "charcodes";
function makePredicate(words: string): (str: string) => boolean { export const isES2015ReservedWord = (word: string): boolean => {
const wordsArr = words.split(" "); return word === "enum" || word === "await";
return function(str) {
return wordsArr.indexOf(str) >= 0;
}; };
const reservedWordsStrict = new Set([
"implements",
"interface",
"let",
"package",
"private",
"protected",
"public",
"static",
"yield",
]);
export function isStrictReservedWord(word: string): boolean {
return reservedWordsStrict.has(word);
} }
// Reserved word lists for various dialects of the language export function isStrictBindReservedWord(word: string): boolean {
return word === "eval" || word === "arguments";
}
export const reservedWords = { const keywords = new Set([
"6": makePredicate("enum await"), "break",
strict: makePredicate( "case",
"implements interface let package private protected public static yield", "catch",
), "continue",
strictBind: makePredicate("eval arguments"), "debugger",
}; "default",
"do",
"else",
"finally",
"for",
"function",
"if",
"return",
"switch",
"throw",
"try",
"var",
"while",
"with",
"null",
"true",
"false",
"instanceof",
"typeof",
"void",
"delete",
"new",
"in",
"this",
"let",
"const",
"class",
"extends",
"export",
"import",
"yield",
"super",
]);
// And the keywords export function isKeyword(word: string): boolean {
return keywords.has(word);
export const isKeyword = makePredicate( }
"break case catch continue debugger default do else finally for function if return switch throw try var while with null true false instanceof typeof void delete new in this let const class extends export import yield super",
);
// ## Character categories // ## Character categories

View File

@ -0,0 +1,18 @@
import { isKeyword } from "../../../src/util/identifier";
describe("identifier", () => {
describe("isKeyword", () => {
it("break is a keyword", () => {
expect(isKeyword("break")).toBe(true);
});
it("let is a keyword", () => {
expect(isKeyword("let")).toBe(true);
});
it("super is a keyword", () => {
expect(isKeyword("super")).toBe(true);
});
it("abc is not a keyword", () => {
expect(isKeyword("abc")).toBe(false);
});
});
});