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

added basic support for module attributes and tests updated #10962

Merged
merged 71 commits into from May 24, 2020
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
Show all changes
71 commits
Select commit Hold shift + click to select a range
7e1a783
:recycle: added basic support for module attributes and tests updated
Jan 5, 2020
b810e31
attributes should be set only if moduleAttributes plugin is enabled, …
Jan 5, 2020
c35b06e
Merge branch 'master' of https://github.com/babel/babel into proposal…
Jan 25, 2020
4243ec1
:recycle: use new AST Node ImportAttribute for module attributes, tes…
vivek12345 Jan 25, 2020
202af5a
Merge branch 'master' of https://github.com/babel/babel into proposal…
vivek12345 Mar 11, 2020
14aae84
chore: fixed the eslint issue and sorted the errors in ascending order
vivek12345 Mar 11, 2020
8c4ecf9
improvement: added support to throw error if duplicate attributes found
vivek12345 Mar 11, 2020
bbb6020
chore: fixed the failing test of babel plugin dotall regex
vivek12345 Mar 11, 2020
ba5482e
improvement: fixed error messages, confition to check presence of wit…
vivek12345 Mar 12, 2020
a038601
test: added a new test for allowing hasOwnProperty as one of the modu…
vivek12345 Mar 12, 2020
cde4f92
chore: added a mandatory version option to use along with module attr…
vivek12345 Mar 12, 2020
4f16179
improvement: replaced object create with set and renamed test folder …
vivek12345 Mar 13, 2020
a264662
Update packages/babel-parser/src/plugin-utils.js
vivek12345 Mar 13, 2020
c7c2c78
Update packages/babel-parser/src/parser/statement.js
vivek12345 Mar 13, 2020
2b5b437
chore: unnecesaary comment removed and tests updated
vivek12345 Mar 13, 2020
d36d314
improvement: using node.key.start instead of this.node.start to point…
vivek12345 Mar 13, 2020
0a0958d
improvement: added check for line terminator
vivek12345 Mar 14, 2020
f28f6ad
chore: renamed valid-syntax-with-attributes-multiple-lines to invalid…
vivek12345 Mar 14, 2020
7806809
improvement: changed the logic and tests to only support type as the …
vivek12345 Mar 15, 2020
a3c6a55
improvement: don't throw an error when attribute name is not type, ju…
vivek12345 Mar 15, 2020
65f9f5c
Revert output.js
nicolo-ribaudo Mar 15, 2020
1dacc99
improvement: removed the check for presence of tyep attribute as an e…
vivek12345 Mar 15, 2020
187d0d6
Merge branch 'proposal-module-attributes' of https://github.com/vivek…
vivek12345 Mar 15, 2020
5cb50ed
Merge branch 'master' of https://github.com/babel/babel into proposal…
vivek12345 Mar 15, 2020
40ddfab
feat: added syntax-import-module-attributes
vivek12345 Mar 16, 2020
41bb994
fix: fixed a message test in the readme for syntax-import-module-attr…
vivek12345 Mar 16, 2020
4030426
refactor: removed the error key ModuleAttributesWithoutType as it is …
vivek12345 Mar 16, 2020
792d096
refactor: renamed syntax-import-module-attributes to syntax-module-at…
vivek12345 Mar 16, 2020
a3c56ff
:recycle: added basic support for module attributes and tests updated
Jan 5, 2020
cbcdb3d
attributes should be set only if moduleAttributes plugin is enabled, …
Jan 5, 2020
e392984
:recycle: use new AST Node ImportAttribute for module attributes, tes…
vivek12345 Jan 25, 2020
256510b
chore: fixed the eslint issue and sorted the errors in ascending order
vivek12345 Mar 11, 2020
1ee26a7
improvement: added support to throw error if duplicate attributes found
vivek12345 Mar 11, 2020
2a708a5
improvement: fixed error messages, confition to check presence of wit…
vivek12345 Mar 12, 2020
f795d36
test: added a new test for allowing hasOwnProperty as one of the modu…
vivek12345 Mar 12, 2020
35a85e9
chore: added a mandatory version option to use along with module attr…
vivek12345 Mar 12, 2020
e3976f2
improvement: replaced object create with set and renamed test folder …
vivek12345 Mar 13, 2020
efacdaf
Update packages/babel-parser/src/plugin-utils.js
vivek12345 Mar 13, 2020
4202fa9
Update packages/babel-parser/src/parser/statement.js
vivek12345 Mar 13, 2020
e1016ad
chore: unnecesaary comment removed and tests updated
vivek12345 Mar 13, 2020
f89c15f
improvement: using node.key.start instead of this.node.start to point…
vivek12345 Mar 13, 2020
18dd064
improvement: added check for line terminator
vivek12345 Mar 14, 2020
31f6a38
chore: renamed valid-syntax-with-attributes-multiple-lines to invalid…
vivek12345 Mar 14, 2020
b98824f
improvement: changed the logic and tests to only support type as the …
vivek12345 Mar 15, 2020
1c2be01
improvement: don't throw an error when attribute name is not type, ju…
vivek12345 Mar 15, 2020
180b757
Revert output.js
nicolo-ribaudo Mar 15, 2020
ca2608f
improvement: removed the check for presence of tyep attribute as an e…
vivek12345 Mar 15, 2020
3581a82
feat: added syntax-import-module-attributes
vivek12345 Mar 16, 2020
b9d2939
fix: fixed a message test in the readme for syntax-import-module-attr…
vivek12345 Mar 16, 2020
24f7830
refactor: removed the error key ModuleAttributesWithoutType as it is …
vivek12345 Mar 16, 2020
b1270c6
refactor: renamed syntax-import-module-attributes to syntax-module-at…
vivek12345 Mar 16, 2020
b7280e2
Format output files
nicolo-ribaudo Apr 28, 2020
6e4e730
feb-2020 -> apr-2020
nicolo-ribaudo Apr 28, 2020
7a2f4f8
Revert output.js
nicolo-ribaudo Apr 28, 2020
69f153e
Revert expression.js
nicolo-ribaudo Apr 28, 2020
522bdc6
relaxed the argument condition on dynamic imports from 1 to 2 for pro…
vivek12345 Apr 30, 2020
2a3e3d0
merged with upstream master
vivek12345 Apr 30, 2020
b1e7ddc
merged with remote changes and merge conflicts resolved
vivek12345 Apr 30, 2020
2e243af
bug: fixed the version to apr-2020
vivek12345 Apr 30, 2020
f250937
polish: tune importArity error message
JLHwung May 20, 2020
dbf36f6
fix: allow trailing comma in import()
JLHwung May 20, 2020
0ce6e62
chore: update version to latest month
JLHwung May 20, 2020
9f80885
add moduleAttributes to parse typings
JLHwung May 20, 2020
aa22f1a
feat: add syntax-module-attributes to babel-standalone
JLHwung May 20, 2020
967a9be
fix: forbid spread element in second argument of import()
JLHwung May 20, 2020
d06d08b
expect moduleAttributes when there are two arguments of import()
JLHwung May 20, 2020
f051fa1
refactor: minor tweaks
JLHwung May 20, 2020
01933e4
Merge remote-tracking branch 'upstream/master' into proposal-module-a…
JLHwung May 20, 2020
dde6294
chore: rearrange tests
JLHwung May 20, 2020
907aacd
Update packages/babel-parser/src/parser/expression.js
JLHwung May 21, 2020
63b7c44
Merge remote-tracking branch 'upstream/master' into proposal-module-a…
nicolo-ribaudo May 24, 2020
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
30 changes: 29 additions & 1 deletion packages/babel-parser/src/parser/expression.js
Expand Up @@ -852,6 +852,35 @@ export default class ExpressionParser extends LValParser {
return this.parseSubscripts(this.parseExprAtom(), startPos, startLoc, true);
}

