Skip to content

Remove toSortedArray and toDeduplicatedSortedArray, use sort and sortAndDeduplicate #28214

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

Merged
2 commits merged into from
Oct 30, 2018
Merged
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
2 changes: 1 addition & 1 deletion src/compiler/commandLineParser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1146,7 +1146,7 @@ namespace ts {
}

/* @internal */
export function printHelp(optionsList: CommandLineOption[], syntaxPrefix = "") {
export function printHelp(optionsList: ReadonlyArray<CommandLineOption>, syntaxPrefix = "") {
const output: string[] = [];

// We want to align our "syntax" and "examples" commands to a certain margin.
Expand Down
20 changes: 13 additions & 7 deletions src/compiler/core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ namespace ts {
[index: string]: T;
}

export interface SortedReadonlyArray<T> extends ReadonlyArray<T> {
" __sortedArrayBrand": any;
}

export interface SortedArray<T> extends Array<T> {
" __sortedArrayBrand": any;
}
Expand Down Expand Up @@ -815,8 +819,8 @@ namespace ts {
/**
* Deduplicates an array that has already been sorted.
*/
function deduplicateSorted<T>(array: ReadonlyArray<T>, comparer: EqualityComparer<T> | Comparer<T>): T[] {
if (array.length === 0) return [];
function deduplicateSorted<T>(array: SortedReadonlyArray<T>, comparer: EqualityComparer<T> | Comparer<T>): SortedReadonlyArray<T> {
if (array.length === 0) return emptyArray as any as SortedReadonlyArray<T>;

let last = array[0];
const deduplicated: T[] = [last];
Expand All @@ -838,7 +842,7 @@ namespace ts {
deduplicated.push(last = next);
}

return deduplicated;
return deduplicated as any as SortedReadonlyArray<T>;
}

export function insertSorted<T>(array: SortedArray<T>, insert: T, compare: Comparer<T>): void {
Expand All @@ -853,8 +857,10 @@ namespace ts {
}
}

export function sortAndDeduplicate<T>(array: ReadonlyArray<T>, comparer: Comparer<T>, equalityComparer?: EqualityComparer<T>) {
return deduplicateSorted(sort(array, comparer), equalityComparer || comparer);
export function sortAndDeduplicate<T>(array: ReadonlyArray<string>): SortedReadonlyArray<string>;
export function sortAndDeduplicate<T>(array: ReadonlyArray<T>, comparer: Comparer<T>, equalityComparer?: EqualityComparer<T>): SortedReadonlyArray<T>;
export function sortAndDeduplicate<T>(array: ReadonlyArray<T>, comparer?: Comparer<T>, equalityComparer?: EqualityComparer<T>): SortedReadonlyArray<T> {
return deduplicateSorted(sort(array, comparer), equalityComparer || comparer || compareStringsCaseSensitive as any as Comparer<T>);
}

export function arrayIsEqualTo<T>(array1: ReadonlyArray<T> | undefined, array2: ReadonlyArray<T> | undefined, equalityComparer: (a: T, b: T, index: number) => boolean = equateValues): boolean {
Expand Down Expand Up @@ -1035,8 +1041,8 @@ namespace ts {
/**
* Returns a new sorted array.
*/
export function sort<T>(array: ReadonlyArray<T>, comparer: Comparer<T>): T[] {
return array.slice().sort(comparer);
export function sort<T>(array: ReadonlyArray<T>, comparer?: Comparer<T>): SortedReadonlyArray<T> {
return (array.length === 0 ? array : array.slice().sort(comparer)) as SortedReadonlyArray<T>;
}

export function arrayIterator<T>(array: ReadonlyArray<T>): Iterator<T> {
Expand Down
6 changes: 3 additions & 3 deletions src/compiler/program.ts
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ namespace ts {
};
}

export function getPreEmitDiagnostics(program: Program, sourceFile?: SourceFile, cancellationToken?: CancellationToken): Diagnostic[] {
export function getPreEmitDiagnostics(program: Program, sourceFile?: SourceFile, cancellationToken?: CancellationToken): ReadonlyArray<Diagnostic> {
const diagnostics = [
...program.getConfigFileParsingDiagnostics(),
...program.getOptionsDiagnostics(cancellationToken),
Expand Down Expand Up @@ -1817,7 +1817,7 @@ namespace ts {
return sourceFile.isDeclarationFile ? [] : getDeclarationDiagnosticsWorker(sourceFile, cancellationToken);
}

function getOptionsDiagnostics(): Diagnostic[] {
function getOptionsDiagnostics(): SortedReadonlyArray<Diagnostic> {
return sortAndDeduplicateDiagnostics(concatenate(
fileProcessingDiagnostics.getGlobalDiagnostics(),
concatenate(
Expand All @@ -1838,7 +1838,7 @@ namespace ts {
return diagnostics;
}

function getGlobalDiagnostics(): Diagnostic[] {
function getGlobalDiagnostics(): SortedReadonlyArray<Diagnostic> {
return sortAndDeduplicateDiagnostics(getDiagnosticsProducingTypeChecker().getGlobalDiagnostics().slice());
}

Expand Down
2 changes: 1 addition & 1 deletion src/compiler/utilities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ namespace ts {
return pathIsRelative(moduleName) || isRootedDiskPath(moduleName);
}

export function sortAndDeduplicateDiagnostics<T extends Diagnostic>(diagnostics: ReadonlyArray<T>): T[] {
export function sortAndDeduplicateDiagnostics<T extends Diagnostic>(diagnostics: ReadonlyArray<T>): SortedReadonlyArray<T> {
return sortAndDeduplicate<T>(diagnostics, compareDiagnostics);
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/harness/compiler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ namespace compiler {
private _inputs: documents.TextDocument[] = [];
private _inputsAndOutputs: collections.SortedMap<string, CompilationOutput>;

constructor(host: fakes.CompilerHost, options: ts.CompilerOptions, program: ts.Program | undefined, result: ts.EmitResult | undefined, diagnostics: ts.Diagnostic[]) {
constructor(host: fakes.CompilerHost, options: ts.CompilerOptions, program: ts.Program | undefined, result: ts.EmitResult | undefined, diagnostics: ReadonlyArray<ts.Diagnostic>) {
this.host = host;
this.program = program;
this.result = result;
Expand Down
4 changes: 0 additions & 4 deletions src/jsTyping/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,6 @@ declare namespace ts.server {
export type EventEndInstallTypes = "event::endInstallTypes";
export type EventInitializationFailed = "event::initializationFailed";

export interface SortedReadonlyArray<T> extends ReadonlyArray<T> {
" __sortedArrayBrand": any;
}

export interface TypingInstallerResponse {
readonly kind: ActionSet | ActionInvalidate | EventTypesRegistry | ActionPackageInstalled | ActionValueInspected | EventBeginInstallTypes | EventEndInstallTypes | EventInitializationFailed;
}
Expand Down
8 changes: 4 additions & 4 deletions src/server/project.ts
Original file line number Diff line number Diff line change
Expand Up @@ -554,7 +554,7 @@ namespace ts.server {
}

getExternalFiles(): SortedReadonlyArray<string> {
return toSortedArray(flatMapToMutable(this.plugins, plugin => {
return sort(flatMap(this.plugins, plugin => {
if (typeof plugin.module.getExternalFiles !== "function") return;
try {
return plugin.module.getExternalFiles(this);
Expand Down Expand Up @@ -871,7 +871,7 @@ namespace ts.server {
(result || (result = [])).push(...unResolved);
}
}
this.lastCachedUnresolvedImportsList = result ? toDeduplicatedSortedArray(result) : emptyArray;
this.lastCachedUnresolvedImportsList = result ? sortAndDeduplicate(result) : emptyArray;
}

this.projectService.typingsCache.enqueueInstallTypingsForProject(this, this.lastCachedUnresolvedImportsList, hasAddedorRemovedFiles);
Expand All @@ -888,7 +888,7 @@ namespace ts.server {

/*@internal*/
updateTypingFiles(typingFiles: SortedReadonlyArray<string>) {
enumerateInsertsAndDeletes(typingFiles, this.typingFiles, getStringComparer(!this.useCaseSensitiveFileNames()),
enumerateInsertsAndDeletes<string, string>(typingFiles, this.typingFiles, getStringComparer(!this.useCaseSensitiveFileNames()),
/*inserted*/ noop,
removed => this.detachScriptInfoFromProject(removed)
);
Expand Down Expand Up @@ -959,7 +959,7 @@ namespace ts.server {

const oldExternalFiles = this.externalFiles || emptyArray as SortedReadonlyArray<string>;
this.externalFiles = this.getExternalFiles();
enumerateInsertsAndDeletes(this.externalFiles, oldExternalFiles, getStringComparer(!this.useCaseSensitiveFileNames()),
enumerateInsertsAndDeletes<string, string>(this.externalFiles, oldExternalFiles, getStringComparer(!this.useCaseSensitiveFileNames()),
// Ensure a ScriptInfo is created for new external files. This is performed indirectly
// by the LSHost for files in the program when the program is retrieved above but
// the program doesn't contain external files so this must be done explicitly.
Expand Down
2 changes: 1 addition & 1 deletion src/server/typingsCache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ namespace ts.server {
}

updateTypingsForProject(projectName: string, compilerOptions: CompilerOptions, typeAcquisition: TypeAcquisition, unresolvedImports: SortedReadonlyArray<string>, newTypings: string[]) {
const typings = toSortedArray(newTypings);
const typings = sort(newTypings);
this.perProjectCache.set(projectName, {
compilerOptions,
typeAcquisition,
Expand Down
16 changes: 0 additions & 16 deletions src/server/utilities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -206,22 +206,6 @@ namespace ts.server {
}
}

export function toSortedArray(arr: string[]): SortedArray<string>;
export function toSortedArray<T>(arr: T[], comparer: Comparer<T>): SortedArray<T>;
export function toSortedArray<T>(arr: T[], comparer?: Comparer<T>): SortedArray<T> {
arr.sort(comparer);
return arr as SortedArray<T>;
}

export function toDeduplicatedSortedArray(arr: string[]): SortedArray<string> {
arr.sort();
filterMutate(arr, isNonDuplicateInSortedArray);
return arr as SortedArray<string>;
}
function isNonDuplicateInSortedArray<T>(value: T, index: number, array: T[]) {
return index === 0 || value !== array[index - 1];
}

const indentStr = "\n ";

/* @internal */
Expand Down
6 changes: 2 additions & 4 deletions src/testRunner/projectsRunner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -310,9 +310,7 @@ namespace project {
const program = ts.createProgram(getInputFiles(), compilerOptions, compilerHost);
const errors = ts.getPreEmitDiagnostics(program);

const emitResult = program.emit();
ts.addRange(errors, emitResult.diagnostics);
const sourceMapData = emitResult.sourceMaps;
const { sourceMaps: sourceMapData, diagnostics: emitDiagnostics } = program.emit();

// Clean up source map data that will be used in baselining
if (sourceMapData) {
Expand All @@ -329,7 +327,7 @@ namespace project {
configFileSourceFiles,
moduleKind,
program,
errors,
errors: ts.concatenate(errors, emitDiagnostics),
sourceMapData
};
}
Expand Down
2 changes: 1 addition & 1 deletion src/testRunner/unittests/tsserverProjectSystem.ts
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ namespace ts.projectSystem {
this.projectService.updateTypingsForProject(response);
}

enqueueInstallTypingsRequest(project: server.Project, typeAcquisition: TypeAcquisition, unresolvedImports: server.SortedReadonlyArray<string>) {
enqueueInstallTypingsRequest(project: server.Project, typeAcquisition: TypeAcquisition, unresolvedImports: SortedReadonlyArray<string>) {
const request = server.createInstallTypingsRequest(project, typeAcquisition, unresolvedImports, this.globalTypingsCacheLocation);
this.install(request);
}
Expand Down
6 changes: 3 additions & 3 deletions src/testRunner/unittests/typingsInstaller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,7 @@ namespace ts.projectSystem {
constructor() {
super(host, { typesRegistry: createTypesRegistry("jquery") });
}
enqueueInstallTypingsRequest(project: server.Project, typeAcquisition: TypeAcquisition, unresolvedImports: server.SortedReadonlyArray<string>) {
enqueueInstallTypingsRequest(project: server.Project, typeAcquisition: TypeAcquisition, unresolvedImports: SortedReadonlyArray<string>) {
enqueueIsCalled = true;
super.enqueueInstallTypingsRequest(project, typeAcquisition, unresolvedImports);
}
Expand Down Expand Up @@ -409,7 +409,7 @@ namespace ts.projectSystem {
constructor() {
super(host, { typesRegistry: createTypesRegistry("jquery") });
}
enqueueInstallTypingsRequest(project: server.Project, typeAcquisition: TypeAcquisition, unresolvedImports: server.SortedReadonlyArray<string>) {
enqueueInstallTypingsRequest(project: server.Project, typeAcquisition: TypeAcquisition, unresolvedImports: SortedReadonlyArray<string>) {
super.enqueueInstallTypingsRequest(project, typeAcquisition, unresolvedImports);
}
installWorker(_requestId: number, _args: string[], _cwd: string, cb: TI.RequestCompletedAction): void {
Expand Down Expand Up @@ -451,7 +451,7 @@ namespace ts.projectSystem {
constructor() {
super(host, { typesRegistry: createTypesRegistry("jquery") });
}
enqueueInstallTypingsRequest(project: server.Project, typeAcquisition: TypeAcquisition, unresolvedImports: server.SortedReadonlyArray<string>) {
enqueueInstallTypingsRequest(project: server.Project, typeAcquisition: TypeAcquisition, unresolvedImports: SortedReadonlyArray<string>) {
super.enqueueInstallTypingsRequest(project, typeAcquisition, unresolvedImports);
}
installWorker(_requestId: number, _args: string[], _cwd: string, cb: TI.RequestCompletedAction): void {
Expand Down
10 changes: 5 additions & 5 deletions tests/baselines/reference/api/tsserverlibrary.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ declare namespace ts {
interface MapLike<T> {
[index: string]: T;
}
interface SortedReadonlyArray<T> extends ReadonlyArray<T> {
" __sortedArrayBrand": any;
}
interface SortedArray<T> extends Array<T> {
" __sortedArrayBrand": any;
}
Expand Down Expand Up @@ -3126,7 +3129,7 @@ declare namespace ts {
/** Non-internal stuff goes here */
declare namespace ts {
function isExternalModuleNameRelative(moduleName: string): boolean;
function sortAndDeduplicateDiagnostics<T extends Diagnostic>(diagnostics: ReadonlyArray<T>): T[];
function sortAndDeduplicateDiagnostics<T extends Diagnostic>(diagnostics: ReadonlyArray<T>): SortedReadonlyArray<T>;
}
declare namespace ts {
function getDefaultLibFileName(options: CompilerOptions): string;
Expand Down Expand Up @@ -4153,7 +4156,7 @@ declare namespace ts {
function findConfigFile(searchPath: string, fileExists: (fileName: string) => boolean, configName?: string): string | undefined;
function resolveTripleslashReference(moduleName: string, containingFile: string): string;
function createCompilerHost(options: CompilerOptions, setParentNodes?: boolean): CompilerHost;
function getPreEmitDiagnostics(program: Program, sourceFile?: SourceFile, cancellationToken?: CancellationToken): Diagnostic[];
function getPreEmitDiagnostics(program: Program, sourceFile?: SourceFile, cancellationToken?: CancellationToken): ReadonlyArray<Diagnostic>;
interface FormatDiagnosticsHost {
getCurrentDirectory(): string;
getCanonicalFileName(fileName: string): string;
Expand Down Expand Up @@ -4457,9 +4460,6 @@ declare namespace ts.server {
type EventBeginInstallTypes = "event::beginInstallTypes";
type EventEndInstallTypes = "event::endInstallTypes";
type EventInitializationFailed = "event::initializationFailed";
interface SortedReadonlyArray<T> extends ReadonlyArray<T> {
" __sortedArrayBrand": any;
}
interface TypingInstallerResponse {
readonly kind: ActionSet | ActionInvalidate | EventTypesRegistry | ActionPackageInstalled | ActionValueInspected | EventBeginInstallTypes | EventEndInstallTypes | EventInitializationFailed;
}
Expand Down
10 changes: 5 additions & 5 deletions tests/baselines/reference/api/typescript.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ declare namespace ts {
interface MapLike<T> {
[index: string]: T;
}
interface SortedReadonlyArray<T> extends ReadonlyArray<T> {
" __sortedArrayBrand": any;
}
interface SortedArray<T> extends Array<T> {
" __sortedArrayBrand": any;
}
Expand Down Expand Up @@ -3126,7 +3129,7 @@ declare namespace ts {
/** Non-internal stuff goes here */
declare namespace ts {
function isExternalModuleNameRelative(moduleName: string): boolean;
function sortAndDeduplicateDiagnostics<T extends Diagnostic>(diagnostics: ReadonlyArray<T>): T[];
function sortAndDeduplicateDiagnostics<T extends Diagnostic>(diagnostics: ReadonlyArray<T>): SortedReadonlyArray<T>;
}
declare namespace ts {
function getDefaultLibFileName(options: CompilerOptions): string;
Expand Down Expand Up @@ -4153,7 +4156,7 @@ declare namespace ts {
function findConfigFile(searchPath: string, fileExists: (fileName: string) => boolean, configName?: string): string | undefined;
function resolveTripleslashReference(moduleName: string, containingFile: string): string;
function createCompilerHost(options: CompilerOptions, setParentNodes?: boolean): CompilerHost;
function getPreEmitDiagnostics(program: Program, sourceFile?: SourceFile, cancellationToken?: CancellationToken): Diagnostic[];
function getPreEmitDiagnostics(program: Program, sourceFile?: SourceFile, cancellationToken?: CancellationToken): ReadonlyArray<Diagnostic>;
interface FormatDiagnosticsHost {
getCurrentDirectory(): string;
getCanonicalFileName(fileName: string): string;
Expand Down Expand Up @@ -4457,9 +4460,6 @@ declare namespace ts.server {
type EventBeginInstallTypes = "event::beginInstallTypes";
type EventEndInstallTypes = "event::endInstallTypes";
type EventInitializationFailed = "event::initializationFailed";
interface SortedReadonlyArray<T> extends ReadonlyArray<T> {
" __sortedArrayBrand": any;
}
interface TypingInstallerResponse {
readonly kind: ActionSet | ActionInvalidate | EventTypesRegistry | ActionPackageInstalled | ActionValueInspected | EventBeginInstallTypes | EventEndInstallTypes | EventInitializationFailed;
}
Expand Down