Skip to content

Commit 435b44c

Browse files
committed
Put specialized signatures at the top of the list of call candidates
Fixes microsoft#1133.
1 parent edd3974 commit 435b44c

5 files changed

Lines changed: 140 additions & 43 deletions

File tree

src/compiler/checker.ts

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6112,6 +6112,8 @@ module ts {
61126112
var lastSymbol: Symbol;
61136113
var cutoffPos: number = 0;
61146114
var pos: number;
6115+
var specializedPos: number = -1;
6116+
var splicePos: number;
61156117
Debug.assert(!result.length);
61166118
for (var i = 0; i < signatures.length; i++) {
61176119
var signature = signatures[i];
@@ -6134,10 +6136,23 @@ module ts {
61346136
}
61356137
lastSymbol = symbol;
61366138

6137-
for (var j = result.length; j > pos; j--) {
6139+
// specialized signatures always need to be placed before non-specialized signatures regardless
6140+
// of the cutoff position; see GH#1133
6141+
if (signature.hasStringLiterals) {
6142+
splicePos = ++specializedPos;
6143+
// The cutoff position needs to be increased to account for the fact that we are adding things
6144+
// before the cutoff point. If the cutoff position is not incremented, merged interfaces will
6145+
// start adding their merged signatures at the wrong position
6146+
++cutoffPos;
6147+
}
6148+
else {
6149+
splicePos = pos;
6150+
}
6151+
6152+
for (var j = result.length; j > splicePos; j--) {
61386153
result[j] = result[j - 1];
61396154
}
6140-
result[pos] = signature;
6155+
result[splicePos] = signature;
61416156
}
61426157
}
61436158
}

tests/baselines/reference/inheritedOverloadedSpecializedSignatures.js

Lines changed: 35 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -28,22 +28,43 @@ interface B {
2828
(x: 'B2'): string[];
2929
}
3030

31-
var b: B;
32-
// non of these lines should error
33-
var x1: string[] = b('B2');
34-
var x2: number = b('B1');
35-
var x3: boolean = b('A2');
36-
var x4: string = b('A1');
37-
var x5: void = b('A0');
31+
interface C1 extends B {
32+
(x: 'C1'): number[];
33+
}
34+
35+
interface C2 extends B {
36+
(x: 'C2'): boolean[];
37+
}
38+
39+
interface C extends C1, C2 {
40+
(x: 'C'): string;
41+
}
42+
43+
var c: C;
44+
// none of these lines should error
45+
var x1: string[] = c('B2');
46+
var x2: number = c('B1');
47+
var x3: boolean = c('A2');
48+
var x4: string = c('A1');
49+
var x5: void = c('A0');
50+
var x6: number[] = c('C1');
51+
var x7: boolean[] = c('C2');
52+
var x8: string = c('C');
53+
var x9: void = c('generic');
54+
3855

3956
//// [inheritedOverloadedSpecializedSignatures.js]
4057
var b;
4158
// Should not error
4259
b('foo').charAt(0);
43-
var b;
44-
// non of these lines should error
45-
var x1 = b('B2');
46-
var x2 = b('B1');
47-
var x3 = b('A2');
48-
var x4 = b('A1');
49-
var x5 = b('A0');
60+
var c;
61+
// none of these lines should error
62+
var x1 = c('B2');
63+
var x2 = c('B1');
64+
var x3 = c('A2');
65+
var x4 = c('A1');
66+
var x5 = c('A0');
67+
var x6 = c('C1');
68+
var x7 = c('C2');
69+
var x8 = c('C');
70+
var x9 = c('generic');

tests/baselines/reference/inheritedOverloadedSpecializedSignatures.types

Lines changed: 63 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -58,33 +58,78 @@ interface B {
5858
>x : 'B2'
5959
}
6060

