Implement optional trailing commas (#97)

This commit is contained in:
Alan Pierce 2018-05-06 17:16:26 -07:00 committed by Daniel Wirtz
parent 25a1f6230a
commit 00fee73022
4 changed files with 148 additions and 88 deletions

View File

@ -967,6 +967,7 @@ export class ASTBuilder {
this.serializeDecorator(decorators[i]);
}
}
this.serializeExternalModifiers(node);
this.serializeAccessModifiers(node);
if (node.name.text.length) {
sb.push("function ");

View File

@ -819,13 +819,14 @@ export class Parser extends DiagnosticEmitter {
return null;
}
var members = new Array<EnumValueDeclaration>();
if (!tn.skip(Token.CLOSEBRACE)) {
do {
while (!tn.skip(Token.CLOSEBRACE)) {
let member = this.parseEnumValue(tn, CommonFlags.NONE);
if (!member) return null;
members.push(<EnumValueDeclaration>member);
} while (tn.skip(Token.COMMA));
if (!tn.skip(Token.CLOSEBRACE)) {
if (!tn.skip(Token.COMMA)) {
if (tn.skip(Token.CLOSEBRACE)) {
break;
} else {
this.error(
DiagnosticCode._0_expected,
tn.range(), "}"
@ -833,6 +834,7 @@ export class Parser extends DiagnosticEmitter {
return null;
}
}
}
var ret = Node.createEnumDeclaration(
identifier,
members,
@ -899,20 +901,23 @@ export class Parser extends DiagnosticEmitter {
// at '<': TypeParameter (',' TypeParameter)* '>'
var typeParameters = new Array<TypeParameterNode>();
if (!tn.skip(Token.GREATERTHAN)) {
do {
while (!tn.skip(Token.GREATERTHAN)) {
let typeParameter = this.parseTypeParameter(tn);
if (!typeParameter) return null;
typeParameters.push(<TypeParameterNode>typeParameter);
} while (tn.skip(Token.COMMA));
if (!tn.skip(Token.GREATERTHAN)) {
if (!tn.skip(Token.COMMA)) {
if (tn.skip(Token.GREATERTHAN)) {
break;
} else {
this.error(
DiagnosticCode._0_expected,
tn.range(), ">"
);
return null;
}
} else {
}
}
if (typeParameters.length === 0) {
this.error(
DiagnosticCode.Type_parameter_list_cannot_be_empty,
tn.range()
@ -971,8 +976,7 @@ export class Parser extends DiagnosticEmitter {
var seenOptional = false;
var reportedRest = false;
if (tn.peek() != Token.CLOSEPAREN) {
do {
while (!tn.skip(Token.CLOSEPAREN)) {
let param = this.parseParameter(tn, isConstructor);
if (!param) return null;
if (seenRest && !reportedRest) {
@ -1002,15 +1006,18 @@ export class Parser extends DiagnosticEmitter {
}
}
parameters.push(param);
} while (tn.skip(Token.COMMA));
}
if (!tn.skip(Token.CLOSEPAREN)) {
if (!tn.skip(Token.COMMA)) {
if (tn.skip(Token.CLOSEPAREN)) {
break;
} else {
this.error(
DiagnosticCode._0_expected,
tn.range(), ")"
);
return null;
}
}
}
return parameters;
}
@ -2877,8 +2884,7 @@ export class Parser extends DiagnosticEmitter {
// ArrayLiteralExpression
case Token.OPENBRACKET: {
let elementExpressions = new Array<Expression | null>();
if (!tn.skip(Token.CLOSEBRACKET)) {
do {
while (!tn.skip(Token.CLOSEBRACKET)) {
if (tn.peek() == Token.COMMA) {
expr = null; // omitted
} else {
@ -2886,9 +2892,10 @@ export class Parser extends DiagnosticEmitter {
if (!expr) return null;
}
elementExpressions.push(expr);
if (tn.peek() == Token.CLOSEBRACKET) break;
} while (tn.skip(Token.COMMA));
if (!tn.skip(Token.CLOSEBRACKET)) {
if (!tn.skip(Token.COMMA)) {
if (tn.skip(Token.CLOSEBRACKET)) {
break;
} else {
this.error(
DiagnosticCode._0_expected,
tn.range(), "]"
@ -2896,6 +2903,7 @@ export class Parser extends DiagnosticEmitter {
return null;
}
}
}
return Node.createArrayLiteralExpression(elementExpressions, tn.range(startPos, tn.pos));
}
// AssertionExpression (unary prefix)
@ -2979,6 +2987,9 @@ export class Parser extends DiagnosticEmitter {
if (!tn.skip(Token.LESSTHAN)) return null;
var typeArguments = new Array<CommonTypeNode>();
do {
if (tn.peek() === Token.GREATERTHAN) {
break;
}
let type = this.parseType(tn, true, true);
if (!type) {
tn.reset(state);
@ -3000,13 +3011,14 @@ export class Parser extends DiagnosticEmitter {
// at '(': (Expression (',' Expression)*)? ')'
var args = new Array<Expression>();
if (!tn.skip(Token.CLOSEPAREN)) {
do {
while (!tn.skip(Token.CLOSEPAREN)) {
let expr = this.parseExpression(tn, Precedence.COMMA + 1);
if (!expr) return null;
args.push(expr);
} while (tn.skip(Token.COMMA));
if (!tn.skip(Token.CLOSEPAREN)) {
if (!tn.skip(Token.COMMA)) {
if (tn.skip(Token.CLOSEPAREN)) {
break;
} else {
this.error(
DiagnosticCode._0_expected,
tn.range(), ")"
@ -3014,6 +3026,7 @@ export class Parser extends DiagnosticEmitter {
return null;
}
}
}
return args;
}

View File

@ -0,0 +1,33 @@
enum Foo {
A,
B,
}
function add(
x: i32,
y: i32,
): i32 {
return x + y;
}
function parameterized<
A,
B,
>(a: A, b: B): void {
}
export function compute(): i32 {
const arr: Array<i8> = [
1,
2,
];
parameterized<
i8,
// @ts-ignore: Waiting on https://github.com/Microsoft/TypeScript/issues/21984
i32,
>(0, 0);
return add(
1,
2,
);
}

View File

@ -0,0 +1,13 @@
enum Foo {
A,
B
}
function add(x: i32, y: i32): i32 {
return x + y;
}
function parameterized<A, B>(a: A, b: B): void {}
export function compute(): i32 {
const arr: Array<i8> = [1, 2];
parameterized<i8, i32>(0, 0);
return add(1, 2);
}