Skip to content

Commit 2846d2b

Browse files
Lucian-4a25成仕伟
andauthored
Make token context more accurate (#1064)
Closes #875 Closes #991 FIX: Improve context-dependent tokenization in a number of corner cases. Co-authored-by: 成仕伟 <[email protected]>
1 parent 470ec08 commit 2846d2b

File tree

6 files changed

+323
-7
lines changed

6 files changed

+323
-7
lines changed

acorn-loose/src/expression.js

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import {LooseParser} from "./state.js"
22
import {isDummy} from "./parseutil.js"
3-
import {tokTypes as tt} from "acorn"
3+
import {tokTypes as tt, tokContexts as tokContextTypes} from "acorn"
44

55
const lp = LooseParser.prototype
66

@@ -245,8 +245,10 @@ lp.parseExprAtom = function() {
245245
let id = this.parseIdent()
246246
let isAsync = false
247247
if (id.name === "async" && !this.canInsertSemicolon()) {
248-
if (this.eat(tt._function))
248+
if (this.eat(tt._function)) {
249+
this.toks.overrideContext(tokContextTypes.f_expr)
249250
return this.parseFunction(this.startNodeAt(start), false, true)
251+
}
250252
if (this.tok.type === tt.name) {
251253
id = this.parseIdent()
252254
isAsync = true
@@ -303,6 +305,7 @@ lp.parseExprAtom = function() {
303305
return this.finishNode(node, "ArrayExpression")
304306

305307
case tt.braceL:
308+
this.toks.overrideContext(tokContextTypes.b_expr)
306309
return this.parseObj()
307310

308311
case tt._class:

acorn/dist/acorn.d.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,9 @@ declare namespace acorn {
173173
p_expr: TokContext
174174
q_tmpl: TokContext
175175
f_expr: TokContext
176+
f_stat: TokContext
177+
f_expr_gen: TokContext
178+
f_gen: TokContext
176179
}
177180

178181
function isIdentifierStart(code: number, astral?: boolean): boolean

acorn/src/expression.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
// [opp]: http://en.wikipedia.org/wiki/Operator-precedence_parser
1818

1919
import {types as tt} from "./tokentype.js"
20+
import {types as tokenCtxTypes} from "./tokencontext.js"
2021
import {Parser} from "./state.js"
2122
import {DestructuringErrors} from "./parseutil.js"
2223
import {lineBreak} from "./whitespace.js"
@@ -411,8 +412,10 @@ pp.parseExprAtom = function(refDestructuringErrors, forInit) {
411412
case tt.name:
412413
let startPos = this.start, startLoc = this.startLoc, containsEsc = this.containsEsc
413414
let id = this.parseIdent(false)
414-
if (this.options.ecmaVersion >= 8 && !containsEsc && id.name === "async" && !this.canInsertSemicolon() && this.eat(tt._function))
415+
if (this.options.ecmaVersion >= 8 && !containsEsc && id.name === "async" && !this.canInsertSemicolon() && this.eat(tt._function)) {
416+
this.overrideContext(tokenCtxTypes.f_expr)
415417
return this.parseFunction(this.startNodeAt(startPos, startLoc), 0, false, true, forInit)
418+
}
416419
if (canBeArrow && !this.canInsertSemicolon()) {
417420
if (this.eat(tt.arrow))
418421
return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), [id], false, forInit)
@@ -459,6 +462,7 @@ pp.parseExprAtom = function(refDestructuringErrors, forInit) {
459462
return this.finishNode(node, "ArrayExpression")
460463

461464
case tt.braceL:
465+
this.overrideContext(tokenCtxTypes.b_expr)
462466
return this.parseObj(false, refDestructuringErrors)
463467

464468
case tt._function:

acorn/src/tokencontext.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,10 @@ pp.initialContext = function() {
3535
return [types.b_stat]
3636
}
3737

38+
pp.curContext = function() {
39+
return this.context[this.context.length - 1]
40+
}
41+
3842
pp.braceIsBlock = function(prevType) {
3943
let parent = this.curContext()
4044
if (parent === types.f_expr || parent === types.f_stat)
@@ -75,6 +79,13 @@ pp.updateContext = function(prevType) {
7579
this.exprAllowed = type.beforeExpr
7680
}
7781

82+
// Used to handle egde case when token context could not be inferred correctly in tokenize phase
83+
pp.overrideContext = function(tokenCtx) {
84+
if (this.curContext() !== tokenCtx) {
85+
this.context[this.context.length - 1] = tokenCtx
86+
}
87+
}
88+
7889
// Token-specific context update code
7990

8091
tt.parenR.updateContext = tt.braceR.updateContext = function() {

acorn/src/tokenize.js

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -63,10 +63,6 @@ if (typeof Symbol !== "undefined")
6363
// Toggle strict mode. Re-reads the next number or string to please
6464
// pedantic tests (`"use strict"; 010;` should fail).
6565

66-
pp.curContext = function() {
67-
return this.context[this.context.length - 1]
68-
}
69-
7066
// Read a single token, updating the parser object's token-related
7167
// properties.
7268

0 commit comments

Comments
 (0)