perf: remove double check for keywords in readWord

Instead of calling isKeyword we simple check directly if the keyword token is available
This commit is contained in:
Daniel Tschinder 2019-01-17 01:46:22 -08:00
parent b66d921053
commit 4e5e319d5b
4 changed files with 70 additions and 84 deletions

View File

@ -24,6 +24,7 @@ import LValParser from "./lval";
import {
isStrictReservedWord,
isStrictBindReservedWord,
isKeyword,
} from "../util/identifier";
import type { Pos, Position } from "../util/location";
import * as charCodes from "charcodes";
@ -2020,7 +2021,7 @@ export default class ExpressionParser extends LValParser {
);
}
if (this.isReservedWord(word) || (checkKeywords && this.isKeyword(word))) {
if (this.isReservedWord(word) || (checkKeywords && isKeyword(word))) {
this.raise(startLoc, word + " is a reserved word");
}
}

View File

@ -1190,9 +1190,6 @@ export default (superClass: Class<Parser>): Class<Parser> =>
case "any":
return this.finishNode(node, "AnyTypeAnnotation");
case "void":
return this.finishNode(node, "VoidTypeAnnotation");
case "bool":
case "boolean":
return this.finishNode(node, "BooleanTypeAnnotation");
@ -1369,6 +1366,10 @@ export default (superClass: Class<Parser>): Class<Parser> =>
"NumberLiteralTypeAnnotation",
);
case tt._void:
this.next();
return this.finishNode(node, "VoidTypeAnnotation");
case tt._null:
this.next();
return this.finishNode(node, "NullLiteralTypeAnnotation");
@ -1922,16 +1923,6 @@ export default (superClass: Class<Parser>): Class<Parser> =>
}
}
// don't consider `void` to be a keyword as then it'll use the void token type
// and set startExpr
isKeyword(name: string): boolean {
if (this.state.inType && name === "void") {
return false;
} else {
return super.isKeyword(name);
}
}
// ensure that inside flow types, we bypass the jsx parser plugin
getTokenFromCode(code: number): void {
const next = this.state.input.charCodeAt(this.state.pos + 1);

View File

@ -3,11 +3,7 @@
import type { Options } from "../options";
import type { Position } from "../util/location";
import * as charCodes from "charcodes";
import {
isIdentifierStart,
isIdentifierChar,
isKeyword,
} from "../util/identifier";
import { isIdentifierStart, isIdentifierChar } from "../util/identifier";
import { types as tt, keywords as keywordTypes, type TokenType } from "./types";
import { type TokContext, types as ct } from "./context";
import LocationParser from "../parser/location";
@ -157,12 +153,6 @@ export default class Tokenizer extends LocationParser {
// TODO
isKeyword(word: string): boolean {
return isKeyword(word);
}
// TODO
lookahead(): State {
const old = this.state;
this.state = old.clone(true);
@ -1336,14 +1326,10 @@ export default class Tokenizer extends LocationParser {
readWord(): void {
const word = this.readWord1();
let type = tt.name;
const type = keywordTypes[word] || tt.name;
if (this.isKeyword(word)) {
if (this.state.containsEsc) {
this.raise(this.state.pos, `Escape sequence in keyword ${word}`);
}
type = keywordTypes[word];
if (type.keyword && this.state.containsEsc) {
this.raise(this.state.pos, `Escape sequence in keyword ${word}`);
}
// Allow @@iterator and @@asyncIterator as a identifier only inside type

View File

@ -133,20 +133,20 @@ export const types: { [name: string]: TokenType } = {
incDec: new TokenType("++/--", { prefix, postfix, startsExpr }),
bang: new TokenType("!", { beforeExpr, prefix, startsExpr }),
tilde: new TokenType("~", { beforeExpr, prefix, startsExpr }),
pipeline: new BinopTokenType("|>", 0),
nullishCoalescing: new BinopTokenType("??", 1),
logicalOR: new BinopTokenType("||", 1),
logicalAND: new BinopTokenType("&&", 2),
bitwiseOR: new BinopTokenType("|", 3),
bitwiseXOR: new BinopTokenType("^", 4),
bitwiseAND: new BinopTokenType("&", 5),
equality: new BinopTokenType("==/!=", 6),
relational: new BinopTokenType("</>", 7),
bitShift: new BinopTokenType("<</>>", 8),
pipeline: BinopTokenType("|>", 0),
nullishCoalescing: BinopTokenType("??", 1),
logicalOR: BinopTokenType("||", 1),
logicalAND: BinopTokenType("&&", 2),
bitwiseOR: BinopTokenType("|", 3),
bitwiseXOR: BinopTokenType("^", 4),
bitwiseAND: BinopTokenType("&", 5),
equality: BinopTokenType("==/!=", 6),
relational: BinopTokenType("</>", 7),
bitShift: BinopTokenType("<</>>", 8),
plusMin: new TokenType("+/-", { beforeExpr, binop: 9, prefix, startsExpr }),
modulo: new BinopTokenType("%", 10),
star: new BinopTokenType("*", 10),
slash: new BinopTokenType("/", 10),
modulo: BinopTokenType("%", 10),
star: BinopTokenType("*", 10),
slash: BinopTokenType("/", 10),
exponent: new TokenType("**", {
beforeExpr,
binop: 11,
@ -154,45 +154,53 @@ export const types: { [name: string]: TokenType } = {
}),
};
export const keywords = {
break: new KeywordTokenType("break"),
case: new KeywordTokenType("case", { beforeExpr }),
catch: new KeywordTokenType("catch"),
continue: new KeywordTokenType("continue"),
debugger: new KeywordTokenType("debugger"),
default: new KeywordTokenType("default", { beforeExpr }),
do: new KeywordTokenType("do", { isLoop, beforeExpr }),
else: new KeywordTokenType("else", { beforeExpr }),
finally: new KeywordTokenType("finally"),
for: new KeywordTokenType("for", { isLoop }),
function: new KeywordTokenType("function", { startsExpr }),
if: new KeywordTokenType("if"),
return: new KeywordTokenType("return", { beforeExpr }),
switch: new KeywordTokenType("switch"),
throw: new KeywordTokenType("throw", { beforeExpr, prefix, startsExpr }),
try: new KeywordTokenType("try"),
var: new KeywordTokenType("var"),
let: new KeywordTokenType("let"),
const: new KeywordTokenType("const"),
while: new KeywordTokenType("while", { isLoop }),
with: new KeywordTokenType("with"),
new: new KeywordTokenType("new", { beforeExpr, startsExpr }),
this: new KeywordTokenType("this", { startsExpr }),
super: new KeywordTokenType("super", { startsExpr }),
class: new KeywordTokenType("class", { startsExpr }),
extends: new KeywordTokenType("extends", { beforeExpr }),
export: new KeywordTokenType("export"),
import: new KeywordTokenType("import", { startsExpr }),
yield: new KeywordTokenType("yield", { beforeExpr, startsExpr }),
null: new KeywordTokenType("null", { startsExpr }),
true: new KeywordTokenType("true", { startsExpr }),
false: new KeywordTokenType("false", { startsExpr }),
in: new KeywordTokenType("in", { beforeExpr, binop: 7 }),
instanceof: new KeywordTokenType("instanceof", { beforeExpr, binop: 7 }),
typeof: new KeywordTokenType("typeof", { beforeExpr, prefix, startsExpr }),
void: new KeywordTokenType("void", { beforeExpr, prefix, startsExpr }),
delete: new KeywordTokenType("delete", { beforeExpr, prefix, startsExpr }),
};
function makeKeywordProps(
name: string,
conf: any,
): PropertyDescriptor<TokenType> {
return { value: KeywordTokenType(name, conf), enumerable: true };
}
// $FlowIssue
export const keywords = Object.create(null, {
break: makeKeywordProps("break"),
case: makeKeywordProps("case", { beforeExpr }),
catch: makeKeywordProps("catch"),
continue: makeKeywordProps("continue"),
debugger: makeKeywordProps("debugger"),
default: makeKeywordProps("default", { beforeExpr }),
do: makeKeywordProps("do", { isLoop, beforeExpr }),
else: makeKeywordProps("else", { beforeExpr }),
finally: makeKeywordProps("finally"),
for: makeKeywordProps("for", { isLoop }),
function: makeKeywordProps("function", { startsExpr }),
if: makeKeywordProps("if"),
return: makeKeywordProps("return", { beforeExpr }),
switch: makeKeywordProps("switch"),
throw: makeKeywordProps("throw", { beforeExpr, prefix, startsExpr }),
try: makeKeywordProps("try"),
var: makeKeywordProps("var"),
let: makeKeywordProps("let"),
const: makeKeywordProps("const"),
while: makeKeywordProps("while", { isLoop }),
with: makeKeywordProps("with"),
new: makeKeywordProps("new"),
this: makeKeywordProps("this", { startsExpr }),
super: makeKeywordProps("super", { startsExpr }),
class: makeKeywordProps("class", { startsExpr }),
extends: makeKeywordProps("extends", { beforeExpr }),
export: makeKeywordProps("export"),
import: makeKeywordProps("import", { startsExpr }),
yield: makeKeywordProps("yield", { beforeExpr, startsExpr }),
null: makeKeywordProps("null", { startsExpr }),
true: makeKeywordProps("true", { startsExpr }),
false: makeKeywordProps("false", { startsExpr }),
in: makeKeywordProps("in", { beforeExpr, binop: 7 }),
instanceof: makeKeywordProps("instanceof", { beforeExpr, binop: 7 }),
typeof: makeKeywordProps("typeof", { beforeExpr, prefix, startsExpr }),
void: makeKeywordProps("void", { beforeExpr, prefix, startsExpr }),
delete: makeKeywordProps("delete", { beforeExpr, prefix, startsExpr }),
});
// Map keyword names to token types.
Object.keys(keywords).forEach(name => {