Skip to content

Commit f7f95f8

Browse files
authored
Apply tsgo PR 1987 to tsgo-port (#62696)
1 parent 763d882 commit f7f95f8

File tree

39 files changed

+493
-453
lines changed

39 files changed

+493
-453
lines changed

src/compiler/checker.ts

Lines changed: 53 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5552,23 +5552,63 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
55525552
(name as string).charCodeAt(2) !== CharacterCodes.hash;
55535553
}
55545554

5555-
function getNamedMembers(members: SymbolTable): Symbol[] {
5556-
let result: Symbol[] | undefined;
5555+
function getNamedMembers(members: SymbolTable, container: Symbol | undefined): Symbol[] {
5556+
if (!TSGO_COMPAT) {
5557+
let result: Symbol[] | undefined;
5558+
members.forEach((symbol, id) => {
5559+
if (isNamedMember(symbol, id)) {
5560+
(result || (result = [])).push(symbol);
5561+
}
5562+
});
5563+
return result || emptyArray;
5564+
}
5565+
5566+
if (members.size === 0) {
5567+
return emptyArray;
5568+
}
5569+
5570+
// For classes and interfaces, we store explicitly declared members ahead of inherited members. This ensures we process
5571+
// explicitly declared members first in type relations, which is beneficial because explicitly declared members are more
5572+
// likely to contain discriminating differences. See for example https://github.com/microsoft/typescript-go/issues/1968.
5573+
let contained: Symbol[] | undefined;
5574+
if (container && container.flags & (SymbolFlags.Class | SymbolFlags.Interface)) {
5575+
members.forEach((symbol, id) => {
5576+
if (isNamedMember(symbol, id) && isDeclarationContainedBy(symbol, container)) {
5577+
contained = append(contained, symbol);
5578+
}
5579+
});
5580+
}
5581+
5582+
let nonContained: Symbol[] | undefined;
55575583
members.forEach((symbol, id) => {
5558-
if (isNamedMember(symbol, id)) {
5559-
(result || (result = [])).push(symbol);
5584+
if (isNamedMember(symbol, id) && (!container || !(container.flags & (SymbolFlags.Class | SymbolFlags.Interface)) || !isDeclarationContainedBy(symbol, container))) {
5585+
nonContained = append(nonContained, symbol);
55605586
}
55615587
});
5562-
sortSymbolsIfTSGoCompat(result);
5563-
return result || emptyArray;
5588+
5589+
contained?.sort(compareSymbols);
5590+
nonContained?.sort(compareSymbols);
5591+
return concatenate(contained, nonContained) || emptyArray;
5592+
5593+
function isDeclarationContainedBy(symbol: Symbol, container: Symbol): boolean {
5594+
const declaration = symbol.valueDeclaration;
5595+
if (declaration) {
5596+
return some(container.declarations, d => containedBy(declaration, d));
5597+
}
5598+
return false;
5599+
5600+
function containedBy(a: Node, b: Node): boolean {
5601+
return b.pos <= a.pos && b.end >= a.end;
5602+
}
5603+
}
55645604
}
55655605

55665606
function isNamedMember(member: Symbol, escapedName: __String) {
55675607
return !isReservedMemberName(escapedName) && symbolIsValue(member);
55685608
}
55695609

5570-
function getNamedOrIndexSignatureMembers(members: SymbolTable): Symbol[] {
5571-
const result = getNamedMembers(members);
5610+
function getNamedOrIndexSignatureMembers(members: SymbolTable, symbol: Symbol): Symbol[] {
5611+
const result = getNamedMembers(members, symbol);
55725612
const index = getIndexSymbolFromSymbolTable(members);
55735613
return index ? concatenate(result, [index]) : result;
55745614
}
@@ -5581,7 +5621,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
55815621
resolved.constructSignatures = constructSignatures;
55825622
resolved.indexInfos = indexInfos;
55835623
// This can loop back to getPropertyOfType() which would crash if `callSignatures` & `constructSignatures` are not initialized.
5584-
if (members !== emptySymbols) resolved.properties = getNamedMembers(members);
5624+
if (members !== emptySymbols) resolved.properties = getNamedMembers(members, type.symbol);
55855625
return resolved;
55865626
}
55875627

@@ -13689,7 +13729,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
1368913729
if (!(type as InterfaceTypeWithDeclaredMembers).declaredProperties) {
1369013730
const symbol = type.symbol;
1369113731
const members = getMembersOfSymbol(symbol);
13692-
(type as InterfaceTypeWithDeclaredMembers).declaredProperties = getNamedMembers(members);
13732+
(type as InterfaceTypeWithDeclaredMembers).declaredProperties = getNamedMembers(members, symbol);
1369313733
// Start with signatures at empty array in case of recursive types
1369413734
(type as InterfaceTypeWithDeclaredMembers).declaredCallSignatures = emptyArray;
1369513735
(type as InterfaceTypeWithDeclaredMembers).declaredConstructSignatures = emptyArray;
@@ -14565,7 +14605,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
1456514605
const classType = getDeclaredTypeOfClassOrInterface(symbol);
1456614606
const baseConstructorType = getBaseConstructorTypeOfClass(classType);
1456714607
if (baseConstructorType.flags & (TypeFlags.Object | TypeFlags.Intersection | TypeFlags.TypeVariable)) {
14568-
members = createSymbolTable(getNamedOrIndexSignatureMembers(members));
14608+
members = createSymbolTable(getNamedOrIndexSignatureMembers(members, symbol));
1456914609
addInheritedMembers(members, getPropertiesOfType(baseConstructorType));
1457014610
}
1457114611
else if (baseConstructorType === anyType) {
@@ -15028,7 +15068,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
1502815068
break;
1502915069
}
1503015070
}
15031-
type.resolvedProperties = getNamedMembers(members);
15071+
type.resolvedProperties = getNamedMembers(members, type.symbol);
1503215072
}
1503315073
return type.resolvedProperties;
1503415074
}
@@ -50033,7 +50073,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
5003350073
}
5003450074
});
5003550075
}
50036-
return getNamedMembers(propsByName);
50076+
return getNamedMembers(propsByName, /*container*/ undefined);
5003750077
}
5003850078

