Simplify tokenizer update context (#11944)

* replace lineBreak.test by hasPrecedingLingBreak

* refactor: simplify updateContext
This commit is contained in:
Huáng Jùnliàng 2020-08-11 13:43:03 -04:00 committed by GitHub
parent 3995160fc7
commit df9ee2c7cd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 19 additions and 37 deletions

View File

@ -2306,20 +2306,23 @@ export default class ExpressionParser extends LValParser {
parseIdentifierName(pos: number, liberal?: boolean): string { parseIdentifierName(pos: number, liberal?: boolean): string {
let name: string; let name: string;
if (this.match(tt.name)) { const { start, type } = this.state;
if (type === tt.name) {
name = this.state.value; name = this.state.value;
} else if (this.state.type.keyword) { } else if (type.keyword) {
name = this.state.type.keyword; name = type.keyword;
// `class` and `function` keywords push function-type token context into this.context. // `class` and `function` keywords push function-type token context into this.context.
// But there is no chance to pop the context if the keyword is consumed // But there is no chance to pop the context if the keyword is consumed
// as an identifier such as a property name. // as an identifier such as a property name.
const context = this.state.context; const curContext = this.curContext();
if ( if (
(name === "class" || name === "function") && (type === tt._class || type === tt._function) &&
context[context.length - 1].token === "function" (curContext === ct.functionStatement ||
curContext === ct.functionExpression)
) { ) {
context.pop(); this.state.context.pop();
} }
} else { } else {
throw this.unexpected(); throw this.unexpected();
@ -2330,12 +2333,7 @@ export default class ExpressionParser extends LValParser {
// This will prevent this.next() from throwing about unexpected escapes. // This will prevent this.next() from throwing about unexpected escapes.
this.state.type = tt.name; this.state.type = tt.name;
} else { } else {
this.checkReservedWord( this.checkReservedWord(name, start, !!type.keyword, false);
name,
this.state.start,
!!this.state.type.keyword,
false,
);
} }
this.next(); this.next();

View File

@ -629,9 +629,7 @@ export default class StatementParser extends ExpressionParser {
parseThrowStatement(node: N.ThrowStatement): N.ThrowStatement { parseThrowStatement(node: N.ThrowStatement): N.ThrowStatement {
this.next(); this.next();
if ( if (this.hasPrecedingLineBreak()) {
lineBreak.test(this.input.slice(this.state.lastTokEnd, this.state.start))
) {
this.raise(this.state.lastTokEnd, Errors.NewlineAfterThrow); this.raise(this.state.lastTokEnd, Errors.NewlineAfterThrow);
} }
node.argument = this.parseExpression(); node.argument = this.parseExpression();

View File

@ -5,7 +5,6 @@
// See https://github.com/mozilla/sweet.js/wiki/design // See https://github.com/mozilla/sweet.js/wiki/design
import { types as tt } from "./types"; import { types as tt } from "./types";
import { lineBreak } from "../util/whitespace";
export class TokContext { export class TokContext {
constructor( constructor(
@ -105,17 +104,11 @@ tt.incDec.updateContext = function () {
}; };
tt._function.updateContext = tt._class.updateContext = function (prevType) { tt._function.updateContext = tt._class.updateContext = function (prevType) {
if (prevType === tt.dot || prevType === tt.questionDot) { if (
// when function/class follows dot/questionDot, it is part of
// (optional)MemberExpression, then we don't need to push new token context
} else if (
prevType.beforeExpr && prevType.beforeExpr &&
prevType !== tt.semi && prevType !== tt.semi &&
prevType !== tt._else && prevType !== tt._else &&
!( !(prevType === tt._return && this.hasPrecedingLineBreak()) &&
prevType === tt._return &&
lineBreak.test(this.input.slice(this.state.lastTokEnd, this.state.start))
) &&
!( !(
(prevType === tt.colon || prevType === tt.braceL) && (prevType === tt.colon || prevType === tt.braceL) &&
this.curContext() === types.b_stat this.curContext() === types.b_stat
@ -138,10 +131,6 @@ tt.backQuote.updateContext = function () {
this.state.exprAllowed = false; this.state.exprAllowed = false;
}; };
tt.star.updateContext = function () {
this.state.exprAllowed = false;
};
// we don't need to update context for tt.braceBarL because we do not pop context for tt.braceBarR // we don't need to update context for tt.braceBarL because we do not pop context for tt.braceBarR
tt.braceHashL.updateContext = function () { tt.braceHashL.updateContext = function () {
this.state.context.push(types.recordExpression); this.state.context.push(types.recordExpression);

View File

@ -114,6 +114,7 @@ export default class Tokenizer extends ParserErrors {
// Forward-declarations // Forward-declarations
// parser/util.js // parser/util.js
/*:: /*::
+hasPrecedingLineBreak: () => boolean;
+unexpected: (pos?: ?number, messageOrType?: string | TokenType) => empty; +unexpected: (pos?: ?number, messageOrType?: string | TokenType) => empty;
+expectPlugin: (name: string, pos?: ?number) => true; +expectPlugin: (name: string, pos?: ?number) => true;
*/ */
@ -603,10 +604,7 @@ export default class Tokenizer extends ParserErrors {
next === charCodes.dash && next === charCodes.dash &&
!this.inModule && !this.inModule &&
this.input.charCodeAt(this.state.pos + 2) === charCodes.greaterThan && this.input.charCodeAt(this.state.pos + 2) === charCodes.greaterThan &&
(this.state.lastTokEnd === 0 || (this.state.lastTokEnd === 0 || this.hasPrecedingLineBreak())
lineBreak.test(
this.input.slice(this.state.lastTokEnd, this.state.pos),
))
) { ) {
// A `-->` line comment // A `-->` line comment
this.skipLineComment(3); this.skipLineComment(3);
@ -1525,9 +1523,7 @@ export default class Tokenizer extends ParserErrors {
prevType === tt._return || prevType === tt._return ||
(prevType === tt.name && this.state.exprAllowed) (prevType === tt.name && this.state.exprAllowed)
) { ) {
return lineBreak.test( return this.hasPrecedingLineBreak();
this.input.slice(this.state.lastTokEnd, this.state.start),
);
} }
if ( if (

View File

@ -155,7 +155,8 @@ export const types: { [name: string]: TokenType } = {
plusMin: new TokenType("+/-", { beforeExpr, binop: 9, prefix, startsExpr }), plusMin: new TokenType("+/-", { beforeExpr, binop: 9, prefix, startsExpr }),
// startsExpr: required by v8intrinsic plugin // startsExpr: required by v8intrinsic plugin
modulo: new TokenType("%", { beforeExpr, binop: 10, startsExpr }), modulo: new TokenType("%", { beforeExpr, binop: 10, startsExpr }),
star: createBinop("*", 10), // unset `beforeExpr` as it can be `function *`
star: new TokenType("*", { binop: 10 }),
slash: createBinop("/", 10), slash: createBinop("/", 10),
exponent: new TokenType("**", { exponent: new TokenType("**", {
beforeExpr, beforeExpr,