fix: support string assertion key in assert entries (#12281)
* fix: support string assertion key in assert entries * Update packages/babel-parser/src/parser/statement.js Co-authored-by: Sosuke Suzuki <aosukeke@gmail.com> Co-authored-by: Sosuke Suzuki <aosukeke@gmail.com>
This commit is contained in:
parent
963537d5f5
commit
766df9c369
@ -2182,9 +2182,14 @@ export default class StatementParser extends ExpressionParser {
|
||||
node.specifiers.push(this.finishNode(specifier, type));
|
||||
}
|
||||
|
||||
parseAssertEntries() {
|
||||
this.expectPlugin("importAssertions");
|
||||
|
||||
/**
|
||||
* parse assert entries
|
||||
*
|
||||
* @see {@link https://tc39.es/proposal-import-assertions/#prod-AssertEntries |AssertEntries}
|
||||
* @returns {N.ImportAttribute[]}
|
||||
* @memberof StatementParser
|
||||
*/
|
||||
parseAssertEntries(): N.ImportAttribute[] {
|
||||
const attrs = [];
|
||||
const attrNames = new Set();
|
||||
|
||||
@ -2193,37 +2198,36 @@ export default class StatementParser extends ExpressionParser {
|
||||
break;
|
||||
}
|
||||
|
||||
const node = this.startNode();
|
||||
const node = this.startNode<N.ImportAttribute>();
|
||||
|
||||
// parse AssertionKey : IdentifierName, StringLiteral
|
||||
let assertionKeyNode;
|
||||
const keyName = this.state.value;
|
||||
if (this.match(tt.string)) {
|
||||
assertionKeyNode = this.parseLiteral(this.state.value, "StringLiteral");
|
||||
node.key = this.parseLiteral<N.StringLiteral>(keyName, "StringLiteral");
|
||||
} else {
|
||||
assertionKeyNode = this.parseIdentifier(true);
|
||||
node.key = this.parseIdentifier(true);
|
||||
}
|
||||
this.next();
|
||||
node.key = assertionKeyNode;
|
||||
this.expect(tt.colon);
|
||||
|
||||
// for now we are only allowing `type` as the only allowed module attribute
|
||||
if (node.key.name !== "type") {
|
||||
if (keyName !== "type") {
|
||||
this.raise(
|
||||
node.key.start,
|
||||
Errors.ModuleAttributeDifferentFromType,
|
||||
node.key.name,
|
||||
keyName,
|
||||
);
|
||||
}
|
||||
// check if we already have an entry for an attribute
|
||||
// if a duplicate entry is found, throw an error
|
||||
// for now this logic will come into play only when someone declares `type` twice
|
||||
if (attrNames.has(node.key.name)) {
|
||||
if (attrNames.has(keyName)) {
|
||||
this.raise(
|
||||
node.key.start,
|
||||
Errors.ModuleAttributesWithDuplicateKeys,
|
||||
node.key.name,
|
||||
keyName,
|
||||
);
|
||||
}
|
||||
attrNames.add(node.key.name);
|
||||
attrNames.add(keyName);
|
||||
|
||||
if (!this.match(tt.string)) {
|
||||
throw this.unexpected(
|
||||
@ -2231,8 +2235,11 @@ export default class StatementParser extends ExpressionParser {
|
||||
Errors.ModuleAttributeInvalidValue,
|
||||
);
|
||||
}
|
||||
node.value = this.parseLiteral(this.state.value, "StringLiteral");
|
||||
this.finishNode(node, "ImportAttribute");
|
||||
node.value = this.parseLiteral<N.StringLiteral>(
|
||||
this.state.value,
|
||||
"StringLiteral",
|
||||
);
|
||||
this.finishNode<N.ImportAttribute>(node, "ImportAttribute");
|
||||
attrs.push(node);
|
||||
} while (this.eat(tt.comma));
|
||||
|
||||
@ -2291,18 +2298,15 @@ export default class StatementParser extends ExpressionParser {
|
||||
}
|
||||
|
||||
maybeParseImportAssertions() {
|
||||
if (
|
||||
this.match(tt.name) &&
|
||||
this.state.value === "assert" &&
|
||||
!this.hasPrecedingLineBreak()
|
||||
) {
|
||||
// [no LineTerminator here] AssertClause
|
||||
if (this.isContextual("assert") && !this.hasPrecedingLineBreak()) {
|
||||
this.expectPlugin("importAssertions");
|
||||
this.next();
|
||||
this.next(); // eat `assert`
|
||||
} else {
|
||||
if (this.hasPlugin("importAssertions")) return [];
|
||||
return null;
|
||||
}
|
||||
|
||||
// https://tc39.es/proposal-import-assertions/#prod-AssertClause
|
||||
this.eat(tt.braceL);
|
||||
const attrs = this.parseAssertEntries();
|
||||
this.eat(tt.braceR);
|
||||
|
||||
@ -0,0 +1 @@
|
||||
import "foo" assert { type, "json" };
|
||||
@ -0,0 +1,9 @@
|
||||
{
|
||||
"plugins": [
|
||||
[
|
||||
"importAssertions"
|
||||
]
|
||||
],
|
||||
"sourceType": "module",
|
||||
"throws": "Unexpected token, expected \":\" (1:26)"
|
||||
}
|
||||
@ -0,0 +1 @@
|
||||
import "foo" \u{61}ssert { type: "json" };
|
||||
@ -0,0 +1,9 @@
|
||||
{
|
||||
"plugins": [
|
||||
[
|
||||
"importAssertions"
|
||||
]
|
||||
],
|
||||
"sourceType": "module",
|
||||
"throws": "Unexpected token, expected \";\" (1:13)"
|
||||
}
|
||||
@ -0,0 +1 @@
|
||||
import foo from "foo.json" assert { "type": "json", type: "html", "type": "js" };
|
||||
@ -0,0 +1,105 @@
|
||||
{
|
||||
"type": "File",
|
||||
"start":0,"end":81,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":81}},
|
||||
"errors": [
|
||||
"SyntaxError: Duplicate key \"type\" is not allowed in module attributes (1:52)",
|
||||
"SyntaxError: Duplicate key \"type\" is not allowed in module attributes (1:66)"
|
||||
],
|
||||
"program": {
|
||||
"type": "Program",
|
||||
"start":0,"end":81,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":81}},
|
||||
"sourceType": "module",
|
||||
"interpreter": null,
|
||||
"body": [
|
||||
{
|
||||
"type": "ImportDeclaration",
|
||||
"start":0,"end":81,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":81}},
|
||||
"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"
|
||||
},
|
||||
"assertions": [
|
||||
{
|
||||
"type": "ImportAttribute",
|
||||
"start":36,"end":50,"loc":{"start":{"line":1,"column":36},"end":{"line":1,"column":50}},
|
||||
"key": {
|
||||
"type": "StringLiteral",
|
||||
"start":36,"end":42,"loc":{"start":{"line":1,"column":36},"end":{"line":1,"column":42}},
|
||||
"extra": {
|
||||
"rawValue": "type",
|
||||
"raw": "\"type\""
|
||||
},
|
||||
"value": "type"
|
||||
},
|
||||
"value": {
|
||||
"type": "StringLiteral",
|
||||
"start":44,"end":50,"loc":{"start":{"line":1,"column":44},"end":{"line":1,"column":50}},
|
||||
"extra": {
|
||||
"rawValue": "json",
|
||||
"raw": "\"json\""
|
||||
},
|
||||
"value": "json"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "ImportAttribute",
|
||||
"start":52,"end":64,"loc":{"start":{"line":1,"column":52},"end":{"line":1,"column":64}},
|
||||
"key": {
|
||||
"type": "Identifier",
|
||||
"start":52,"end":56,"loc":{"start":{"line":1,"column":52},"end":{"line":1,"column":56},"identifierName":"type"},
|
||||
"name": "type"
|
||||
},
|
||||
"value": {
|
||||
"type": "StringLiteral",
|
||||
"start":58,"end":64,"loc":{"start":{"line":1,"column":58},"end":{"line":1,"column":64}},
|
||||
"extra": {
|
||||
"rawValue": "html",
|
||||
"raw": "\"html\""
|
||||
},
|
||||
"value": "html"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "ImportAttribute",
|
||||
"start":66,"end":78,"loc":{"start":{"line":1,"column":66},"end":{"line":1,"column":78}},
|
||||
"key": {
|
||||
"type": "StringLiteral",
|
||||
"start":66,"end":72,"loc":{"start":{"line":1,"column":66},"end":{"line":1,"column":72}},
|
||||
"extra": {
|
||||
"rawValue": "type",
|
||||
"raw": "\"type\""
|
||||
},
|
||||
"value": "type"
|
||||
},
|
||||
"value": {
|
||||
"type": "StringLiteral",
|
||||
"start":74,"end":78,"loc":{"start":{"line":1,"column":74},"end":{"line":1,"column":78}},
|
||||
"extra": {
|
||||
"rawValue": "js",
|
||||
"raw": "\"js\""
|
||||
},
|
||||
"value": "js"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"directives": []
|
||||
}
|
||||
}
|
||||
@ -0,0 +1 @@
|
||||
import "foo" assert { "type": "json" };
|
||||
@ -0,0 +1,51 @@
|
||||
{
|
||||
"type": "File",
|
||||
"start":0,"end":39,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":39}},
|
||||
"program": {
|
||||
"type": "Program",
|
||||
"start":0,"end":39,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":39}},
|
||||
"sourceType": "module",
|
||||
"interpreter": null,
|
||||
"body": [
|
||||
{
|
||||
"type": "ImportDeclaration",
|
||||
"start":0,"end":39,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":39}},
|
||||
"specifiers": [],
|
||||
"source": {
|
||||
"type": "StringLiteral",
|
||||
"start":7,"end":12,"loc":{"start":{"line":1,"column":7},"end":{"line":1,"column":12}},
|
||||
"extra": {
|
||||
"rawValue": "foo",
|
||||
"raw": "\"foo\""
|
||||
},
|
||||
"value": "foo"
|
||||
},
|
||||
"assertions": [
|
||||
{
|
||||
"type": "ImportAttribute",
|
||||
"start":22,"end":36,"loc":{"start":{"line":1,"column":22},"end":{"line":1,"column":36}},
|
||||
"key": {
|
||||
"type": "StringLiteral",
|
||||
"start":22,"end":28,"loc":{"start":{"line":1,"column":22},"end":{"line":1,"column":28}},
|
||||
"extra": {
|
||||
"rawValue": "type",
|
||||
"raw": "\"type\""
|
||||
},
|
||||
"value": "type"
|
||||
},
|
||||
"value": {
|
||||
"type": "StringLiteral",
|
||||
"start":30,"end":36,"loc":{"start":{"line":1,"column":30},"end":{"line":1,"column":36}},
|
||||
"extra": {
|
||||
"rawValue": "json",
|
||||
"raw": "\"json\""
|
||||
},
|
||||
"value": "json"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"directives": []
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user