Skip to content
This repository has been archived by the owner on May 19, 2018. It is now read-only.

Commit

Permalink
Type-check UtilParser (#485)
Browse files Browse the repository at this point in the history
  • Loading branch information
Andy authored and hzoo committed Apr 25, 2017
1 parent 3199cee commit 7627c5a
Showing 1 changed file with 17 additions and 14 deletions.
31 changes: 17 additions & 14 deletions src/parser/util.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
import { types as tt } from "../tokenizer/types";
// @flow

import { types as tt, type TokenType } from "../tokenizer/types";
import Tokenizer from "../tokenizer";
import type { Node } from "../types";
import { lineBreak } from "../util/whitespace";

// ## Parser utilities

export default class UtilParser extends Tokenizer {
// TODO

addExtra(node, key, val) {
addExtra(node: Node, key: string, val: any): void {
if (!node) return;

const extra = node.extra = node.extra || {};
Expand All @@ -16,13 +19,13 @@ export default class UtilParser extends Tokenizer {

// TODO

isRelational(op) {
isRelational(op: "<" | ">"): boolean {
return this.match(tt.relational) && this.state.value === op;
}

// TODO

expectRelational(op) {
expectRelational(op: "<" | ">"): void {
if (this.isRelational(op)) {
this.next();
} else {
Expand All @@ -32,57 +35,57 @@ export default class UtilParser extends Tokenizer {

// Tests whether parsed token is a contextual keyword.

isContextual(name) {
isContextual(name: string): boolean {
return this.match(tt.name) && this.state.value === name;
}

// Consumes contextual keyword if possible.

eatContextual(name) {
eatContextual(name: string): boolean {
return this.state.value === name && this.eat(tt.name);
}

// Asserts that following token is given contextual keyword.

expectContextual(name, message) {
expectContextual(name: string, message?: string): void {
if (!this.eatContextual(name)) this.unexpected(null, message);
}

// Test whether a semicolon can be inserted at the current position.

canInsertSemicolon() {
canInsertSemicolon(): boolean {
return this.match(tt.eof) ||
this.match(tt.braceR) ||
lineBreak.test(this.input.slice(this.state.lastTokEnd, this.state.start));
}

// TODO

isLineTerminator() {
isLineTerminator(): boolean {
return this.eat(tt.semi) || this.canInsertSemicolon();
}

// Consume a semicolon, or, failing that, see if we are allowed to
// pretend that there is a semicolon at this position.

semicolon() {
semicolon(): void {
if (!this.isLineTerminator()) this.unexpected(null, tt.semi);
}

// Expect a token of a given type. If found, consume it, otherwise,
// raise an unexpected token error at given pos.

expect(type, pos) {
return this.eat(type) || this.unexpected(pos, type);
expect(type: TokenType, pos?: ?number): void {
this.eat(type) || this.unexpected(pos, type);
}

// Raise an unexpected token error. Can take the expected token type
// instead of a message string.

unexpected(pos, messageOrType = "Unexpected token") {
unexpected(pos: ?number, messageOrType: string | TokenType = "Unexpected token"): empty {
if (messageOrType && typeof messageOrType === "object" && messageOrType.label) {
messageOrType = `Unexpected token, expected ${messageOrType.label}`;
}
this.raise(pos != null ? pos : this.state.start, messageOrType);
throw this.raise(pos != null ? pos : this.state.start, messageOrType);
}
}

0 comments on commit 7627c5a

Please sign in to comment.