Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sort symbol members #61420

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 40 additions & 6 deletions src/compiler/checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ import {
classOrConstructorParameterIsDecorated,
ClassStaticBlockDeclaration,
clear,
compareComparableValues,
compareDiagnostics,
comparePaths,
compareValues,
Expand Down Expand Up @@ -1492,6 +1493,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {

var scanner: Scanner | undefined;

var fileIndexMap = new Map(host.getSourceFiles().map((file, i) => [file, i]));

var Symbol = objectAllocator.getSymbolConstructor();
var Type = objectAllocator.getTypeConstructor();
var Signature = objectAllocator.getSignatureConstructor();
Expand Down Expand Up @@ -5467,6 +5470,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
(result || (result = [])).push(symbol);
}
});
result?.sort(compareSymbols);
return result || emptyArray;
}

Expand Down Expand Up @@ -34524,18 +34528,15 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
// So the table *contains* `x` but `x` isn't actually in scope.
// However, resolveNameHelper will continue and call this callback again, so we'll eventually get a correct suggestion.
if (symbol) return symbol;
let candidates: Symbol[];
let candidates = arrayFrom(symbols.values()).sort(compareSymbols);
if (symbols === globals) {
const primitives = mapDefined(
["string", "number", "boolean", "object", "bigint", "symbol"],
s => symbols.has((s.charAt(0).toUpperCase() + s.slice(1)) as __String)
? createSymbol(SymbolFlags.TypeAlias, s as __String) as Symbol
: undefined,
);
candidates = primitives.concat(arrayFrom(symbols.values()));
}
else {
candidates = arrayFrom(symbols.values());
candidates = concatenate(candidates, primitives);
}
return getSpellingSuggestionForName(unescapeLeadingUnderscores(name), candidates, meaning);
}
Expand All @@ -34546,7 +34547,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
}

function getSuggestedSymbolForNonexistentModule(name: Identifier, targetModule: Symbol): Symbol | undefined {
return targetModule.exports && getSpellingSuggestionForName(idText(name), getExportsOfModuleAsArray(targetModule), SymbolFlags.ModuleMember);
return targetModule.exports && getSpellingSuggestionForName(idText(name), getExportsOfModuleAsArray(targetModule).sort(compareSymbols), SymbolFlags.ModuleMember); // eslint-disable-line local/no-array-mutating-method-expressions
}

function getSuggestionForNonexistentIndexSignature(objectType: Type, expr: ElementAccessExpression, keyedType: Type): string | undefined {
Expand Down Expand Up @@ -52817,6 +52818,39 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
Debug.assert(specifier && nodeIsSynthesized(specifier) && specifier.text === "tslib", `Expected sourceFile.imports[0] to be the synthesized tslib import`);
return specifier;
}

function compareSymbols(s1: Symbol | undefined, s2: Symbol | undefined): number {
if (s1 === s2) return 0;
if (s1 === undefined) return 1;
if (s2 === undefined) return -1;
if (length(s1.declarations) !== 0 && length(s2.declarations) !== 0) {
const r = compareNodes(s1.declarations![0], s2.declarations![0]);
if (r !== 0) return r;
}
else if (length(s1.declarations) !== 0) {
return -1;
}
else if (length(s2.declarations) !== 0) {
return 1;
}
const r = compareComparableValues(s1.escapedName as string, s2.escapedName as string);
if (r !== 0) return r;
return getSymbolId(s1) - getSymbolId(s2);
}

function compareNodes(n1: Node | undefined, n2: Node | undefined): number {
if (n1 === n2) return 0;
if (n1 === undefined) return 1;
if (n2 === undefined) return -1;
const f1 = fileIndexMap.get(getSourceFileOfNode(n1))!;
const f2 = fileIndexMap.get(getSourceFileOfNode(n2))!;
if (f1 !== f2) {
// Order by index of file in the containing program
return f1 - f2;
}
// In the same file, order by source position
return n1.pos - n2.pos;
}
}

