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

Add plugin for import.meta proposal #544

Merged
merged 4 commits into from
May 30, 2017
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ require("babylon").parse("code", {
- `functionSent`
- `dynamicImport` ([proposal](https://github.com/tc39/proposal-dynamic-import))
- `numericSeparator` ([proposal](https://github.com/samuelgoto/proposal-numeric-separator))
- `importMeta` ([proposal](https://github.com/tc39/proposal-import-meta))

### FAQ

Expand Down
16 changes: 15 additions & 1 deletion src/parser/expression.js
Original file line number Diff line number Diff line change
Expand Up @@ -427,6 +427,10 @@ export default class ExpressionParser extends LValParser {
return this.finishNode(node, "Super");

case tt._import:
if (this.hasPlugin("importMeta") && this.lookahead().type === tt.dot) {
return this.parseImportMetaProperty();
}

if (!this.hasPlugin("dynamicImport")) this.unexpected();

node = this.startNode();
Expand Down Expand Up @@ -588,12 +592,22 @@ export default class ExpressionParser extends LValParser {
node.property = this.parseIdentifier(true);

if (node.property.name !== propertyName) {
this.raise(node.property.start, `The only valid meta property for new is ${meta.name}.${propertyName}`);
this.raise(node.property.start, `The only valid meta property for ${meta.name} is ${meta.name}.${propertyName}`);
}

return this.finishNode(node, "MetaProperty");
}

parseImportMetaProperty(): N.MetaProperty {
const node = this.startNode();
const id = this.parseIdentifier(true);
this.expect(tt.dot);
if (this.options.sourceType !== "module") {
Copy link
Member

Choose a reason for hiding this comment

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

Can also do if (!this.inModule) here

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Weird, I thought I tried that first but .inModule was only true top-level. Must have missed something. You're right, definitely works fine.

this.raise(id.start, "import.meta can only be used in modules");
Copy link
Member

Choose a reason for hiding this comment

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

May want to make this consistent with other sourceType errors?

'import.meta' can only be used with 'sourceType: module'

Copy link
Contributor Author

@jkrems jkrems May 29, 2017

Choose a reason for hiding this comment

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

Heh, good point. Copied the wording from "can only be used in functions". Should've taken the wording from import/export statements. Fixed.

}
return this.parseMetaProperty(node, id, "meta");
Copy link
Member

Choose a reason for hiding this comment

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

The error message if the meta property isn't .meta is confusing (it's hardcoded to mention new)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Oops, good point. Added a test that checks for that & made it use the correct name.

}

parseLiteral<T : N.Literal>(value: any, type: /*T["kind"]*/string, startPos?: number, startLoc?: Position): T {
startPos = startPos || this.state.start;
startLoc = startLoc || this.state.startLoc;
Expand Down
3 changes: 2 additions & 1 deletion src/parser/statement.js
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,8 @@ export default class StatementParser extends ExpressionParser {
case tt.semi: return this.parseEmptyStatement(node);
case tt._export:
case tt._import:
if (this.hasPlugin("dynamicImport") && this.lookahead().type === tt.parenL) break;
if ((this.hasPlugin("dynamicImport") && this.lookahead().type === tt.parenL) ||
(this.hasPlugin("importMeta") && this.lookahead().type === tt.dot)) break;

if (!this.options.allowImportExportEverywhere) {
if (!topLevel) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
const x = import.meta;
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"throws": "import.meta can only be used in modules (1:10)",
"plugins": ["dynamicImport", "importMeta"],
"sourceType": "script"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
import.notMeta;
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"throws": "The only valid meta property for import is import.meta (1:7)",
"sourceType": "module",
"plugins": ["dynamicImport", "importMeta"]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
import.meta = true;
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"throws": "Invalid left-hand side in assignment expression (1:0)",
"sourceType": "module",
"plugins": ["dynamicImport", "importMeta"]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
const x = import.meta;
const url = import.meta.url;
import.meta;
import.meta.url;
import.meta.couldBeMutable = true;
Loading