From 6286c7577df80a4faabfbcde523ab61682703adf Mon Sep 17 00:00:00 2001 From: Andy Date: Wed, 4 Apr 2018 11:33:29 -0700 Subject: [PATCH] Allow rest parameter trailing commas in ambient contexts (#23139) --- src/compiler/checker.ts | 4 ++- ...nFunctionParametersAndArguments.errors.txt | 3 ++ ...gCommasInFunctionParametersAndArguments.js | 3 ++ ...asInFunctionParametersAndArguments.symbols | 35 +++++++++++-------- ...mmasInFunctionParametersAndArguments.types | 5 +++ ...gCommasInFunctionParametersAndArguments.ts | 3 ++ 6 files changed, 37 insertions(+), 16 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 1315c12cdce..07801f5b5bc 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -26662,7 +26662,9 @@ namespace ts { if (i !== (parameterCount - 1)) { return grammarErrorOnNode(parameter.dotDotDotToken, Diagnostics.A_rest_parameter_must_be_last_in_a_parameter_list); } - checkGrammarForDisallowedTrailingComma(parameters, Diagnostics.A_rest_parameter_or_binding_pattern_may_not_have_a_trailing_comma); + if (!(parameter.flags & NodeFlags.Ambient)) { // Allow `...foo,` in ambient declarations; see GH#23070 + checkGrammarForDisallowedTrailingComma(parameters, Diagnostics.A_rest_parameter_or_binding_pattern_may_not_have_a_trailing_comma); + } if (isBindingPattern(parameter.name)) { return grammarErrorOnNode(parameter.name, Diagnostics.A_rest_element_cannot_contain_a_binding_pattern); diff --git a/tests/baselines/reference/trailingCommasInFunctionParametersAndArguments.errors.txt b/tests/baselines/reference/trailingCommasInFunctionParametersAndArguments.errors.txt index 6511b4f0264..e0c53c25efc 100644 --- a/tests/baselines/reference/trailingCommasInFunctionParametersAndArguments.errors.txt +++ b/tests/baselines/reference/trailingCommasInFunctionParametersAndArguments.errors.txt @@ -10,6 +10,9 @@ tests/cases/conformance/es7/trailingCommasInFunctionParametersAndArguments.ts(5, ~ !!! error TS1013: A rest parameter or binding pattern may not have a trailing comma. + // Allowed for ambient declarations + declare function f25(...args,): void; + f2(...[],); // Not confused by overloads diff --git a/tests/baselines/reference/trailingCommasInFunctionParametersAndArguments.js b/tests/baselines/reference/trailingCommasInFunctionParametersAndArguments.js index e796a6b518c..3f803038ec9 100644 --- a/tests/baselines/reference/trailingCommasInFunctionParametersAndArguments.js +++ b/tests/baselines/reference/trailingCommasInFunctionParametersAndArguments.js @@ -5,6 +5,9 @@ f1(1,); function f2(...args,) {} +// Allowed for ambient declarations +declare function f25(...args,): void; + f2(...[],); // Not confused by overloads diff --git a/tests/baselines/reference/trailingCommasInFunctionParametersAndArguments.symbols b/tests/baselines/reference/trailingCommasInFunctionParametersAndArguments.symbols index 2d7a1f07e5a..7b1dc8b2f98 100644 --- a/tests/baselines/reference/trailingCommasInFunctionParametersAndArguments.symbols +++ b/tests/baselines/reference/trailingCommasInFunctionParametersAndArguments.symbols @@ -10,47 +10,52 @@ function f2(...args,) {} >f2 : Symbol(f2, Decl(trailingCommasInFunctionParametersAndArguments.ts, 2, 7)) >args : Symbol(args, Decl(trailingCommasInFunctionParametersAndArguments.ts, 4, 12)) +// Allowed for ambient declarations +declare function f25(...args,): void; +>f25 : Symbol(f25, Decl(trailingCommasInFunctionParametersAndArguments.ts, 4, 24)) +>args : Symbol(args, Decl(trailingCommasInFunctionParametersAndArguments.ts, 7, 21)) + f2(...[],); >f2 : Symbol(f2, Decl(trailingCommasInFunctionParametersAndArguments.ts, 2, 7)) // Not confused by overloads declare function f3(x, ): number; ->f3 : Symbol(f3, Decl(trailingCommasInFunctionParametersAndArguments.ts, 6, 11), Decl(trailingCommasInFunctionParametersAndArguments.ts, 9, 33)) ->x : Symbol(x, Decl(trailingCommasInFunctionParametersAndArguments.ts, 9, 20)) +>f3 : Symbol(f3, Decl(trailingCommasInFunctionParametersAndArguments.ts, 9, 11), Decl(trailingCommasInFunctionParametersAndArguments.ts, 12, 33)) +>x : Symbol(x, Decl(trailingCommasInFunctionParametersAndArguments.ts, 12, 20)) declare function f3(x, y,): string; ->f3 : Symbol(f3, Decl(trailingCommasInFunctionParametersAndArguments.ts, 6, 11), Decl(trailingCommasInFunctionParametersAndArguments.ts, 9, 33)) ->x : Symbol(x, Decl(trailingCommasInFunctionParametersAndArguments.ts, 10, 20)) ->y : Symbol(y, Decl(trailingCommasInFunctionParametersAndArguments.ts, 10, 22)) +>f3 : Symbol(f3, Decl(trailingCommasInFunctionParametersAndArguments.ts, 9, 11), Decl(trailingCommasInFunctionParametersAndArguments.ts, 12, 33)) +>x : Symbol(x, Decl(trailingCommasInFunctionParametersAndArguments.ts, 13, 20)) +>y : Symbol(y, Decl(trailingCommasInFunctionParametersAndArguments.ts, 13, 22)) f3(1,); ->f3 : Symbol(f3, Decl(trailingCommasInFunctionParametersAndArguments.ts, 6, 11), Decl(trailingCommasInFunctionParametersAndArguments.ts, 9, 33)) +>f3 : Symbol(f3, Decl(trailingCommasInFunctionParametersAndArguments.ts, 9, 11), Decl(trailingCommasInFunctionParametersAndArguments.ts, 12, 33)) f3(1, 2,); ->f3 : Symbol(f3, Decl(trailingCommasInFunctionParametersAndArguments.ts, 6, 11), Decl(trailingCommasInFunctionParametersAndArguments.ts, 9, 33)) +>f3 : Symbol(f3, Decl(trailingCommasInFunctionParametersAndArguments.ts, 9, 11), Decl(trailingCommasInFunctionParametersAndArguments.ts, 12, 33)) // Works for constructors too class X { ->X : Symbol(X, Decl(trailingCommasInFunctionParametersAndArguments.ts, 13, 18)) +>X : Symbol(X, Decl(trailingCommasInFunctionParametersAndArguments.ts, 16, 18)) constructor(a,) { } ->a : Symbol(a, Decl(trailingCommasInFunctionParametersAndArguments.ts, 17, 16)) +>a : Symbol(a, Decl(trailingCommasInFunctionParametersAndArguments.ts, 20, 16)) // See trailingCommasInGetter.ts set x(value,) { } ->x : Symbol(X.x, Decl(trailingCommasInFunctionParametersAndArguments.ts, 17, 23)) ->value : Symbol(value, Decl(trailingCommasInFunctionParametersAndArguments.ts, 19, 10)) +>x : Symbol(X.x, Decl(trailingCommasInFunctionParametersAndArguments.ts, 20, 23)) +>value : Symbol(value, Decl(trailingCommasInFunctionParametersAndArguments.ts, 22, 10)) } interface Y { ->Y : Symbol(Y, Decl(trailingCommasInFunctionParametersAndArguments.ts, 20, 1)) +>Y : Symbol(Y, Decl(trailingCommasInFunctionParametersAndArguments.ts, 23, 1)) new(x,); ->x : Symbol(x, Decl(trailingCommasInFunctionParametersAndArguments.ts, 22, 8)) +>x : Symbol(x, Decl(trailingCommasInFunctionParametersAndArguments.ts, 25, 8)) (x,); ->x : Symbol(x, Decl(trailingCommasInFunctionParametersAndArguments.ts, 23, 5)) +>x : Symbol(x, Decl(trailingCommasInFunctionParametersAndArguments.ts, 26, 5)) } new X(1,); ->X : Symbol(X, Decl(trailingCommasInFunctionParametersAndArguments.ts, 13, 18)) +>X : Symbol(X, Decl(trailingCommasInFunctionParametersAndArguments.ts, 16, 18)) diff --git a/tests/baselines/reference/trailingCommasInFunctionParametersAndArguments.types b/tests/baselines/reference/trailingCommasInFunctionParametersAndArguments.types index 9df4b0afb50..b269083a832 100644 --- a/tests/baselines/reference/trailingCommasInFunctionParametersAndArguments.types +++ b/tests/baselines/reference/trailingCommasInFunctionParametersAndArguments.types @@ -12,6 +12,11 @@ function f2(...args,) {} >f2 : (...args: any[]) => void >args : any[] +// Allowed for ambient declarations +declare function f25(...args,): void; +>f25 : (...args: any[]) => void +>args : any[] + f2(...[],); >f2(...[],) : void >f2 : (...args: any[]) => void diff --git a/tests/cases/conformance/es7/trailingCommasInFunctionParametersAndArguments.ts b/tests/cases/conformance/es7/trailingCommasInFunctionParametersAndArguments.ts index 6b57235cbeb..6db7ec9c853 100644 --- a/tests/cases/conformance/es7/trailingCommasInFunctionParametersAndArguments.ts +++ b/tests/cases/conformance/es7/trailingCommasInFunctionParametersAndArguments.ts @@ -6,6 +6,9 @@ f1(1,); function f2(...args,) {} +// Allowed for ambient declarations +declare function f25(...args,): void; + f2(...[],); // Not confused by overloads