diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index f8c4caa9630..2f16de1b1c1 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -6112,6 +6112,8 @@ module ts { var lastSymbol: Symbol; var cutoffPos: number = 0; var pos: number; + var specializedPos: number = -1; + var splicePos: number; Debug.assert(!result.length); for (var i = 0; i < signatures.length; i++) { var signature = signatures[i]; @@ -6134,10 +6136,23 @@ module ts { } lastSymbol = symbol; - for (var j = result.length; j > pos; j--) { + // specialized signatures always need to be placed before non-specialized signatures regardless + // of the cutoff position; see GH#1133 + if (signature.hasStringLiterals) { + splicePos = ++specializedPos; + // The cutoff position needs to be increased to account for the fact that we are adding things + // before the cutoff point. If the cutoff position is not incremented, merged interfaces will + // start adding their merged signatures at the wrong position + ++cutoffPos; + } + else { + splicePos = pos; + } + + for (var j = result.length; j > splicePos; j--) { result[j] = result[j - 1]; } - result[pos] = signature; + result[splicePos] = signature; } } } diff --git a/tests/baselines/reference/inheritedOverloadedSpecializedSignatures.js b/tests/baselines/reference/inheritedOverloadedSpecializedSignatures.js index 792c9232fa2..da16ad0d0e5 100644 --- a/tests/baselines/reference/inheritedOverloadedSpecializedSignatures.js +++ b/tests/baselines/reference/inheritedOverloadedSpecializedSignatures.js @@ -28,22 +28,43 @@ interface B { (x: 'B2'): string[]; } -var b: B; -// non of these lines should error -var x1: string[] = b('B2'); -var x2: number = b('B1'); -var x3: boolean = b('A2'); -var x4: string = b('A1'); -var x5: void = b('A0'); +interface C1 extends B { + (x: 'C1'): number[]; +} + +interface C2 extends B { + (x: 'C2'): boolean[]; +} + +interface C extends C1, C2 { + (x: 'C'): string; +} + +var c: C; +// none of these lines should error +var x1: string[] = c('B2'); +var x2: number = c('B1'); +var x3: boolean = c('A2'); +var x4: string = c('A1'); +var x5: void = c('A0'); +var x6: number[] = c('C1'); +var x7: boolean[] = c('C2'); +var x8: string = c('C'); +var x9: void = c('generic'); + //// [inheritedOverloadedSpecializedSignatures.js] var b; // Should not error b('foo').charAt(0); -var b; -// non of these lines should error -var x1 = b('B2'); -var x2 = b('B1'); -var x3 = b('A2'); -var x4 = b('A1'); -var x5 = b('A0'); +var c; +// none of these lines should error +var x1 = c('B2'); +var x2 = c('B1'); +var x3 = c('A2'); +var x4 = c('A1'); +var x5 = c('A0'); +var x6 = c('C1'); +var x7 = c('C2'); +var x8 = c('C'); +var x9 = c('generic'); diff --git a/tests/baselines/reference/inheritedOverloadedSpecializedSignatures.types b/tests/baselines/reference/inheritedOverloadedSpecializedSignatures.types index 0284fa4bc43..dcbab74b681 100644 --- a/tests/baselines/reference/inheritedOverloadedSpecializedSignatures.types +++ b/tests/baselines/reference/inheritedOverloadedSpecializedSignatures.types @@ -58,33 +58,78 @@ interface B { >x : 'B2' } -var b: B; ->b : B +interface C1 extends B { +>C1 : C1 >B : B -// non of these lines should error -var x1: string[] = b('B2'); + (x: 'C1'): number[]; +>x : 'C1' +} + +interface C2 extends B { +>C2 : C2 +>B : B + + (x: 'C2'): boolean[]; +>x : 'C2' +} + +interface C extends C1, C2 { +>C : C +>C1 : C1 +>C2 : C2 + + (x: 'C'): string; +>x : 'C' +} + +var c: C; +>c : C +>C : C + +// none of these lines should error +var x1: string[] = c('B2'); >x1 : string[] ->b('B2') : string[] ->b : B +>c('B2') : string[] +>c : C -var x2: number = b('B1'); +var x2: number = c('B1'); >x2 : number ->b('B1') : number ->b : B +>c('B1') : number +>c : C -var x3: boolean = b('A2'); +var x3: boolean = c('A2'); >x3 : boolean ->b('A2') : boolean ->b : B +>c('A2') : boolean +>c : C -var x4: string = b('A1'); +var x4: string = c('A1'); >x4 : string ->b('A1') : string ->b : B +>c('A1') : string +>c : C -var x5: void = b('A0'); +var x5: void = c('A0'); >x5 : void ->b('A0') : void ->b : B +>c('A0') : void +>c : C + +var x6: number[] = c('C1'); +>x6 : number[] +>c('C1') : number[] +>c : C + +var x7: boolean[] = c('C2'); +>x7 : boolean[] +>c('C2') : boolean[] +>c : C + +var x8: string = c('C'); +>x8 : string +>c('C') : string +>c : C + +var x9: void = c('generic'); +>x9 : void +>c('generic') : void +>c : C diff --git a/tests/cases/compiler/inheritedOverloadedSpecializedSignatures.ts b/tests/cases/compiler/inheritedOverloadedSpecializedSignatures.ts index c513cecb2cb..03a433382ce 100644 --- a/tests/cases/compiler/inheritedOverloadedSpecializedSignatures.ts +++ b/tests/cases/compiler/inheritedOverloadedSpecializedSignatures.ts @@ -27,10 +27,26 @@ interface B { (x: 'B2'): string[]; } -var b: B; -// non of these lines should error -var x1: string[] = b('B2'); -var x2: number = b('B1'); -var x3: boolean = b('A2'); -var x4: string = b('A1'); -var x5: void = b('A0'); \ No newline at end of file +interface C1 extends B { + (x: 'C1'): number[]; +} + +interface C2 extends B { + (x: 'C2'): boolean[]; +} + +interface C extends C1, C2 { + (x: 'C'): string; +} + +var c: C; +// none of these lines should error +var x1: string[] = c('B2'); +var x2: number = c('B1'); +var x3: boolean = c('A2'); +var x4: string = c('A1'); +var x5: void = c('A0'); +var x6: number[] = c('C1'); +var x7: boolean[] = c('C2'); +var x8: string = c('C'); +var x9: void = c('generic'); diff --git a/tests/cases/fourslash/overloadOnConstCallSignature.ts b/tests/cases/fourslash/overloadOnConstCallSignature.ts index 52e0f3c02e0..7e8075e3652 100644 --- a/tests/cases/fourslash/overloadOnConstCallSignature.ts +++ b/tests/cases/fourslash/overloadOnConstCallSignature.ts @@ -11,8 +11,8 @@ goTo.marker('1'); verify.signatureHelpCountIs(4); -verify.currentSignatureHelpIs('foo(name: string): string'); +verify.currentSignatureHelpIs('foo(name: \'order\'): string'); edit.insert('"hi"'); goTo.marker('2'); -verify.quickInfoIs('(var) x: string'); \ No newline at end of file +verify.quickInfoIs('(var) x: string');