5003950079
function typeHasCallOrConstructSignatures(type: Type): boolean {

tests/baselines/reference/arrayAssignmentTest1.errors.txt

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
arrayAssignmentTest1.ts(46,5): error TS2741: Property 'IM1' is missing in type 'undefined[]' but required in type 'I1'.
22
arrayAssignmentTest1.ts(47,5): error TS2739: Type 'undefined[]' is missing the following properties from type 'C1': IM1, C1M1
3-
arrayAssignmentTest1.ts(48,5): error TS2739: Type 'undefined[]' is missing the following properties from type 'C2': IM1, C1M1, C2M1
3+
arrayAssignmentTest1.ts(48,5): error TS2739: Type 'undefined[]' is missing the following properties from type 'C2': C2M1, IM1, C1M1
44
arrayAssignmentTest1.ts(49,5): error TS2741: Property 'CM3M1' is missing in type 'undefined[]' but required in type 'C3'.
55
arrayAssignmentTest1.ts(60,1): error TS2322: Type 'C3[]' is not assignable to type 'I1[]'.
66
Property 'IM1' is missing in type 'C3' but required in type 'I1'.
@@ -11,9 +11,9 @@ arrayAssignmentTest1.ts(65,1): error TS2322: Type 'C3[]' is not assignable to ty
1111
arrayAssignmentTest1.ts(68,1): error TS2322: Type 'C1[]' is not assignable to type 'C2[]'.
1212
Property 'C2M1' is missing in type 'C1' but required in type 'C2'.
1313
arrayAssignmentTest1.ts(69,1): error TS2322: Type 'I1[]' is not assignable to type 'C2[]'.
14-
Type 'I1' is missing the following properties from type 'C2': C1M1, C2M1
14+
Type 'I1' is missing the following properties from type 'C2': C2M1, C1M1
1515
arrayAssignmentTest1.ts(70,1): error TS2322: Type 'C3[]' is not assignable to type 'C2[]'.
16-
Type 'C3' is missing the following properties from type 'C2': IM1, C1M1, C2M1
16+
Type 'C3' is missing the following properties from type 'C2': C2M1, IM1, C1M1
1717
arrayAssignmentTest1.ts(75,1): error TS2322: Type 'C2[]' is not assignable to type 'C3[]'.
1818
Property 'CM3M1' is missing in type 'C2' but required in type 'C3'.
1919
arrayAssignmentTest1.ts(76,1): error TS2322: Type 'C1[]' is not assignable to type 'C3[]'.
@@ -83,7 +83,7 @@ arrayAssignmentTest1.ts(85,1): error TS2740: Type 'I1' is missing the following
8383
!!! error TS2739: Type 'undefined[]' is missing the following properties from type 'C1': IM1, C1M1
8484
var c2_error: C2 = []; // should be an error - is
8585
~~~~~~~~
86-
!!! error TS2739: Type 'undefined[]' is missing the following properties from type 'C2': IM1, C1M1, C2M1
86+
!!! error TS2739: Type 'undefined[]' is missing the following properties from type 'C2': C2M1, IM1, C1M1
8787
var c3_error: C3 = []; // should be an error - is
8888
~~~~~~~~
8989
!!! error TS2741: Property 'CM3M1' is missing in type 'undefined[]' but required in type 'C3'.
@@ -125,11 +125,11 @@ arrayAssignmentTest1.ts(85,1): error TS2740: Type 'I1' is missing the following
125125
arr_c2 = arr_i1; // should be an error - subtype relationship - is
126126
~~~~~~
127127
!!! error TS2322: Type 'I1[]' is not assignable to type 'C2[]'.
128-
!!! error TS2322: Type 'I1' is missing the following properties from type 'C2': C1M1, C2M1
128+
!!! error TS2322: Type 'I1' is missing the following properties from type 'C2': C2M1, C1M1
129129
arr_c2 = arr_c3; // should be an error - is
130130
~~~~~~
131131
!!! error TS2322: Type 'C3[]' is not assignable to type 'C2[]'.
132-
!!! error TS2322: Type 'C3' is missing the following properties from type 'C2': IM1, C1M1, C2M1
132+
!!! error TS2322: Type 'C3' is missing the following properties from type 'C2': C2M1, IM1, C1M1
133133

134134
// "clean up bug" occurs at this point
135135
// if you move these three expressions to another file, they raise an error

tests/baselines/reference/assignmentCompatWithCallSignatures3.errors.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ assignmentCompatWithCallSignatures3.ts(80,1): error TS2322: Type '(x: Base[], y:
4646
Types of parameters 'y' and 'y' are incompatible.
4747
Type 'T' is not assignable to type 'Derived2[]'.
4848
Type 'Base[]' is not assignable to type 'Derived2[]'.
49-
Type 'Base' is missing the following properties from type 'Derived2': bar, baz
49+
Type 'Base' is missing the following properties from type 'Derived2': baz, bar
5050
assignmentCompatWithCallSignatures3.ts(83,1): error TS2322: Type '(x: Base[], y: Derived[]) => Derived[]' is not assignable to type '<T extends Array<Derived>>(x: Base[], y: T) => T'.
5151
Type 'Derived[]' is not assignable to type 'T'.
5252
'Derived[]' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'Derived[]'.
@@ -208,7 +208,7 @@ assignmentCompatWithCallSignatures3.ts(86,1): error TS2322: Type '(x: { a: strin
208208
!!! error TS2322: Types of parameters 'y' and 'y' are incompatible.
209209
!!! error TS2322: Type 'T' is not assignable to type 'Derived2[]'.
210210
!!! error TS2322: Type 'Base[]' is not assignable to type 'Derived2[]'.
211-
!!! error TS2322: Type 'Base' is missing the following properties from type 'Derived2': bar, baz
211+
!!! error TS2322: Type 'Base' is missing the following properties from type 'Derived2': baz, bar
212212
var b13: <T extends Array<Derived>>(x: Array<Base>, y: T) => T;
213213
a13 = b13; // ok
214214
b13 = a13; // ok

tests/baselines/reference/assignmentCompatWithConstructSignatures3.errors.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ assignmentCompatWithConstructSignatures3.ts(80,1): error TS2322: Type 'new (x: B
4646
Types of parameters 'y' and 'y' are incompatible.
4747
Type 'T' is not assignable to type 'Derived2[]'.
4848
Type 'Base[]' is not assignable to type 'Derived2[]'.
49-
Type 'Base' is missing the following properties from type 'Derived2': bar, baz
49+
Type 'Base' is missing the following properties from type 'Derived2': baz, bar
5050
assignmentCompatWithConstructSignatures3.ts(83,1): error TS2322: Type 'new (x: Base[], y: Derived[]) => Derived[]' is not assignable to type 'new <T extends Array<Derived>>(x: Base[], y: T) => T'.
5151
Type 'Derived[]' is not assignable to type 'T'.
5252
'Derived[]' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'Derived[]'.
@@ -208,7 +208,7 @@ assignmentCompatWithConstructSignatures3.ts(86,1): error TS2322: Type 'new (x: {
208208
!!! error TS2322: Types of parameters 'y' and 'y' are incompatible.
209209
!!! error TS2322: Type 'T' is not assignable to type 'Derived2[]'.
210210
!!! error TS2322: Type 'Base[]' is not assignable to type 'Derived2[]'.
211-
!!! error TS2322: Type 'Base' is missing the following properties from type 'Derived2': bar, baz
211+
!!! error TS2322: Type 'Base' is missing the following properties from type 'Derived2': baz, bar
212212
var b13: new <T extends Array<Derived>>(x: Array<Base>, y: T) => T;
213213
a13 = b13; // ok
214214
b13 = a13; // ok

tests/baselines/reference/assignmentCompatWithNumericIndexer.errors.txt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ assignmentCompatWithNumericIndexer.ts(14,1): error TS2322: Type 'A' is not assig
33
Property 'bar' is missing in type 'Base' but required in type 'Derived'.
44
assignmentCompatWithNumericIndexer.ts(18,1): error TS2322: Type 'A' is not assignable to type '{ [x: number]: Derived2; }'.
55
'number' index signatures are incompatible.
6-
Type 'Base' is missing the following properties from type 'Derived2': bar, baz
6+
Type 'Base' is missing the following properties from type 'Derived2': baz, bar
77
assignmentCompatWithNumericIndexer.ts(32,9): error TS2322: Type '{ [x: number]: Derived; }' is not assignable to type 'A<T>'.
88
'number' index signatures are incompatible.
99
Type 'Derived' is not assignable to type 'T'.
@@ -19,7 +19,7 @@ assignmentCompatWithNumericIndexer.ts(36,9): error TS2322: Type '{ [x: number]:
1919
assignmentCompatWithNumericIndexer.ts(37,9): error TS2322: Type 'A<T>' is not assignable to type '{ [x: number]: Derived2; }'.
2020
'number' index signatures are incompatible.
2121
Type 'T' is not assignable to type 'Derived2'.
22-
Type 'Base' is missing the following properties from type 'Derived2': bar, baz
22+
Type 'Base' is missing the following properties from type 'Derived2': baz, bar
2323

2424

2525
==== assignmentCompatWithNumericIndexer.ts (6 errors) ====
@@ -49,7 +49,7 @@ assignmentCompatWithNumericIndexer.ts(37,9): error TS2322: Type 'A<T>' is not as
4949
~~
5050
!!! error TS2322: Type 'A' is not assignable to type '{ [x: number]: Derived2; }'.
5151
!!! error TS2322: 'number' index signatures are incompatible.
52-
!!! error TS2322: Type 'Base' is missing the following properties from type 'Derived2': bar, baz
52+
!!! error TS2322: Type 'Base' is missing the following properties from type 'Derived2': baz, bar
5353

5454
module Generics {
5555
class A<T extends Base> {
@@ -89,7 +89,7 @@ assignmentCompatWithNumericIndexer.ts(37,9): error TS2322: Type 'A<T>' is not as
8989
!!! error TS2322: Type 'A<T>' is not assignable to type '{ [x: number]: Derived2; }'.
9090
!!! error TS2322: 'number' index signatures are incompatible.
9191
!!! error TS2322: Type 'T' is not assignable to type 'Derived2'.
92-
!!! error TS2322: Type 'Base' is missing the following properties from type 'Derived2': bar, baz
92+
!!! error TS2322: Type 'Base' is missing the following properties from type 'Derived2': baz, bar
9393

9494
var b3: { [x: number]: T; }
9595
a = b3; // ok

tests/baselines/reference/assignmentCompatWithNumericIndexer2.errors.txt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ assignmentCompatWithNumericIndexer2.ts(14,1): error TS2322: Type 'A' is not assi
33
Property 'bar' is missing in type 'Base' but required in type 'Derived'.
44
assignmentCompatWithNumericIndexer2.ts(18,1): error TS2322: Type 'A' is not assignable to type '{ [x: number]: Derived2; }'.
55
'number' index signatures are incompatible.
6-
Type 'Base' is missing the following properties from type 'Derived2': bar, baz
6+
Type 'Base' is missing the following properties from type 'Derived2': baz, bar
77
assignmentCompatWithNumericIndexer2.ts(32,9): error TS2322: Type '{ [x: number]: Derived; }' is not assignable to type 'A<T>'.
88
'number' index signatures are incompatible.
99
Type 'Derived' is not assignable to type 'T'.
@@ -19,7 +19,7 @@ assignmentCompatWithNumericIndexer2.ts(36,9): error TS2322: Type '{ [x: number]:
1919
assignmentCompatWithNumericIndexer2.ts(37,9): error TS2322: Type 'A<T>' is not assignable to type '{ [x: number]: Derived2; }'.
2020
'number' index signatures are incompatible.
2121
Type 'T' is not assignable to type 'Derived2'.
22-
Type 'Base' is missing the following properties from type 'Derived2': bar, baz
22+
Type 'Base' is missing the following properties from type 'Derived2': baz, bar
2323

2424

2525
==== assignmentCompatWithNumericIndexer2.ts (6 errors) ====
@@ -49,7 +49,7 @@ assignmentCompatWithNumericIndexer2.ts(37,9): error TS2322: Type 'A<T>' is not a
4949
~~
5050
!!! error TS2322: Type 'A' is not assignable to type '{ [x: number]: Derived2; }'.
5151
!!! error TS2322: 'number' index signatures are incompatible.
52-
!!! error TS2322: Type 'Base' is missing the following properties from type 'Derived2': bar, baz
52+
!!! error TS2322: Type 'Base' is missing the following properties from type 'Derived2': baz, bar
5353

5454
module Generics {
5555
interface A<T extends Base> {
@@ -89,7 +89,7 @@ assignmentCompatWithNumericIndexer2.ts(37,9): error TS2322: Type 'A<T>' is not a
8989
!!! error TS2322: Type 'A<T>' is not assignable to type '{ [x: number]: Derived2; }'.
9090
!!! error TS2322: 'number' index signatures are incompatible.
9191
!!! error TS2322: Type 'T' is not assignable to type 'Derived2'.
92-
!!! error TS2322: Type 'Base' is missing the following properties from type 'Derived2': bar, baz
92+
!!! error TS2322: Type 'Base' is missing the following properties from type 'Derived2': baz, bar
9393

9494
var b3: { [x: number]: T; }
9595
a = b3; // ok

0 commit comments

Comments
 (0)