Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: improve module block program location tracking #15052

Merged
merged 2 commits into from Oct 19, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
9 changes: 6 additions & 3 deletions packages/babel-parser/src/parser/expression.ts
Expand Up @@ -3142,18 +3142,21 @@ export default abstract class ExpressionParser extends LValParser {
this.expectPlugin("moduleBlocks");
const node = this.startNode<N.ModuleExpression>();
this.next(); // eat "module"
this.expect(tt.braceL);
if (!this.match(tt.braceL)) {
this.unexpected(null, tt.braceL);
}
// start program node immediately after `{`
const program = this.startNodeAt<N.Program>(this.state.endLoc);
this.next(); // eat `{`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit, but we could use this.state.lastTokEnd/this.state.lastTokEnd.index to keep using expect instead of this math-createNode-next dance.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

They are not equivalent. For example

module { /* 1 */ }

When we see a left brace {, this.state.endLoc points to the whitespace after {, while this.state.lastTokEnd after { is eaten will point to the whitespace immediately after the comment /* 1 */.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍


const revertScopes = this.initializeScopes(/** inModule */ true);
this.enterInitialScopes();

const program = this.startNode<N.Program>();
try {
node.body = this.parseProgram(program, tt.braceR, "module");
} finally {
revertScopes();
}
this.eat(tt.braceR);
return this.finishNode<N.ModuleExpression>(node, "ModuleExpression");
}

Expand Down
17 changes: 13 additions & 4 deletions packages/babel-parser/src/parser/statement.ts
Expand Up @@ -222,10 +222,19 @@ export default abstract class StatementParser extends ExpressionParser {
this.raise(Errors.ModuleExportUndefined, { at, localName });
}
}
let finishedProgram: N.Program;
if (end === tt.eof) {
this.next(); // consume eof for the top level program
// finish at eof for top level program
finishedProgram = this.finishNode(program, "Program");
} else {
// finish immediately before the end token
finishedProgram = this.finishNodeAt(
program,
"Program",
createPositionWithColumnOffset(this.state.startLoc, -1),
);
}
return this.finishNode(program, "Program");
return finishedProgram;
}

// TODO
Expand Down Expand Up @@ -1124,7 +1133,6 @@ export default abstract class StatementParser extends ExpressionParser {
tt.braceR,
afterBlockParse,
);
this.next(); // eat tt.braceR
if (createNewLexicalScope) {
this.scope.exit();
}
Expand Down Expand Up @@ -1206,6 +1214,8 @@ export default abstract class StatementParser extends ExpressionParser {
if (!oldStrict) {
this.setStrict(false);
}

this.next();
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is essentially reverting changes in 101cad5.

}

// Parse a regular `for` loop. The disambiguation code in
Expand Down Expand Up @@ -1881,7 +1891,6 @@ export default abstract class StatementParser extends ExpressionParser {
this.prodParam.enter(PARAM);
const body: N.Node[] = (member.body = []);
this.parseBlockOrModuleBlockBody(body, undefined, false, tt.braceR);
this.next(); // eat tt.braceR
this.prodParam.exit();
this.scope.exit();
this.state.labels = oldLabels;
Expand Down
1 change: 0 additions & 1 deletion packages/babel-parser/src/plugins/typescript/index.ts
Expand Up @@ -1869,7 +1869,6 @@ export default (superClass: ClassWithMixin<typeof Parser, IJSXParserMixin>) =>
/* topLevel */ true,
/* end */ tt.braceR,
);
this.next(); // eat tt.braceR
this.scope.exit();
return this.finishNode(node, "TSModuleBlock");
}
Expand Down
Expand Up @@ -53,7 +53,7 @@
"start":23,"end":66,"loc":{"start":{"line":3,"column":4,"index":23},"end":{"line":5,"column":5,"index":66}},
"body": {
"type": "Program",
"start":38,"end":60,"loc":{"start":{"line":4,"column":6,"index":38},"end":{"line":4,"column":28,"index":60}},
"start":31,"end":65,"loc":{"start":{"line":3,"column":12,"index":31},"end":{"line":5,"column":4,"index":65}},
"sourceType": "module",
"interpreter": null,
"body": [
Expand Down
Expand Up @@ -27,7 +27,7 @@
"start":10,"end":66,"loc":{"start":{"line":1,"column":10,"index":10},"end":{"line":4,"column":1,"index":66}},
"body": {
"type": "Program",
"start":21,"end":64,"loc":{"start":{"line":2,"column":2,"index":21},"end":{"line":3,"column":17,"index":64}},
"start":18,"end":65,"loc":{"start":{"line":1,"column":18,"index":18},"end":{"line":4,"column":0,"index":65}},
"sourceType": "module",
"interpreter": null,
"body": [
Expand Down
@@ -0,0 +1 @@
module { #!/usr/bin/env node };
@@ -0,0 +1,3 @@
{
"throws": "Unexpected token (1:9)"
}
Expand Up @@ -18,7 +18,7 @@
"start":0,"end":27,"loc":{"start":{"line":1,"column":0,"index":0},"end":{"line":3,"column":1,"index":27}},
"body": {
"type": "Program",
"start":11,"end":25,"loc":{"start":{"line":2,"column":2,"index":11},"end":{"line":2,"column":16,"index":25}},
"start":8,"end":26,"loc":{"start":{"line":1,"column":8,"index":8},"end":{"line":3,"column":0,"index":26}},
"sourceType": "module",
"interpreter": null,
"body": [
Expand Down
Expand Up @@ -35,7 +35,7 @@
"start":9,"end":37,"loc":{"start":{"line":2,"column":0,"index":9},"end":{"line":4,"column":1,"index":37}},
"body": {
"type": "Program",
"start":20,"end":35,"loc":{"start":{"line":3,"column":2,"index":20},"end":{"line":3,"column":17,"index":35}},
"start":17,"end":36,"loc":{"start":{"line":2,"column":8,"index":17},"end":{"line":4,"column":0,"index":36}},
"sourceType": "module",
"interpreter": null,
"body": [
Expand Down
Expand Up @@ -24,7 +24,7 @@
"start":10,"end":48,"loc":{"start":{"line":1,"column":10,"index":10},"end":{"line":3,"column":1,"index":48}},
"body": {
"type": "Program",
"start":21,"end":46,"loc":{"start":{"line":2,"column":2,"index":21},"end":{"line":2,"column":27,"index":46}},
"start":18,"end":47,"loc":{"start":{"line":1,"column":18,"index":18},"end":{"line":3,"column":0,"index":47}},
"sourceType": "module",
"interpreter": null,
"body": [
Expand Down
Expand Up @@ -50,7 +50,7 @@
"start":23,"end":96,"loc":{"start":{"line":3,"column":4,"index":23},"end":{"line":8,"column":5,"index":96}},
"body": {
"type": "Program",
"start":38,"end":90,"loc":{"start":{"line":4,"column":6,"index":38},"end":{"line":7,"column":7,"index":90}},
"start":31,"end":95,"loc":{"start":{"line":3,"column":12,"index":31},"end":{"line":8,"column":4,"index":95}},
"sourceType": "module",
"interpreter": null,
"body": [
Expand Down
@@ -0,0 +1 @@
module {/* comment */}
@@ -0,0 +1,43 @@
{
"type": "File",
"start":0,"end":22,"loc":{"start":{"line":1,"column":0,"index":0},"end":{"line":1,"column":22,"index":22}},
"program": {
"type": "Program",
"start":0,"end":22,"loc":{"start":{"line":1,"column":0,"index":0},"end":{"line":1,"column":22,"index":22}},
"sourceType": "module",
"interpreter": null,
"body": [
{
"type": "ExpressionStatement",
"start":0,"end":22,"loc":{"start":{"line":1,"column":0,"index":0},"end":{"line":1,"column":22,"index":22}},
"expression": {
"type": "ModuleExpression",
"start":0,"end":22,"loc":{"start":{"line":1,"column":0,"index":0},"end":{"line":1,"column":22,"index":22}},
"body": {
"type": "Program",
"start":8,"end":21,"loc":{"start":{"line":1,"column":8,"index":8},"end":{"line":1,"column":21,"index":21}},
"sourceType": "module",
"interpreter": null,
"body": [],
"directives": [],
"innerComments": [
{
"type": "CommentBlock",
"value": " comment ",
"start":8,"end":21,"loc":{"start":{"line":1,"column":8,"index":8},"end":{"line":1,"column":21,"index":21}}
}
]
}
}
}
],
"directives": []
},
"comments": [
{
"type": "CommentBlock",
"value": " comment ",
"start":8,"end":21,"loc":{"start":{"line":1,"column":8,"index":8},"end":{"line":1,"column":21,"index":21}}
}
]
}
Expand Up @@ -55,7 +55,7 @@
"start":37,"end":72,"loc":{"start":{"line":2,"column":11,"index":37},"end":{"line":2,"column":46,"index":72}},
"body": {
"type": "Program",
"start":46,"end":70,"loc":{"start":{"line":2,"column":20,"index":46},"end":{"line":2,"column":44,"index":70}},
"start":45,"end":71,"loc":{"start":{"line":2,"column":19,"index":45},"end":{"line":2,"column":45,"index":71}},
"sourceType": "module",
"interpreter": null,
"body": [
Expand Down Expand Up @@ -115,7 +115,7 @@
"start":85,"end":120,"loc":{"start":{"line":3,"column":11,"index":85},"end":{"line":3,"column":46,"index":120}},
"body": {
"type": "Program",
"start":94,"end":118,"loc":{"start":{"line":3,"column":20,"index":94},"end":{"line":3,"column":44,"index":118}},
"start":93,"end":119,"loc":{"start":{"line":3,"column":19,"index":93},"end":{"line":3,"column":45,"index":119}},
"sourceType": "module",
"interpreter": null,
"body": [
Expand Down
Expand Up @@ -49,7 +49,7 @@
"start":29,"end":60,"loc":{"start":{"line":2,"column":10,"index":29},"end":{"line":4,"column":1,"index":60}},
"body": {
"type": "Program",
"start":40,"end":58,"loc":{"start":{"line":3,"column":2,"index":40},"end":{"line":3,"column":20,"index":58}},
"start":37,"end":59,"loc":{"start":{"line":2,"column":18,"index":37},"end":{"line":4,"column":0,"index":59}},
"sourceType": "module",
"interpreter": null,
"body": [
Expand Down
Expand Up @@ -24,7 +24,7 @@
"start":10,"end":48,"loc":{"start":{"line":1,"column":10,"index":10},"end":{"line":3,"column":1,"index":48}},
"body": {
"type": "Program",
"start":21,"end":46,"loc":{"start":{"line":2,"column":2,"index":21},"end":{"line":2,"column":27,"index":46}},
"start":18,"end":47,"loc":{"start":{"line":1,"column":18,"index":18},"end":{"line":3,"column":0,"index":47}},
"sourceType": "module",
"interpreter": null,
"body": [
Expand Down
Expand Up @@ -33,7 +33,7 @@
"start":26,"end":66,"loc":{"start":{"line":1,"column":26,"index":26},"end":{"line":3,"column":1,"index":66}},
"body": {
"type": "Program",
"start":39,"end":64,"loc":{"start":{"line":2,"column":4,"index":39},"end":{"line":2,"column":29,"index":64}},
"start":34,"end":65,"loc":{"start":{"line":1,"column":34,"index":34},"end":{"line":3,"column":0,"index":65}},
"sourceType": "module",
"interpreter": null,
"body": [
Expand Down
Expand Up @@ -24,7 +24,7 @@
"start":8,"end":62,"loc":{"start":{"line":1,"column":8,"index":8},"end":{"line":5,"column":1,"index":62}},
"body": {
"type": "Program",
"start":19,"end":60,"loc":{"start":{"line":2,"column":2,"index":19},"end":{"line":4,"column":4,"index":60}},
"start":16,"end":61,"loc":{"start":{"line":1,"column":16,"index":16},"end":{"line":5,"column":0,"index":61}},
"sourceType": "module",
"interpreter": null,
"body": [
Expand All @@ -36,7 +36,7 @@
"start":19,"end":59,"loc":{"start":{"line":2,"column":2,"index":19},"end":{"line":4,"column":3,"index":59}},
"body": {
"type": "Program",
"start":32,"end":55,"loc":{"start":{"line":3,"column":4,"index":32},"end":{"line":3,"column":27,"index":55}},
"start":27,"end":58,"loc":{"start":{"line":2,"column":10,"index":27},"end":{"line":4,"column":2,"index":58}},
"sourceType": "module",
"interpreter": null,
"body": [
Expand Down
Expand Up @@ -24,7 +24,7 @@
"start":10,"end":45,"loc":{"start":{"line":1,"column":10,"index":10},"end":{"line":1,"column":45,"index":45}},
"body": {
"type": "Program",
"start":19,"end":43,"loc":{"start":{"line":1,"column":19,"index":19},"end":{"line":1,"column":43,"index":43}},
"start":18,"end":44,"loc":{"start":{"line":1,"column":18,"index":18},"end":{"line":1,"column":44,"index":44}},
"sourceType": "module",
"interpreter": null,
"body": [
Expand Down
Expand Up @@ -15,7 +15,7 @@
"start":0,"end":18,"loc":{"start":{"line":1,"column":0,"index":0},"end":{"line":1,"column":18,"index":18}},
"body": {
"type": "Program",
"start":9,"end":16,"loc":{"start":{"line":1,"column":9,"index":9},"end":{"line":1,"column":16,"index":16}},
"start":8,"end":17,"loc":{"start":{"line":1,"column":8,"index":8},"end":{"line":1,"column":17,"index":17}},
"sourceType": "module",
"interpreter": null,
"body": [
Expand Down
@@ -0,0 +1,3 @@
module {
/* leading */ x /* trailing */
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Currently Babel attaches trailing as the trailing comment of the Program node because the parser finishes the Program node before /* trailing */.

Now the behaviour is aligned to how we parse plain /* leading */ x /* trailing */.

}
@@ -0,0 +1,65 @@
{
"type": "File",
"start":0,"end":43,"loc":{"start":{"line":1,"column":0,"index":0},"end":{"line":3,"column":1,"index":43}},
"program": {
"type": "Program",
"start":0,"end":43,"loc":{"start":{"line":1,"column":0,"index":0},"end":{"line":3,"column":1,"index":43}},
"sourceType": "module",
"interpreter": null,
"body": [
{
"type": "ExpressionStatement",
"start":0,"end":43,"loc":{"start":{"line":1,"column":0,"index":0},"end":{"line":3,"column":1,"index":43}},
"expression": {
"type": "ModuleExpression",
"start":0,"end":43,"loc":{"start":{"line":1,"column":0,"index":0},"end":{"line":3,"column":1,"index":43}},
"body": {
"type": "Program",
"start":8,"end":42,"loc":{"start":{"line":1,"column":8,"index":8},"end":{"line":3,"column":0,"index":42}},
"sourceType": "module",
"interpreter": null,
"body": [
{
"type": "ExpressionStatement",
"start":25,"end":26,"loc":{"start":{"line":2,"column":16,"index":25},"end":{"line":2,"column":17,"index":26}},
"expression": {
"type": "Identifier",
"start":25,"end":26,"loc":{"start":{"line":2,"column":16,"index":25},"end":{"line":2,"column":17,"index":26},"identifierName":"x"},
"name": "x"
},
"trailingComments": [
{
"type": "CommentBlock",
"value": " trailing ",
"start":27,"end":41,"loc":{"start":{"line":2,"column":18,"index":27},"end":{"line":2,"column":32,"index":41}}
}
],
"leadingComments": [
{
"type": "CommentBlock",
"value": " leading ",
"start":11,"end":24,"loc":{"start":{"line":2,"column":2,"index":11},"end":{"line":2,"column":15,"index":24}}
}
]
}
],
"directives": []
}
}
}
],
"directives": []
},
"comments": [
{
"type": "CommentBlock",
"value": " leading ",
"start":11,"end":24,"loc":{"start":{"line":2,"column":2,"index":11},"end":{"line":2,"column":15,"index":24}}
},
{
"type": "CommentBlock",
"value": " trailing ",
"start":27,"end":41,"loc":{"start":{"line":2,"column":18,"index":27},"end":{"line":2,"column":32,"index":41}}
}
]
}