/**
* Parse a primitive value
* primitive values are null, undefined, number, bigint, string, boolean
*/
parsePrimitiveValue(): N.Expression {
let node;
switch (this.state.type) {
case tt.num:
return this.parseLiteral(this.state.value, "NumericLiteral");

case tt.bigint:
return this.parseLiteral(this.state.value, "BigIntLiteral");

case tt.string:
return this.parseLiteral(this.state.value, "StringLiteral");

case tt._null:
node = this.startNode();
this.next();
return this.finishNode(node, "NullLiteral");

case tt._true:
case tt._false:
return this.parseBooleanLiteral();
default:
vivek12345 marked this conversation as resolved.
Show resolved Hide resolved
throw this.unexpected();
vivek12345 marked this conversation as resolved.
Show resolved Hide resolved
}
}

// Parse an atomic expression — either a single token that is an
// expression, an expression started by a keyword like `function` or
// `new`, or an expression wrapped in punctuation like `()`, `[]`,
Expand Down Expand Up @@ -1459,7 +1488,6 @@ export default class ExpressionParser extends LValParser {
this.next();
return this.finishNode(node, "TemplateLiteral");
}

Copy link
Member

Choose a reason for hiding this comment

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

Nit: undo

// Parse an object literal or binding pattern.

parseObj<T: N.ObjectPattern | N.ObjectExpression>(
Expand Down
37 changes: 37 additions & 0 deletions packages/babel-parser/src/parser/statement.js
Expand Up @@ -2005,13 +2005,29 @@ export default class StatementParser extends ExpressionParser {
// import '...'
node.specifiers = [];
if (!this.match(tt.string)) {
// check if we have a default import like
// import React from "react";
const hasDefault = this.maybeParseDefaultImportSpecifier(node);
/* we are checking if we do not have a default import, then it is obvious that we need named imports
* import { get } from "axios";
* but if we do have a default import
* we need to check if we have a comma after that and
* that is where this || this.eat comes into play
*/
Copy link
Member

Choose a reason for hiding this comment

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

@vivek12345 I don't know if I already thanked you, but I love these comments!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thank you @nicolo-ribaudo . Means a lot 🙏

const parseNext = !hasDefault || this.eat(tt.comma);
// if we do have to parse the next set of specifiers, we first check for start imports
// import React, * from "react";
const hasStar = parseNext && this.maybeParseStarImportSpecifier(node);
// now we check that if we need to parse the next imports
// but only if he/she is not importing * which means all
vivek12345 marked this conversation as resolved.
Show resolved Hide resolved
if (parseNext && !hasStar) this.parseNamedImportSpecifiers(node);
this.expectContextual("from");
}
node.source = this.parseImportSource();
const attributes = this.maybeParseModuleAttributes();
vivek12345 marked this conversation as resolved.
Show resolved Hide resolved
if (Array.isArray(attributes)) {
node.attributes = attributes;
}
xtuc marked this conversation as resolved.
Show resolved Hide resolved
this.semicolon();
return this.finishNode(node, "ImportDeclaration");
}
Expand Down Expand Up @@ -2042,6 +2058,27 @@ export default class StatementParser extends ExpressionParser {
node.specifiers.push(this.finishNode(specifier, type));
}

maybeParseModuleAttributes() {
if (!this.eat(tt._with)) {
if (this.hasPlugin("moduleAttributes")) return [];
xtuc marked this conversation as resolved.
Show resolved Hide resolved
return null;
}
this.expectPlugin("moduleAttributes");
Copy link
Member

Choose a reason for hiding this comment

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

Nit: can we do something like this?

Suggested change
if (!this.eat(tt._with)) {
if (this.hasPlugin("moduleAttributes")) return [];
return null;
}
this.expectPlugin("moduleAttributes");
if (this.matches(tt._with)) {
this.expectPlugin("moduleAttributes");
this.next(); // Consume the `with` keyword
} else {
if (this.hasPlugin("moduleAttributes")) return [];
return null;
}

By doing so, we throw the "missing plugin" error pointing at with rather than at what comes after.

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 makes sense. I will update the code 👍

const attrs = [];
do {
const node = this.startNode();
node.key = this.parseIdentifier();
Copy link
Contributor

@JLHwung JLHwung Feb 5, 2020

Choose a reason for hiding this comment

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

Suggested change
node.key = this.parseIdentifier();
node.key = this.parseIdentifier(true);

To align with Property Name, the identifier name should be liberal, that is,

import foo from "bar" with for: "test"

should be valid.

node.computed = false;
node.method = false;
node.shorthand = false;
this.expect(tt.colon);
xtuc marked this conversation as resolved.
Show resolved Hide resolved
node.value = this.parsePrimitiveValue();

Choose a reason for hiding this comment

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

IMO this.parseLiteral(this.state.value, "StringLiteral"); would be sufficient; then, you don't need to introduce parsePrimitiveValue.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Noted. Thank you @littledan 👍

Copy link
Member

@xtuc xtuc Jan 13, 2020

Choose a reason for hiding this comment

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

I agree with @littledan

That said, we didn't define the grammar yet but we might want to consider things like:

import u from "a" with lazy: true, startAtLine: 1;

instead of a string literal?

Choose a reason for hiding this comment

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

Yes, we might want to consider it. But I don't think this is worth complicating the Babel codebase at the moment.

this.finishNode(node, "ObjectProperty");
Copy link
Member

Choose a reason for hiding this comment

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

I don't think that we should re-use ObjectProperty: it's conceptually and syntactically different. We should introduce a new ModuleAttribute node.

Copy link
Member

Choose a reason for hiding this comment

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

Would it help if we agreed on the Babel AST before the implemation?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Changed the code to now use the new AST node ImportAttribute

attrs.push(node);
} while (this.eat(tt.comma));
return attrs;
}

maybeParseDefaultImportSpecifier(node: N.ImportDeclaration): boolean {
if (this.shouldParseDefaultImport(node)) {
// import defaultObj, { x, y as z } from '...'
Expand Down
@@ -0,0 +1 @@
import foo from "foo.json" with type: "json";
@@ -0,0 +1,5 @@
{
"throws": "This experimental syntax requires enabling the parser plugin: 'moduleAttributes' (1:32)",
"sourceType": "module",
"plugins": []
}
@@ -0,0 +1 @@
import foo from "foo.json" with type: "json";
@@ -0,0 +1,4 @@
{
"plugins": ["moduleAttributes"],
"sourceType": "module"
}
@@ -0,0 +1,161 @@
{
"type": "File",
"start": 0,
"end": 45,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 45
}
},
"program": {
"type": "Program",
"start": 0,
"end": 45,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 45
}
},
"sourceType": "module",
"interpreter": null,
"body": [
{
"type": "ImportDeclaration",
"start": 0,
"end": 45,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 45
}
},
"specifiers": [
{
"type": "ImportDefaultSpecifier",
"start": 7,
"end": 10,
"loc": {
"start": {
"line": 1,
"column": 7
},
"end": {
"line": 1,
"column": 10
}
},
"local": {
"type": "Identifier",
"start": 7,
"end": 10,
"loc": {
"start": {
"line": 1,
"column": 7
},
"end": {
"line": 1,
"column": 10
},
"identifierName": "foo"
},
"name": "foo"
}
}
],
"source": {
"type": "StringLiteral",
"start": 16,
"end": 26,
"loc": {
"start": {
"line": 1,
"column": 16
},
"end": {
"line": 1,
"column": 26
}
},
"extra": {
"rawValue": "foo.json",
"raw": "\"foo.json\""
},
"value": "foo.json"
},
"attributes": [
{
"type": "ObjectProperty",
"start": 32,
"end": 44,
"loc": {
"start": {
"line": 1,
"column": 32
},
"end": {
"line": 1,
"column": 44
}
},
"key": {
"type": "Identifier",
"start": 32,
"end": 36,
"loc": {
"start": {
"line": 1,
"column": 32
},
"end": {
"line": 1,
"column": 36
},
"identifierName": "type"
},
"name": "type"
},
"computed": false,
"method": false,
"shorthand": false,
"value": {
"type": "StringLiteral",
"start": 38,
"end": 44,
"loc": {
"start": {
"line": 1,
"column": 38
},
"end": {
"line": 1,
"column": 44
}
},
"extra": {
"rawValue": "json",
"raw": "\"json\""
},
"value": "json"
}
}
]
}
],
"directives": []
}
}
@@ -0,0 +1 @@
import foo from "foo.json";
@@ -0,0 +1,4 @@
{
"plugins": ["moduleAttributes"],
"sourceType": "module"
}
@@ -0,0 +1,105 @@
{
"type": "File",
"start": 0,
"end": 27,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 27
}
},
"program": {
"type": "Program",
"start": 0,
"end": 27,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 27
}
},
"sourceType": "module",
"interpreter": null,
"body": [
{
"type": "ImportDeclaration",
"start": 0,
"end": 27,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 27
}
},
"specifiers": [
{
"type": "ImportDefaultSpecifier",
"start": 7,
"end": 10,
"loc": {
"start": {
"line": 1,
"column": 7
},
"end": {
"line": 1,
"column": 10
}
},
"local": {
"type": "Identifier",
"start": 7,
"end": 10,
"loc": {
"start": {
"line": 1,
"column": 7
},
"end": {
"line": 1,
"column": 10
},
"identifierName": "foo"
},
"name": "foo"
}
}
],
"source": {
"type": "StringLiteral",
"start": 16,
"end": 26,
"loc": {
"start": {
"line": 1,
"column": 16
},
"end": {
"line": 1,
"column": 26
}
},
"extra": {
"rawValue": "foo.json",
"raw": "\"foo.json\""
},
"value": "foo.json"
},
"attributes": []
}
],
"directives": []
}
}