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

Migrate maps and sets #39264

Merged
merged 4 commits into from
Jul 13, 2020
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
20 changes: 20 additions & 0 deletions src/compat/deprecations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1321,4 +1321,24 @@ namespace ts {
});

// #endregion Renamed node Tests

// DEPRECATION: Renamed `Map` and `ReadonlyMap` interfaces
// DEPRECATION PLAN:
// - soft: 4.0
// - remove: TBD (will remove for at least one release before replacing with `ESMap`/`ReadonlyESMap`)
// - replace: TBD (will eventually replace with `ESMap`/`ReadonlyESMap`)
// #region Renamed `Map` and `ReadonlyMap` interfaces

/**
* @deprecated Use `ts.ReadonlyESMap<K, V>` instead.
*/
export interface ReadonlyMap<T> extends ReadonlyESMap<string, T> {
}

/**
* @deprecated Use `ts.ESMap<K, V>` instead.
*/
export interface Map<T> extends ESMap<string, T> { }

// #endregion
}
10 changes: 5 additions & 5 deletions src/compiler/binder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,7 @@ namespace ts {
let symbolCount = 0;

let Symbol: new (flags: SymbolFlags, name: __String) => Symbol;
let classifiableNames: UnderscoreEscapedMap<true>;
let classifiableNames: Set<__String>;

const unreachableFlow: FlowNode = { flags: FlowFlags.Unreachable };
const reportedUnreachableFlow: FlowNode = { flags: FlowFlags.Unreachable };
Expand All @@ -237,7 +237,7 @@ namespace ts {
options = opts;
languageVersion = getEmitScriptTarget(options);
inStrictMode = bindInStrictMode(file, opts);
classifiableNames = createUnderscoreEscapedMap<true>();
classifiableNames = new Set();
symbolCount = 0;

Symbol = objectAllocator.getSymbolConstructor();
Expand Down Expand Up @@ -445,7 +445,7 @@ namespace ts {
symbol = symbolTable.get(name);

if (includes & SymbolFlags.Classifiable) {
classifiableNames.set(name, true);
classifiableNames.add(name);
}

if (!symbol) {
Expand Down Expand Up @@ -1965,7 +1965,7 @@ namespace ts {
}

if (inStrictMode && !isAssignmentTarget(node)) {
const seen = createUnderscoreEscapedMap<ElementKind>();
const seen = new Map<__String, ElementKind>();

for (const prop of node.properties) {
if (prop.kind === SyntaxKind.SpreadAssignment || prop.name.kind !== SyntaxKind.Identifier) {
Expand Down Expand Up @@ -3143,7 +3143,7 @@ namespace ts {
bindAnonymousDeclaration(node, SymbolFlags.Class, bindingName);
// Add name of class expression into the map for semantic classifier
if (node.name) {
classifiableNames.set(node.name.escapedText, true);
classifiableNames.add(node.name.escapedText);
}
}

Expand Down
230 changes: 116 additions & 114 deletions src/compiler/checker.ts

Large diffs are not rendered by default.

48 changes: 24 additions & 24 deletions src/compiler/commandLineParser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,33 +83,33 @@ namespace ts {
export const optionsForWatch: CommandLineOption[] = [
{
name: "watchFile",
type: createMapFromTemplate({
type: new Map(getEntries({
fixedpollinginterval: WatchFileKind.FixedPollingInterval,
prioritypollinginterval: WatchFileKind.PriorityPollingInterval,
dynamicprioritypolling: WatchFileKind.DynamicPriorityPolling,
usefsevents: WatchFileKind.UseFsEvents,
usefseventsonparentdirectory: WatchFileKind.UseFsEventsOnParentDirectory,
}),
})),
category: Diagnostics.Advanced_Options,
description: Diagnostics.Specify_strategy_for_watching_file_Colon_FixedPollingInterval_default_PriorityPollingInterval_DynamicPriorityPolling_UseFsEvents_UseFsEventsOnParentDirectory,
},
{
name: "watchDirectory",
type: createMapFromTemplate({
type: new Map(getEntries({
usefsevents: WatchDirectoryKind.UseFsEvents,
fixedpollinginterval: WatchDirectoryKind.FixedPollingInterval,
dynamicprioritypolling: WatchDirectoryKind.DynamicPriorityPolling,
}),
})),
category: Diagnostics.Advanced_Options,
description: Diagnostics.Specify_strategy_for_watching_directory_on_platforms_that_don_t_support_recursive_watching_natively_Colon_UseFsEvents_default_FixedPollingInterval_DynamicPriorityPolling,
},
{
name: "fallbackPolling",
type: createMapFromTemplate({
type: new Map(getEntries({
fixedinterval: PollingWatchKind.FixedInterval,
priorityinterval: PollingWatchKind.PriorityInterval,
dynamicpriority: PollingWatchKind.DynamicPriority,
}),
})),
category: Diagnostics.Advanced_Options,
description: Diagnostics.Specify_strategy_for_creating_a_polling_watch_when_it_fails_to_create_using_file_system_events_Colon_FixedInterval_default_PriorityInterval_DynamicPriority,
},
Expand Down Expand Up @@ -286,7 +286,7 @@ namespace ts {
{
name: "target",
shortName: "t",
type: createMapFromTemplate({
type: new Map(getEntries({
es3: ScriptTarget.ES3,
es5: ScriptTarget.ES5,
es6: ScriptTarget.ES2015,
Expand All @@ -297,7 +297,7 @@ namespace ts {
es2019: ScriptTarget.ES2019,
es2020: ScriptTarget.ES2020,
esnext: ScriptTarget.ESNext,
}),
})),
affectsSourceFile: true,
affectsModuleResolution: true,
affectsEmit: true,
Expand All @@ -309,7 +309,7 @@ namespace ts {
{
name: "module",
shortName: "m",
type: createMapFromTemplate({
type: new Map(getEntries({
none: ModuleKind.None,
commonjs: ModuleKind.CommonJS,
amd: ModuleKind.AMD,
Expand All @@ -319,7 +319,7 @@ namespace ts {
es2015: ModuleKind.ES2015,
es2020: ModuleKind.ES2020,
esnext: ModuleKind.ESNext
}),
})),
affectsModuleResolution: true,
affectsEmit: true,
paramType: Diagnostics.KIND,
Expand Down Expand Up @@ -356,11 +356,11 @@ namespace ts {
},
{
name: "jsx",
type: createMapFromTemplate({
type: new Map(getEntries({
"preserve": JsxEmit.Preserve,
"react-native": JsxEmit.ReactNative,
"react": JsxEmit.React
}),
})),
affectsSourceFile: true,
paramType: Diagnostics.KIND,
showInSimplifiedHelpView: true,
Expand Down Expand Up @@ -476,11 +476,11 @@ namespace ts {
},
{
name: "importsNotUsedAsValues",
type: createMapFromTemplate({
type: new Map(getEntries({
remove: ImportsNotUsedAsValues.Remove,
preserve: ImportsNotUsedAsValues.Preserve,
error: ImportsNotUsedAsValues.Error
}),
})),
affectsEmit: true,
affectsSemanticDiagnostics: true,
category: Diagnostics.Advanced_Options,
Expand Down Expand Up @@ -610,10 +610,10 @@ namespace ts {
// Module Resolution
{
name: "moduleResolution",
type: createMapFromTemplate({
type: new Map(getEntries({
node: ModuleResolutionKind.NodeJs,
classic: ModuleResolutionKind.Classic,
}),
})),
affectsModuleResolution: true,
paramType: Diagnostics.STRATEGY,
category: Diagnostics.Module_Resolution_Options,
Expand Down Expand Up @@ -818,10 +818,10 @@ namespace ts {
},
{
name: "newLine",
type: createMapFromTemplate({
type: new Map(getEntries({
crlf: NewLineKind.CarriageReturnLineFeed,
lf: NewLineKind.LineFeed
}),
})),
affectsEmit: true,
paramType: Diagnostics.NEWLINE,
category: Diagnostics.Advanced_Options,
Expand Down Expand Up @@ -1096,8 +1096,8 @@ namespace ts {

/*@internal*/
export function createOptionNameMap(optionDeclarations: readonly CommandLineOption[]): OptionsNameMap {
const optionsNameMap = createMap<CommandLineOption>();
const shortOptionNames = createMap<string>();
const optionsNameMap = new Map<string, CommandLineOption>();
const shortOptionNames = new Map<string, string>();
forEach(optionDeclarations, option => {
optionsNameMap.set(option.name.toLowerCase(), option);
if (option.shortName) {
Expand Down Expand Up @@ -2032,7 +2032,7 @@ namespace ts {
{ optionsNameMap }: OptionsNameMap,
pathOptions?: { configFilePath: string, useCaseSensitiveFileNames: boolean }
): ESMap<string, CompilerOptionsValue> {
const result = createMap<CompilerOptionsValue>();
const result = new Map<string, CompilerOptionsValue>();
const getCanonicalFileName = pathOptions && createGetCanonicalFileName(pathOptions.useCaseSensitiveFileNames);

for (const name in options) {
Expand Down Expand Up @@ -2962,17 +2962,17 @@ namespace ts {
// Literal file names (provided via the "files" array in tsconfig.json) are stored in a
// file map with a possibly case insensitive key. We use this map later when when including
// wildcard paths.
const literalFileMap = createMap<string>();
const literalFileMap = new Map<string, string>();

// Wildcard paths (provided via the "includes" array in tsconfig.json) are stored in a
// file map with a possibly case insensitive key. We use this map to store paths matched
// via wildcard, and to handle extension priority.
const wildcardFileMap = createMap<string>();
const wildcardFileMap = new Map<string, string>();

// Wildcard paths of json files (provided via the "includes" array in tsconfig.json) are stored in a
// file map with a possibly case insensitive key. We use this map to store paths matched
// via wildcard of *.json kind
const wildCardJsonFileMap = createMap<string>();
const wildCardJsonFileMap = new Map<string, string>();
const { filesSpecs, validatedIncludeSpecs, validatedExcludeSpecs, wildcardDirectories } = spec;

// Rather than requery this for each file and filespec, we query the supported extensions
Expand Down
40 changes: 36 additions & 4 deletions src/compiler/core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,15 +40,23 @@ namespace ts {
}

export const emptyArray: never[] = [] as never[];
export const emptyMap: ReadonlyESMap<never, never> = new Map<never, never>();
export const emptySet: ReadonlySet<never> = new Set<never>();

/** Create a new map. */
/**
* Create a new map.
* @deprecated Use `new Map()` instead.
*/
export function createMap<K, V>(): ESMap<K, V>;
export function createMap<T>(): ESMap<string, T>;
export function createMap<K, V>(): ESMap<K, V> {
return new Map<K, V>();
}

/** Create a new map from a template object is provided, the map will copy entries from it. */
/**
* Create a new map from a template object is provided, the map will copy entries from it.
* @deprecated Use `new Map(getEntries(template))` instead.
*/
export function createMapFromTemplate<T>(template: MapLike<T>): ESMap<string, T> {
const map: ESMap<string, T> = new Map<string, T>();

Expand Down Expand Up @@ -590,6 +598,15 @@ namespace ts {
}
}

export function getOrUpdate<K, V>(map: ESMap<K, V>, key: K, callback: () => V) {
if (map.has(key)) {
return map.get(key)!;
}
const value = callback();
map.set(key, value);
return value;
}

export function tryAddToSet<T>(set: Set<T>, value: T) {
if (!set.has(value)) {
set.add(value);
Expand Down Expand Up @@ -1275,6 +1292,19 @@ namespace ts {
return values;
}

const _entries = Object.entries ? Object.entries : <T>(obj: MapLike<T>) => {
const keys = getOwnKeys(obj);
const result: [string, T][] = Array(keys.length);
for (const key of keys) {
result.push([key, obj[key]]);
}
return result;
};

export function getEntries<T>(obj: MapLike<T>): [string, T][] {
return obj ? _entries(obj) : [];
}

export function arrayOf<T>(count: number, f: (index: number) => T): T[] {
const result = new Array(count);
for (let i = 0; i < count; i++) {
Expand Down Expand Up @@ -1375,9 +1405,11 @@ namespace ts {
return result;
}

export function group<T, K>(values: readonly T[], getGroupId: (value: T) => K): readonly (readonly T[])[];
export function group<T, K, R>(values: readonly T[], getGroupId: (value: T) => K, resultSelector: (values: readonly T[]) => R): R[];
export function group<T>(values: readonly T[], getGroupId: (value: T) => string): readonly (readonly T[])[];
export function group<T, R>(values: readonly T[], getGroupId: (value: T) => string, resultSelector: (values: readonly T[]) => R): R[];
export function group<T>(values: readonly T[], getGroupId: (value: T) => string, resultSelector: (values: readonly T[]) => readonly T[] = identity): readonly (readonly T[])[] {
export function group<T, K>(values: readonly T[], getGroupId: (value: T) => K, resultSelector: (values: readonly T[]) => readonly T[] = identity): readonly (readonly T[])[] {
return arrayFrom(arrayToMultiMap(values, getGroupId).values(), resultSelector);
}

Expand Down Expand Up @@ -1596,7 +1628,7 @@ namespace ts {

/** A version of `memoize` that supports a single primitive argument */
export function memoizeOne<A extends string | number | boolean | undefined, T>(callback: (arg: A) => T): (arg: A) => T {
const map = createMap<T>();
const map = new Map<string, T>();
return (arg: A) => {
const key = `${typeof arg}:${arg}`;
let value = map.get(key);
Expand Down
2 changes: 0 additions & 2 deletions src/compiler/corePublic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ namespace ts {

/**
* ES6 Map interface, only read methods included.
* @deprecated Use `ts.ReadonlyESMap<K, V>` instead.
*/
export interface ReadonlyMap<T> extends ReadonlyESMap<string, T> {
}
Expand All @@ -57,7 +56,6 @@ namespace ts {

/**
* ES6 Map interface.
* @deprecated Use `ts.ESMap<K, V>` instead.
*/
export interface Map<T> extends ESMap<string, T> {
}
Expand Down
8 changes: 4 additions & 4 deletions src/compiler/emitter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -682,9 +682,9 @@ namespace ts {

function createSourceFilesFromBundleBuildInfo(bundle: BundleBuildInfo, buildInfoDirectory: string, host: EmitUsingBuildInfoHost): readonly SourceFile[] {
const jsBundle = Debug.checkDefined(bundle.js);
const prologueMap = jsBundle.sources?.prologues && arrayToMap(jsBundle.sources.prologues, prologueInfo => "" + prologueInfo.file);
const prologueMap = jsBundle.sources?.prologues && arrayToMap(jsBundle.sources.prologues, prologueInfo => prologueInfo.file);
return bundle.sourceFiles.map((fileName, index) => {
const prologueInfo = prologueMap?.get("" + index);
const prologueInfo = prologueMap?.get(index);
const statements = prologueInfo?.directives.map(directive => {
const literal = setTextRange(factory.createStringLiteral(directive.expression.text), directive.expression);
const statement = setTextRange(factory.createExpressionStatement(literal), directive);
Expand Down Expand Up @@ -834,7 +834,7 @@ namespace ts {
const extendedDiagnostics = !!printerOptions.extendedDiagnostics;
const newLine = getNewLineCharacter(printerOptions);
const moduleKind = getEmitModuleKind(printerOptions);
const bundledHelpers = createMap<boolean>();
const bundledHelpers = new Map<string, boolean>();

let currentSourceFile: SourceFile | undefined;
let nodeIdToGeneratedName: string[]; // Map of generated names for specific nodes.
Expand Down Expand Up @@ -1682,7 +1682,7 @@ namespace ts {
if (moduleKind === ModuleKind.None || printerOptions.noEmitHelpers) {
return undefined;
}
const bundledHelpers = createMap<boolean>();
const bundledHelpers = new Map<string, boolean>();
for (const sourceFile of bundle.sourceFiles) {
const shouldSkip = getExternalHelpersModuleName(sourceFile) !== undefined;
const helpers = getSortedEmitHelpers(sourceFile);
Expand Down
4 changes: 2 additions & 2 deletions src/compiler/factory/nodeFactory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5654,7 +5654,7 @@ namespace ts {
left.splice(0, 0, ...declarations.slice(0, rightStandardPrologueEnd));
}
else {
const leftPrologues = createMap<boolean>();
const leftPrologues = new Map<string, boolean>();
for (let i = 0; i < leftStandardPrologueEnd; i++) {
const leftPrologue = statements[i] as PrologueDirective;
leftPrologues.set(leftPrologue.expression.text, true);
Expand Down Expand Up @@ -6159,7 +6159,7 @@ namespace ts {
): InputFiles {
const node = parseNodeFactory.createInputFiles();
if (!isString(javascriptTextOrReadFileText)) {
const cache = createMap<string | false>();
const cache = new Map<string, string | false>();
const textGetter = (path: string | undefined) => {
if (path === undefined) return undefined;
let value = cache.get(path);
Expand Down
Loading