61-
var b: B;
62-
>b : B
61+
interface C1 extends B {
62+
>C1 : C1
63+
>B : B
64+
65+
(x: 'C1'): number[];
66+
>x : 'C1'
67+
}
68+
69+
interface C2 extends B {
70+
>C2 : C2
6371
>B : B
6472

65-
// non of these lines should error
66-
var x1: string[] = b('B2');
73+
(x: 'C2'): boolean[];
74+
>x : 'C2'
75+
}
76+
77+
interface C extends C1, C2 {
78+
>C : C
79+
>C1 : C1
80+
>C2 : C2
81+
82+
(x: 'C'): string;
83+
>x : 'C'
84+
}
85+
86+
var c: C;
87+
>c : C
88+
>C : C
89+
90+
// none of these lines should error
91+
var x1: string[] = c('B2');
6792
>x1 : string[]
68-
>b('B2') : string[]
69-
>b : B
93+
>c('B2') : string[]
94+
>c : C
7095

71-
var x2: number = b('B1');
96+
var x2: number = c('B1');
7297
>x2 : number
73-
>b('B1') : number
74-
>b : B
98+
>c('B1') : number
99+
>c : C
75100

76-
var x3: boolean = b('A2');
101+
var x3: boolean = c('A2');
77102
>x3 : boolean
78-
>b('A2') : boolean
79-
>b : B
103+
>c('A2') : boolean
104+
>c : C
80105

81-
var x4: string = b('A1');
106+
var x4: string = c('A1');
82107
>x4 : string
83-
>b('A1') : string
84-
>b : B
108+
>c('A1') : string
109+
>c : C
85110

86-
var x5: void = b('A0');
111+
var x5: void = c('A0');
87112
>x5 : void
88-
>b('A0') : void
89-
>b : B
113+
>c('A0') : void
114+
>c : C
115+
116+
var x6: number[] = c('C1');
117+
>x6 : number[]
118+
>c('C1') : number[]
119+
>c : C
120+
121+
var x7: boolean[] = c('C2');
122+
>x7 : boolean[]
123+
>c('C2') : boolean[]
124+
>c : C
125+
126+
var x8: string = c('C');
127+
>x8 : string
128+
>c('C') : string
129+
>c : C
130+
131+
var x9: void = c('generic');
132+
>x9 : void
133+
>c('generic') : void
134+
>c : C
90135

tests/cases/compiler/inheritedOverloadedSpecializedSignatures.ts

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,26 @@ interface B {
2727
(x: 'B2'): string[];
2828
}
2929

30-
var b: B;
31-
// non of these lines should error
32-
var x1: string[] = b('B2');
33-
var x2: number = b('B1');
34-
var x3: boolean = b('A2');
35-
var x4: string = b('A1');
36-
var x5: void = b('A0');
30+
interface C1 extends B {
31+
(x: 'C1'): number[];
32+
}
33+
34+
interface C2 extends B {
35+
(x: 'C2'): boolean[];
36+
}
37+
38+
interface C extends C1, C2 {
39+
(x: 'C'): string;
40+
}
41+
42+
var c: C;
43+
// none of these lines should error
44+
var x1: string[] = c('B2');
45+
var x2: number = c('B1');
46+
var x3: boolean = c('A2');
47+
var x4: string = c('A1');
48+
var x5: void = c('A0');
49+
var x6: number[] = c('C1');
50+
var x7: boolean[] = c('C2');
51+
var x8: string = c('C');
52+
var x9: void = c('generic');

tests/cases/fourslash/overloadOnConstCallSignature.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@
1111

1212
goTo.marker('1');
1313
verify.signatureHelpCountIs(4);
14-
verify.currentSignatureHelpIs('foo(name: string): string');
14+
verify.currentSignatureHelpIs('foo(name: \'order\'): string');
1515
edit.insert('"hi"');
1616

1717
goTo.marker('2');
18-
verify.quickInfoIs('(var) x: string');
18+
verify.quickInfoIs('(var) x: string');

0 commit comments

Comments
 (0)