Skip to content

Commit

Permalink
Fix review comments
Browse files Browse the repository at this point in the history
  • Loading branch information
danez committed Nov 6, 2018
1 parent 7a00bd7 commit 7e21cfe
Show file tree
Hide file tree
Showing 5 changed files with 30 additions and 50 deletions.
15 changes: 11 additions & 4 deletions packages/babel-parser/src/parser/expression.js
Expand Up @@ -23,6 +23,7 @@ import * as N from "../types";
import LValParser from "./lval";
import { reservedWords } from "../util/identifier";
import type { Pos, Position } from "../util/location";
import * as charCodes from "charcodes";

export default class ExpressionParser extends LValParser {
// Forward-declaration: defined in statement.js
Expand Down Expand Up @@ -718,6 +719,10 @@ export default class ExpressionParser extends LValParser {
// or `{}`.

parseExprAtom(refShorthandDefaultPos?: ?Pos): N.Expression {
// If a division operator appears in an expression position, the
// tokenizer got confused, and we force it to read a regexp instead.
if (this.state.type === tt.slash) this.readRegexp();

const canBeArrow = this.state.potentialArrowAt === this.state.start;
let node;

Expand Down Expand Up @@ -965,9 +970,11 @@ export default class ExpressionParser extends LValParser {
parseFunctionExpression(): N.FunctionExpression | N.MetaProperty {
const node = this.startNode();

// We do not do parseIdentifier here because of perf but more importantly
// because parseIdentifier will remove an item from the expression stack
// if function or class is parsed as identifier (in objects e.g.).
// We do not do parseIdentifier here because when parseFunctionExpression
// is called we already know that the current token is a "name" with the value "function"
// This will improve perf a tiny little bit as we do not do validation but more importantly
// here is that parseIdentifier will remove an item from the expression stack
// if "function" or "class" is parsed as identifier (in objects e.g.), which should not happen here.
let meta = this.startNode();
this.next();
meta = this.createIdentifier(meta, "function");
Expand Down Expand Up @@ -1906,7 +1913,7 @@ export default class ExpressionParser extends LValParser {
if (
(name === "class" || name === "function") &&
(this.state.lastTokEnd !== this.state.lastTokStart + 1 ||
this.input.charCodeAt(this.state.lastTokStart) !== 46)
this.input.charCodeAt(this.state.lastTokStart) !== charCodes.dot)
) {
this.state.context.pop();
}
Expand Down
11 changes: 9 additions & 2 deletions packages/babel-parser/src/plugins/flow.js
Expand Up @@ -6,6 +6,7 @@ import * as N from "../types";
import type { Options } from "../options";
import type { Pos, Position } from "../util/location";
import type State from "../tokenizer/state";
import { types as tc } from "../tokenizer/context";
import * as charCodes from "charcodes";
import { isIteratorStart } from "../util/identifier";

Expand Down Expand Up @@ -2392,7 +2393,10 @@ export default (superClass: Class<Parser>): Class<Parser> =>
refNeedsArrowPos?: ?Pos,
): N.Expression {
let jsxError = null;
if (tt.jsxTagStart && this.match(tt.jsxTagStart)) {
if (
this.hasPlugin("jsx") &&
(this.match(tt.jsxTagStart) || this.isRelational("<"))
) {
const state = this.state.clone();
try {
return super.parseMaybeAssign(
Expand All @@ -2408,7 +2412,10 @@ export default (superClass: Class<Parser>): Class<Parser> =>
// Remove `tc.j_expr` and `tc.j_oTag` from context added
// by parsing `jsxTagStart` to stop the JSX plugin from
// messing with the tokens
this.state.context.length -= 2;
const cLength = this.state.context.length;
if (this.state.context[cLength - 1] === tc.j_oTag) {
this.state.context.length -= 2;
}

jsxError = err;
} else {
Expand Down
9 changes: 9 additions & 0 deletions packages/babel-parser/src/plugins/jsx/index.js
Expand Up @@ -506,6 +506,15 @@ export default (superClass: Class<Parser>): Class<Parser> =>
return this.parseLiteral(this.state.value, "JSXText");
} else if (this.match(tt.jsxTagStart)) {
return this.jsxParseElement();
} else if (
this.isRelational("<") &&
this.state.input.charCodeAt(this.state.pos) !==
charCodes.exclamationMark
) {
// In case we encounter an lt token here it will always be the start of
// jsx as the lt sign is not allowed in places that expect an expression
this.finishToken(tt.jsxTagStart);
return this.jsxParseElement();
} else {
return super.parseExprAtom(refShortHandDefaultPos);
}
Expand Down
37 changes: 1 addition & 36 deletions packages/babel-parser/src/tokenizer/context.js
Expand Up @@ -40,20 +40,6 @@ export const types: {
template: new TokContext("`", true, true, p => p.readTmplToken()),
functionExpression: new TokContext("function", true),
functionStatement: new TokContext("function", false),
functionExpressionGenerator: new TokContext(
"function",
true,
false,
null,
true,
),
functionStatementGenerator: new TokContext(
"function",
false,
false,
null,
true,
),
};

// Token-specific context update code
Expand All @@ -72,39 +58,18 @@ tt.parenR.updateContext = tt.braceR.updateContext = function() {
this.state.exprAllowed = !out.isExpr;
};

tt.star.updateContext = function(prevType) {
if (prevType === tt._function) {
const index = this.state.context.length - 1;
if (this.state.context[index] === types.functionExpression) {
this.state.context[index] = types.functionExpressionGenerator;
} else {
this.state.context[index] = types.functionStatementGenerator;
}
}
this.state.exprAllowed = true;
};

tt.name.updateContext = function(prevType) {
let allowed = false;
if (prevType !== tt.dot) {
if (
(this.state.value === "of" && !this.state.exprAllowed) ||
(this.state.value === "yield" && this.inGeneratorContext())
(this.state.value === "yield" && this.state.inGenerator)
) {
allowed = true;
}
}
this.state.exprAllowed = allowed;

if (prevType === tt._let || prevType === tt._const || prevType === tt._var) {
if (
lineBreak.test(
this.input.slice(this.state.end, this.lookahead(true).start),
)
) {
this.state.exprAllowed = true;
}
}
if (this.state.isIterator) {
this.state.isIterator = false;
}
Expand Down
8 changes: 0 additions & 8 deletions packages/babel-parser/src/tokenizer/index.js
Expand Up @@ -1378,14 +1378,6 @@ export default class Tokenizer extends LocationParser {
return !this.state.exprAllowed;
}

inGeneratorContext() {
for (let i = this.state.context.length - 1; i >= 1; i--) {
const context = this.state.context[i];
if (context.token === "function") return context.generator;
}
return false;
}

updateContext(prevType: TokenType): void {
const type = this.state.type;
let update;
Expand Down

0 comments on commit 7e21cfe

Please sign in to comment.