function isNotAccessor(declaration: Declaration): boolean {
Expand Down
8 changes: 5 additions & 3 deletions src/compiler/core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1967,9 +1967,11 @@ export function equateStringsCaseSensitive(a: string, b: string): boolean {
return equateValues(a, b);
}

function compareComparableValues(a: string | undefined, b: string | undefined): Comparison;
function compareComparableValues(a: number | undefined, b: number | undefined): Comparison;
function compareComparableValues(a: string | number | undefined, b: string | number | undefined) {
/** @internal */
export function compareComparableValues(a: string | undefined, b: string | undefined): Comparison;
/** @internal */
export function compareComparableValues(a: number | undefined, b: number | undefined): Comparison;
export function compareComparableValues(a: string | number | undefined, b: string | number | undefined) {
return a === b ? Comparison.EqualTo :
a === undefined ? Comparison.LessThan :
b === undefined ? Comparison.GreaterThan :
Expand Down
20 changes: 12 additions & 8 deletions tests/baselines/reference/arityAndOrderCompatibility01.errors.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,16 @@ arityAndOrderCompatibility01.ts(23,5): error TS2322: Type '{ 0: string; 1: numbe
arityAndOrderCompatibility01.ts(24,5): error TS2322: Type '[string, number]' is not assignable to type '[number]'.
Source has 2 element(s) but target allows only 1.
arityAndOrderCompatibility01.ts(25,5): error TS2322: Type 'StrNum' is not assignable to type '[number]'.
Types of property '0' are incompatible.
Type 'string' is not assignable to type 'number'.
The types returned by 'pop()' are incompatible between these types.
Type 'string | number' is not assignable to type 'number'.
Type 'string' is not assignable to type 'number'.
arityAndOrderCompatibility01.ts(26,5): error TS2322: Type '{ 0: string; 1: number; length: 2; }' is not assignable to type '[number]'.
arityAndOrderCompatibility01.ts(27,5): error TS2322: Type '[string, number]' is not assignable to type '[string]'.
Source has 2 element(s) but target allows only 1.
arityAndOrderCompatibility01.ts(28,5): error TS2322: Type 'StrNum' is not assignable to type '[string]'.
Types of property 'length' are incompatible.
Type '2' is not assignable to type '1'.
The types returned by 'pop()' are incompatible between these types.
Type 'string | number' is not assignable to type 'string'.
Type 'number' is not assignable to type 'string'.
arityAndOrderCompatibility01.ts(29,5): error TS2322: Type '{ 0: string; 1: number; length: 2; }' is not assignable to type '[string]'.
arityAndOrderCompatibility01.ts(30,5): error TS2322: Type '[string, number]' is not assignable to type '[number, string]'.
Type at position 0 in source is not compatible with type at position 0 in target.
Expand Down Expand Up @@ -78,8 +80,9 @@ arityAndOrderCompatibility01.ts(32,5): error TS2322: Type '{ 0: string; 1: numbe
var l2: [number] = y;
~~
!!! error TS2322: Type 'StrNum' is not assignable to type '[number]'.
!!! error TS2322: Types of property '0' are incompatible.
!!! error TS2322: Type 'string' is not assignable to type 'number'.
!!! error TS2322: The types returned by 'pop()' are incompatible between these types.
!!! error TS2322: Type 'string | number' is not assignable to type 'number'.
!!! error TS2322: Type 'string' is not assignable to type 'number'.
var l3: [number] = z;
~~
!!! error TS2322: Type '{ 0: string; 1: number; length: 2; }' is not assignable to type '[number]'.
Expand All @@ -90,8 +93,9 @@ arityAndOrderCompatibility01.ts(32,5): error TS2322: Type '{ 0: string; 1: numbe
var m2: [string] = y;
~~
!!! error TS2322: Type 'StrNum' is not assignable to type '[string]'.
!!! error TS2322: Types of property 'length' are incompatible.
!!! error TS2322: Type '2' is not assignable to type '1'.
!!! error TS2322: The types returned by 'pop()' are incompatible between these types.
!!! error TS2322: Type 'string | number' is not assignable to type 'string'.
!!! error TS2322: Type 'number' is not assignable to type 'string'.
var m3: [string] = z;
~~
!!! error TS2322: Type '{ 0: string; 1: number; length: 2; }' is not assignable to type '[string]'.
Expand Down
12 changes: 6 additions & 6 deletions tests/baselines/reference/arrayAssignmentTest1.errors.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
arrayAssignmentTest1.ts(46,5): error TS2741: Property 'IM1' is missing in type 'undefined[]' but required in type 'I1'.
arrayAssignmentTest1.ts(47,5): error TS2739: Type 'undefined[]' is missing the following properties from type 'C1': IM1, C1M1
arrayAssignmentTest1.ts(48,5): error TS2739: Type 'undefined[]' is missing the following properties from type 'C2': C2M1, IM1, C1M1
arrayAssignmentTest1.ts(48,5): error TS2739: Type 'undefined[]' is missing the following properties from type 'C2': IM1, C1M1, C2M1
arrayAssignmentTest1.ts(49,5): error TS2741: Property 'CM3M1' is missing in type 'undefined[]' but required in type 'C3'.
arrayAssignmentTest1.ts(60,1): error TS2322: Type 'C3[]' is not assignable to type 'I1[]'.
Property 'IM1' is missing in type 'C3' but required in type 'I1'.
Expand All @@ -11,9 +11,9 @@ arrayAssignmentTest1.ts(65,1): error TS2322: Type 'C3[]' is not assignable to ty
arrayAssignmentTest1.ts(68,1): error TS2322: Type 'C1[]' is not assignable to type 'C2[]'.
Property 'C2M1' is missing in type 'C1' but required in type 'C2'.
arrayAssignmentTest1.ts(69,1): error TS2322: Type 'I1[]' is not assignable to type 'C2[]'.
Type 'I1' is missing the following properties from type 'C2': C2M1, C1M1
Type 'I1' is missing the following properties from type 'C2': C1M1, C2M1
arrayAssignmentTest1.ts(70,1): error TS2322: Type 'C3[]' is not assignable to type 'C2[]'.
Type 'C3' is missing the following properties from type 'C2': C2M1, IM1, C1M1
Type 'C3' is missing the following properties from type 'C2': IM1, C1M1, C2M1
arrayAssignmentTest1.ts(75,1): error TS2322: Type 'C2[]' is not assignable to type 'C3[]'.
Property 'CM3M1' is missing in type 'C2' but required in type 'C3'.
arrayAssignmentTest1.ts(76,1): error TS2322: Type 'C1[]' is not assignable to type 'C3[]'.
Expand Down Expand Up @@ -83,7 +83,7 @@ arrayAssignmentTest1.ts(85,1): error TS2740: Type 'I1' is missing the following
!!! error TS2739: Type 'undefined[]' is missing the following properties from type 'C1': IM1, C1M1
var c2_error: C2 = []; // should be an error - is
~~~~~~~~
!!! error TS2739: Type 'undefined[]' is missing the following properties from type 'C2': C2M1, IM1, C1M1
!!! error TS2739: Type 'undefined[]' is missing the following properties from type 'C2': IM1, C1M1, C2M1
var c3_error: C3 = []; // should be an error - is
~~~~~~~~
!!! error TS2741: Property 'CM3M1' is missing in type 'undefined[]' but required in type 'C3'.
Expand Down Expand Up @@ -125,11 +125,11 @@ arrayAssignmentTest1.ts(85,1): error TS2740: Type 'I1' is missing the following
arr_c2 = arr_i1; // should be an error - subtype relationship - is
~~~~~~
!!! error TS2322: Type 'I1[]' is not assignable to type 'C2[]'.
!!! error TS2322: Type 'I1' is missing the following properties from type 'C2': C2M1, C1M1
!!! error TS2322: Type 'I1' is missing the following properties from type 'C2': C1M1, C2M1
arr_c2 = arr_c3; // should be an error - is
~~~~~~
!!! error TS2322: Type 'C3[]' is not assignable to type 'C2[]'.
!!! error TS2322: Type 'C3' is missing the following properties from type 'C2': C2M1, IM1, C1M1
!!! error TS2322: Type 'C3' is missing the following properties from type 'C2': IM1, C1M1, C2M1

// "clean up bug" occurs at this point
// if you move these three expressions to another file, they raise an error
Expand Down
4 changes: 2 additions & 2 deletions tests/baselines/reference/arrowFunctionExpressions.types
Original file line number Diff line number Diff line change
Expand Up @@ -175,9 +175,9 @@ var p9 = ({ a: { b = 1 } = { b: 1 } }) => { };
> : ^

var p10 = ([{ value, done }]) => { };
>p10 : ([{ value, done }]: [{ value: any; done: any; }]) => void
>p10 : ([{ value, done }]: [{ done: any; value: any; }]) => void
> : ^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>([{ value, done }]) => { } : ([{ value, done }]: [{ value: any; done: any; }]) => void
>([{ value, done }]) => { } : ([{ value, done }]: [{ done: any; value: any; }]) => void
> : ^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>value : any
> : ^^^
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ assignmentCompatWithCallSignatures3.ts(80,1): error TS2322: Type '(x: Base[], y:
Types of parameters 'y' and 'y' are incompatible.
Type 'T' is not assignable to type 'Derived2[]'.
Type 'Base[]' is not assignable to type 'Derived2[]'.
Type 'Base' is missing the following properties from type 'Derived2': baz, bar
Type 'Base' is missing the following properties from type 'Derived2': bar, baz
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'.
Type 'Derived[]' is not assignable to type 'T'.
'Derived[]' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'Derived[]'.
Expand Down Expand Up @@ -208,7 +208,7 @@ assignmentCompatWithCallSignatures3.ts(86,1): error TS2322: Type '(x: { a: strin
!!! error TS2322: Types of parameters 'y' and 'y' are incompatible.
!!! error TS2322: Type 'T' is not assignable to type 'Derived2[]'.
!!! error TS2322: Type 'Base[]' is not assignable to type 'Derived2[]'.
!!! error TS2322: Type 'Base' is missing the following properties from type 'Derived2': baz, bar
!!! error TS2322: Type 'Base' is missing the following properties from type 'Derived2': bar, baz
var b13: <T extends Array<Derived>>(x: Array<Base>, y: T) => T;
a13 = b13; // ok
b13 = a13; // ok
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ assignmentCompatWithConstructSignatures3.ts(80,1): error TS2322: Type 'new (x: B
Types of parameters 'y' and 'y' are incompatible.
Type 'T' is not assignable to type 'Derived2[]'.
Type 'Base[]' is not assignable to type 'Derived2[]'.
Type 'Base' is missing the following properties from type 'Derived2': baz, bar
Type 'Base' is missing the following properties from type 'Derived2': bar, baz
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'.
Type 'Derived[]' is not assignable to type 'T'.
'Derived[]' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'Derived[]'.
Expand Down Expand Up @@ -208,7 +208,7 @@ assignmentCompatWithConstructSignatures3.ts(86,1): error TS2322: Type 'new (x: {
!!! error TS2322: Types of parameters 'y' and 'y' are incompatible.
!!! error TS2322: Type 'T' is not assignable to type 'Derived2[]'.
!!! error TS2322: Type 'Base[]' is not assignable to type 'Derived2[]'.
!!! error TS2322: Type 'Base' is missing the following properties from type 'Derived2': baz, bar
!!! error TS2322: Type 'Base' is missing the following properties from type 'Derived2': bar, baz
var b13: new <T extends Array<Derived>>(x: Array<Base>, y: T) => T;
a13 = b13; // ok
b13 = a13; // ok
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ assignmentCompatWithNumericIndexer.ts(14,1): error TS2322: Type 'A' is not assig
Property 'bar' is missing in type 'Base' but required in type 'Derived'.
assignmentCompatWithNumericIndexer.ts(18,1): error TS2322: Type 'A' is not assignable to type '{ [x: number]: Derived2; }'.
'number' index signatures are incompatible.
Type 'Base' is missing the following properties from type 'Derived2': baz, bar
Type 'Base' is missing the following properties from type 'Derived2': bar, baz
assignmentCompatWithNumericIndexer.ts(32,9): error TS2322: Type '{ [x: number]: Derived; }' is not assignable to type 'A<T>'.
'number' index signatures are incompatible.
Type 'Derived' is not assignable to type 'T'.
Expand All @@ -19,7 +19,7 @@ assignmentCompatWithNumericIndexer.ts(36,9): error TS2322: Type '{ [x: number]:
assignmentCompatWithNumericIndexer.ts(37,9): error TS2322: Type 'A<T>' is not assignable to type '{ [x: number]: Derived2; }'.
'number' index signatures are incompatible.
Type 'T' is not assignable to type 'Derived2'.
Type 'Base' is missing the following properties from type 'Derived2': baz, bar
Type 'Base' is missing the following properties from type 'Derived2': bar, baz


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

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

var b3: { [x: number]: T; }
a = b3; // ok
Expand Down
Loading