Skip to content

Commit fa12a8e

Browse files
committed
Update to Acorn 6.
1 parent d1cf202 commit fa12a8e

File tree

3 files changed

+153
-196
lines changed

3 files changed

+153
-196
lines changed

index.js

+147-194
Original file line numberDiff line numberDiff line change
@@ -1,212 +1,165 @@
1-
import {
2-
tokTypes as tt,
3-
tokenizer,
4-
parse,
5-
plugins
6-
} from "acorn";
1+
import {tokTypes as tt, Parser} from "acorn";
72

8-
const options = {
9-
ecmaVersion: 9,
10-
plugins: {
11-
observable: true
12-
}
13-
};
3+
const SCOPE_FUNCTION = 2;
4+
const SCOPE_ASYNC = 4;
5+
const SCOPE_GENERATOR = 8;
6+
const CellParser = Parser.extend(observable);
147

158
export function parseCell(input) {
16-
return parse(input, options);
9+
return CellParser.parse(input);
1710
}
1811

19-
function extendEnterFunctionScope(next) {
20-
return function() {
21-
++this.O_function;
22-
return next.apply(this, arguments);
23-
};
24-
}
25-
26-
function extendExitFunctionScope(next) {
27-
return function() {
28-
--this.O_function;
29-
return next.apply(this, arguments);
30-
};
31-
}
32-
33-
function extendIsKeyword(next) {
34-
return function(name) {
35-
return name === "viewof" || name === "mutable" || next.apply(this, arguments);
36-
};
37-
}
38-
39-
function extendParseForIn(next) {
40-
return function(node) {
41-
if (this.O_function === 1 && node.await) this.O_async = true;
42-
return next.apply(this, arguments);
43-
};
44-
}
45-
46-
function extendParseAwait(next) {
47-
return function() {
48-
if (this.O_function === 1) this.O_async = true;
49-
return next.apply(this, arguments);
50-
};
51-
}
52-
53-
function extendParseYield(next) {
54-
return function() {
55-
if (this.O_function === 1) this.O_generator = true;
56-
return next.apply(this, arguments);
57-
};
58-
}
59-
60-
function extendParseExprAtom(next) {
61-
return function() {
62-
return this.parseMaybeKeywordExpression("viewof", "ViewExpression")
63-
|| this.parseMaybeKeywordExpression("mutable", "MutableExpression")
64-
|| next.apply(this, arguments);
65-
};
66-
}
67-
68-
function extendToAssignable(next) {
69-
return function(node) {
70-
return node.type === "MutableExpression" ? node : next.apply(this, arguments);
71-
};
72-
}
73-
74-
function extendCheckLVal(next) {
75-
return function(expr, bindingType, checkClashes) {
76-
return expr.type === "MutableExpression"
77-
? next.call(this, expr.id, bindingType, checkClashes)
78-
: next.apply(this, arguments);
79-
};
80-
}
81-
82-
function parseMaybeKeywordExpression(keyword, type) {
83-
if (this.isContextual(keyword)) {
84-
const node = this.startNode();
85-
this.next();
86-
node.id = this.parseIdent();
87-
return this.finishNode(node, type);
88-
}
89-
}
90-
91-
function parseImport(node) {
92-
this.next();
93-
node.specifiers = this.parseImportSpecifiers();
94-
if (this.type === tt._with) {
95-
this.next();
96-
node.injections = this.parseImportSpecifiers();
97-
}
98-
this.expectContextual("from");
99-
node.source = this.type === tt.string ? this.parseExprAtom() : this.unexpected();
100-
return this.finishNode(node, "ImportDeclaration");
101-
}
102-
103-
function parseImportSpecifiers() {
104-
const nodes = [];
105-
let first = true;
106-
this.expect(tt.braceL);
107-
while (!this.eat(tt.braceR)) {
108-
if (first) {
109-
first = false;
110-
} else {
111-
this.expect(tt.comma);
112-
if (this.afterTrailingComma(tt.braceR)) break;
12+
function observable(Parser) {
13+
return class extends Parser {
14+
constructor(...options) {
15+
super(...options);
16+
this.O_function = 0;
17+
this.O_async = false;
18+
this.O_generator = false;
11319
}
114-
const node = this.startNode();
115-
node.view = this.eatContextual("viewof");
116-
if (!node.view) node.mutable = this.eatContextual("mutable");
117-
node.imported = this.parseIdent();
118-
if (this.eatContextual("as")) {
119-
node.local = this.parseIdent();
120-
} else {
121-
this.checkUnreserved(node.imported);
122-
node.local = node.imported;
20+
enterScope(flags) {
21+
if (flags & SCOPE_FUNCTION) ++this.O_function;
22+
return super.enterScope.apply(this, arguments);
12323
}
124-
this.checkLVal(node.local, "let");
125-
nodes.push(this.finishNode(node, "ImportSpecifier"));
126-
}
127-
return nodes;
128-
}
129-
130-
function parseTopLevel(node) {
131-
const lookahead = tokenizer(this.input, {plugins});
132-
let token = lookahead.getToken();
133-
let body = null;
134-
let id = null;
135-
136-
this.strict = true;
137-
this.inAsync = true;
138-
this.inGenerator = true;
139-
this.inFunction = true;
24+
exitScope() {
25+
if (this.scopeStack[this.scopeStack.length - 1] & SCOPE_FUNCTION) --this.O_function;
26+
return super.exitScope.apply(this, arguments);
27+
}
28+
parseForIn(node) {
29+
if (this.O_function === 1 && node.await) this.O_async = true;
30+
return super.parseForIn.apply(this, arguments);
31+
}
32+
parseAwait() {
33+
if (this.O_function === 1) this.O_async = true;
34+
return super.parseAwait.apply(this, arguments);
35+
}
36+
parseYield() {
37+
if (this.O_function === 1) this.O_generator = true;
38+
return super.parseYield.apply(this, arguments);
39+
}
40+
parseImport(node) {
41+
this.next();
42+
node.specifiers = this.parseImportSpecifiers();
43+
if (this.type === tt._with) {
44+
this.next();
45+
node.injections = this.parseImportSpecifiers();
46+
}
47+
this.expectContextual("from");
48+
node.source = this.type === tt.string ? this.parseExprAtom() : this.unexpected();
49+
return this.finishNode(node, "ImportDeclaration");
50+
}
51+
parseImportSpecifiers() {
52+
const nodes = [];
53+
let first = true;
54+
this.expect(tt.braceL);
55+
while (!this.eat(tt.braceR)) {
56+
if (first) {
57+
first = false;
58+
} else {
59+
this.expect(tt.comma);
60+
if (this.afterTrailingComma(tt.braceR)) break;
61+
}
62+
const node = this.startNode();
63+
node.view = this.eatContextual("viewof");
64+
if (!node.view) node.mutable = this.eatContextual("mutable");
65+
node.imported = this.parseIdent();
66+
if (this.eatContextual("as")) {
67+
node.local = this.parseIdent();
68+
} else {
69+
this.checkUnreserved(node.imported);
70+
node.local = node.imported;
71+
}
72+
this.checkLVal(node.local, "let");
73+
nodes.push(this.finishNode(node, "ImportSpecifier"));
74+
}
75+
return nodes;
76+
}
77+
parseExprAtom() {
78+
return this.parseMaybeKeywordExpression("viewof", "ViewExpression")
79+
|| this.parseMaybeKeywordExpression("mutable", "MutableExpression")
80+
|| super.parseExprAtom.apply(this, arguments);
81+
}
82+
parseTopLevel(node) {
83+
const lookahead = CellParser.tokenizer(this.input);
84+
let token = lookahead.getToken();
85+
let body = null;
86+
let id = null;
87+
88+
this.strict = true;
89+
this.enterScope(SCOPE_FUNCTION | SCOPE_ASYNC | SCOPE_GENERATOR);
90+
91+
// An import?
92+
if (token.type === tt._import) {
93+
body = this.parseImport(this.startNode());
94+
}
14095

141-
// An import?
142-
if (token.type === tt._import) {
143-
body = this.parseImport(this.startNode());
144-
}
96+
// A non-empty cell?
97+
else if (token.type !== tt.eof) {
98+
99+
// A named cell?
100+
if (token.type === tt.name) {
101+
if (token.value === "viewof" || token.value === "mutable") {
102+
token = lookahead.getToken();
103+
if (token.type !== tt.name) {
104+
lookahead.unexpected();
105+
}
106+
}
107+
token = lookahead.getToken();
108+
if (token.type === tt.eq) {
109+
id = this.parseMaybeKeywordExpression("viewof", "ViewExpression")
110+
|| this.parseMaybeKeywordExpression("mutable", "MutableExpression")
111+
|| this.parseIdent();
112+
token = lookahead.getToken();
113+
this.expect(tt.eq);
114+
}
115+
}
145116

146-
// A non-empty cell?
147-
else if (token.type !== tt.eof) {
117+
// A block?
118+
if (token.type === tt.braceL) {
119+
body = this.parseBlock();
120+
}
148121

149-
// A named cell?
150-
if (token.type === tt.name) {
151-
if (token.value === "viewof" || token.value === "mutable") {
152-
token = lookahead.getToken();
153-
if (token.type !== tt.name) {
154-
lookahead.unexpected();
122+
// An expression?
123+
// Possibly a function or class declaration?
124+
else {
125+
body = this.parseExpression();
126+
if (id === null && (body.type === "FunctionExpression" || body.type === "ClassExpression")) {
127+
id = body.id;
128+
}
155129
}
156130
}
157-
token = lookahead.getToken();
158-
if (token.type === tt.eq) {
159-
id = this.parseMaybeKeywordExpression("viewof", "ViewExpression")
160-
|| this.parseMaybeKeywordExpression("mutable", "MutableExpression")
161-
|| this.parseIdent();
162-
token = lookahead.getToken();
163-
this.expect(tt.eq);
131+
132+
this.expect(tt.eof);
133+
node.id = id;
134+
node.async = this.O_async;
135+
node.generator = this.O_generator;
136+
node.body = body;
137+
return this.finishNode(node, "Cell");
138+
}
139+
toAssignable(node) {
140+
return node.type === "MutableExpression" ? node : super.toAssignable.apply(this, arguments);
141+
}
142+
checkUnreserved(node) {
143+
if (node.name ==="viewof" || node.name === "mutable") {
144+
this.raise(node.start, `Unexpected keyword '${node.name}'`);
164145
}
146+
return super.checkUnreserved(node);
165147
}
166-
167-
// A block?
168-
if (token.type === tt.braceL) {
169-
body = this.parseBlock();
148+
checkLVal(expr, bindingType, checkClashes) {
149+
return expr.type === "MutableExpression"
150+
? super.checkLVal.call(this, expr.id, bindingType, checkClashes)
151+
: super.checkLVal.apply(this, arguments);
170152
}
171-
172-
// An expression?
173-
// Possibly a function or class declaration?
174-
else {
175-
body = this.parseExpression();
176-
if (id === null && (body.type === "FunctionExpression" || body.type === "ClassExpression")) {
177-
id = body.id;
153+
unexpected(pos) {
154+
this.raise(pos != null ? pos : this.start, this.type === tt.eof ? "Unexpected end of input" : "Unexpected token");
155+
}
156+
parseMaybeKeywordExpression(keyword, type) {
157+
if (this.isContextual(keyword)) {
158+
const node = this.startNode();
159+
this.next();
160+
node.id = this.parseIdent();
161+
return this.finishNode(node, type);
178162
}
179163
}
180-
}
181-
182-
this.expect(tt.eof);
183-
node.id = id;
184-
node.async = this.O_async;
185-
node.generator = this.O_generator;
186-
node.body = body;
187-
return this.finishNode(node, "Cell");
188-
}
189-
190-
function unexpected(pos) {
191-
this.raise(pos != null ? pos : this.start, this.type === tt.eof ? "Unexpected end of input" : "Unexpected token");
164+
};
192165
}
193-
194-
plugins.observable = function(that) {
195-
that.extend("enterFunctionScope", extendEnterFunctionScope);
196-
that.extend("exitFunctionScope", extendExitFunctionScope);
197-
that.extend("isKeyword", extendIsKeyword);
198-
that.extend("parseForIn", extendParseForIn);
199-
that.extend("parseAwait", extendParseAwait);
200-
that.extend("parseYield", extendParseYield);
201-
that.extend("parseImport", () => parseImport);
202-
that.extend("parseImportSpecifiers", () => parseImportSpecifiers);
203-
that.extend("parseExprAtom", extendParseExprAtom);
204-
that.extend("parseTopLevel", () => parseTopLevel);
205-
that.extend("toAssignable", extendToAssignable);
206-
that.extend("checkLVal", extendCheckLVal);
207-
that.extend("unexpected", () => unexpected);
208-
that.parseMaybeKeywordExpression = parseMaybeKeywordExpression;
209-
that.O_function = 0;
210-
that.O_async = false;
211-
that.O_generator = false;
212-
};

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
"cjs": true
1818
},
1919
"dependencies": {
20-
"acorn": "^5.7.3"
20+
"acorn": "^6.0.4"
2121
},
2222
"devDependencies": {
2323
"eslint": "^4.14.0",

yarn.lock

+5-1
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,14 @@ acorn@^3.0.4:
1212
version "3.3.0"
1313
resolved "http://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz#45e37fb39e8da3f25baee3ff5369e2bb5f22017a"
1414

15-
acorn@^5.5.0, acorn@^5.7.3:
15+
acorn@^5.5.0:
1616
version "5.7.3"
1717
resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.7.3.tgz#67aa231bf8812974b85235a96771eb6bd07ea279"
1818

19+
acorn@^6.0.4:
20+
version "6.0.4"
21+
resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.0.4.tgz#77377e7353b72ec5104550aa2d2097a2fd40b754"
22+
1923
ajv-keywords@^2.1.0:
2024
version "2.1.1"
2125
resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-2.1.1.tgz#617997fc5f60576894c435f940d819e135b80762"

0 commit comments

Comments
 (0)