Skip to content
This repository has been archived by the owner on Nov 4, 2024. It is now read-only.

Commit

Permalink
Parse async generator methods (#152)
Browse files Browse the repository at this point in the history
Parse async generator methods.
  • Loading branch information
tilgovi authored and jdalton committed Nov 14, 2017
1 parent b96873f commit f69e1f1
Show file tree
Hide file tree
Showing 2 changed files with 87 additions and 0 deletions.
82 changes: 82 additions & 0 deletions src/acorn-ext/async-generator.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,95 @@ import { types as tt } from "../vendor/acorn/src/tokentype.js"
const loopLabel = { kind: "loop" }

function enable(parser) {
parser.parseClass = parseClass
parser.parseForIn = parseForIn
parser.parseForStatement = parseForStatement
parser.parseFunction = parseFunction
parser.parseProperty = parseProperty
return parser
}

function parseClass(node, isStatement) {
this.next()

this.parseClassId(node, isStatement)
this.parseClassSuper(node)
let classBody = this.startNode()
let hadConstructor = false
classBody.body = []
this.expect(tt.braceL)
while (!this.eat(tt.braceR)) {
if (this.eat(tt.semi)) {
continue
}
let method = this.startNode()
let isGenerator = this.eat(tt.star)
let isAsync = false
let isMaybeStatic = this.type === tt.name && this.value === "static"
this.parsePropertyName(method)
method.static = isMaybeStatic && this.type !== tt.parenL
if (method.static) {
if (isGenerator) {
this.unexpected()
}
isGenerator = this.eat(tt.star)
this.parsePropertyName(method)
}
if (this.options.ecmaVersion >= 8 && !isGenerator && !method.computed &&
method.key.type === "Identifier" && method.key.name === "async" && this.type !== tt.parenL &&
!this.canInsertSemicolon()) {
isAsync = true
isGenerator = this.eat(tt.star)
this.parsePropertyName(method)
}
method.kind = "method"
let isGetSet = false
if (!method.computed) {
let {key} = method
if (!isGenerator && !isAsync && key.type === "Identifier" && this.type !== tt.parenL && (key.name === "get" || key.name === "set")) {
isGetSet = true
method.kind = key.name
key = this.parsePropertyName(method)
}
if (!method.static && (key.type === "Identifier" && key.name === "constructor" ||
key.type === "Literal" && key.value === "constructor")) {
if (hadConstructor) {
this.raise(key.start, "Duplicate constructor in the same class")
}
if (isGetSet) {
this.raise(key.start, "Constructor can't have get/set modifier")
}
if (isGenerator) {
this.raise(key.start, "Constructor can't be a generator")
}
if (isAsync) {
this.raise(key.start, "Constructor can't be an async method")
}
method.kind = "constructor"
hadConstructor = true
}
}
this.parseClassMethod(classBody, method, isGenerator, isAsync)
if (isGetSet) {
let paramCount = method.kind === "get" ? 0 : 1
if (method.value.params.length !== paramCount) {
let start = method.value.start
if (method.kind === "get") {
this.raiseRecoverable(start, "getter should have no params")
} else {
this.raiseRecoverable(start, "setter should have exactly one param")
}
} else {
if (method.kind === "set" && method.value.params[0].type === "RestElement") {
this.raiseRecoverable(method.value.params[0].start, "Setter cannot use rest params")
}
}
}
}
node.body = this.finishNode(classBody, "ClassBody")
return this.finishNode(node, isStatement ? "ClassDeclaration" : "ClassExpression")
}

function parseForIn(node, init, forAwait) {
const type = forAwait
? "ForAwaitStatement"
Expand Down
5 changes: 5 additions & 0 deletions test/fixture/export/async-generators.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,8 @@ const b = {
async *b() {
}
}

class C {
async *c() {
}
}

0 comments on commit f69e1f1

Please sign in to comment.