mirror of
https://github.com/fluencelabs/assemblyscript
synced 2025-04-25 07:02:13 +00:00
Implement optional trailing commas (#97)
This commit is contained in:
parent
25a1f6230a
commit
00fee73022
@ -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 ");
|
||||||
|
189
src/parser.ts
189
src/parser.ts
@ -819,18 +819,20 @@ 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);
|
if (!tn.skip(Token.COMMA)) {
|
||||||
} while (tn.skip(Token.COMMA));
|
if (tn.skip(Token.CLOSEBRACE)) {
|
||||||
if (!tn.skip(Token.CLOSEBRACE)) {
|
break;
|
||||||
this.error(
|
} else {
|
||||||
DiagnosticCode._0_expected,
|
this.error(
|
||||||
tn.range(), "}"
|
DiagnosticCode._0_expected,
|
||||||
);
|
tn.range(), "}"
|
||||||
return null;
|
);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var ret = Node.createEnumDeclaration(
|
var ret = Node.createEnumDeclaration(
|
||||||
@ -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);
|
if (!tn.skip(Token.COMMA)) {
|
||||||
} while (tn.skip(Token.COMMA));
|
if (tn.skip(Token.GREATERTHAN)) {
|
||||||
if (!tn.skip(Token.GREATERTHAN)) {
|
break;
|
||||||
this.error(
|
} else {
|
||||||
DiagnosticCode._0_expected,
|
this.error(
|
||||||
tn.range(), ">"
|
DiagnosticCode._0_expected,
|
||||||
);
|
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,45 +976,47 @@ 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) {
|
this.error(
|
||||||
|
DiagnosticCode.A_rest_parameter_must_be_last_in_a_parameter_list,
|
||||||
|
seenRest.name.range
|
||||||
|
);
|
||||||
|
reportedRest = true;
|
||||||
|
}
|
||||||
|
switch (param.parameterKind) {
|
||||||
|
default: {
|
||||||
|
if (seenOptional) {
|
||||||
|
this.error(
|
||||||
|
DiagnosticCode.A_required_parameter_cannot_follow_an_optional_parameter,
|
||||||
|
param.name.range
|
||||||
|
);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ParameterKind.OPTIONAL: {
|
||||||
|
seenOptional = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ParameterKind.REST: {
|
||||||
|
seenRest = param;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
parameters.push(param);
|
||||||
|
if (!tn.skip(Token.COMMA)) {
|
||||||
|
if (tn.skip(Token.CLOSEPAREN)) {
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
this.error(
|
this.error(
|
||||||
DiagnosticCode.A_rest_parameter_must_be_last_in_a_parameter_list,
|
DiagnosticCode._0_expected,
|
||||||
seenRest.name.range
|
tn.range(), ")"
|
||||||
);
|
);
|
||||||
reportedRest = true;
|
return null;
|
||||||
}
|
}
|
||||||
switch (param.parameterKind) {
|
}
|
||||||
default: {
|
|
||||||
if (seenOptional) {
|
|
||||||
this.error(
|
|
||||||
DiagnosticCode.A_required_parameter_cannot_follow_an_optional_parameter,
|
|
||||||
param.name.range
|
|
||||||
);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case ParameterKind.OPTIONAL: {
|
|
||||||
seenOptional = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case ParameterKind.REST: {
|
|
||||||
seenRest = param;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
parameters.push(param);
|
|
||||||
} while (tn.skip(Token.COMMA));
|
|
||||||
}
|
|
||||||
if (!tn.skip(Token.CLOSEPAREN)) {
|
|
||||||
this.error(
|
|
||||||
DiagnosticCode._0_expected,
|
|
||||||
tn.range(), ")"
|
|
||||||
);
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
return parameters;
|
return parameters;
|
||||||
}
|
}
|
||||||
@ -2877,23 +2884,24 @@ 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 {
|
||||||
|
expr = this.parseExpression(tn, Precedence.COMMA + 1);
|
||||||
|
if (!expr) return null;
|
||||||
|
}
|
||||||
|
elementExpressions.push(expr);
|
||||||
|
if (!tn.skip(Token.COMMA)) {
|
||||||
|
if (tn.skip(Token.CLOSEBRACKET)) {
|
||||||
|
break;
|
||||||
} else {
|
} else {
|
||||||
expr = this.parseExpression(tn, Precedence.COMMA + 1);
|
this.error(
|
||||||
if (!expr) return null;
|
DiagnosticCode._0_expected,
|
||||||
|
tn.range(), "]"
|
||||||
|
);
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
elementExpressions.push(expr);
|
|
||||||
if (tn.peek() == Token.CLOSEBRACKET) break;
|
|
||||||
} while (tn.skip(Token.COMMA));
|
|
||||||
if (!tn.skip(Token.CLOSEBRACKET)) {
|
|
||||||
this.error(
|
|
||||||
DiagnosticCode._0_expected,
|
|
||||||
tn.range(), "]"
|
|
||||||
);
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return Node.createArrayLiteralExpression(elementExpressions, tn.range(startPos, tn.pos));
|
return Node.createArrayLiteralExpression(elementExpressions, tn.range(startPos, tn.pos));
|
||||||
@ -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,18 +3011,20 @@ 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);
|
if (!tn.skip(Token.COMMA)) {
|
||||||
} while (tn.skip(Token.COMMA));
|
if (tn.skip(Token.CLOSEPAREN)) {
|
||||||
if (!tn.skip(Token.CLOSEPAREN)) {
|
break;
|
||||||
this.error(
|
} else {
|
||||||
DiagnosticCode._0_expected,
|
this.error(
|
||||||
tn.range(), ")"
|
DiagnosticCode._0_expected,
|
||||||
);
|
tn.range(), ")"
|
||||||
return null;
|
);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return args;
|
return args;
|
||||||
|
33
tests/parser/trailing-commas.ts
Normal file
33
tests/parser/trailing-commas.ts
Normal 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,
|
||||||
|
);
|
||||||
|
}
|
13
tests/parser/trailing-commas.ts.fixture.ts
Normal file
13
tests/parser/trailing-commas.ts.fixture.ts
Normal 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);
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user