Skip to content

Commit edf4aaa

Browse files
alangpiercedcodeIO
authored andcommitted
Allow trailing commas in import and export statements (#114)
1 parent 33b10e3 commit edf4aaa

File tree

4 files changed

+52
-22
lines changed

4 files changed

+52
-22
lines changed

src/extra/ast.ts

+9-1
Original file line numberDiff line numberDiff line change
@@ -710,7 +710,10 @@ export class ASTBuilder {
710710
sb.push(";\n");
711711
} else {
712712
let last = sb[sb.length - 1];
713-
if (last.length && last.charCodeAt(last.length - 1) == CharCode.CLOSEBRACE) {
713+
if (last.length && (
714+
last.charCodeAt(last.length - 1) == CharCode.CLOSEBRACE ||
715+
last.charCodeAt(last.length - 1) == CharCode.SEMICOLON)
716+
) {
714717
sb.push("\n");
715718
} else {
716719
sb.push(";\n");
@@ -892,11 +895,15 @@ export class ASTBuilder {
892895
var numMembers = members.length;
893896
if (numMembers) {
894897
sb.push("export {\n");
898+
let indentLevel = ++this.indentLevel;
899+
indent(sb, indentLevel);
895900
this.visitExportMember(node.members[0]);
896901
for (let i = 1; i < numMembers; ++i) {
897902
sb.push(",\n");
903+
indent(sb, indentLevel);
898904
this.visitExportMember(node.members[i]);
899905
}
906+
--this.indentLevel;
900907
sb.push("\n}");
901908
} else {
902909
sb.push("export {}");
@@ -906,6 +913,7 @@ export class ASTBuilder {
906913
sb.push(" from ");
907914
this.visitStringLiteralExpression(path);
908915
}
916+
sb.push(";");
909917
}
910918

911919
visitExpressionStatement(node: ExpressionStatement): void {

src/parser.ts

+25-21
Original file line numberDiff line numberDiff line change
@@ -1878,18 +1878,20 @@ export class Parser extends DiagnosticEmitter {
18781878

18791879
if (tn.skip(Token.OPENBRACE)) {
18801880
let members = new Array<ExportMember>();
1881-
if (!tn.skip(Token.CLOSEBRACE)) {
1882-
do {
1881+
while (!tn.skip(Token.CLOSEBRACE)) {
18831882
let member = this.parseExportMember(tn);
18841883
if (!member) return null;
18851884
members.push(member);
1886-
} while (tn.skip(Token.COMMA));
1887-
if (!tn.skip(Token.CLOSEBRACE)) {
1888-
this.error(
1889-
DiagnosticCode._0_expected,
1890-
tn.range(), "}"
1891-
);
1892-
return null;
1885+
if (!tn.skip(Token.COMMA)) {
1886+
if (tn.skip(Token.CLOSEBRACE)) {
1887+
break;
1888+
} else {
1889+
this.error(
1890+
DiagnosticCode._0_expected,
1891+
tn.range(), "}"
1892+
);
1893+
return null;
1894+
}
18931895
}
18941896
}
18951897
let path: StringLiteralExpression | null = null;
@@ -1971,18 +1973,20 @@ export class Parser extends DiagnosticEmitter {
19711973
var skipFrom = false;
19721974
if (tn.skip(Token.OPENBRACE)) {
19731975
members = new Array();
1974-
if (!tn.skip(Token.CLOSEBRACE)) {
1975-
do {
1976-
let member = this.parseImportDeclaration(tn);
1977-
if (!member) return null;
1978-
members.push(member);
1979-
} while (tn.skip(Token.COMMA));
1980-
if (!tn.skip(Token.CLOSEBRACE)) {
1981-
this.error(
1982-
DiagnosticCode._0_expected,
1983-
tn.range(), "}"
1984-
);
1985-
return null;
1976+
while (!tn.skip(Token.CLOSEBRACE)) {
1977+
let member = this.parseImportDeclaration(tn);
1978+
if (!member) return null;
1979+
members.push(member);
1980+
if (!tn.skip(Token.COMMA)) {
1981+
if (tn.skip(Token.CLOSEBRACE)) {
1982+
break;
1983+
} else {
1984+
this.error(
1985+
DiagnosticCode._0_expected,
1986+
tn.range(), "}"
1987+
);
1988+
return null;
1989+
}
19861990
}
19871991
}
19881992
} else if (tn.skip(Token.ASTERISK)) {

tests/parser/trailing-commas.ts

+10
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
import {
2+
a,
3+
b,
4+
} from "c";
5+
16
enum Foo {
27
A,
38
B,
@@ -31,3 +36,8 @@ export function compute(): i32 {
3136
2,
3237
);
3338
}
39+
40+
export {
41+
a,
42+
b,
43+
};

tests/parser/trailing-commas.ts.fixture.ts

+8
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
import {
2+
a,
3+
b
4+
} from "c";
15
enum Foo {
26
A,
37
B
@@ -11,3 +15,7 @@ export function compute(): i32 {
1115
parameterized<i8, i32>(0, 0);
1216
return add(1, 2);
1317
}
18+
export {
19+
a,
20+
b
21+
};

0 commit comments

Comments
 (0)