Skip to content

Commit

Permalink
Added simplified version of bugfix for microsoft#19220
Browse files Browse the repository at this point in the history
  • Loading branch information
rFlorian committed May 20, 2018
1 parent 7189a66 commit 9cf84de
Show file tree
Hide file tree
Showing 9 changed files with 127 additions and 312 deletions.
75 changes: 21 additions & 54 deletions src/compiler/checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18382,70 +18382,37 @@ namespace ts {
argc++;
} while (argc <= maxArgs);
});
if (availableArgumentCounts.length === 0) availableArgumentCounts.push(0);

const orderNumerically = (a: number, b: number) => a < b ? 0 : 1;
const availableArgumentCountsSorted = sort(availableArgumentCounts, orderNumerically);

const min = first(availableArgumentCountsSorted);
const max = last(availableArgumentCountsSorted);
const availableArgumentCountsAscending = sort(availableArgumentCounts, (a, b) => a - b);
const min = first(availableArgumentCountsAscending);
const max = last(availableArgumentCountsAscending);

const hasRestParameter = some(signatures, sig => sig.hasRestParameter);
const hasSpreadArgument = getSpreadArgumentIndex(args) > -1;

const paramCount = hasRestParameter ?
min :
min < max ?
min + "-" + max :
min;
let argCount = args.length;
if (argCount <= max && hasSpreadArgument) argCount--;

const availableBelowCurrentArgCount = filter(availableArgumentCountsSorted, c => c < argCount);
const availableAboveCurrentArgCount = filter(availableArgumentCountsSorted, c => c > argCount);

const minAboveArgCount = firstOrUndefined(availableAboveCurrentArgCount);
const maxBelowArgCount = lastOrUndefined(availableBelowCurrentArgCount);

const sortedArrayIsContiguous = (arr: number[]) => arr.length === 0 ? true : last(arr) - first(arr) === arr.length - 1;
const contiguousBelow = sortedArrayIsContiguous(availableBelowCurrentArgCount);
const contiguousAbove = sortedArrayIsContiguous(availableAboveCurrentArgCount);

const rangeErrorBelow = maxBelowArgCount && min !== maxBelowArgCount ?
min + "-" + maxBelowArgCount :
min;
const rangeErrorAbove = minAboveArgCount && minAboveArgCount !== max ?
minAboveArgCount + "-" + max :
max;

