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.serializeDecorator(decorators[i]);
} }
} }
this.serializeExternalModifiers(node);
this.serializeAccessModifiers(node); this.serializeAccessModifiers(node);
if (node.name.text.length) { if (node.name.text.length) {
sb.push("function "); sb.push("function ");

View File

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