do not reorder signatures from derived and base types
This commit is contained in:
parent
97987b1c3e
commit
236e24b468
|
@ -3793,21 +3793,40 @@ module ts {
|
|||
}
|
||||
|
||||
// The candidate list orders groups in reverse, but within a group signatures are kept in declaration order
|
||||
// A nit here is that we reorder only signatures that belong to the same symbol,
|
||||
// so order how inherited signatures are processed is still preserved.
|
||||
// interface A { (x: string): void }
|
||||
// interface B { (x: 'foo'): string }
|
||||
// var b: B;
|
||||
// b('foo') // <- here overloads should be processed as [(x:'foo'): string, (x: string): void]
|
||||
function collectCandidates(node: CallExpression, signatures: Signature[]): Signature[]{
|
||||
var result: Signature[] = [];
|
||||
var lastParent: Node;
|
||||
var lastSymbol: Symbol;
|
||||
var cutoffPos: number = 0;
|
||||
var pos: number;
|
||||
for (var i = 0; i < signatures.length; i++) {
|
||||
var signature = signatures[i];
|
||||
if (isCandidateSignature(node, signature)) {
|
||||
var parent = signature.declaration ? signature.declaration.parent : undefined;
|
||||
if (lastParent && parent === lastParent) {
|
||||
pos++;
|
||||
var symbol = signature.declaration && getSymbolOfNode(signature.declaration);
|
||||
var parent = signature.declaration && signature.declaration.parent;
|
||||
if (!lastSymbol || symbol === lastSymbol) {
|
||||
if (lastParent && parent === lastParent) {
|
||||
pos++;
|
||||
}
|
||||
else {
|
||||
lastParent = parent;
|
||||
pos = cutoffPos;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// current declaration belongs to a different symbol
|
||||
// set cutoffPos so reorderings in the future won't change result set from 0 to cutoffPos
|
||||
pos = cutoffPos = result.length;
|
||||
lastParent = parent;
|
||||
pos = 0;
|
||||
}
|
||||
lastSymbol = symbol;
|
||||
|
||||
for (var j = result.length; j > pos; j--) {
|
||||
result[j] = result[j - 1];
|
||||
}
|
||||
|
|
|
@ -0,0 +1,47 @@
|
|||
//// [inheritedOverloadedSpecializedSignatures.ts]
|
||||
interface A {
|
||||
(key:string):void;
|
||||
}
|
||||
|
||||
interface B extends A {
|
||||
(key:'foo'):string;
|
||||
}
|
||||
|
||||
var b:B;
|
||||
// Should not error
|
||||
b('foo').charAt(0);
|
||||
|
||||
interface A {
|
||||
(x: 'A1'): string;
|
||||
(x: string): void;
|
||||
}
|
||||
|
||||
interface B extends A {
|
||||
(x: 'B1'): number;
|
||||
}
|
||||
|
||||
interface A {
|
||||
(x: 'A2'): boolean;
|
||||
}
|
||||
|
||||
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');
|
||||
|
||||
//// [inheritedOverloadedSpecializedSignatures.js]
|
||||
var b;
|
||||
b('foo').charAt(0);
|
||||
var b;
|
||||
var x1 = b('B2');
|
||||
var x2 = b('B1');
|
||||
var x3 = b('A2');
|
||||
var x4 = b('A1');
|
||||
var x5 = b('A0');
|
|
@ -0,0 +1,36 @@
|
|||
interface A {
|
||||
(key:string):void;
|
||||
}
|
||||
|
||||
interface B extends A {
|
||||
(key:'foo'):string;
|
||||
}
|
||||
|
||||
var b:B;
|
||||
// Should not error
|
||||
b('foo').charAt(0);
|
||||
|
||||
interface A {
|
||||
(x: 'A1'): string;
|
||||
(x: string): void;
|
||||
}
|
||||
|
||||
interface B extends A {
|
||||
(x: 'B1'): number;
|
||||
}
|
||||
|
||||
interface A {
|
||||
(x: 'A2'): boolean;
|
||||
}
|
||||
|
||||
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');
|
Loading…
Reference in a new issue