if (hasSpreadArgument) {
if (!hasRestParameter && contiguousAbove && argCount < min) {
diagnostics.add(createDiagnosticForNode(node, Diagnostics.Expected_0_arguments_but_got_1_or_more, rangeErrorAbove, argCount));
}
else if (contiguousBelow && argCount > max) {
diagnostics.add(createDiagnosticForNode(node, Diagnostics.Expected_0_arguments_but_got_1_or_more, rangeErrorBelow, argCount));
}
else diagnostics.add(createDiagnosticForNode(node, Diagnostics.Expected_at_least_0_arguments_but_got_1_or_more, min, argCount));
if (hasRestParameter || hasSpreadArgument) {
const error = hasRestParameter && hasSpreadArgument ? Diagnostics.Expected_at_least_0_arguments_but_got_1_or_more :
hasRestParameter ? Diagnostics.Expected_at_least_0_arguments_but_got_1 :
hasSpreadArgument ? Diagnostics.Expected_0_arguments_but_got_1_or_more :
undefined;
diagnostics.add(createDiagnosticForNode(node, error, paramCount, argCount));
}
else if (argCount > max) {
if (contiguousBelow && !hasRestParameter) {
diagnostics.add(createDiagnosticForNode(node, Diagnostics.Expected_0_arguments_but_got_1, rangeErrorBelow, argCount));
}
else diagnostics.add(createDiagnosticForNode(node, Diagnostics.Expected_no_more_than_0_arguments_but_got_1, max, argCount));
}
else if (argCount < min) {
if (contiguousAbove && !hasRestParameter) {
diagnostics.add(createDiagnosticForNode(node, Diagnostics.Expected_0_arguments_but_got_1, rangeErrorAbove, argCount));
}
else diagnostics.add(createDiagnosticForNode(node, Diagnostics.Expected_at_least_0_arguments_but_got_1, min, argCount));
}
else { // there are both signatures taking less and more arguments
if (contiguousBelow) {
if (contiguousAbove && !hasRestParameter) {
diagnostics.add(createDiagnosticForNode(node, Diagnostics.Expected_0_or_1_arguments_but_got_2, rangeErrorBelow, rangeErrorAbove, argCount));
}
else diagnostics.add(createDiagnosticForNode(node, Diagnostics.No_overload_expects_0_arguments_The_most_likely_overloads_that_match_expect_either_1_arguments_or_at_least_2_arguments, argCount, rangeErrorBelow, minAboveArgCount));
else {
if (min < argCount && argCount < max) {
const maxBelowArgCount = lastOrUndefined(filter(availableArgumentCountsAscending, c => c < argCount));
const minAboveArgCount = firstOrUndefined(filter(availableArgumentCountsAscending, c => c > argCount));

diagnostics.add(createDiagnosticForNode(node, Diagnostics.No_overload_expects_0_arguments_The_most_likely_overloads_that_match_expect_either_1_arguments_or_at_least_2_arguments, argCount, maxBelowArgCount, minAboveArgCount));
}
else {
if (contiguousAbove && !hasRestParameter) {
diagnostics.add(createDiagnosticForNode(node, Diagnostics.No_overload_expects_0_arguments_The_most_likely_overloads_that_match_expect_either_up_to_1_arguments_or_2_arguments, argCount, maxBelowArgCount, rangeErrorAbove));
}
else diagnostics.add(createDiagnosticForNode(node, Diagnostics.No_overload_expects_0_arguments_The_most_likely_overloads_that_match_expect_either_up_to_1_arguments_or_at_least_2_arguments, argCount, maxBelowArgCount, minAboveArgCount));
diagnostics.add(createDiagnosticForNode(node, Diagnostics.Expected_0_arguments_but_got_1, paramCount, argCount));
}
}
}
Expand Down
18 changes: 1 addition & 17 deletions src/compiler/diagnosticMessages.json
Original file line number Diff line number Diff line change
Expand Up @@ -2024,25 +2024,9 @@
"category": "Error",
"code": 2570
},
"Expected no more than {0} arguments but got {1}.": {
"category": "Error",
"code": 2571
},
"Expected {0} or {1} arguments but got {2}.": {
"category": "Error",
"code": 2572
},
"No overload expects {0} arguments. The most likely overloads that match expect either {1} arguments or at least {2} arguments.": {
"category": "Error",
"code": 2573
},
"No overload expects {0} arguments. The most likely overloads that match expect either up to {1} arguments or {2} arguments.": {
"category": "Error",
"code": 2574
},
"No overload expects {0} arguments. The most likely overloads that match expect either up to {1} arguments or at least {2} arguments.": {
"category": "Error",
"code": 2575
"code": 2571
},
"JSX element attributes type '{0}' may not be a union type.": {
"category": "Error",
Expand Down
71 changes: 25 additions & 46 deletions tests/baselines/reference/functionParameterArityMismatch.errors.txt
Original file line number Diff line number Diff line change
@@ -1,60 +1,39 @@
tests/cases/compiler/functionParameterArityMismatch.ts(3,1): error TS2555: Expected at least 1 arguments, but got 0.
tests/cases/compiler/functionParameterArityMismatch.ts(4,1): error TS2572: Expected 1 or 3 arguments but got 2.
tests/cases/compiler/functionParameterArityMismatch.ts(5,1): error TS2571: Expected no more than 3 arguments but got 4.
tests/cases/compiler/functionParameterArityMismatch.ts(9,1): error TS2573: No overload expects 2 arguments. The most likely overloads that match expect either 0-1 arguments or at least 3 arguments.
tests/cases/compiler/functionParameterArityMismatch.ts(14,1): error TS2573: No overload expects 1 arguments. The most likely overloads that match expect either 0 arguments or at least 2 arguments.
tests/cases/compiler/functionParameterArityMismatch.ts(15,1): error TS2574: No overload expects 3 arguments. The most likely overloads that match expect either up to 2 arguments or 4-5 arguments.
tests/cases/compiler/functionParameterArityMismatch.ts(20,1): error TS2573: No overload expects 1 arguments. The most likely overloads that match expect either 0 arguments or at least 2 arguments.
tests/cases/compiler/functionParameterArityMismatch.ts(21,1): error TS2575: No overload expects 3 arguments. The most likely overloads that match expect either up to 2 arguments or at least 4 arguments.
tests/cases/compiler/functionParameterArityMismatch.ts(25,1): error TS2572: Expected 0-2 or 4-5 arguments but got 3.
tests/cases/compiler/functionParameterArityMismatch.ts(26,1): error TS2571: Expected no more than 5 arguments but got 6.
tests/cases/compiler/functionParameterArityMismatch.ts(3,1): error TS2554: Expected 1-3 arguments, but got 0.
tests/cases/compiler/functionParameterArityMismatch.ts(4,1): error TS2571: No overload expects 2 arguments. The most likely overloads that match expect either 1 arguments or at least 3 arguments.
tests/cases/compiler/functionParameterArityMismatch.ts(5,1): error TS2554: Expected 1-3 arguments, but got 4.
tests/cases/compiler/functionParameterArityMismatch.ts(11,1): error TS2571: No overload expects 1 arguments. The most likely overloads that match expect either 0 arguments or at least 2 arguments.
tests/cases/compiler/functionParameterArityMismatch.ts(12,1): error TS2571: No overload expects 3 arguments. The most likely overloads that match expect either 2 arguments or at least 4 arguments.
tests/cases/compiler/functionParameterArityMismatch.ts(13,1): error TS2571: No overload expects 5 arguments. The most likely overloads that match expect either 4 arguments or at least 6 arguments.
tests/cases/compiler/functionParameterArityMismatch.ts(14,1): error TS2554: Expected 0-6 arguments, but got 7.


==== tests/cases/compiler/functionParameterArityMismatch.ts (10 errors) ====
==== tests/cases/compiler/functionParameterArityMismatch.ts (7 errors) ====
declare function f1(a: number);
declare function f1(a: number, b: number, c: number);
f1();
~~~~
!!! error TS2555: Expected at least 1 arguments, but got 0.
!!! error TS2554: Expected 1-3 arguments, but got 0.
f1(1, 2);
~~~~~~~~
!!! error TS2572: Expected 1 or 3 arguments but got 2.
!!! error TS2571: No overload expects 2 arguments. The most likely overloads that match expect either 1 arguments or at least 3 arguments.
f1(1, 2, 3, 4);
~~~~~~~~~~~~~~
!!! error TS2571: Expected no more than 3 arguments but got 4.
!!! error TS2554: Expected 1-3 arguments, but got 4.

declare function f2(a?: number);
declare function f2(a: number, b: number, c: number, ...d: number[]);
f2(1, 2);
~~~~~~~~
!!! error TS2573: No overload expects 2 arguments. The most likely overloads that match expect either 0-1 arguments or at least 3 arguments.

declare function f3();
declare function f3(a: number, b: number);
declare function f3(a: number, b: number, c: number, d: number, e?: number);
f3(1);
declare function f2();
declare function f2(a: number, b: number);
declare function f2(a: number, b: number, c: number, d: number);
declare function f2(a: number, b: number, c: number, d: number, e: number, f: number);
f2(1);
~~~~~
!!! error TS2573: No overload expects 1 arguments. The most likely overloads that match expect either 0 arguments or at least 2 arguments.
f3(1, 2, 3);
~~~~~~~~~~~
!!! error TS2574: No overload expects 3 arguments. The most likely overloads that match expect either up to 2 arguments or 4-5 arguments.

declare function f4();
declare function f4(a: number, b: number);
declare function f4(a: number, b: number, c: number, d: number, ...e: number[]);
f4(1);
~~~~~
!!! error TS2573: No overload expects 1 arguments. The most likely overloads that match expect either 0 arguments or at least 2 arguments.
f4(1, 2, 3);
~~~~~~~~~~~
!!! error TS2575: No overload expects 3 arguments. The most likely overloads that match expect either up to 2 arguments or at least 4 arguments.

declare function f5(a?: number, b?: number);
declare function f5(a: number, b: number, c: number, d: number, e?: number);
f5(1, 2, 3);
!!! error TS2571: No overload expects 1 arguments. The most likely overloads that match expect either 0 arguments or at least 2 arguments.
f2(1, 2, 3);
~~~~~~~~~~~
!!! error TS2572: Expected 0-2 or 4-5 arguments but got 3.
f5(1, 2, 3, 4, 5, 6);
~~~~~~~~~~~~~~~~~~~~
!!! error TS2571: Expected no more than 5 arguments but got 6.
!!! error TS2571: No overload expects 3 arguments. The most likely overloads that match expect either 2 arguments or at least 4 arguments.
f2(1, 2, 3, 4, 5);
~~~~~~~~~~~~~~~~~
!!! error TS2571: No overload expects 5 arguments. The most likely overloads that match expect either 4 arguments or at least 6 arguments.
f2(1, 2, 3, 4, 5, 6, 7);
~~~~~~~~~~~~~~~~~~~~~~~
!!! error TS2554: Expected 0-6 arguments, but got 7.

39 changes: 12 additions & 27 deletions tests/baselines/reference/functionParameterArityMismatch.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,36 +5,21 @@ f1();
f1(1, 2);
f1(1, 2, 3, 4);

declare function f2(a?: number);
declare function f2(a: number, b: number, c: number, ...d: number[]);
f2(1, 2);

declare function f3();
declare function f3(a: number, b: number);
declare function f3(a: number, b: number, c: number, d: number, e?: number);
f3(1);
f3(1, 2, 3);

declare function f4();
declare function f4(a: number, b: number);
declare function f4(a: number, b: number, c: number, d: number, ...e: number[]);
f4(1);
f4(1, 2, 3);

declare function f5(a?: number, b?: number);
declare function f5(a: number, b: number, c: number, d: number, e?: number);
f5(1, 2, 3);
f5(1, 2, 3, 4, 5, 6);
declare function f2();
declare function f2(a: number, b: number);
declare function f2(a: number, b: number, c: number, d: number);
declare function f2(a: number, b: number, c: number, d: number, e: number, f: number);
f2(1);
f2(1, 2, 3);
f2(1, 2, 3, 4, 5);
f2(1, 2, 3, 4, 5, 6, 7);


//// [functionParameterArityMismatch.js]
f1();
f1(1, 2);
f1(1, 2, 3, 4);
f2(1, 2);
f3(1);
f3(1, 2, 3);
f4(1);
f4(1, 2, 3);
f5(1, 2, 3);
f5(1, 2, 3, 4, 5, 6);
f2(1);
f2(1, 2, 3);
f2(1, 2, 3, 4, 5);
f2(1, 2, 3, 4, 5, 6, 7);
Loading

0 comments on commit 9cf84de

Please sign in to comment.