From 611b77f2e64112786038a5925aeadd3bdd9a8b45 Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Thu, 25 Jun 2020 16:03:25 -0700 Subject: [PATCH 1/2] Migrate more places to use Map/Set --- src/compiler/binder.ts | 10 +- src/compiler/checker.ts | 230 +++++++++--------- src/compiler/commandLineParser.ts | 48 ++-- src/compiler/core.ts | 44 +++- src/compiler/emitter.ts | 8 +- src/compiler/factory/nodeFactory.ts | 4 +- src/compiler/moduleNameResolver.ts | 8 +- src/compiler/moduleSpecifiers.ts | 2 +- src/compiler/parser.ts | 10 +- src/compiler/performance.ts | 6 +- src/compiler/program.ts | 42 ++-- src/compiler/resolutionCache.ts | 12 +- src/compiler/scanner.ts | 6 +- src/compiler/sourcemap.ts | 4 +- src/compiler/transformers/classFields.ts | 2 +- src/compiler/transformers/declarations.ts | 30 +-- src/compiler/transformers/es2015.ts | 6 +- src/compiler/transformers/es2017.ts | 24 +- src/compiler/transformers/es2018.ts | 6 +- src/compiler/transformers/generators.ts | 2 +- src/compiler/transformers/jsx.ts | 4 +- .../transformers/module/esnextAnd2015.ts | 2 +- src/compiler/transformers/module/system.ts | 2 +- src/compiler/transformers/ts.ts | 2 +- src/compiler/transformers/utilities.ts | 2 +- src/compiler/tsbuildPublic.ts | 14 +- src/compiler/types.ts | 95 ++++---- src/compiler/utilities.ts | 137 +++-------- src/compiler/watchPublic.ts | 6 +- src/compiler/watchUtilities.ts | 5 +- src/executeCommandLine/executeCommandLine.ts | 2 +- src/harness/client.ts | 2 +- src/harness/fourslashImpl.ts | 16 +- src/harness/harnessIO.ts | 18 +- src/harness/harnessUtils.ts | 2 +- src/harness/loggedIO.ts | 2 +- src/harness/sourceMapRecorder.ts | 2 +- src/harness/virtualFileSystemWithWatch.ts | 12 +- src/jsTyping/jsTyping.ts | 14 +- src/server/editorServices.ts | 48 ++-- src/server/packageJsonCache.ts | 4 +- src/server/project.ts | 8 +- src/server/session.ts | 6 +- src/server/typingsCache.ts | 4 +- src/server/utilities.ts | 2 +- src/server/utilitiesPublic.ts | 2 +- src/services/callHierarchy.ts | 2 +- src/services/classifier.ts | 4 +- src/services/codeFixProvider.ts | 2 +- src/services/codefixes/addMissingConst.ts | 8 +- .../codefixes/addMissingDeclareProperty.ts | 6 +- .../codefixes/convertToAsyncFunction.ts | 4 +- src/services/codefixes/convertToEs6Module.ts | 10 +- .../codefixes/convertToTypeOnlyExport.ts | 2 +- src/services/codefixes/fixAddMissingMember.ts | 6 +- .../codefixes/fixAwaitInSyncFunction.ts | 2 +- ...sDoesntImplementInheritedAbstractMember.ts | 2 +- .../fixClassIncorrectlyImplementsInterface.ts | 2 +- .../fixClassSuperMustPrecedeThisAccess.ts | 2 +- src/services/codefixes/importFixes.ts | 4 +- src/services/codefixes/inferFromUsage.ts | 8 +- src/services/completions.ts | 40 +-- src/services/documentRegistry.ts | 2 +- src/services/findAllReferences.ts | 4 +- src/services/importTracker.ts | 2 +- src/services/navigationBar.ts | 4 +- src/services/patternMatcher.ts | 2 +- src/services/refactorProvider.ts | 2 +- src/services/refactors/convertImport.ts | 4 +- src/services/refactors/extractSymbol.ts | 16 +- src/services/refactors/extractType.ts | 2 +- src/services/refactors/moveToNewFile.ts | 2 +- src/services/services.ts | 6 +- src/services/sourcemaps.ts | 4 +- src/services/stringCompletions.ts | 8 +- src/services/suggestionDiagnostics.ts | 2 +- src/services/textChanges.ts | 10 +- src/services/transpile.ts | 2 +- src/services/utilities.ts | 4 +- src/testRunner/parallel/host.ts | 2 +- src/testRunner/parallel/worker.ts | 6 +- src/testRunner/rwcRunner.ts | 2 +- .../unittests/config/commandLineParsing.ts | 4 +- .../unittests/config/projectReferences.ts | 2 +- src/testRunner/unittests/createMapShim.ts | 8 +- src/testRunner/unittests/customTransforms.ts | 2 +- src/testRunner/unittests/moduleResolution.ts | 54 ++-- src/testRunner/unittests/programApi.ts | 8 +- .../unittests/reuseProgramStructure.ts | 12 +- .../unittests/services/extract/helpers.ts | 2 +- .../unittests/services/languageService.ts | 2 +- src/testRunner/unittests/tsbuild/sample.ts | 2 +- .../unittests/tscWatch/watchEnvironment.ts | 6 +- .../tsserver/cachingFileSystemInformation.ts | 2 +- .../events/projectUpdatedInBackground.ts | 2 +- src/testRunner/unittests/tsserver/helpers.ts | 4 +- .../unittests/tsserver/inferredProjects.ts | 4 +- .../unittests/tsserver/resolutionCache.ts | 8 +- src/testRunner/unittests/tsserver/session.ts | 2 +- src/testRunner/unittests/tsserver/symLinks.ts | 2 +- .../unittests/tsserver/typingsInstaller.ts | 28 +-- .../unittests/tsserver/watchEnvironment.ts | 8 +- src/tsserver/server.ts | 6 +- src/typingsInstaller/nodeTypingsInstaller.ts | 6 +- src/typingsInstallerCore/typingsInstaller.ts | 8 +- .../reference/api/tsserverlibrary.d.ts | 6 +- tests/baselines/reference/api/typescript.d.ts | 6 +- 107 files changed, 631 insertions(+), 670 deletions(-) diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index ca3399375a28a..60aaa48ad419e 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -218,7 +218,7 @@ namespace ts { let symbolCount = 0; let Symbol: new (flags: SymbolFlags, name: __String) => Symbol; - let classifiableNames: UnderscoreEscapedMap; + let classifiableNames: Set<__String>; const unreachableFlow: FlowNode = { flags: FlowFlags.Unreachable }; const reportedUnreachableFlow: FlowNode = { flags: FlowFlags.Unreachable }; @@ -237,7 +237,7 @@ namespace ts { options = opts; languageVersion = getEmitScriptTarget(options); inStrictMode = bindInStrictMode(file, opts); - classifiableNames = createUnderscoreEscapedMap(); + classifiableNames = new Set(); symbolCount = 0; Symbol = objectAllocator.getSymbolConstructor(); @@ -445,7 +445,7 @@ namespace ts { symbol = symbolTable.get(name); if (includes & SymbolFlags.Classifiable) { - classifiableNames.set(name, true); + classifiableNames.add(name); } if (!symbol) { @@ -1964,7 +1964,7 @@ namespace ts { } if (inStrictMode && !isAssignmentTarget(node)) { - const seen = createUnderscoreEscapedMap(); + const seen = new Map<__String, ElementKind>(); for (const prop of node.properties) { if (prop.kind === SyntaxKind.SpreadAssignment || prop.name.kind !== SyntaxKind.Identifier) { @@ -3142,7 +3142,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); } } diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index b3d1183b6f31e..7525f9437feed 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -134,7 +134,7 @@ namespace ts { EmptyObjectFacts = All, } - const typeofEQFacts: ReadonlyMap = createMapFromTemplate({ + const typeofEQFacts: ReadonlyMap = new Map(getEntries({ string: TypeFacts.TypeofEQString, number: TypeFacts.TypeofEQNumber, bigint: TypeFacts.TypeofEQBigInt, @@ -143,9 +143,9 @@ namespace ts { undefined: TypeFacts.EQUndefined, object: TypeFacts.TypeofEQObject, function: TypeFacts.TypeofEQFunction - }); + })); - const typeofNEFacts: ReadonlyMap = createMapFromTemplate({ + const typeofNEFacts: ReadonlyMap = new Map(getEntries({ string: TypeFacts.TypeofNEString, number: TypeFacts.TypeofNENumber, bigint: TypeFacts.TypeofNEBigInt, @@ -154,7 +154,7 @@ namespace ts { undefined: TypeFacts.NEUndefined, object: TypeFacts.TypeofNEObject, function: TypeFacts.TypeofNEFunction - }); + })); type TypeSystemEntity = Node | Symbol | Type | Signature; @@ -261,7 +261,7 @@ namespace ts { return node.id; } - export function getSymbolId(symbol: Symbol): number { + export function getSymbolId(symbol: Symbol): SymbolId { if (!symbol.id) { symbol.id = nextSymbolId; nextSymbolId++; @@ -685,14 +685,14 @@ namespace ts { return res; } - const tupleTypes = createMap(); - const unionTypes = createMap(); - const intersectionTypes = createMap(); - const literalTypes = createMap(); - const indexedAccessTypes = createMap(); - const substitutionTypes = createMap(); + const tupleTypes = new Map(); + const unionTypes = new Map(); + const intersectionTypes = new Map(); + const literalTypes = new Map(); + const indexedAccessTypes = new Map(); + const substitutionTypes = new Map(); const evolvingArrayTypes: EvolvingArrayType[] = []; - const undefinedProperties = createMap() as UnderscoreEscapedMap; + const undefinedProperties: SymbolTable = new Map(); const unknownSymbol = createSymbol(SymbolFlags.Property, "unknown" as __String); const resolvingSymbol = createSymbol(0, InternalSymbolName.Resolving); @@ -753,7 +753,7 @@ namespace ts { const emptyTypeLiteralType = createAnonymousType(emptyTypeLiteralSymbol, emptySymbols, emptyArray, emptyArray, undefined, undefined); const emptyGenericType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, undefined, undefined); - emptyGenericType.instantiations = createMap(); + emptyGenericType.instantiations = new Map(); const anyFunctionType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, undefined, undefined); // The anyFunctionType contains the anyFunctionType by definition. The flag is further propagated @@ -778,7 +778,7 @@ namespace ts { const enumNumberIndexInfo = createIndexInfo(stringType, /*isReadonly*/ true); - const iterationTypesCache = createMap(); // cache for common IterationTypes instances + const iterationTypesCache = new Map(); // cache for common IterationTypes instances const noIterationTypes: IterationTypes = { get yieldType(): Type { return Debug.fail("Not supported"); }, get returnType(): Type { return Debug.fail("Not supported"); }, @@ -830,7 +830,7 @@ namespace ts { } /** Key is "/path/to/a.ts|/path/to/b.ts". */ let amalgamatedDuplicates: Map | undefined; - const reverseMappedCache = createMap(); + const reverseMappedCache = new Map(); let inInferTypeForHomomorphicMappedType = false; let ambientModulesCache: Symbol[] | undefined; /** @@ -883,7 +883,7 @@ namespace ts { let deferredGlobalOmitSymbol: Symbol; let deferredGlobalBigIntType: ObjectType; - const allPotentiallyUnusedIdentifiers = createMap(); // key is file name + const allPotentiallyUnusedIdentifiers = new Map(); // key is file name let flowLoopStart = 0; let flowLoopCount = 0; @@ -923,26 +923,26 @@ namespace ts { const diagnostics = createDiagnosticCollection(); const suggestionDiagnostics = createDiagnosticCollection(); - const typeofTypesByName: ReadonlyMap = createMapFromTemplate({ + const typeofTypesByName: ReadonlyMap = new Map(getEntries({ string: stringType, number: numberType, bigint: bigintType, boolean: booleanType, symbol: esSymbolType, undefined: undefinedType - }); + })); const typeofType = createTypeofType(); let _jsxNamespace: __String; let _jsxFactoryEntity: EntityName | undefined; let outofbandVarianceMarkerHandler: ((onlyUnreliable: boolean) => void) | undefined; - const subtypeRelation = createMap(); - const strictSubtypeRelation = createMap(); - const assignableRelation = createMap(); - const comparableRelation = createMap(); - const identityRelation = createMap(); - const enumRelation = createMap(); + const subtypeRelation = new Map(); + const strictSubtypeRelation = new Map(); + const assignableRelation = new Map(); + const comparableRelation = new Map(); + const identityRelation = new Map(); + const enumRelation = new Map(); const builtinGlobals = createSymbolTable(); builtinGlobals.set(undefinedSymbol.escapedName, undefinedSymbol); @@ -1111,8 +1111,8 @@ namespace ts { result.parent = symbol.parent; if (symbol.valueDeclaration) result.valueDeclaration = symbol.valueDeclaration; if (symbol.constEnumOnlyModule) result.constEnumOnlyModule = true; - if (symbol.members) result.members = cloneMap(symbol.members); - if (symbol.exports) result.exports = cloneMap(symbol.exports); + if (symbol.members) result.members = new Map(symbol.members); + if (symbol.exports) result.exports = new Map(symbol.exports); recordMergedSymbol(result, symbol); return result; } @@ -1182,10 +1182,10 @@ namespace ts { if (sourceSymbolFile && targetSymbolFile && amalgamatedDuplicates && !isEitherEnum && sourceSymbolFile !== targetSymbolFile) { const firstFile = comparePaths(sourceSymbolFile.path, targetSymbolFile.path) === Comparison.LessThan ? sourceSymbolFile : targetSymbolFile; const secondFile = firstFile === sourceSymbolFile ? targetSymbolFile : sourceSymbolFile; - const filesDuplicates = getOrUpdate(amalgamatedDuplicates, `${firstFile.path}|${secondFile.path}`, () => - ({ firstFile, secondFile, conflictingSymbols: createMap() })); - const conflictingSymbolInfo = getOrUpdate(filesDuplicates.conflictingSymbols, symbolName, () => - ({ isBlockScoped: isEitherBlockScoped, firstFileLocations: [], secondFileLocations: [] })); + const filesDuplicates = getOrUpdate(amalgamatedDuplicates, `${firstFile.path}|${secondFile.path}`, () => + ({ firstFile, secondFile, conflictingSymbols: new Map() } as DuplicateInfoForFiles)); + const conflictingSymbolInfo = getOrUpdate(filesDuplicates.conflictingSymbols, symbolName, () => + ({ isBlockScoped: isEitherBlockScoped, firstFileLocations: [], secondFileLocations: [] } as DuplicateInfoForSymbol)); addDuplicateLocations(conflictingSymbolInfo.firstFileLocations, source); addDuplicateLocations(conflictingSymbolInfo.secondFileLocations, target); } @@ -1224,8 +1224,8 @@ namespace ts { } function combineSymbolTables(first: SymbolTable | undefined, second: SymbolTable | undefined): SymbolTable | undefined { - if (!hasEntries(first)) return second; - if (!hasEntries(second)) return first; + if (!first?.size) return second; + if (!second?.size) return first; const combined = createSymbolTable(); mergeSymbolTable(combined, first); mergeSymbolTable(combined, second); @@ -1273,7 +1273,7 @@ namespace ts { if (some(patternAmbientModules, module => mainModule === module.symbol)) { const merged = mergeSymbol(moduleAugmentation.symbol, mainModule, /*unidirectional*/ true); if (!patternAmbientModuleAugmentations) { - patternAmbientModuleAugmentations = createMap(); + patternAmbientModuleAugmentations = new Map(); } // moduleName will be a StringLiteral since this is not `declare global`. patternAmbientModuleAugmentations.set((moduleName as StringLiteral).text, merged); @@ -2573,8 +2573,8 @@ namespace ts { result.declarations = deduplicate(concatenate(valueSymbol.declarations, typeSymbol.declarations), equateValues); result.parent = valueSymbol.parent || typeSymbol.parent; if (valueSymbol.valueDeclaration) result.valueDeclaration = valueSymbol.valueDeclaration; - if (typeSymbol.members) result.members = cloneMap(typeSymbol.members); - if (valueSymbol.exports) result.exports = cloneMap(valueSymbol.exports); + if (typeSymbol.members) result.members = new Map(typeSymbol.members); + if (valueSymbol.exports) result.exports = new Map(valueSymbol.exports); return result; } @@ -3300,8 +3300,8 @@ namespace ts { result.originatingImport = referenceParent; if (symbol.valueDeclaration) result.valueDeclaration = symbol.valueDeclaration; if (symbol.constEnumOnlyModule) result.constEnumOnlyModule = true; - if (symbol.members) result.members = cloneMap(symbol.members); - if (symbol.exports) result.exports = cloneMap(symbol.exports); + if (symbol.members) result.members = new Map(symbol.members); + if (symbol.exports) result.exports = new Map(symbol.exports); const resolvedModuleType = resolveStructuredTypeMembers(moduleType as StructuredType); // Should already be resolved from the signature checks above result.type = createAnonymousType(result, resolvedModuleType.members, emptyArray, emptyArray, resolvedModuleType.stringIndexInfo, resolvedModuleType.numberIndexInfo); return result; @@ -3417,12 +3417,12 @@ namespace ts { if (!(symbol && symbol.exports && pushIfUnique(visitedSymbols, symbol))) { return; } - const symbols = cloneMap(symbol.exports); + const symbols = new Map(symbol.exports); // All export * declarations are collected in an __export symbol by the binder const exportStars = symbol.exports.get(InternalSymbolName.ExportStar); if (exportStars) { const nestedSymbols = createSymbolTable(); - const lookupTable = createMap() as ExportCollisionTrackerTable; + const lookupTable: ExportCollisionTrackerTable = new Map(); for (const node of exportStars.declarations) { const resolvedModule = resolveExternalModuleName(node, (node as ExportDeclaration).moduleSpecifier!); const exportedSymbols = visit(resolvedModule); @@ -3472,7 +3472,7 @@ namespace ts { function getAlternativeContainingModules(symbol: Symbol, enclosingDeclaration: Node): Symbol[] { const containingFile = getSourceFileOfNode(enclosingDeclaration); - const id = "" + getNodeId(containingFile); + const id = getNodeId(containingFile); const links = getSymbolLinks(symbol); let results: Symbol[] | undefined; if (links.extendedContainersByFile && (results = links.extendedContainersByFile.get(id))) { @@ -3489,7 +3489,7 @@ namespace ts { results = append(results, resolvedModule); } if (length(results)) { - (links.extendedContainersByFile || (links.extendedContainersByFile = createMap())).set(id, results!); + (links.extendedContainersByFile || (links.extendedContainersByFile = new Map())).set(id, results!); return results!; } } @@ -3753,12 +3753,12 @@ namespace ts { return rightMeaning === SymbolFlags.Value ? SymbolFlags.Value : SymbolFlags.Namespace; } - function getAccessibleSymbolChain(symbol: Symbol | undefined, enclosingDeclaration: Node | undefined, meaning: SymbolFlags, useOnlyExternalAliasing: boolean, visitedSymbolTablesMap: Map = createMap()): Symbol[] | undefined { + function getAccessibleSymbolChain(symbol: Symbol | undefined, enclosingDeclaration: Node | undefined, meaning: SymbolFlags, useOnlyExternalAliasing: boolean, visitedSymbolTablesMap: Map = new Map()): Symbol[] | undefined { if (!(symbol && !isPropertyOrMethodDeclarationSymbol(symbol))) { return undefined; } - const id = "" + getSymbolId(symbol); + const id = getSymbolId(symbol); let visitedSymbolTables = visitedSymbolTablesMap.get(id); if (!visitedSymbolTables) { visitedSymbolTablesMap.set(id, visitedSymbolTables = []); @@ -4551,7 +4551,7 @@ namespace ts { context.visitedTypes = new Set(); } if (id && !context.symbolDepth) { - context.symbolDepth = createMap(); + context.symbolDepth = new Map(); } let depth: number | undefined; @@ -5333,7 +5333,7 @@ namespace ts { moduleResolverHost, { importModuleSpecifierPreference: isBundle ? "non-relative" : "relative" }, )); - links.specifierCache = links.specifierCache || createMap(); + links.specifierCache ??= new Map(); links.specifierCache.set(contextFile.path, specifier); } return specifier; @@ -5455,7 +5455,7 @@ namespace ts { function typeParameterToName(type: TypeParameter, context: NodeBuilderContext) { if (context.flags & NodeBuilderFlags.GenerateNamesForShadowedTypeParams && context.typeParameterNames) { - const cached = context.typeParameterNames.get("" + getTypeId(type)); + const cached = context.typeParameterNames.get(getTypeId(type)); if (cached) { return cached; } @@ -5475,7 +5475,7 @@ namespace ts { if (text !== rawtext) { result = factory.createIdentifier(text, result.typeArguments); } - (context.typeParameterNames || (context.typeParameterNames = createMap())).set("" + getTypeId(type), result); + (context.typeParameterNames || (context.typeParameterNames = new Map())).set(getTypeId(type), result); (context.typeParameterNamesByText || (context.typeParameterNamesByText = new Set())).add(result.escapedText as string); } return result; @@ -5632,7 +5632,7 @@ namespace ts { // export const x: (x: T) => T // export const y: (x: T_1) => T_1 if (initial.typeParameterNames) { - initial.typeParameterNames = cloneMap(initial.typeParameterNames); + initial.typeParameterNames = new Map(initial.typeParameterNames); } if (initial.typeParameterNamesByText) { initial.typeParameterNamesByText = new Set(initial.typeParameterNamesByText); @@ -5878,12 +5878,12 @@ namespace ts { const enclosingDeclaration = context.enclosingDeclaration!; let results: Statement[] = []; const visitedSymbols = new Set(); - let deferredPrivates: Map | undefined; + let deferredPrivates: Map | undefined; const oldcontext = context; context = { ...oldcontext, usedSymbolNames: new Set(oldcontext.usedSymbolNames), - remappedSymbolNames: createMap(), + remappedSymbolNames: new Map(), tracker: { ...oldcontext.tracker, trackSymbol: (sym, decl, meaning) => { @@ -6091,7 +6091,7 @@ namespace ts { function visitSymbolTable(symbolTable: SymbolTable, suppressNewPrivateContext?: boolean, propertyAsAlias?: boolean) { const oldDeferredPrivates = deferredPrivates; if (!suppressNewPrivateContext) { - deferredPrivates = createMap(); + deferredPrivates = new Map(); } symbolTable.forEach((symbol: Symbol) => { serializeSymbol(symbol, /*isPrivate*/ false, !!propertyAsAlias); @@ -6290,7 +6290,7 @@ namespace ts { if (some(symbol.declarations, isParameterDeclaration)) return; Debug.assertIsDefined(deferredPrivates); getUnusedName(unescapeLeadingUnderscores(symbol.escapedName), symbol); // Call to cache unique name for symbol - deferredPrivates.set("" + getSymbolId(symbol), symbol); + deferredPrivates.set(getSymbolId(symbol), symbol); } function isExportingScope(enclosingDeclaration: Node) { @@ -7059,9 +7059,10 @@ namespace ts { } function getUnusedName(input: string, symbol?: Symbol): string { - if (symbol) { - if (context.remappedSymbolNames!.has("" + getSymbolId(symbol))) { - return context.remappedSymbolNames!.get("" + getSymbolId(symbol))!; + const id = symbol ? getSymbolId(symbol) : undefined; + if (id) { + if (context.remappedSymbolNames!.has(id)) { + return context.remappedSymbolNames!.get(id)!; } } if (symbol) { @@ -7074,8 +7075,8 @@ namespace ts { input = `${original}_${i}`; } context.usedSymbolNames?.add(input); - if (symbol) { - context.remappedSymbolNames!.set("" + getSymbolId(symbol), input); + if (id) { + context.remappedSymbolNames!.set(id, input); } return input; } @@ -7099,12 +7100,13 @@ namespace ts { } function getInternalSymbolName(symbol: Symbol, localName: string) { - if (context.remappedSymbolNames!.has("" + getSymbolId(symbol))) { - return context.remappedSymbolNames!.get("" + getSymbolId(symbol))!; + const id = getSymbolId(symbol); + if (context.remappedSymbolNames!.has(id)) { + return context.remappedSymbolNames!.get(id)!; } localName = getNameCandidateWorker(symbol, localName); // The result of this is going to be used as the symbol's name - lock it in, so `getUnusedName` will also pick it up - context.remappedSymbolNames!.set("" + getSymbolId(symbol), localName); + context.remappedSymbolNames!.set(id, localName); return localName; } } @@ -7191,10 +7193,10 @@ namespace ts { approximateLength: number; truncating?: boolean; typeParameterSymbolList?: Set; - typeParameterNames?: Map; + typeParameterNames?: Map; typeParameterNamesByText?: Set; usedSymbolNames?: Set; - remappedSymbolNames?: Map; + remappedSymbolNames?: Map; } function isDefaultBindingContext(location: Node) { @@ -7985,13 +7987,13 @@ namespace ts { const exports = createSymbolTable(); while (isBinaryExpression(decl) || isPropertyAccessExpression(decl)) { const s = getSymbolOfNode(decl); - if (s && hasEntries(s.exports)) { + if (s?.exports?.size) { mergeSymbolTable(exports, s.exports); } decl = isBinaryExpression(decl) ? decl.parent : decl.parent.parent; } const s = getSymbolOfNode(decl); - if (s && hasEntries(s.exports)) { + if (s?.exports?.size) { mergeSymbolTable(exports, s.exports); } const type = createAnonymousType(symbol, exports, emptyArray, emptyArray, undefined, undefined); @@ -9086,7 +9088,7 @@ namespace ts { type.typeParameters = concatenate(outerTypeParameters, localTypeParameters); type.outerTypeParameters = outerTypeParameters; type.localTypeParameters = localTypeParameters; - (type).instantiations = createMap(); + (type).instantiations = new Map(); (type).instantiations.set(getTypeListId(type.typeParameters), type); (type).target = type; (type).resolvedTypeArguments = type.typeParameters; @@ -9118,7 +9120,7 @@ namespace ts { // Initialize the instantiation cache for generic type aliases. The declared type corresponds to // an instantiation of the type alias with the type parameters supplied as type arguments. links.typeParameters = typeParameters; - links.instantiations = createMap(); + links.instantiations = new Map(); links.instantiations.set(getTypeListId(typeParameters), type); } } @@ -10112,7 +10114,7 @@ namespace ts { if (symbol.exports) { members = getExportsOfSymbol(symbol); if (symbol === globalThisSymbol) { - const varsOnly = createMap() as SymbolTable; + const varsOnly = new Map() as SymbolTable; members.forEach(p => { if (!(p.flags & SymbolFlags.BlockScoped)) { varsOnly.set(p.escapedName, p); @@ -10819,7 +10821,7 @@ namespace ts { function createUnionOrIntersectionProperty(containingType: UnionOrIntersectionType, name: __String): Symbol | undefined { let singleProp: Symbol | undefined; - let propSet: Map | undefined; + let propSet: Map | undefined; let indexTypes: Type[] | undefined; const isUnion = containingType.flags & TypeFlags.Union; // Flags we want to propagate to the result if they exist in all source symbols @@ -10843,10 +10845,10 @@ namespace ts { } else if (prop !== singleProp) { if (!propSet) { - propSet = createMap(); - propSet.set("" + getSymbolId(singleProp), singleProp); + propSet = new Map(); + propSet.set(getSymbolId(singleProp), singleProp); } - const id = "" + getSymbolId(prop); + const id = getSymbolId(prop); if (!propSet.has(id)) { propSet.set(id, prop); } @@ -11562,7 +11564,7 @@ namespace ts { } function getSignatureInstantiationWithoutFillingInTypeArguments(signature: Signature, typeArguments: readonly Type[] | undefined): Signature { - const instantiations = signature.instantiations || (signature.instantiations = createMap()); + const instantiations = signature.instantiations || (signature.instantiations = new Map()); const id = getTypeListId(typeArguments); let instantiation = instantiations.get(id); if (!instantiation) { @@ -12521,7 +12523,7 @@ namespace ts { type.typeParameters = typeParameters; type.outerTypeParameters = undefined; type.localTypeParameters = typeParameters; - type.instantiations = createMap(); + type.instantiations = new Map(); type.instantiations.set(getTypeListId(type.typeParameters), type); type.target = type; type.resolvedTypeArguments = type.typeParameters; @@ -12647,7 +12649,7 @@ namespace ts { return strictNullChecks ? getOptionalType(type) : type; } - function getTypeId(type: Type) { + function getTypeId(type: Type): TypeId { return type.id; } @@ -13027,7 +13029,7 @@ namespace ts { // Also, unlike union types, the order of the constituent types is preserved in order that overload resolution // for intersections of types with signatures can be deterministic. function getIntersectionType(types: readonly Type[], aliasSymbol?: Symbol, aliasTypeArguments?: readonly Type[]): Type { - const typeMembershipMap: Map = createMap(); + const typeMembershipMap: Map = new Map(); const includes = addTypesToIntersection(typeMembershipMap, 0, types); const typeSet: Type[] = arrayFrom(typeMembershipMap.values()); // An intersection type is considered empty if it contains @@ -13821,7 +13823,7 @@ namespace ts { }; links.resolvedType = getConditionalType(root, /*mapper*/ undefined); if (outerTypeParameters) { - root.instantiations = createMap(); + root.instantiations = new Map(); root.instantiations.set(getTypeListId(outerTypeParameters), links.resolvedType); } } @@ -14059,7 +14061,7 @@ namespace ts { } const members = createSymbolTable(); - const skippedPrivateMembers = createUnderscoreEscapedMap(); + const skippedPrivateMembers = new Set<__String>(); let stringIndexInfo: IndexInfo | undefined; let numberIndexInfo: IndexInfo | undefined; if (left === emptyObjectType) { @@ -14074,7 +14076,7 @@ namespace ts { for (const rightProp of getPropertiesOfType(right)) { if (getDeclarationModifierFlagsFromSymbol(rightProp) & (ModifierFlags.Private | ModifierFlags.Protected)) { - skippedPrivateMembers.set(rightProp.escapedName, true); + skippedPrivateMembers.add(rightProp.escapedName); } else if (isSpreadableProperty(rightProp)) { members.set(rightProp.escapedName, getSpreadSymbol(rightProp, readonly)); @@ -14589,7 +14591,7 @@ namespace ts { typeParameters; links.outerTypeParameters = typeParameters; if (typeParameters.length) { - links.instantiations = createMap(); + links.instantiations = new Map(); links.instantiations.set(getTypeListId(typeParameters), target); } } @@ -17213,14 +17215,14 @@ namespace ts { // Compute the set of types for each discriminant property. const sourceDiscriminantTypes: Type[][] = new Array(sourcePropertiesFiltered.length); - const excludedProperties = createUnderscoreEscapedMap(); + const excludedProperties = new Set<__String>(); for (let i = 0; i < sourcePropertiesFiltered.length; i++) { const sourceProperty = sourcePropertiesFiltered[i]; const sourcePropertyType = getTypeOfSymbol(sourceProperty); sourceDiscriminantTypes[i] = sourcePropertyType.flags & TypeFlags.Union ? (sourcePropertyType as UnionType).types : [sourcePropertyType]; - excludedProperties.set(sourceProperty.escapedName, true); + excludedProperties.add(sourceProperty.escapedName); } // Match each combination of the cartesian product of discriminant properties to one or more @@ -17275,7 +17277,7 @@ namespace ts { return result; } - function excludeProperties(properties: Symbol[], excludedProperties: UnderscoreEscapedMap | undefined) { + function excludeProperties(properties: Symbol[], excludedProperties: Set<__String> | undefined) { if (!excludedProperties || properties.length === 0) return properties; let result: Symbol[] | undefined; for (let i = 0; i < properties.length; i++) { @@ -17444,7 +17446,7 @@ namespace ts { // No array like or unmatched property error - just issue top level error (errorInfo = undefined) } - function propertiesRelatedTo(source: Type, target: Type, reportErrors: boolean, excludedProperties: UnderscoreEscapedMap | undefined, intersectionState: IntersectionState): Ternary { + function propertiesRelatedTo(source: Type, target: Type, reportErrors: boolean, excludedProperties: Set<__String> | undefined, intersectionState: IntersectionState): Ternary { if (relation === identityRelation) { return propertiesIdenticalTo(source, target, excludedProperties); } @@ -17563,7 +17565,7 @@ namespace ts { return result; } - function propertiesIdenticalTo(source: Type, target: Type, excludedProperties: UnderscoreEscapedMap | undefined): Ternary { + function propertiesIdenticalTo(source: Type, target: Type, excludedProperties: Set<__String> | undefined): Ternary { if (!(source.flags & TypeFlags.Object && target.flags & TypeFlags.Object)) { return Ternary.False; } @@ -18689,7 +18691,7 @@ namespace ts { function getPropertiesOfContext(context: WideningContext): Symbol[] { if (!context.resolvedProperties) { - const names = createMap() as UnderscoreEscapedMap; + const names = new Map() as UnderscoreEscapedMap; for (const t of getSiblingsOfContext(context)) { if (isObjectLiteralType(t) && !(getObjectFlags(t) & ObjectFlags.ContainsSpread)) { for (const prop of getPropertiesOfType(t)) { @@ -19441,7 +19443,7 @@ namespace ts { inferencePriority = Math.min(inferencePriority, status); return; } - (visited || (visited = createMap())).set(key, InferencePriority.Circularity); + (visited || (visited = new Map())).set(key, InferencePriority.Circularity); const saveInferencePriority = inferencePriority; inferencePriority = InferencePriority.MaxValue; action(source, target); @@ -21249,7 +21251,7 @@ namespace ts { // If we have previously computed the control flow type for the reference at // this flow loop junction, return the cached type. const id = getFlowNodeId(flow); - const cache = flowLoopCaches[id] || (flowLoopCaches[id] = createMap()); + const cache = flowLoopCaches[id] || (flowLoopCaches[id] = new Map()); const key = getOrSetCacheKey(); if (!key) { // No cache key is generated when binding patterns are in unnarrowable situations @@ -27339,7 +27341,7 @@ namespace ts { // If the symbol of the node has members, treat it like a constructor. const symbol = getSymbolOfNode(func); - return !!symbol && hasEntries(symbol.members); + return !!symbol?.members?.size; } return false; } @@ -27347,21 +27349,21 @@ namespace ts { function mergeJSSymbols(target: Symbol, source: Symbol | undefined) { if (source) { const links = getSymbolLinks(source); - if (!links.inferredClassSymbol || !links.inferredClassSymbol.has("" + getSymbolId(target))) { + if (!links.inferredClassSymbol || !links.inferredClassSymbol.has(getSymbolId(target))) { const inferred = isTransientSymbol(target) ? target : cloneSymbol(target) as TransientSymbol; inferred.exports = inferred.exports || createSymbolTable(); inferred.members = inferred.members || createSymbolTable(); inferred.flags |= source.flags & SymbolFlags.Class; - if (hasEntries(source.exports)) { + if (source.exports?.size) { mergeSymbolTable(inferred.exports, source.exports); } - if (hasEntries(source.members)) { + if (source.members?.size) { mergeSymbolTable(inferred.members, source.members); } - (links.inferredClassSymbol || (links.inferredClassSymbol = createMap())).set("" + getSymbolId(inferred), inferred); + (links.inferredClassSymbol || (links.inferredClassSymbol = new Map())).set(getSymbolId(inferred), inferred); return inferred; } - return links.inferredClassSymbol.get("" + getSymbolId(target)); + return links.inferredClassSymbol.get(getSymbolId(target)); } } @@ -27452,7 +27454,7 @@ namespace ts { const decl = getDeclarationOfExpando(node); if (decl) { const jsSymbol = getSymbolOfNode(decl); - if (jsSymbol && hasEntries(jsSymbol.exports)) { + if (jsSymbol?.exports?.size) { const jsAssignmentType = createAnonymousType(jsSymbol, jsSymbol.exports, emptyArray, emptyArray, undefined, undefined); jsAssignmentType.objectFlags |= ObjectFlags.JSLiteral; return getIntersectionType([returnType, jsAssignmentType]); @@ -29478,8 +29480,8 @@ namespace ts { case AssignmentDeclarationKind.ThisProperty: const symbol = getSymbolOfNode(left); const init = getAssignedExpandoInitializer(right); - return init && isObjectLiteralExpression(init) && - symbol && hasEntries(symbol.exports); + return !!init && isObjectLiteralExpression(init) && + !!symbol?.exports?.size; default: return false; } @@ -30438,10 +30440,10 @@ namespace ts { } function checkClassForDuplicateDeclarations(node: ClassLikeDeclaration) { - const instanceNames = createUnderscoreEscapedMap(); - const staticNames = createUnderscoreEscapedMap(); + const instanceNames = new Map<__String, DeclarationMeaning>(); + const staticNames = new Map<__String, DeclarationMeaning>(); // instance and static private identifiers share the same scope - const privateIdentifiers = createUnderscoreEscapedMap(); + const privateIdentifiers = new Map<__String, DeclarationMeaning>(); for (const member of node.members) { if (member.kind === SyntaxKind.Constructor) { for (const param of (member as ConstructorDeclaration).parameters) { @@ -30537,7 +30539,7 @@ namespace ts { } function checkObjectTypeForDuplicateDeclarations(node: TypeLiteralNode | InterfaceDeclaration) { - const names = createMap(); + const names = new Map(); for (const member of node.members) { if (member.kind === SyntaxKind.PropertySignature) { let memberName: string; @@ -32234,7 +32236,7 @@ namespace ts { if (last(getSymbolOfNode(node).declarations) !== node) return; const typeParameters = getEffectiveTypeParameterDeclarations(node); - const seenParentsWithEveryUnused = new NodeSet(); + const seenParentsWithEveryUnused = new Set(); for (const typeParameter of typeParameters) { if (!isTypeParameterUnused(typeParameter)) continue; @@ -32242,7 +32244,7 @@ namespace ts { const name = idText(typeParameter.name); const { parent } = typeParameter; if (parent.kind !== SyntaxKind.InferType && parent.typeParameters!.every(isTypeParameterUnused)) { - if (seenParentsWithEveryUnused.tryAdd(parent)) { + if (tryAddToSet(seenParentsWithEveryUnused, parent)) { const range = isJSDocTemplateTag(parent) // Whole @template tag ? rangeOfNode(parent) @@ -32292,9 +32294,9 @@ namespace ts { function checkUnusedLocalsAndParameters(nodeWithLocals: Node, addDiagnostic: AddUnusedDiagnostic): void { // Ideally we could use the ImportClause directly as a key, but must wait until we have full ES6 maps. So must store key along with value. - const unusedImports = createMap<[ImportClause, ImportedDeclaration[]]>(); - const unusedDestructures = createMap<[ObjectBindingPattern, BindingElement[]]>(); - const unusedVariables = createMap<[VariableDeclarationList, VariableDeclaration[]]>(); + const unusedImports = new Map(); + const unusedDestructures = new Map(); + const unusedVariables = new Map(); nodeWithLocals.locals!.forEach(local => { // If it's purely a type parameter, ignore, will be checked in `checkUnusedTypeParameters`. // If it's a type parameter merged with a parameter, check if the parameter-side is used. @@ -32721,7 +32723,7 @@ namespace ts { const isJSObjectLiteralInitializer = isInJSFile(node) && isObjectLiteralExpression(initializer) && (initializer.properties.length === 0 || isPrototypeAccess(node.name)) && - hasEntries(symbol.exports); + !!symbol.exports?.size; if (!isJSObjectLiteralInitializer && node.parent.parent.kind !== SyntaxKind.ForInStatement) { checkTypeAssignableToAndOptionallyElaborate(checkExpressionCached(initializer), type, node, initializer, /*headMessage*/ undefined); } @@ -34545,7 +34547,7 @@ namespace ts { if (!length(baseTypes)) { return properties; } - const seen = createUnderscoreEscapedMap(); + const seen = new Map<__String, Symbol>(); forEach(properties, p => { seen.set(p.escapedName, p); }); for (const base of baseTypes) { @@ -34568,7 +34570,7 @@ namespace ts { } interface InheritanceInfoMap { prop: Symbol; containingType: Type; } - const seen = createUnderscoreEscapedMap(); + const seen = new Map<__String, InheritanceInfoMap>(); forEach(resolveDeclaredMembers(type).declaredProperties, p => { seen.set(p.escapedName, { prop: p, containingType: type }); }); let ok = true; @@ -35758,8 +35760,8 @@ namespace ts { const enclosingFile = getSourceFileOfNode(node); const links = getNodeLinks(enclosingFile); if (!(links.flags & NodeCheckFlags.TypeChecked)) { - links.deferredNodes = links.deferredNodes || createMap(); - const id = "" + getNodeId(node); + links.deferredNodes = links.deferredNodes || new Map(); + const id = getNodeId(node); links.deferredNodes.set(id, node); } } @@ -37157,7 +37159,7 @@ namespace ts { let fileToDirective: Map; if (resolvedTypeReferenceDirectives) { // populate reverse mapping: file path -> type reference directive that was resolved to this file - fileToDirective = createMap(); + fileToDirective = new Map(); resolvedTypeReferenceDirectives.forEach((resolvedDirective, key) => { if (!resolvedDirective || !resolvedDirective.resolvedFileName) { return; @@ -37390,7 +37392,7 @@ namespace ts { bindSourceFile(file, compilerOptions); } - amalgamatedDuplicates = createMap(); + amalgamatedDuplicates = new Map(); // Initialize global symbol table let augmentations: (readonly (StringLiteral | Identifier)[])[] | undefined; @@ -38196,7 +38198,7 @@ namespace ts { } function checkGrammarObjectLiteralExpression(node: ObjectLiteralExpression, inDestructuring: boolean) { - const seen = createUnderscoreEscapedMap(); + const seen = new Map<__String, DeclarationMeaning>(); for (const prop of node.properties) { if (prop.kind === SyntaxKind.SpreadAssignment) { @@ -38301,7 +38303,7 @@ namespace ts { function checkGrammarJsxElement(node: JsxOpeningLikeElement) { checkGrammarTypeArguments(node, node.typeArguments); - const seen = createUnderscoreEscapedMap(); + const seen = new Map<__String, boolean>(); for (const attr of node.attributes.properties) { if (attr.kind === SyntaxKind.JsxSpreadAttribute) { diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index b2884340dfce0..173650e00129b 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -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, }, @@ -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, @@ -297,7 +297,7 @@ namespace ts { es2019: ScriptTarget.ES2019, es2020: ScriptTarget.ES2020, esnext: ScriptTarget.ESNext, - }), + })), affectsSourceFile: true, affectsModuleResolution: true, affectsEmit: true, @@ -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, @@ -319,7 +319,7 @@ namespace ts { es2015: ModuleKind.ES2015, es2020: ModuleKind.ES2020, esnext: ModuleKind.ESNext - }), + })), affectsModuleResolution: true, affectsEmit: true, paramType: Diagnostics.KIND, @@ -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, @@ -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, @@ -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, @@ -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, @@ -1096,8 +1096,8 @@ namespace ts { /*@internal*/ export function createOptionNameMap(optionDeclarations: readonly CommandLineOption[]): OptionsNameMap { - const optionsNameMap = createMap(); - const shortOptionNames = createMap(); + const optionsNameMap = new Map(); + const shortOptionNames = new Map(); forEach(optionDeclarations, option => { optionsNameMap.set(option.name.toLowerCase(), option); if (option.shortName) { @@ -2032,7 +2032,7 @@ namespace ts { { optionsNameMap }: OptionsNameMap, pathOptions?: { configFilePath: string, useCaseSensitiveFileNames: boolean } ): Map { - const result = createMap(); + const result = new Map(); const getCanonicalFileName = pathOptions && createGetCanonicalFileName(pathOptions.useCaseSensitiveFileNames); for (const name in options) { @@ -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(); + const literalFileMap = new Map(); // 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(); + const wildcardFileMap = new Map(); // 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(); + const wildCardJsonFileMap = new Map(); const { filesSpecs, validatedIncludeSpecs, validatedExcludeSpecs, wildcardDirectories } = spec; // Rather than requery this for each file and filespec, we query the supported extensions diff --git a/src/compiler/core.ts b/src/compiler/core.ts index 573a45b9f3b1d..6f45ee012a5ac 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -40,17 +40,23 @@ namespace ts { } export const emptyArray: never[] = [] as never[]; + export const emptyMap: ReadonlyMap = new Map(); + export const emptySet: ReadonlySet = new Set(); - /** Create a new map. */ - export function createMap(): Map; - export function createMap(): Map; + /** + * Create a new map. + * @deprecated Use `new Map()` instead. + */ export function createMap(): Map { return new Map(); } - /** 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(template: MapLike): Map { - const map: Map = new Map(); + const map = new Map(); // Copies keys/values from template. Note that for..in will not throw if // template is undefined, and instead will just exit the loop. @@ -590,6 +596,15 @@ namespace ts { } } + export function getOrUpdate(map: Map, key: K, callback: () => V) { + if (map.has(key)) { + return map.get(key)!; + } + const value = callback(); + map.set(key, value); + return value; + } + export function tryAddToSet(set: Set, value: T) { if (!set.has(value)) { set.add(value); @@ -1275,6 +1290,19 @@ namespace ts { return values; } + const _entries = Object.entries ? Object.entries : (obj: MapLike) => { + 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(obj: MapLike): [string, T][] { + return obj ? _entries(obj) : []; + } + export function arrayOf(count: number, f: (index: number) => T): T[] { const result = new Array(count); for (let i = 0; i < count; i++) { @@ -1375,9 +1403,11 @@ namespace ts { return result; } + export function group(values: readonly T[], getGroupId: (value: T) => K): readonly (readonly T[])[]; + export function group(values: readonly T[], getGroupId: (value: T) => K, resultSelector: (values: readonly T[]) => R): R[]; export function group(values: readonly T[], getGroupId: (value: T) => string): readonly (readonly T[])[]; export function group(values: readonly T[], getGroupId: (value: T) => string, resultSelector: (values: readonly T[]) => R): R[]; - export function group(values: readonly T[], getGroupId: (value: T) => string, resultSelector: (values: readonly T[]) => readonly T[] = identity): readonly (readonly T[])[] { + export function group(values: readonly T[], getGroupId: (value: T) => K, resultSelector: (values: readonly T[]) => readonly T[] = identity): readonly (readonly T[])[] { return arrayFrom(arrayToMultiMap(values, getGroupId).values(), resultSelector); } @@ -1596,7 +1626,7 @@ namespace ts { /** A version of `memoize` that supports a single primitive argument */ export function memoizeOne(callback: (arg: A) => T): (arg: A) => T { - const map = createMap(); + const map = new Map(); return (arg: A) => { const key = `${typeof arg}:${arg}`; let value = map.get(key); diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 6cbe25b92671e..7c1b29ed39271 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -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); @@ -834,7 +834,7 @@ namespace ts { const extendedDiagnostics = !!printerOptions.extendedDiagnostics; const newLine = getNewLineCharacter(printerOptions); const moduleKind = getEmitModuleKind(printerOptions); - const bundledHelpers = createMap(); + const bundledHelpers = new Map(); let currentSourceFile: SourceFile | undefined; let nodeIdToGeneratedName: string[]; // Map of generated names for specific nodes. @@ -1682,7 +1682,7 @@ namespace ts { if (moduleKind === ModuleKind.None || printerOptions.noEmitHelpers) { return undefined; } - const bundledHelpers = createMap(); + const bundledHelpers = new Map(); for (const sourceFile of bundle.sourceFiles) { const shouldSkip = getExternalHelpersModuleName(sourceFile) !== undefined; const helpers = getSortedEmitHelpers(sourceFile); diff --git a/src/compiler/factory/nodeFactory.ts b/src/compiler/factory/nodeFactory.ts index ef019d3df30d3..a9679f453fe43 100644 --- a/src/compiler/factory/nodeFactory.ts +++ b/src/compiler/factory/nodeFactory.ts @@ -5654,7 +5654,7 @@ namespace ts { left.splice(0, 0, ...declarations.slice(0, rightStandardPrologueEnd)); } else { - const leftPrologues = createMap(); + const leftPrologues = new Map(); for (let i = 0; i < leftStandardPrologueEnd; i++) { const leftPrologue = statements[i] as PrologueDirective; leftPrologues.set(leftPrologue.expression.text, true); @@ -6159,7 +6159,7 @@ namespace ts { ): InputFiles { const node = parseNodeFactory.createInputFiles(); if (!isString(javascriptTextOrReadFileText)) { - const cache = createMap(); + const cache = new Map(); const textGetter = (path: string | undefined) => { if (path === undefined) return undefined; let value = cache.get(path); diff --git a/src/compiler/moduleNameResolver.ts b/src/compiler/moduleNameResolver.ts index 50d7e9a4d0f53..13d7c451d6d2e 100644 --- a/src/compiler/moduleNameResolver.ts +++ b/src/compiler/moduleNameResolver.ts @@ -482,7 +482,7 @@ namespace ts { /*@internal*/ export function createCacheWithRedirects(options?: CompilerOptions): CacheWithRedirects { - let ownMap: Map = createMap(); + let ownMap: Map = new Map(); const redirectsMap = new Map>(); return { ownMap, @@ -509,7 +509,7 @@ namespace ts { let redirects = redirectsMap.get(path); if (!redirects) { // Reuse map if redirected reference map uses same resolution - redirects = !options || optionsHaveModuleResolutionChanges(options, redirectedReference.commandLine.options) ? createMap() : ownMap; + redirects = !options || optionsHaveModuleResolutionChanges(options, redirectedReference.commandLine.options) ? new Map() : ownMap; redirectsMap.set(path, redirects); } return redirects; @@ -532,7 +532,7 @@ namespace ts { function getOrCreateCacheForDirectory(directoryName: string, redirectedReference?: ResolvedProjectReference) { const path = toPath(directoryName, currentDirectory, getCanonicalFileName); - return getOrCreateCache>(directoryToModuleNameMap, redirectedReference, path, createMap); + return getOrCreateCache>(directoryToModuleNameMap, redirectedReference, path, () => new Map()); } function getOrCreateCacheForModuleName(nonRelativeModuleName: string, redirectedReference?: ResolvedProjectReference): PerModuleNameCache { @@ -551,7 +551,7 @@ namespace ts { } function createPerModuleNameCache(): PerModuleNameCache { - const directoryPathMap = createMap(); + const directoryPathMap = new Map(); return { get, set }; diff --git a/src/compiler/moduleSpecifiers.ts b/src/compiler/moduleSpecifiers.ts index b173bb1336453..96925b838e4ed 100644 --- a/src/compiler/moduleSpecifiers.ts +++ b/src/compiler/moduleSpecifiers.ts @@ -216,7 +216,7 @@ namespace ts.moduleSpecifiers { function getAllModulePaths(importingFileName: string, importedFileName: string, host: ModuleSpecifierResolutionHost): readonly string[] { const cwd = host.getCurrentDirectory(); const getCanonicalFileName = hostGetCanonicalFileName(host); - const allFileNames = createMap(); + const allFileNames = new Map(); let importedFileFromNodeModules = false; forEachFileNameOfModule( importingFileName, diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 2e8729b29c220..0f9bb3603aa67 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -820,7 +820,7 @@ namespace ts { result.libReferenceDirectives = emptyArray; result.amdDependencies = emptyArray; result.hasNoDefaultLib = false; - result.pragmas = emptyMap; + result.pragmas = emptyMap as ReadonlyPragmaMap; return result; } @@ -929,8 +929,8 @@ namespace ts { parseDiagnostics = []; parsingContext = 0; - identifiers = createMap(); - privateIdentifiers = createMap(); + identifiers = new Map(); + privateIdentifiers = new Map(); identifierCount = 0; nodeCount = 0; sourceFlags = 0; @@ -8678,7 +8678,7 @@ namespace ts { extractPragmas(pragmas, range, comment); } - context.pragmas = createMap() as PragmaMap; + context.pragmas = new Map() as PragmaMap; for (const pragma of pragmas) { if (context.pragmas.has(pragma.name)) { const currentValue = context.pragmas.get(pragma.name); @@ -8776,7 +8776,7 @@ namespace ts { }); } - const namedArgRegExCache = createMap(); + const namedArgRegExCache = new Map(); function getNamedArgRegEx(name: string): RegExp { if (namedArgRegExCache.has(name)) { return namedArgRegExCache.get(name)!; diff --git a/src/compiler/performance.ts b/src/compiler/performance.ts index 3da794c638b16..3d6f154fbf4ca 100644 --- a/src/compiler/performance.ts +++ b/src/compiler/performance.ts @@ -108,9 +108,9 @@ namespace ts.performance { /** Enables (and resets) performance measurements for the compiler. */ export function enable() { - counts = createMap(); - marks = createMap(); - measures = createMap(); + counts = new Map(); + marks = new Map(); + measures = new Map(); enabled = true; profilerStart = timestamp(); } diff --git a/src/compiler/program.ts b/src/compiler/program.ts index 8cee3aae854d7..b64bb1348da8d 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -71,7 +71,7 @@ namespace ts { /*@internal*/ // TODO(shkamat): update this after reworking ts build API export function createCompilerHostWorker(options: CompilerOptions, setParentNodes?: boolean, system = sys): CompilerHost { - const existingDirectories = createMap(); + const existingDirectories = new Map(); const getCanonicalFileName = createGetCanonicalFileName(system.useCaseSensitiveFileNames); function getSourceFile(fileName: string, languageVersion: ScriptTarget, onError?: (message: string) => void): SourceFile | undefined { let text: string | undefined; @@ -134,7 +134,7 @@ namespace ts { } if (!outputFingerprints) { - outputFingerprints = createMap(); + outputFingerprints = new Map(); } const hash = system.createHash(data); @@ -211,10 +211,10 @@ namespace ts { const originalDirectoryExists = host.directoryExists; const originalCreateDirectory = host.createDirectory; const originalWriteFile = host.writeFile; - const readFileCache = createMap(); - const fileExistsCache = createMap(); - const directoryExistsCache = createMap(); - const sourceFileCache = createMap(); + const readFileCache = new Map(); + const fileExistsCache = new Map(); + const directoryExistsCache = new Map(); + const sourceFileCache = new Map(); const readFileWithCache = (fileName: string): string | undefined => { const key = toPath(fileName); @@ -515,7 +515,7 @@ namespace ts { return []; } const resolutions: T[] = []; - const cache = createMap(); + const cache = new Map(); for (const name of names) { let result: T; if (cache.has(name)) { @@ -706,15 +706,15 @@ namespace ts { let commonSourceDirectory: string; let diagnosticsProducingTypeChecker: TypeChecker; let noDiagnosticsTypeChecker: TypeChecker; - let classifiableNames: UnderscoreEscapedMap; - const ambientModuleNameToUnmodifiedFileName = createMap(); + let classifiableNames: Set<__String>; + const ambientModuleNameToUnmodifiedFileName = new Map(); // Todo:: Use this to report why file was included in --extendedDiagnostics let refFileMap: MultiMap | undefined; const cachedBindAndCheckDiagnosticsForFile: DiagnosticCache = {}; const cachedDeclarationDiagnosticsForFile: DiagnosticCache = {}; - let resolvedTypeReferenceDirectives = createMap(); + let resolvedTypeReferenceDirectives = new Map(); let fileProcessingDiagnostics = createDiagnosticCollection(); // The below settings are to track if a .js file should be add to the program if loaded via searching under node_modules. @@ -729,10 +729,10 @@ namespace ts { // If a module has some of its imports skipped due to being at the depth limit under node_modules, then track // this, as it may be imported at a shallower depth later, and then it will need its skipped imports processed. - const modulesWithElidedImports = createMap(); + const modulesWithElidedImports = new Map(); // Track source files that are source files found by searching under node_modules, as these shouldn't be compiled. - const sourceFilesFoundSearchingNodeModules = createMap(); + const sourceFilesFoundSearchingNodeModules = new Map(); performance.mark("beforeProgram"); @@ -748,7 +748,7 @@ namespace ts { const supportedExtensionsWithJsonIfResolveJsonModule = getSuppoertedExtensionsWithJsonIfResolveJsonModule(options, supportedExtensions); // Map storing if there is emit blocking diagnostics for given input - const hasEmitBlockingDiagnostics = createMap(); + const hasEmitBlockingDiagnostics = new Map(); let _compilerOptionsObjectLiteralSyntax: ObjectLiteralExpression | null | undefined; let moduleResolutionCache: ModuleResolutionCache | undefined; @@ -783,9 +783,9 @@ namespace ts { // Map from a stringified PackageId to the source file with that id. // Only one source file may have a given packageId. Others become redirects (see createRedirectSourceFile). // `packageIdToSourceFile` is only used while building the program, while `sourceFileToPackageName` and `isSourceFileTargetOfRedirect` are kept around. - const packageIdToSourceFile = createMap(); + const packageIdToSourceFile = new Map(); // Maps from a SourceFile's `.path` to the name of the package it was imported with. - let sourceFileToPackageName = createMap(); + let sourceFileToPackageName = new Map(); // Key is a file name. Value is the (non-empty, or undefined) list of files that redirect to it. let redirectTargetsMap = createMultiMap(); @@ -795,11 +795,11 @@ namespace ts { * - false if sourceFile missing for source of project reference redirect * - undefined otherwise */ - const filesByName = createMap(); + const filesByName = new Map(); let missingFilePaths: readonly Path[] | undefined; // stores 'filename -> file association' ignoring case // used to track cases when two file names differ only in casing - const filesByNameIgnoreCase = host.useCaseSensitiveFileNames() ? createMap() : undefined; + const filesByNameIgnoreCase = host.useCaseSensitiveFileNames() ? new Map() : undefined; // A parallel array to projectReferences storing the results of reading in the referenced tsconfig files let resolvedProjectReferences: readonly (ResolvedProjectReference | undefined)[] | undefined; @@ -1051,10 +1051,10 @@ namespace ts { if (!classifiableNames) { // Initialize a checker so that all our files are bound. getTypeChecker(); - classifiableNames = createUnderscoreEscapedMap(); + classifiableNames = new Set(); for (const sourceFile of files) { - copyEntries(sourceFile.classifiableNames!, classifiableNames); + sourceFile.classifiableNames?.forEach(value => classifiableNames.add(value)); } } @@ -1270,7 +1270,7 @@ namespace ts { const oldSourceFiles = oldProgram.getSourceFiles(); const enum SeenPackageName { Exists, Modified } - const seenPackageNames = createMap(); + const seenPackageNames = new Map(); for (const oldSourceFile of oldSourceFiles) { let newSourceFile = host.getSourceFileByPath @@ -2571,7 +2571,7 @@ namespace ts { function getSourceOfProjectReferenceRedirect(file: string) { if (!isDeclarationFileName(file)) return undefined; if (mapFromToProjectReferenceRedirectSource === undefined) { - mapFromToProjectReferenceRedirectSource = createMap(); + mapFromToProjectReferenceRedirectSource = new Map(); forEachResolvedProjectReference(resolvedRef => { if (resolvedRef) { const out = outFile(resolvedRef.commandLine.options); diff --git a/src/compiler/resolutionCache.ts b/src/compiler/resolutionCache.ts index dc79fe0fabff9..3d804f3113702 100644 --- a/src/compiler/resolutionCache.ts +++ b/src/compiler/resolutionCache.ts @@ -181,15 +181,15 @@ namespace ts { * Note that .d.ts file also has .d.ts extension hence will be part of default extensions */ const failedLookupDefaultExtensions = [Extension.Ts, Extension.Tsx, Extension.Js, Extension.Jsx, Extension.Json]; - const customFailedLookupPaths = createMap(); + const customFailedLookupPaths = new Map(); - const directoryWatchesOfFailedLookups = createMap(); + const directoryWatchesOfFailedLookups = new Map(); const rootDir = rootDirForResolution && removeTrailingDirectorySeparator(getNormalizedAbsolutePath(rootDirForResolution, getCurrentDirectory())); const rootPath = (rootDir && resolutionHost.toPath(rootDir)) as Path; // TODO: GH#18217 const rootSplitLength = rootPath !== undefined ? rootPath.split(directorySeparator).length : 0; // TypeRoot watches for the types that get added as part of getAutomaticTypeDirectiveNames - const typeRootsWatches = createMap(); + const typeRootsWatches = new Map(); return { startRecordingFilesWithChangedResolutions, @@ -349,12 +349,12 @@ namespace ts { shouldRetryResolution, reusedNames, logChanges }: ResolveNamesWithLocalCacheInput): (R | undefined)[] { const path = resolutionHost.toPath(containingFile); - const resolutionsInFile = cache.get(path) || cache.set(path, createMap()).get(path)!; + const resolutionsInFile = cache.get(path) || cache.set(path, new Map()).get(path)!; const dirPath = getDirectoryPath(path); const perDirectoryCache = perDirectoryCacheWithRedirects.getOrCreateMapOfCacheRedirects(redirectedReference); let perDirectoryResolution = perDirectoryCache.get(dirPath); if (!perDirectoryResolution) { - perDirectoryResolution = createMap(); + perDirectoryResolution = new Map(); perDirectoryCache.set(dirPath, perDirectoryResolution); } const resolvedModules: (R | undefined)[] = []; @@ -368,7 +368,7 @@ namespace ts { !redirectedReference || redirectedReference.sourceFile.path !== oldRedirect.sourceFile.path : !!redirectedReference; - const seenNamesInFile = createMap(); + const seenNamesInFile = new Map(); for (const name of names) { let resolution = resolutionsInFile.get(name); // Resolution is valid if it is present and not invalidated diff --git a/src/compiler/scanner.ts b/src/compiler/scanner.ts index ab2a37032ced2..9619dc76a186b 100644 --- a/src/compiler/scanner.ts +++ b/src/compiler/scanner.ts @@ -153,9 +153,9 @@ namespace ts { of: SyntaxKind.OfKeyword, }; - const textToKeyword = createMapFromTemplate(textToKeywordObj); + const textToKeyword = new Map(getEntries(textToKeywordObj)); - const textToToken = createMapFromTemplate({ + const textToToken = new Map(getEntries({ ...textToKeywordObj, "{": SyntaxKind.OpenBraceToken, "}": SyntaxKind.CloseBraceToken, @@ -217,7 +217,7 @@ namespace ts { "??=": SyntaxKind.QuestionQuestionEqualsToken, "@": SyntaxKind.AtToken, "`": SyntaxKind.BacktickToken - }); + })); /* As per ECMAScript Language Specification 3th Edition, Section 7.6: Identifiers diff --git a/src/compiler/sourcemap.ts b/src/compiler/sourcemap.ts index 3e70d335566bb..a73e2a9e85ce6 100644 --- a/src/compiler/sourcemap.ts +++ b/src/compiler/sourcemap.ts @@ -12,7 +12,7 @@ namespace ts { // Current source map file and its index in the sources list const rawSources: string[] = []; const sources: string[] = []; - const sourceToSourceIndexMap = createMap(); + const sourceToSourceIndexMap = new Map(); let sourcesContent: (string | null)[] | undefined; const names: string[] = []; @@ -84,7 +84,7 @@ namespace ts { function addName(name: string) { enter(); - if (!nameToNameIndexMap) nameToNameIndexMap = createMap(); + if (!nameToNameIndexMap) nameToNameIndexMap = new Map(); let nameIndex = nameToNameIndexMap.get(name); if (nameIndex === undefined) { nameIndex = names.length; diff --git a/src/compiler/transformers/classFields.ts b/src/compiler/transformers/classFields.ts index 774ded70dfef4..01e3d7c7896a8 100644 --- a/src/compiler/transformers/classFields.ts +++ b/src/compiler/transformers/classFields.ts @@ -890,7 +890,7 @@ namespace ts { } function getPrivateIdentifierEnvironment() { - return currentPrivateIdentifierEnvironment || (currentPrivateIdentifierEnvironment = createUnderscoreEscapedMap()); + return currentPrivateIdentifierEnvironment || (currentPrivateIdentifierEnvironment = new Map()); } function getPendingExpressions() { diff --git a/src/compiler/transformers/declarations.ts b/src/compiler/transformers/declarations.ts index 8d05347bc6f31..0a045e398d203 100644 --- a/src/compiler/transformers/declarations.ts +++ b/src/compiler/transformers/declarations.ts @@ -60,7 +60,7 @@ namespace ts { let enclosingDeclaration: Node; let necessaryTypeReferences: Set | undefined; let lateMarkedStatements: LateVisibilityPaintedStatement[] | undefined; - let lateStatementReplacementMap: Map>; + let lateStatementReplacementMap: Map>; let suppressNewDiagnosticContexts: boolean; let exportedModulesFromDeclarationEmit: Symbol[] | undefined; @@ -81,7 +81,7 @@ namespace ts { let errorNameNode: DeclarationName | undefined; let currentSourceFile: SourceFile; - let refs: Map; + let refs: Map; let libs: Map; let emittedImports: readonly AnyImportSyntax[] | undefined; // must be declared in container so it can be `undefined` while transformer's first pass const resolver = context.getEmitResolver(); @@ -107,7 +107,7 @@ namespace ts { } // Otherwise we should emit a path-based reference const container = getSourceFileOfNode(node); - refs.set("" + getOriginalNodeId(container), container); + refs.set(getOriginalNodeId(container), container); } function handleSymbolAccessibilityError(symbolAccessibilityResult: SymbolAccessibilityResult) { @@ -231,8 +231,8 @@ namespace ts { if (node.kind === SyntaxKind.Bundle) { isBundledEmit = true; - refs = createMap(); - libs = createMap(); + refs = new Map(); + libs = new Map(); let hasNoDefaultLib = false; const bundle = factory.createBundle(map(node.sourceFiles, sourceFile => { @@ -242,7 +242,7 @@ namespace ts { enclosingDeclaration = sourceFile; lateMarkedStatements = undefined; suppressNewDiagnosticContexts = false; - lateStatementReplacementMap = createMap(); + lateStatementReplacementMap = new Map(); getSymbolAccessibilityDiagnostic = throwDiagnostic; needsScopeFixMarker = false; resultHasScopeMarker = false; @@ -296,10 +296,10 @@ namespace ts { resultHasExternalModuleIndicator = false; suppressNewDiagnosticContexts = false; lateMarkedStatements = undefined; - lateStatementReplacementMap = createMap(); + lateStatementReplacementMap = new Map(); necessaryTypeReferences = undefined; - refs = collectReferences(currentSourceFile, createMap()); - libs = collectLibs(currentSourceFile, createMap()); + refs = collectReferences(currentSourceFile, new Map()); + libs = collectLibs(currentSourceFile, new Map()); const references: FileReference[] = []; const outputFilePath = getDirectoryPath(normalizeSlashes(getOutputPathsFor(node, host, /*forceDtsPaths*/ true).declarationFilePath!)); const referenceVisitor = mapReferencesIntoArray(references, outputFilePath); @@ -402,12 +402,12 @@ namespace ts { } } - function collectReferences(sourceFile: SourceFile | UnparsedSource, ret: Map) { + function collectReferences(sourceFile: SourceFile | UnparsedSource, ret: Map) { if (noResolve || (!isUnparsedSource(sourceFile) && isSourceFileJS(sourceFile))) return ret; forEach(sourceFile.referencedFiles, f => { const elem = host.getSourceFileFromReference(sourceFile, f); if (elem) { - ret.set("" + getOriginalNodeId(elem), elem); + ret.set(getOriginalNodeId(elem), elem); } }); return ret; @@ -772,7 +772,7 @@ namespace ts { needsDeclare = i.parent && isSourceFile(i.parent) && !(isExternalModule(i.parent) && isBundledEmit); const result = transformTopLevelDeclaration(i); needsDeclare = priorNeedsDeclare; - lateStatementReplacementMap.set("" + getOriginalNodeId(i), result); + lateStatementReplacementMap.set(getOriginalNodeId(i), result); } // And lastly, we need to get the final form of all those indetermine import declarations from before and add them to the output list @@ -781,7 +781,7 @@ namespace ts { function visitLateVisibilityMarkedStatements(statement: Statement) { if (isLateVisibilityPaintedStatement(statement)) { - const key = "" + getOriginalNodeId(statement); + const key = getOriginalNodeId(statement); if (lateStatementReplacementMap.has(key)) { const result = lateStatementReplacementMap.get(key); lateStatementReplacementMap.delete(key); @@ -1103,7 +1103,7 @@ namespace ts { const result = transformTopLevelDeclaration(input); // Don't actually transform yet; just leave as original node - will be elided/swapped by late pass - lateStatementReplacementMap.set("" + getOriginalNodeId(input), result); + lateStatementReplacementMap.set(getOriginalNodeId(input), result); return input; } @@ -1305,7 +1305,7 @@ namespace ts { needsDeclare = false; visitNode(inner, visitDeclarationStatements); // eagerly transform nested namespaces (the nesting doesn't need any elision or painting done) - const id = "" + getOriginalNodeId(inner!); // TODO: GH#18217 + const id = getOriginalNodeId(inner!); // TODO: GH#18217 const body = lateStatementReplacementMap.get(id); lateStatementReplacementMap.delete(id); return cleanup(factory.updateModuleDeclaration( diff --git a/src/compiler/transformers/es2015.ts b/src/compiler/transformers/es2015.ts index f9d94f3ee5976..82fc41b811dfb 100644 --- a/src/compiler/transformers/es2015.ts +++ b/src/compiler/transformers/es2015.ts @@ -2242,7 +2242,7 @@ namespace ts { function visitLabeledStatement(node: LabeledStatement): VisitResult { if (convertedLoopState && !convertedLoopState.labels) { - convertedLoopState.labels = createMap(); + convertedLoopState.labels = new Map(); } const statement = unwrapInnermostStatementOfLabel(node, convertedLoopState && recordLabel); return isIterationStatement(statement, /*lookInLabeledStatements*/ false) @@ -3279,13 +3279,13 @@ namespace ts { function setLabeledJump(state: ConvertedLoopState, isBreak: boolean, labelText: string, labelMarker: string): void { if (isBreak) { if (!state.labeledNonLocalBreaks) { - state.labeledNonLocalBreaks = createMap(); + state.labeledNonLocalBreaks = new Map(); } state.labeledNonLocalBreaks.set(labelText, labelMarker); } else { if (!state.labeledNonLocalContinues) { - state.labeledNonLocalContinues = createMap(); + state.labeledNonLocalContinues = new Map(); } state.labeledNonLocalContinues.set(labelText, labelMarker); } diff --git a/src/compiler/transformers/es2017.ts b/src/compiler/transformers/es2017.ts index 64971fffe6369..6c3c8c1332acf 100644 --- a/src/compiler/transformers/es2017.ts +++ b/src/compiler/transformers/es2017.ts @@ -37,12 +37,12 @@ namespace ts { */ let enclosingSuperContainerFlags: NodeCheckFlags = 0; - let enclosingFunctionParameterNames: UnderscoreEscapedMap; + let enclosingFunctionParameterNames: Set<__String>; /** * Keeps track of property names accessed on super (`super.x`) within async functions. */ - let capturedSuperProperties: UnderscoreEscapedMap; + let capturedSuperProperties: Set<__String>; /** Whether the async function contains an element access on super (`super[x]`). */ let hasSuperElementAccess: boolean; /** A set of node IDs for generated super accessors (variable statements). */ @@ -129,7 +129,7 @@ namespace ts { case SyntaxKind.PropertyAccessExpression: if (capturedSuperProperties && isPropertyAccessExpression(node) && node.expression.kind === SyntaxKind.SuperKeyword) { - capturedSuperProperties.set(node.name.escapedText, true); + capturedSuperProperties.add(node.name.escapedText); } return visitEachChild(node, visitor, context); @@ -184,15 +184,15 @@ namespace ts { } function visitCatchClauseInAsyncBody(node: CatchClause) { - const catchClauseNames = createUnderscoreEscapedMap(); + const catchClauseNames = new Set<__String>(); recordDeclarationName(node.variableDeclaration!, catchClauseNames); // TODO: GH#18217 // names declared in a catch variable are block scoped - let catchClauseUnshadowedNames: UnderscoreEscapedMap | undefined; + let catchClauseUnshadowedNames: Set<__String> | undefined; catchClauseNames.forEach((_, escapedName) => { if (enclosingFunctionParameterNames.has(escapedName)) { if (!catchClauseUnshadowedNames) { - catchClauseUnshadowedNames = cloneMap(enclosingFunctionParameterNames); + catchClauseUnshadowedNames = new Set(enclosingFunctionParameterNames); } catchClauseUnshadowedNames.delete(escapedName); } @@ -372,9 +372,9 @@ namespace ts { ); } - function recordDeclarationName({ name }: ParameterDeclaration | VariableDeclaration | BindingElement, names: UnderscoreEscapedMap) { + function recordDeclarationName({ name }: ParameterDeclaration | VariableDeclaration | BindingElement, names: Set<__String>) { if (isIdentifier(name)) { - names.set(name.escapedText, true); + names.add(name.escapedText); } else { for (const element of name.elements) { @@ -466,7 +466,7 @@ namespace ts { // promise constructor. const savedEnclosingFunctionParameterNames = enclosingFunctionParameterNames; - enclosingFunctionParameterNames = createUnderscoreEscapedMap(); + enclosingFunctionParameterNames = new Set(); for (const parameter of node.parameters) { recordDeclarationName(parameter, enclosingFunctionParameterNames); } @@ -474,7 +474,7 @@ namespace ts { const savedCapturedSuperProperties = capturedSuperProperties; const savedHasSuperElementAccess = hasSuperElementAccess; if (!isArrowFunction) { - capturedSuperProperties = createUnderscoreEscapedMap(); + capturedSuperProperties = new Set(); hasSuperElementAccess = false; } @@ -501,7 +501,7 @@ namespace ts { if (emitSuperHelpers) { enableSubstitutionForAsyncMethodsWithSuper(); - if (hasEntries(capturedSuperProperties)) { + if (capturedSuperProperties.size) { const variableStatement = createSuperAccessVariableStatement(factory, resolver, node, capturedSuperProperties); substitutedSuperAccessors[getNodeId(variableStatement)] = true; insertStatementsAfterStandardPrologue(statements, [variableStatement]); @@ -727,7 +727,7 @@ namespace ts { } /** Creates a variable named `_super` with accessor properties for the given property names. */ - export function createSuperAccessVariableStatement(factory: NodeFactory, resolver: EmitResolver, node: FunctionLikeDeclaration, names: UnderscoreEscapedMap) { + export function createSuperAccessVariableStatement(factory: NodeFactory, resolver: EmitResolver, node: FunctionLikeDeclaration, names: Set<__String>) { // Create a variable declaration with a getter/setter (if binding) definition for each name: // const _super = Object.create(null, { x: { get: () => super.x, set: (v) => super.x = v }, ... }); const hasBinding = (resolver.getNodeCheckFlags(node) & NodeCheckFlags.AsyncMethodWithSuperBinding) !== 0; diff --git a/src/compiler/transformers/es2018.ts b/src/compiler/transformers/es2018.ts index 143a864edb40b..f6c3ae6635431 100644 --- a/src/compiler/transformers/es2018.ts +++ b/src/compiler/transformers/es2018.ts @@ -66,7 +66,7 @@ namespace ts { let taggedTemplateStringDeclarations: VariableDeclaration[]; /** Keeps track of property names accessed on super (`super.x`) within async functions. */ - let capturedSuperProperties: UnderscoreEscapedMap; + let capturedSuperProperties: Set<__String>; /** Whether the async function contains an element access on super (`super[x]`). */ let hasSuperElementAccess: boolean; /** A set of node IDs for generated super accessors. */ @@ -240,7 +240,7 @@ namespace ts { return visitTaggedTemplateExpression(node as TaggedTemplateExpression); case SyntaxKind.PropertyAccessExpression: if (capturedSuperProperties && isPropertyAccessExpression(node) && node.expression.kind === SyntaxKind.SuperKeyword) { - capturedSuperProperties.set(node.name.escapedText, true); + capturedSuperProperties.add(node.name.escapedText); } return visitEachChild(node, visitor, context); case SyntaxKind.ElementAccessExpression: @@ -911,7 +911,7 @@ namespace ts { const savedCapturedSuperProperties = capturedSuperProperties; const savedHasSuperElementAccess = hasSuperElementAccess; - capturedSuperProperties = createUnderscoreEscapedMap(); + capturedSuperProperties = new Set(); hasSuperElementAccess = false; const returnStatement = factory.createReturnStatement( diff --git a/src/compiler/transformers/generators.ts b/src/compiler/transformers/generators.ts index 7b0f8419b0b59..ff1b8398fe1a4 100644 --- a/src/compiler/transformers/generators.ts +++ b/src/compiler/transformers/generators.ts @@ -2111,7 +2111,7 @@ namespace ts { const text = idText(variable.name); name = declareLocal(text); if (!renamedCatchVariables) { - renamedCatchVariables = createMap(); + renamedCatchVariables = new Map(); renamedCatchVariableDeclarations = []; context.enableSubstitution(SyntaxKind.Identifier); } diff --git a/src/compiler/transformers/jsx.ts b/src/compiler/transformers/jsx.ts index cc000666143c0..d399408fbe41f 100644 --- a/src/compiler/transformers/jsx.ts +++ b/src/compiler/transformers/jsx.ts @@ -315,7 +315,7 @@ namespace ts { } } - const entities = createMapFromTemplate({ + const entities = new Map(getEntries({ quot: 0x0022, amp: 0x0026, apos: 0x0027, @@ -569,5 +569,5 @@ namespace ts { clubs: 0x2663, hearts: 0x2665, diams: 0x2666 - }); + })); } diff --git a/src/compiler/transformers/module/esnextAnd2015.ts b/src/compiler/transformers/module/esnextAnd2015.ts index 1b87011064204..79eee5caa82b4 100644 --- a/src/compiler/transformers/module/esnextAnd2015.ts +++ b/src/compiler/transformers/module/esnextAnd2015.ts @@ -124,7 +124,7 @@ namespace ts { function onEmitNode(hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void): void { if (isSourceFile(node)) { if ((isExternalModule(node) || compilerOptions.isolatedModules) && compilerOptions.importHelpers) { - helperNameSubstitutions = createMap(); + helperNameSubstitutions = new Map(); } previousOnEmitNode(hint, node, emitCallback); helperNameSubstitutions = undefined; diff --git a/src/compiler/transformers/module/system.ts b/src/compiler/transformers/module/system.ts index 26590fbb5d9d1..07e99ed12610f 100644 --- a/src/compiler/transformers/module/system.ts +++ b/src/compiler/transformers/module/system.ts @@ -144,7 +144,7 @@ namespace ts { * @param externalImports The imports for the file. */ function collectDependencyGroups(externalImports: (ImportDeclaration | ImportEqualsDeclaration | ExportDeclaration)[]) { - const groupIndices = createMap(); + const groupIndices = new Map(); const dependencyGroups: DependencyGroup[] = []; for (const externalImport of externalImports) { const externalModuleName = getExternalModuleNameLiteral(factory, externalImport, currentSourceFile, host, resolver, compilerOptions); diff --git a/src/compiler/transformers/ts.ts b/src/compiler/transformers/ts.ts index 1eb4ddb777928..45cc2552adbb7 100644 --- a/src/compiler/transformers/ts.ts +++ b/src/compiler/transformers/ts.ts @@ -2528,7 +2528,7 @@ namespace ts { */ function recordEmittedDeclarationInScope(node: FunctionDeclaration | ClassDeclaration | ModuleDeclaration | EnumDeclaration) { if (!currentScopeFirstDeclarationsOfName) { - currentScopeFirstDeclarationsOfName = createUnderscoreEscapedMap(); + currentScopeFirstDeclarationsOfName = new Map(); } const name = declaredNameInScope(node); diff --git a/src/compiler/transformers/utilities.ts b/src/compiler/transformers/utilities.ts index 7c245ca2f1b43..34a1c01766225 100644 --- a/src/compiler/transformers/utilities.ts +++ b/src/compiler/transformers/utilities.ts @@ -69,7 +69,7 @@ namespace ts { const externalImports: (ImportDeclaration | ImportEqualsDeclaration | ExportDeclaration)[] = []; const exportSpecifiers = createMultiMap(); const exportedBindings: Identifier[][] = []; - const uniqueExports = createMap(); + const uniqueExports = new Map(); let exportedNames: Identifier[] | undefined; let hasExportDefault = false; let exportEquals: ExportAssignment | undefined; diff --git a/src/compiler/tsbuildPublic.ts b/src/compiler/tsbuildPublic.ts index 1fa6516340dca..dbb0d921679e6 100644 --- a/src/compiler/tsbuildPublic.ts +++ b/src/compiler/tsbuildPublic.ts @@ -63,7 +63,7 @@ namespace ts { } function getOrCreateValueMapFromConfigFileMap(configFileMap: Map>, resolved: ResolvedConfigFilePath): Map { - return getOrCreateValueFromConfigFileMap>(configFileMap, resolved, createMap); + return getOrCreateValueFromConfigFileMap>(configFileMap, resolved, () => new Map()); } function newer(date1: Date, date2: Date): Date { @@ -439,10 +439,12 @@ namespace ts { // Clear all to ResolvedConfigFilePaths cache to start fresh state.resolvedConfigFilePaths.clear(); - const currentProjects = arrayToSet( - getBuildOrderFromAnyBuildOrder(buildOrder), - resolved => toResolvedConfigFilePath(state, resolved) - ) as Map; + + // TODO(rbuckton): Should be a `Set`, but that requires changing the code below that uses `mutateMapSkippingNewValues` + const currentProjects = new Map( + getBuildOrderFromAnyBuildOrder(buildOrder).map( + resolved => [toResolvedConfigFilePath(state, resolved), true as true]) + ); const noopOnDelete = { onDeleteValue: noop }; // Config file cache @@ -1796,7 +1798,7 @@ namespace ts { if (!state.watch) return; updateWatchingWildcardDirectories( getOrCreateValueMapFromConfigFileMap(state.allWatchedWildcardDirectories, resolvedPath), - createMapFromTemplate(parsed.configFileSpecs!.wildcardDirectories), + new Map(getEntries(parsed.configFileSpecs!.wildcardDirectories)), (dir, flags) => state.watchDirectory( state.hostWithWatch, dir, diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 05ad94c7599f1..c70db08c4a45b 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -822,6 +822,9 @@ namespace ts { ReportsMask = ReportsUnmeasurable | ReportsUnreliable } + /* @internal */ + export type NodeId = number; + export interface Node extends ReadonlyTextRange { readonly kind: SyntaxKind; readonly flags: NodeFlags; @@ -829,7 +832,7 @@ namespace ts { /* @internal */ readonly transformFlags: TransformFlags; // Flags for transforms readonly decorators?: NodeArray; // Array of decorators (in document order) readonly modifiers?: ModifiersArray; // Array of modifiers - /* @internal */ id?: number; // Unique id (used to look up NodeLinks) + /* @internal */ id?: NodeId; // Unique id (used to look up NodeLinks) readonly parent: Node; // Parent node (initialized by binding) /* @internal */ original?: Node; // The original node if this is an updated node. /* @internal */ symbol: Symbol; // Symbol declared by node (initialized by binding) @@ -3445,7 +3448,7 @@ namespace ts { // Stores a line map for the file. // This field should never be used directly to obtain line map, use getLineMap function instead. /* @internal */ lineMap: readonly number[]; - /* @internal */ classifiableNames?: ReadonlyUnderscoreEscapedMap; + /* @internal */ classifiableNames?: ReadonlySet<__String>; // Comments containing @ts-* directives, in order. /* @internal */ commentDirectives?: CommentDirective[]; // Stores a mapping 'external module reference text' -> 'resolved file name' | undefined @@ -3724,7 +3727,7 @@ namespace ts { /* @internal */ getDiagnosticsProducingTypeChecker(): TypeChecker; /* @internal */ dropDiagnosticsProducingTypeChecker(): void; - /* @internal */ getClassifiableNames(): UnderscoreEscapedMap; + /* @internal */ getClassifiableNames(): Set<__String>; getNodeCount(): number; getIdentifierCount(): number; @@ -4575,6 +4578,9 @@ namespace ts { LateBindingContainer = Class | Interface | TypeLiteral | ObjectLiteral | Function, } + /* @internal */ + export type SymbolId = number; + export interface Symbol { flags: SymbolFlags; // Symbol flags escapedName: __String; // Name of symbol @@ -4583,7 +4589,7 @@ namespace ts { members?: SymbolTable; // Class, interface or object literal instance members exports?: SymbolTable; // Module exports globalExports?: SymbolTable; // Conditional global UMD exports - /* @internal */ id?: number; // Unique id (used to look up SymbolLinks) + /* @internal */ id?: SymbolId; // Unique id (used to look up SymbolLinks) /* @internal */ mergeId?: number; // Merge id (used to look up merged symbol) /* @internal */ parent?: Symbol; // Parent symbol /* @internal */ exportSymbol?: Symbol; // Exported symbol associated with this symbol @@ -4604,8 +4610,8 @@ namespace ts { declaredType?: Type; // Type of class, interface, enum, type alias, or type parameter typeParameters?: TypeParameter[]; // Type parameters of type alias (undefined if non-generic) outerTypeParameters?: TypeParameter[]; // Outer type parameters of anonymous object type - instantiations?: Map; // Instantiations of generic type alias (undefined if non-generic) - inferredClassSymbol?: Map; // Symbol of an inferred ES5 constructor function + instantiations?: Map; // Instantiations of generic type alias (undefined if non-generic) + inferredClassSymbol?: Map; // Symbol of an inferred ES5 constructor function mapper?: TypeMapper; // Type mapper for instantiation alias referenced?: boolean; // True if alias symbol has been referenced as a value that can be emitted constEnumReferenced?: boolean; // True if alias symbol resolves to a const enum and is referenced as a value ('referenced' will be false) @@ -4623,16 +4629,16 @@ namespace ts { exportsSomeValue?: boolean; // True if module exports some value (not just types) enumKind?: EnumKind; // Enum declaration classification originatingImport?: ImportDeclaration | ImportCall; // Import declaration which produced the symbol, present if the symbol is marked as uncallable but had call signatures in `resolveESModuleSymbol` - lateSymbol?: Symbol; // Late-bound symbol for a computed property - specifierCache?: Map; // For symbols corresponding to external modules, a cache of incoming path -> module specifier name mappings - extendedContainers?: Symbol[]; // Containers (other than the parent) which this symbol is aliased in - extendedContainersByFile?: Map; // Containers (other than the parent) which this symbol is aliased in - variances?: VarianceFlags[]; // Alias symbol type argument variance cache - deferralConstituents?: Type[]; // Calculated list of constituents for a deferred type - deferralParent?: Type; // Source union/intersection of a deferred type - cjsExportMerged?: Symbol; // Version of the symbol with all non export= exports merged with the export= target + lateSymbol?: Symbol; // Late-bound symbol for a computed property + specifierCache?: Map; // For symbols corresponding to external modules, a cache of incoming path -> module specifier name mappings + extendedContainers?: Symbol[]; // Containers (other than the parent) which this symbol is aliased in + extendedContainersByFile?: Map; // Containers (other than the parent) which this symbol is aliased in + variances?: VarianceFlags[]; // Alias symbol type argument variance cache + deferralConstituents?: Type[]; // Calculated list of constituents for a deferred type + deferralParent?: Type; // Source union/intersection of a deferred type + cjsExportMerged?: Symbol; // Version of the symbol with all non export= exports merged with the export= target typeOnlyDeclaration?: TypeOnlyCompatibleAliasDeclaration | false; // First resolved alias declaration that makes the symbol only usable in type constructs - isConstructorDeclaredProperty?: boolean; // Property declared through 'this.x = ...' assignment in constructor + isConstructorDeclaredProperty?: boolean; // Property declared through 'this.x = ...' assignment in constructor tupleLabelDeclaration?: NamedTupleMember | ParameterDeclaration; // Declaration associated with the tuple's label } @@ -4715,15 +4721,13 @@ namespace ts { * with a normal string (which is good, it cannot be misused on assignment or on usage), * while still being comparable with a normal string via === (also good) and castable from a string. */ - export type __String = (string & { __escapedIdentifier: void }) | (void & { __escapedIdentifier: void }) | InternalSymbolName; + export type __String = (string & { __escapedIdentifier: void }) | (void & { __escapedIdentifier: void }) | InternalSymbolName; // eslint-disable-line @typescript-eslint/naming-convention /** ReadonlyMap where keys are `__String`s. */ - export interface ReadonlyUnderscoreEscapedMap extends ReadonlyMap<__String, T> { - } + export type ReadonlyUnderscoreEscapedMap = ReadonlyMap<__String, T>; /** Map where keys are `__String`s. */ - export interface UnderscoreEscapedMap extends Map<__String, T>, ReadonlyUnderscoreEscapedMap { - } + export type UnderscoreEscapedMap = Map<__String, T>; /** SymbolTable based on ES6 Map interface. */ export type SymbolTable = UnderscoreEscapedMap; @@ -4764,31 +4768,31 @@ namespace ts { /* @internal */ export interface NodeLinks { - flags: NodeCheckFlags; // Set of flags specific to Node - resolvedType?: Type; // Cached type of type node - resolvedEnumType?: Type; // Cached constraint type from enum jsdoc tag - resolvedSignature?: Signature; // Cached signature of signature node or call expression - resolvedSymbol?: Symbol; // Cached name resolution result - resolvedIndexInfo?: IndexInfo; // Cached indexing info resolution result - effectsSignature?: Signature; // Signature with possible control flow effects + flags: NodeCheckFlags; // Set of flags specific to Node + resolvedType?: Type; // Cached type of type node + resolvedEnumType?: Type; // Cached constraint type from enum jsdoc tag + resolvedSignature?: Signature; // Cached signature of signature node or call expression + resolvedSymbol?: Symbol; // Cached name resolution result + resolvedIndexInfo?: IndexInfo; // Cached indexing info resolution result + effectsSignature?: Signature; // Signature with possible control flow effects enumMemberValue?: string | number; // Constant value of enum member - isVisible?: boolean; // Is this node visible + isVisible?: boolean; // Is this node visible containsArgumentsReference?: boolean; // Whether a function-like declaration contains an 'arguments' reference - hasReportedStatementInAmbientContext?: boolean; // Cache boolean if we report statements in ambient context - jsxFlags: JsxFlags; // flags for knowing what kind of element/attributes we're dealing with - resolvedJsxElementAttributesType?: Type; // resolved element attributes type of a JSX openinglike element - resolvedJsxElementAllAttributesType?: Type; // resolved all element attributes type of a JSX openinglike element - resolvedJSDocType?: Type; // Resolved type of a JSDoc type reference - switchTypes?: Type[]; // Cached array of switch case expression types - jsxNamespace?: Symbol | false; // Resolved jsx namespace symbol for this node - contextFreeType?: Type; // Cached context-free type used by the first pass of inference; used when a function's return is partially contextually sensitive - deferredNodes?: Map; // Set of nodes whose checking has been deferred + hasReportedStatementInAmbientContext?: boolean; // Cache boolean if we report statements in ambient context + jsxFlags: JsxFlags; // flags for knowing what kind of element/attributes we're dealing with + resolvedJsxElementAttributesType?: Type; // resolved element attributes type of a JSX openinglike element + resolvedJsxElementAllAttributesType?: Type; // resolved all element attributes type of a JSX openinglike element + resolvedJSDocType?: Type; // Resolved type of a JSDoc type reference + switchTypes?: Type[]; // Cached array of switch case expression types + jsxNamespace?: Symbol | false; // Resolved jsx namespace symbol for this node + contextFreeType?: Type; // Cached context-free type used by the first pass of inference; used when a function's return is partially contextually sensitive + deferredNodes?: Map; // Set of nodes whose checking has been deferred capturedBlockScopeBindings?: Symbol[]; // Block-scoped bindings captured beneath this part of an IterationStatement - outerTypeParameters?: TypeParameter[]; // Outer type parameters of anonymous object type - instantiations?: Map; // Instantiations of generic type alias (undefined if non-generic) - isExhaustive?: boolean; // Is node an exhaustive switch statement + outerTypeParameters?: TypeParameter[]; // Outer type parameters of anonymous object type + instantiations?: Map; // Instantiations of generic type alias (undefined if non-generic) + isExhaustive?: boolean; // Is node an exhaustive switch statement skipDirectInference?: true; // Flag set by the API `getContextualType` call on a node when `Completions` is passed to force the checker to skip making inferences to a node's type - declarationRequiresScopeChange?: boolean; // Set by `useOuterVariableScopeInParameter` in checker when downlevel emit would change the name resolution scope inside of a parameter. + declarationRequiresScopeChange?: boolean; // Set by `useOuterVariableScopeInParameter` in checker when downlevel emit would change the name resolution scope inside of a parameter. } export const enum TypeFlags { @@ -4880,16 +4884,19 @@ namespace ts { export type DestructuringPattern = BindingPattern | ObjectLiteralExpression | ArrayLiteralExpression; + /* @internal */ + export type TypeId = number; + // Properties common to all types export interface Type { flags: TypeFlags; // Flags - /* @internal */ id: number; // Unique ID + /* @internal */ id: TypeId; // Unique ID /* @internal */ checker: TypeChecker; symbol: Symbol; // Symbol associated with type (if any) pattern?: DestructuringPattern; // Destructuring pattern represented by type (if any) aliasSymbol?: Symbol; // Alias associated with type - aliasTypeArguments?: readonly Type[]; // Alias type arguments (if any) - /* @internal */ aliasTypeArgumentsContainsMarker?: boolean; // Alias type arguments (if any) + aliasTypeArguments?: readonly Type[]; // Alias type arguments (if any) + /* @internal */ aliasTypeArgumentsContainsMarker?: boolean; // Alias type arguments (if any) /* @internal */ permissiveInstantiation?: Type; // Instantiation with type parameters mapped to wildcard type /* @internal */ diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index a6978df31b5df..eec7cf1dce09c 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -1,8 +1,6 @@ /* @internal */ namespace ts { - export const resolvingEmptyArray: never[] = [] as never[]; - export const emptyMap = createMap() as ReadonlyMap & ReadonlyPragmaMap; - export const emptyUnderscoreEscapedMap: ReadonlyUnderscoreEscapedMap = emptyMap as ReadonlyUnderscoreEscapedMap; + export const resolvingEmptyArray: never[] = []; export const externalHelpersModuleNameText = "tslib"; @@ -22,17 +20,23 @@ namespace ts { return undefined; } - /** Create a new escaped identifier map. */ + /** + * Create a new escaped identifier map. + * @deprecated Use `new Map<__String, T>()` instead. + */ export function createUnderscoreEscapedMap(): UnderscoreEscapedMap { - return new Map() as UnderscoreEscapedMap; + return new Map<__String, T>(); } - export function hasEntries(map: ReadonlyUnderscoreEscapedMap | undefined): map is ReadonlyUnderscoreEscapedMap { + /** + * @deprecated Use `!!map?.size` instead + */ + export function hasEntries(map: ReadonlyCollection | undefined): map is ReadonlyCollection { return !!map && !!map.size; } export function createSymbolTable(symbols?: readonly Symbol[]): SymbolTable { - const result = createMap() as SymbolTable; + const result = new Map<__String, Symbol>(); if (symbols) { for (const symbol of symbols) { result.set(symbol.escapedName, symbol); @@ -163,27 +167,6 @@ namespace ts { }); } - /** - * Creates a set from the elements of an array. - * - * @param array the array of input elements. - */ - export function arrayToSet(array: readonly string[]): Map; - export function arrayToSet(array: readonly T[], makeKey: (value: T) => string | undefined): Map; - export function arrayToSet(array: readonly T[], makeKey: (value: T) => __String | undefined): UnderscoreEscapedMap; - export function arrayToSet(array: readonly any[], makeKey?: (value: any) => string | __String | undefined): Map | UnderscoreEscapedMap { - return arrayToMap(array, makeKey || (s => s), returnTrue); - } - - export function cloneMap(map: SymbolTable): SymbolTable; - export function cloneMap(map: ReadonlyUnderscoreEscapedMap): UnderscoreEscapedMap; - export function cloneMap(map: ReadonlyMap): Map; - export function cloneMap(map: ReadonlyMap): Map { - const clone = createMap(); - copyEntries(map, clone); - return clone; - } - export function usingSingleLineStringWriter(action: (writer: EmitTextWriter) => void): string { const oldString = stringWriter.getText(); try { @@ -206,7 +189,7 @@ namespace ts { export function setResolvedModule(sourceFile: SourceFile, moduleNameText: string, resolvedModule: ResolvedModuleFull): void { if (!sourceFile.resolvedModules) { - sourceFile.resolvedModules = createMap(); + sourceFile.resolvedModules = new Map(); } sourceFile.resolvedModules.set(moduleNameText, resolvedModule); @@ -214,7 +197,7 @@ namespace ts { export function setResolvedTypeReferenceDirective(sourceFile: SourceFile, typeReferenceDirectiveName: string, resolvedTypeReferenceDirective?: ResolvedTypeReferenceDirective): void { if (!sourceFile.resolvedTypeReferenceDirectiveNames) { - sourceFile.resolvedTypeReferenceDirectiveNames = createMap(); + sourceFile.resolvedTypeReferenceDirectiveNames = new Map(); } sourceFile.resolvedTypeReferenceDirectiveNames.set(typeReferenceDirectiveName, resolvedTypeReferenceDirective); @@ -473,7 +456,7 @@ namespace ts { ])) ); - const usedLines = createMap(); + const usedLines = new Map(); return { getUnusedExpectations, markUsed }; @@ -3586,7 +3569,7 @@ namespace ts { export function createDiagnosticCollection(): DiagnosticCollection { let nonFileDiagnostics = [] as Diagnostic[] as SortedArray; // See GH#19873 const filesWithDiagnostics = [] as string[] as SortedArray; - const fileDiagnostics = createMap>(); + const fileDiagnostics = new Map>(); let hasReadNonFileDiagnostics = false; return { @@ -3684,7 +3667,7 @@ namespace ts { const singleQuoteEscapedCharsRegExp = /[\\\'\u0000-\u001f\t\v\f\b\r\n\u2028\u2029\u0085]/g; // Template strings should be preserved as much as possible const backtickQuoteEscapedCharsRegExp = /[\\`]/g; - const escapedCharsMap = createMapFromTemplate({ + const escapedCharsMap = new Map(getEntries({ "\t": "\\t", "\v": "\\v", "\f": "\\f", @@ -3698,7 +3681,7 @@ namespace ts { "\u2028": "\\u2028", // lineSeparator "\u2029": "\\u2029", // paragraphSeparator "\u0085": "\\u0085" // nextLine - }); + })); function encodeUtf16EscapeSequence(charCode: number): string { const hexCharCode = charCode.toString(16).toUpperCase(); @@ -3748,10 +3731,10 @@ namespace ts { // the map below must be updated. const jsxDoubleQuoteEscapedCharsRegExp = /[\"\u0000-\u001f\u2028\u2029\u0085]/g; const jsxSingleQuoteEscapedCharsRegExp = /[\'\u0000-\u001f\u2028\u2029\u0085]/g; - const jsxEscapedCharsMap = createMapFromTemplate({ + const jsxEscapedCharsMap = new Map(getEntries({ "\"": """, "\'": "'" - }); + })); function encodeJsxCharacterEntity(charCode: number): string { const hexCharCode = charCode.toString(16).toUpperCase(); @@ -5938,7 +5921,7 @@ namespace ts { } export function discoverProbableSymlinks(files: readonly SourceFile[], getCanonicalFileName: GetCanonicalFileName, cwd: string): ReadonlyMap { - const result = createMap(); + const result = new Map(); const symlinks = flatten(mapDefined(files, sf => sf.resolvedModules && compact(arrayFrom(mapIterator(sf.resolvedModules.values(), res => res && res.originalPath && res.resolvedFileName !== res.originalPath ? [res.resolvedFileName, res.originalPath] as const : undefined))))); @@ -6196,7 +6179,7 @@ namespace ts { // Associate an array of results with each include regex. This keeps results in order of the "include" order. // If there are no "includes", then just put everything in results[0]. const results: string[][] = includeFileRegexes ? includeFileRegexes.map(() => []) : [[]]; - const visited = createMap(); + const visited = new Map(); const toCanonical = createGetCanonicalFileName(useCaseSensitiveFileNames); for (const basePath of patterns.basePaths) { visitDirectory(basePath, combinePaths(currentDirectory, basePath), depth); @@ -6560,67 +6543,17 @@ namespace ts { return { min, max }; } - export interface ReadonlyNodeSet { - has(node: TNode): boolean; - forEach(cb: (node: TNode) => void): void; - some(pred: (node: TNode) => boolean): boolean; - } + /** @deprecated Use `ReadonlySet` instead. */ + export type ReadonlyNodeSet = ReadonlySet; - export class NodeSet implements ReadonlyNodeSet { - private map = createMap(); + /** @deprecated Use `Set` instead. */ + export type NodeSet = Set; - add(node: TNode): void { - this.map.set(String(getNodeId(node)), node); - } - tryAdd(node: TNode): boolean { - if (this.has(node)) return false; - this.add(node); - return true; - } - has(node: TNode): boolean { - return this.map.has(String(getNodeId(node))); - } - forEach(cb: (node: TNode) => void): void { - this.map.forEach(cb); - } - some(pred: (node: TNode) => boolean): boolean { - return forEachEntry(this.map, pred) || false; - } - } + /** @deprecated Use `ReadonlyMap` instead. */ + export type ReadonlyNodeMap = ReadonlyMap; - export interface ReadonlyNodeMap { - get(node: TNode): TValue | undefined; - has(node: TNode): boolean; - } - - export class NodeMap implements ReadonlyNodeMap { - private map = createMap<{ node: TNode, value: TValue }>(); - - get(node: TNode): TValue | undefined { - const res = this.map.get(String(getNodeId(node))); - return res && res.value; - } - - getOrUpdate(node: TNode, setValue: () => TValue): TValue { - const res = this.get(node); - if (res) return res; - const value = setValue(); - this.set(node, value); - return value; - } - - set(node: TNode, value: TValue): void { - this.map.set(String(getNodeId(node)), { node, value }); - } - - has(node: TNode): boolean { - return this.map.has(String(getNodeId(node))); - } - - forEach(cb: (value: TValue, node: TNode) => void): void { - this.map.forEach(({ node, value }) => cb(value, node)); - } - } + /** @deprecated Use `Map` instead. */ + export type NodeMap = Map; export function rangeOfNode(node: Node): TextRange { return { pos: getTokenPosOfNode(node), end: node.end }; @@ -6648,18 +6581,6 @@ namespace ts { return a === b || typeof a === "object" && a !== null && typeof b === "object" && b !== null && equalOwnProperties(a as MapLike, b as MapLike, isJsonEqual); } - export function getOrUpdate(map: Map, key: string, getDefault: () => T): T { - const got = map.get(key); - if (got === undefined) { - const value = getDefault(); - map.set(key, value); - return value; - } - else { - return got; - } - } - /** * Converts a bigint literal string, e.g. `0x1234n`, * to its decimal string representation, e.g. `4660`. diff --git a/src/compiler/watchPublic.ts b/src/compiler/watchPublic.ts index 85c5859ee8cbc..72334f234f28e 100644 --- a/src/compiler/watchPublic.ts +++ b/src/compiler/watchPublic.ts @@ -252,7 +252,7 @@ namespace ts { let timerToInvalidateFailedLookupResolutions: any; // timer callback to invalidate resolutions for changes in failed lookup locations - const sourceFilesCache = createMap(); // Cache that stores the source file and version info + const sourceFilesCache = new Map(); // Cache that stores the source file and version info let missingFilePathsRequestedForRelease: Path[] | undefined; // These paths are held temparirly so that we can remove the entry from source file cache if the file is not tracked by missing files let hasChangedCompilerOptions = false; // True if the compiler options have changed between compilations @@ -717,8 +717,8 @@ namespace ts { function watchConfigFileWildCardDirectories() { if (configFileSpecs) { updateWatchingWildcardDirectories( - watchedWildcardDirectories || (watchedWildcardDirectories = createMap()), - createMapFromTemplate(configFileSpecs.wildcardDirectories), + watchedWildcardDirectories || (watchedWildcardDirectories = new Map()), + new Map(getEntries(configFileSpecs.wildcardDirectories)), watchWildcardDirectory ); } diff --git a/src/compiler/watchUtilities.ts b/src/compiler/watchUtilities.ts index f6fd12e29e5a8..c1a320507f09b 100644 --- a/src/compiler/watchUtilities.ts +++ b/src/compiler/watchUtilities.ts @@ -44,7 +44,7 @@ namespace ts { return undefined; } - const cachedReadDirectoryResult = createMap(); + const cachedReadDirectoryResult = new Map(); const getCanonicalFileName = createGetCanonicalFileName(useCaseSensitiveFileNames); return { useCaseSensitiveFileNames, @@ -266,7 +266,8 @@ namespace ts { createMissingFileWatch: (missingFilePath: Path) => FileWatcher, ) { const missingFilePaths = program.getMissingFilePaths(); - const newMissingFilePathMap = arrayToSet(missingFilePaths); + // TODO(rbuckton): Should be a `Set` but that requires changing the below code that uses `mutateMap` + const newMissingFilePathMap = arrayToMap(missingFilePaths, identity, returnTrue); // Update the missing file paths watcher mutateMap( missingFileWatches, diff --git a/src/executeCommandLine/executeCommandLine.ts b/src/executeCommandLine/executeCommandLine.ts index e2e802f1afedc..66b2548dbe26c 100644 --- a/src/executeCommandLine/executeCommandLine.ts +++ b/src/executeCommandLine/executeCommandLine.ts @@ -75,7 +75,7 @@ namespace ts { const usageColumn: string[] = []; // Things like "-d, --declaration" go in here. const descriptionColumn: string[] = []; - const optionsDescriptionMap = createMap(); // Map between option.description and list of option.type if it is a kind + const optionsDescriptionMap = new Map(); // Map between option.description and list of option.type if it is a kind for (const option of optionsList) { // If an option lacks a description, diff --git a/src/harness/client.ts b/src/harness/client.ts index 32b9b7f4e16e3..19a7924701095 100644 --- a/src/harness/client.ts +++ b/src/harness/client.ts @@ -35,7 +35,7 @@ namespace ts.server { export class SessionClient implements LanguageService { private sequence = 0; - private lineMaps: Map = createMap(); + private lineMaps: Map = new Map(); private messages: string[] = []; private lastRenameEntry: RenameEntry | undefined; diff --git a/src/harness/fourslashImpl.ts b/src/harness/fourslashImpl.ts index 88ba1fa6508c7..00371a3b1b363 100644 --- a/src/harness/fourslashImpl.ts +++ b/src/harness/fourslashImpl.ts @@ -177,7 +177,7 @@ namespace FourSlash { public formatCodeSettings: ts.FormatCodeSettings; - private inputFiles = ts.createMap(); // Map between inputFile's fileName and its content for easily looking up when resolving references + private inputFiles = new ts.Map(); // Map between inputFile's fileName and its content for easily looking up when resolving references private static getDisplayPartsJson(displayParts: ts.SymbolDisplayPart[] | undefined) { let result = ""; @@ -830,7 +830,7 @@ namespace FourSlash { this.raiseError(`Expected 'isGlobalCompletion to be ${options.isGlobalCompletion}, got ${actualCompletions.isGlobalCompletion}`); } - const nameToEntries = ts.createMap(); + const nameToEntries = new ts.Map(); for (const entry of actualCompletions.entries) { const entries = nameToEntries.get(entry.name); if (!entries) { @@ -995,7 +995,7 @@ namespace FourSlash { } public setTypesRegistry(map: ts.MapLike): void { - this.languageServiceAdapterHost.typesRegistry = ts.createMapFromTemplate(map); + this.languageServiceAdapterHost.typesRegistry = new ts.Map(ts.getEntries(map)); } public verifyTypeOfSymbolAtLocation(range: Range, symbol: ts.Symbol, expected: string): void { @@ -2888,7 +2888,7 @@ namespace FourSlash { public verifyBraceCompletionAtPosition(negative: boolean, openingBrace: string) { - const openBraceMap = ts.createMapFromTemplate({ + const openBraceMap = new ts.Map(ts.getEntries({ "(": ts.CharacterCodes.openParen, "{": ts.CharacterCodes.openBrace, "[": ts.CharacterCodes.openBracket, @@ -2896,7 +2896,7 @@ namespace FourSlash { '"': ts.CharacterCodes.doubleQuote, "`": ts.CharacterCodes.backtick, "<": ts.CharacterCodes.lessThan - }); + })); const charCode = openBraceMap.get(openingBrace); @@ -3509,7 +3509,7 @@ namespace FourSlash { let text = ""; if (callHierarchyItem) { const file = this.findFile(callHierarchyItem.file); - text += this.formatCallHierarchyItem(file, callHierarchyItem, CallHierarchyItemDirection.Root, ts.createMap(), ""); + text += this.formatCallHierarchyItem(file, callHierarchyItem, CallHierarchyItemDirection.Root, new ts.Map(), ""); } return text; } @@ -3805,7 +3805,7 @@ namespace FourSlash { const lines = contents.split("\n"); let i = 0; - const markerPositions = ts.createMap(); + const markerPositions = new ts.Map(); const markers: Marker[] = []; const ranges: Range[] = []; @@ -4194,7 +4194,7 @@ namespace FourSlash { /** Collects an array of unique outputs. */ function unique(inputs: readonly T[], getOutput: (t: T) => string): string[] { - const set = ts.createMap(); + const set = new ts.Map(); for (const input of inputs) { const out = getOutput(input); set.set(out, true); diff --git a/src/harness/harnessIO.ts b/src/harness/harnessIO.ts index 5f68d021fee16..e0bb3c5116020 100644 --- a/src/harness/harnessIO.ts +++ b/src/harness/harnessIO.ts @@ -251,9 +251,9 @@ namespace Harness { } if (!libFileNameSourceFileMap) { - libFileNameSourceFileMap = ts.createMapFromTemplate({ + libFileNameSourceFileMap = new ts.Map(ts.getEntries({ [defaultLibFileName]: createSourceFileAndAssertInvariants(defaultLibFileName, IO.readFile(libFolder + "lib.es5.d.ts")!, /*languageVersion*/ ts.ScriptTarget.Latest) - }); + })); } let sourceFile = libFileNameSourceFileMap.get(fileName); @@ -316,7 +316,7 @@ namespace Harness { let optionsIndex: ts.Map; function getCommandLineOption(name: string): ts.CommandLineOption | undefined { if (!optionsIndex) { - optionsIndex = ts.createMap(); + optionsIndex = new ts.Map(); const optionDeclarations = harnessOptionDeclarations.concat(ts.optionDeclarations); for (const option of optionDeclarations) { optionsIndex.set(option.name.toLowerCase(), option); @@ -595,7 +595,7 @@ namespace Harness { errorsReported = 0; // 'merge' the lines of each input file with any errors associated with it - const dupeCase = ts.createMap(); + const dupeCase = new ts.Map(); for (const inputFile of inputFiles.filter(f => f.content !== undefined)) { // Filter down to the errors in the file const fileErrors = diagnostics.filter((e): e is ts.DiagnosticWithLocation => { @@ -775,7 +775,7 @@ namespace Harness { if (skipBaseline) { return; } - const dupeCase = ts.createMap(); + const dupeCase = new ts.Map(); for (const file of allFiles) { const { unitName } = file; @@ -946,7 +946,7 @@ namespace Harness { // Collect, test, and sort the fileNames const files = Array.from(outputFiles); files.slice().sort((a, b) => ts.compareStringsCaseSensitive(cleanName(a.file), cleanName(b.file))); - const dupeCase = ts.createMap(); + const dupeCase = new ts.Map(); // Yield them for (const outputFile of files) { yield [checkDuplicatedFileName(outputFile.file, dupeCase), "/*====== " + outputFile.file + " ======*/\r\n" + Utils.removeByteOrderMark(outputFile.text)]; @@ -1075,10 +1075,10 @@ namespace Harness { return option.type; } if (option.type === "boolean") { - return booleanVaryByStarSettingValues || (booleanVaryByStarSettingValues = ts.createMapFromTemplate({ + return booleanVaryByStarSettingValues || (booleanVaryByStarSettingValues = new ts.Map(ts.getEntries({ true: 1, false: 0 - })); + }))); } } } @@ -1403,7 +1403,7 @@ namespace Harness { export function runMultifileBaseline(relativeFileBase: string, extension: string, generateContent: () => IterableIterator<[string, string, number]> | IterableIterator<[string, string]> | null, opts?: BaselineOptions, referencedExtensions?: string[]): void { const gen = generateContent(); - const writtenFiles = ts.createMap(); + const writtenFiles = new ts.Map(); const errors: Error[] = []; // eslint-disable-next-line no-null/no-null diff --git a/src/harness/harnessUtils.ts b/src/harness/harnessUtils.ts index c63afb323a901..d9f410c9945d0 100644 --- a/src/harness/harnessUtils.ts +++ b/src/harness/harnessUtils.ts @@ -52,7 +52,7 @@ namespace Utils { } export function memoize(f: T, memoKey: (...anything: any[]) => string): T { - const cache = ts.createMap(); + const cache = new ts.Map(); return (function (this: any, ...args: any[]) { const key = memoKey(...args); diff --git a/src/harness/loggedIO.ts b/src/harness/loggedIO.ts index fa2c1235d71c5..543079f37107d 100644 --- a/src/harness/loggedIO.ts +++ b/src/harness/loggedIO.ts @@ -219,7 +219,7 @@ namespace Playback { replayLog = log; // Remove non-found files from the log (shouldn't really need them, but we still record them for diagnostic purposes) replayLog.filesRead = replayLog.filesRead.filter(f => f.result!.contents !== undefined); - replayFilesRead = ts.createMap(); + replayFilesRead = new ts.Map(); for (const file of replayLog.filesRead) { replayFilesRead.set(ts.normalizeSlashes(file.path).toLowerCase(), file); } diff --git a/src/harness/sourceMapRecorder.ts b/src/harness/sourceMapRecorder.ts index 668c7812366bf..0d9fd7a1aab5d 100644 --- a/src/harness/sourceMapRecorder.ts +++ b/src/harness/sourceMapRecorder.ts @@ -325,7 +325,7 @@ namespace Harness.SourceMapRecorder { export function getSourceMapRecordWithSystem(sys: ts.System, sourceMapFile: string) { const sourceMapRecorder = new Compiler.WriterAggregator(); let prevSourceFile: documents.TextDocument | undefined; - const files = ts.createMap(); + const files = new ts.Map(); const sourceMap = ts.tryParseRawSourceMap(sys.readFile(sourceMapFile, "utf8")!); if (sourceMap) { const mapDirectory = ts.getDirectoryPath(sourceMapFile); diff --git a/src/harness/virtualFileSystemWithWatch.ts b/src/harness/virtualFileSystemWithWatch.ts index d20e847d57d06..849f9241a79a6 100644 --- a/src/harness/virtualFileSystemWithWatch.ts +++ b/src/harness/virtualFileSystemWithWatch.ts @@ -133,7 +133,7 @@ interface Array { length: number; [n: number]: T; }` } const notInActual: string[] = []; const duplicates: string[] = []; - const seen = createMap(); + const seen = new Map(); forEach(expectedKeys, expectedKey => { if (seen.has(expectedKey)) { duplicates.push(expectedKey); @@ -260,20 +260,20 @@ interface Array { length: number; [n: number]: T; }` } export function checkOutputContains(host: TestServerHost, expected: readonly string[]) { - const mapExpected = arrayToSet(expected); - const mapSeen = createMap(); + const mapExpected = new Set(expected); + const mapSeen = new Set(); for (const f of host.getOutput()) { - assert.isUndefined(mapSeen.get(f), `Already found ${f} in ${JSON.stringify(host.getOutput())}`); + assert.isFalse(mapSeen.has(f), `Already found ${f} in ${JSON.stringify(host.getOutput())}`); if (mapExpected.has(f)) { mapExpected.delete(f); - mapSeen.set(f, true); + mapSeen.add(f); } } assert.equal(mapExpected.size, 0, `Output has missing ${JSON.stringify(arrayFrom(mapExpected.keys()))} in ${JSON.stringify(host.getOutput())}`); } export function checkOutputDoesNotContain(host: TestServerHost, expectedToBeAbsent: string[] | readonly string[]) { - const mapExpectedToBeAbsent = arrayToSet(expectedToBeAbsent); + const mapExpectedToBeAbsent = new Set(expectedToBeAbsent); for (const f of host.getOutput()) { assert.isFalse(mapExpectedToBeAbsent.has(f), `Contains ${f} in ${JSON.stringify(host.getOutput())}`); } diff --git a/src/jsTyping/jsTyping.ts b/src/jsTyping/jsTyping.ts index e1cb9ebfd5584..3b69e797634a7 100644 --- a/src/jsTyping/jsTyping.ts +++ b/src/jsTyping/jsTyping.ts @@ -68,7 +68,7 @@ namespace ts.JsTyping { "zlib" ]; - export const nodeCoreModules = arrayToSet(nodeCoreModuleList); + export const nodeCoreModules = new Set(nodeCoreModuleList); export function nonRelativeModuleNameForTypingCache(moduleName: string) { return nodeCoreModules.has(moduleName) ? "node" : moduleName; @@ -81,13 +81,13 @@ namespace ts.JsTyping { export function loadSafeList(host: TypingResolutionHost, safeListPath: Path): SafeList { const result = readConfigFile(safeListPath, path => host.readFile(path)); - return createMapFromTemplate(result.config); + return new Map(getEntries(result.config)); } export function loadTypesMap(host: TypingResolutionHost, typesMapPath: Path): SafeList | undefined { const result = readConfigFile(typesMapPath, path => host.readFile(path)); if (result.config) { - return createMapFromTemplate(result.config.simpleMap); + return new Map(getEntries(result.config.simpleMap)); } return undefined; } @@ -118,7 +118,7 @@ namespace ts.JsTyping { } // A typing name to typing file path mapping - const inferredTypings = createMap(); + const inferredTypings = new Map(); // Only infer typings for .js and .jsx files fileNames = mapDefined(fileNames, fileName => { @@ -134,9 +134,9 @@ namespace ts.JsTyping { const exclude = typeAcquisition.exclude || []; // Directories to search for package.json, bower.json and other typing information - const possibleSearchDirs = arrayToSet(fileNames, getDirectoryPath); - possibleSearchDirs.set(projectRootPath, true); - possibleSearchDirs.forEach((_true, searchDir) => { + const possibleSearchDirs = new Set(fileNames.map(getDirectoryPath)); + possibleSearchDirs.add(projectRootPath); + possibleSearchDirs.forEach((searchDir) => { const packageJsonPath = combinePaths(searchDir, "package.json"); getTypingNamesFromJson(packageJsonPath, filesToWatch); diff --git a/src/server/editorServices.ts b/src/server/editorServices.ts index 0722616ed6b2c..1dfb899a2c174 100644 --- a/src/server/editorServices.ts +++ b/src/server/editorServices.ts @@ -158,7 +158,7 @@ namespace ts.server { } function prepareConvertersForEnumLikeCompilerOptions(commandLineOptions: CommandLineOption[]): Map> { - const map: Map> = createMap>(); + const map: Map> = new Map>(); for (const option of commandLineOptions) { if (typeof option.type === "object") { const optionMap = >option.type; @@ -174,11 +174,11 @@ namespace ts.server { const compilerOptionConverters = prepareConvertersForEnumLikeCompilerOptions(optionDeclarations); const watchOptionsConverters = prepareConvertersForEnumLikeCompilerOptions(optionsForWatch); - const indentStyle = createMapFromTemplate({ + const indentStyle = new Map(getEntries({ none: IndentStyle.None, block: IndentStyle.Block, smart: IndentStyle.Smart - }); + })); export interface TypesMapFile { typesMap: SafeList; @@ -571,16 +571,16 @@ namespace ts.server { * Container of all known scripts */ /*@internal*/ - readonly filenameToScriptInfo = createMap(); - private readonly scriptInfoInNodeModulesWatchers = createMap (); + readonly filenameToScriptInfo = new Map(); + private readonly scriptInfoInNodeModulesWatchers = new Map(); /** * Contains all the deleted script info's version information so that * it does not reset when creating script info again * (and could have potentially collided with version where contents mismatch) */ - private readonly filenameToScriptInfoVersion = createMap(); + private readonly filenameToScriptInfoVersion = new Map(); // Set of all '.js' files ever opened. - private readonly allJsFilesForOpenFileTelemetry = createMap(); + private readonly allJsFilesForOpenFileTelemetry = new Map(); /** * Map to the real path of the infos @@ -590,7 +590,7 @@ namespace ts.server { /** * maps external project file name to list of config files that were the part of this project */ - private readonly externalProjectToConfiguredProjectMap: Map = createMap(); + private readonly externalProjectToConfiguredProjectMap: Map = new Map(); /** * external projects (configuration and list of root files is not controlled by tsserver) @@ -603,7 +603,7 @@ namespace ts.server { /** * projects specified by a tsconfig.json file */ - readonly configuredProjects = createMap(); + readonly configuredProjects = new Map(); /** * Open files: with value being project root path, and key being Path of the file that is open */ @@ -611,16 +611,16 @@ namespace ts.server { /** * Map of open files that are opened without complete path but have projectRoot as current directory */ - private readonly openFilesWithNonRootedDiskPath = createMap(); + private readonly openFilesWithNonRootedDiskPath = new Map(); private compilerOptionsForInferredProjects: CompilerOptions | undefined; - private compilerOptionsForInferredProjectsPerProjectRoot = createMap(); + private compilerOptionsForInferredProjectsPerProjectRoot = new Map(); private watchOptionsForInferredProjects: WatchOptions | undefined; - private watchOptionsForInferredProjectsPerProjectRoot = createMap(); + private watchOptionsForInferredProjectsPerProjectRoot = new Map(); /** * Project size for configured or external projects */ - private readonly projectToSizeMap: Map = createMap(); + private readonly projectToSizeMap: Map = new Map(); /** * This is a map of config file paths existence that doesnt need query to disk * - The entry can be present because there is inferred project that needs to watch addition of config file to directory @@ -628,14 +628,14 @@ namespace ts.server { * - Or it is present if we have configured project open with config file at that location * In this case the exists property is always true */ - private readonly configFileExistenceInfoCache = createMap(); + private readonly configFileExistenceInfoCache = new Map(); /*@internal*/ readonly throttledOperations: ThrottledOperations; private readonly hostConfiguration: HostConfiguration; private safelist: SafeList = defaultTypeSafeList; - private readonly legacySafelist = createMap(); + private readonly legacySafelist = new Map(); - private pendingProjectUpdates = createMap(); + private pendingProjectUpdates = new Map(); /* @internal */ pendingEnsureProjectForOpenFiles = false; @@ -663,7 +663,7 @@ namespace ts.server { public readonly syntaxOnly?: boolean; /** Tracks projects that we have already sent telemetry for. */ - private readonly seenProjects = createMap(); + private readonly seenProjects = new Map(); /*@internal*/ readonly watchFactory: WatchFactory; @@ -2039,7 +2039,7 @@ namespace ts.server { project.setCompilerOptions(compilerOptions); project.setWatchOptions(parsedCommandLine.watchOptions); project.enableLanguageService(); - project.watchWildcards(createMapFromTemplate(parsedCommandLine.wildcardDirectories!)); // TODO: GH#18217 + project.watchWildcards(new Map(getEntries(parsedCommandLine.wildcardDirectories!))); // TODO: GH#18217 } project.enablePluginsWithOptions(compilerOptions, this.currentPluginConfigOverrides); const filesToAdd = parsedCommandLine.fileNames.concat(project.getExternalFiles()); @@ -2048,7 +2048,7 @@ namespace ts.server { private updateNonInferredProjectFiles(project: ExternalProject | ConfiguredProject | AutoImportProviderProject, files: T[], propertyReader: FilePropertyReader) { const projectRootFilesMap = project.getRootFilesMap(); - const newRootScriptInfoMap = createMap(); + const newRootScriptInfoMap = new Map(); for (const f of files) { const newRootFile = propertyReader.getFileName(f); @@ -2772,7 +2772,7 @@ namespace ts.server { * reloadForInfo provides a way to filter out files to reload configured project for */ private reloadConfiguredProjectForFiles(openFiles: Map, delayReload: boolean, shouldReloadProjectFor: (openFileValue: T) => boolean, reason: string) { - const updatedProjects = createMap(); + const updatedProjects = new Map(); // try to reload config file for all open files openFiles.forEach((openFileValue, path) => { // Filter out the files that need to be ignored @@ -3153,7 +3153,7 @@ namespace ts.server { } private removeOrphanConfiguredProjects(toRetainConfiguredProjects: readonly ConfiguredProject[] | ConfiguredProject | undefined) { - const toRemoveConfiguredProjects = cloneMap(this.configuredProjects); + const toRemoveConfiguredProjects = new Map(this.configuredProjects); const markOriginalProjectsAsUsed = (project: Project) => { if (!project.isOrphan() && project.originalConfiguredProjects) { project.originalConfiguredProjects.forEach( @@ -3208,7 +3208,7 @@ namespace ts.server { } private removeOrphanScriptInfos() { - const toRemoveScriptInfos = cloneMap(this.filenameToScriptInfo); + const toRemoveScriptInfos = new Map(this.filenameToScriptInfo); this.filenameToScriptInfo.forEach(info => { // If script info is open or orphan, retain it and its dependencies if (!info.isScriptOpen() && info.isOrphan() && !info.isContainedByAutoImportProvider()) { @@ -3686,7 +3686,7 @@ namespace ts.server { // Also save the current configuration to pass on to any projects that are yet to be loaded. // If a plugin is configured twice, only the latest configuration will be remembered. - this.currentPluginConfigOverrides = this.currentPluginConfigOverrides || createMap(); + this.currentPluginConfigOverrides = this.currentPluginConfigOverrides || new Map(); this.currentPluginConfigOverrides.set(args.pluginName, args.configuration); } @@ -3721,7 +3721,7 @@ namespace ts.server { /*@internal*/ private watchPackageJsonFile(path: Path) { - const watchers = this.packageJsonFilesMap || (this.packageJsonFilesMap = createMap()); + const watchers = this.packageJsonFilesMap || (this.packageJsonFilesMap = new Map()); if (!watchers.has(path)) { this.invalidateProjectAutoImports(path); watchers.set(path, this.watchFactory.watchFile( diff --git a/src/server/packageJsonCache.ts b/src/server/packageJsonCache.ts index 18a4a8a36bf61..8c09ebda2c4d6 100644 --- a/src/server/packageJsonCache.ts +++ b/src/server/packageJsonCache.ts @@ -11,8 +11,8 @@ namespace ts.server { } export function createPackageJsonCache(host: ProjectService): PackageJsonCache { - const packageJsons = createMap(); - const directoriesWithoutPackageJson = createMap(); + const packageJsons = new Map(); + const directoriesWithoutPackageJson = new Map(); return { addOrUpdate, forEach: packageJsons.forEach.bind(packageJsons), diff --git a/src/server/project.ts b/src/server/project.ts index 9bdbb194472f1..6c5e9b70dd16f 100644 --- a/src/server/project.ts +++ b/src/server/project.ts @@ -127,7 +127,7 @@ namespace ts.server { export abstract class Project implements LanguageServiceHost, ModuleResolutionHost { private rootFiles: ScriptInfo[] = []; - private rootFilesMap = createMap(); + private rootFilesMap = new Map(); private program: Program | undefined; private externalFiles: SortedReadonlyArray | undefined; private missingFilesMap: Map | undefined; @@ -1281,7 +1281,7 @@ namespace ts.server { if (this.generatedFilesMap.has(path)) return; } else { - this.generatedFilesMap = createMap(); + this.generatedFilesMap = new Map(); } this.generatedFilesMap.set(path, this.createGeneratedFileWatcher(generatedFile)); } @@ -1959,7 +1959,7 @@ namespace ts.server { pendingReloadReason: string | undefined; /* @internal */ - openFileWatchTriggered = createMap(); + openFileWatchTriggered = new Map(); /*@internal*/ configFileSpecs: ConfigFileSpecs | undefined; @@ -2169,7 +2169,7 @@ namespace ts.server { /*@internal*/ watchWildcards(wildcardDirectories: Map) { updateWatchingWildcardDirectories( - this.directoriesWatchedForWildcards || (this.directoriesWatchedForWildcards = createMap()), + this.directoriesWatchedForWildcards || (this.directoriesWatchedForWildcards = new Map()), wildcardDirectories, // Create new directory watcher (directory, flags) => this.projectService.watchWildcardDirectory(directory as Path, flags, this), diff --git a/src/server/session.ts b/src/server/session.ts index d02b8dd0e85dc..d8c35c7924c2a 100644 --- a/src/server/session.ts +++ b/src/server/session.ts @@ -1434,7 +1434,7 @@ namespace ts.server { } private toSpanGroups(locations: readonly RenameLocation[]): readonly protocol.SpanGroup[] { - const map = createMap(); + const map = new Map(); for (const { fileName, textSpan, contextSpan, originalContextSpan: _2, originalTextSpan: _, originalFileName: _1, ...prefixSuffixText } of locations) { let group = map.get(fileName); if (!group) map.set(fileName, group = { file: fileName, locs: [] }); @@ -2338,7 +2338,7 @@ namespace ts.server { return { response, responseRequired: true }; } - private handlers = createMapFromTemplate<(request: protocol.Request) => HandlerResponse>({ + private handlers = new Map(getEntries<(request: protocol.Request) => HandlerResponse>({ [CommandNames.Status]: () => { const response: protocol.StatusResponseBody = { version: ts.version }; // eslint-disable-line @typescript-eslint/no-unnecessary-qualifier return this.requiredResponse(response); @@ -2697,7 +2697,7 @@ namespace ts.server { [CommandNames.ProvideCallHierarchyOutgoingCalls]: (request: protocol.ProvideCallHierarchyOutgoingCallsRequest) => { return this.requiredResponse(this.provideCallHierarchyOutgoingCalls(request.arguments)); }, - }); + })); public addProtocolHandler(command: string, handler: (request: protocol.Request) => HandlerResponse) { if (this.handlers.has(command)) { diff --git a/src/server/typingsCache.ts b/src/server/typingsCache.ts index e46fab53c79ab..f3ce3e9e7907c 100644 --- a/src/server/typingsCache.ts +++ b/src/server/typingsCache.ts @@ -41,7 +41,7 @@ namespace ts.server { if ((arr1 || emptyArray).length === 0 && (arr2 || emptyArray).length === 0) { return true; } - const set: Map = createMap(); + const set: Map = new Map(); let unique = 0; for (const v of arr1!) { @@ -83,7 +83,7 @@ namespace ts.server { /*@internal*/ export class TypingsCache { - private readonly perProjectCache: Map = createMap(); + private readonly perProjectCache: Map = new Map(); constructor(private readonly installer: ITypingsInstaller) { } diff --git a/src/server/utilities.ts b/src/server/utilities.ts index 651c11555da02..dc3e1bf8b4a7d 100644 --- a/src/server/utilities.ts +++ b/src/server/utilities.ts @@ -1,7 +1,7 @@ /* @internal */ namespace ts.server { export class ThrottledOperations { - private readonly pendingTimeouts: Map = createMap(); + private readonly pendingTimeouts: Map = new Map(); private readonly logger?: Logger | undefined; constructor(private readonly host: ServerHost, logger: Logger) { this.logger = logger.hasLevel(LogLevel.verbose) ? logger : undefined; diff --git a/src/server/utilitiesPublic.ts b/src/server/utilitiesPublic.ts index 5e9ba6b973223..42f97a435f5eb 100644 --- a/src/server/utilitiesPublic.ts +++ b/src/server/utilitiesPublic.ts @@ -80,7 +80,7 @@ namespace ts.server { } export function createNormalizedPathMap(): NormalizedPathMap { - const map = createMap(); + const map = new Map(); return { get(path) { return map.get(path); diff --git a/src/services/callHierarchy.ts b/src/services/callHierarchy.ts index 2718c76963a8a..9934c91c88e1d 100644 --- a/src/services/callHierarchy.ts +++ b/src/services/callHierarchy.ts @@ -304,7 +304,7 @@ namespace ts.CallHierarchy { } function getCallSiteGroupKey(entry: CallSite) { - return "" + getNodeId(entry.declaration); + return getNodeId(entry.declaration); } function createCallHierarchyIncomingCall(from: CallHierarchyItem, fromSpans: TextSpan[]): CallHierarchyIncomingCall { diff --git a/src/services/classifier.ts b/src/services/classifier.ts index d10f67e0e941e..d6d4ebff38b46 100644 --- a/src/services/classifier.ts +++ b/src/services/classifier.ts @@ -452,7 +452,7 @@ namespace ts { } /* @internal */ - export function getSemanticClassifications(typeChecker: TypeChecker, cancellationToken: CancellationToken, sourceFile: SourceFile, classifiableNames: UnderscoreEscapedMap, span: TextSpan): ClassifiedSpan[] { + export function getSemanticClassifications(typeChecker: TypeChecker, cancellationToken: CancellationToken, sourceFile: SourceFile, classifiableNames: ReadonlySet<__String>, span: TextSpan): ClassifiedSpan[] { return convertClassificationsToSpans(getEncodedSemanticClassifications(typeChecker, cancellationToken, sourceFile, classifiableNames, span)); } @@ -477,7 +477,7 @@ namespace ts { } /* @internal */ - export function getEncodedSemanticClassifications(typeChecker: TypeChecker, cancellationToken: CancellationToken, sourceFile: SourceFile, classifiableNames: UnderscoreEscapedMap, span: TextSpan): Classifications { + export function getEncodedSemanticClassifications(typeChecker: TypeChecker, cancellationToken: CancellationToken, sourceFile: SourceFile, classifiableNames: ReadonlySet<__String>, span: TextSpan): Classifications { const spans: number[] = []; sourceFile.forEachChild(function cb(node: Node): void { // Only walk into nodes that intersect the requested span. diff --git a/src/services/codeFixProvider.ts b/src/services/codeFixProvider.ts index ab88aa97a3d7e..aee5a199fad5b 100644 --- a/src/services/codeFixProvider.ts +++ b/src/services/codeFixProvider.ts @@ -1,7 +1,7 @@ /* @internal */ namespace ts.codefix { const errorCodeToFixes = createMultiMap(); - const fixIdToRegistration = createMap(); + const fixIdToRegistration = new Map(); export type DiagnosticAndArguments = DiagnosticMessage | [DiagnosticMessage, string] | [DiagnosticMessage, string, string]; function diagnosticToString(diag: DiagnosticAndArguments): string { diff --git a/src/services/codefixes/addMissingConst.ts b/src/services/codefixes/addMissingConst.ts index 1c819cafe0f73..5f15572c9789f 100644 --- a/src/services/codefixes/addMissingConst.ts +++ b/src/services/codefixes/addMissingConst.ts @@ -16,12 +16,12 @@ namespace ts.codefix { }, fixIds: [fixId], getAllCodeActions: context => { - const fixedNodes = new NodeSet(); + const fixedNodes = new Set(); return codeFixAll(context, errorCodes, (changes, diag) => makeChange(changes, diag.file, diag.start, context.program, fixedNodes)); }, }); - function makeChange(changeTracker: textChanges.ChangeTracker, sourceFile: SourceFile, pos: number, program: Program, fixedNodes?: NodeSet) { + function makeChange(changeTracker: textChanges.ChangeTracker, sourceFile: SourceFile, pos: number, program: Program, fixedNodes?: Set) { const token = getTokenAtPosition(sourceFile, pos); const forInitializer = findAncestor(token, node => isForInOrOfStatement(node.parent) ? node.parent.initializer === node : @@ -57,8 +57,8 @@ namespace ts.codefix { } } - function applyChange(changeTracker: textChanges.ChangeTracker, initializer: Node, sourceFile: SourceFile, fixedNodes?: NodeSet) { - if (!fixedNodes || fixedNodes.tryAdd(initializer)) { + function applyChange(changeTracker: textChanges.ChangeTracker, initializer: Node, sourceFile: SourceFile, fixedNodes?: Set) { + if (!fixedNodes || tryAddToSet(fixedNodes, initializer)) { changeTracker.insertModifierBefore(sourceFile, SyntaxKind.ConstKeyword, initializer); } } diff --git a/src/services/codefixes/addMissingDeclareProperty.ts b/src/services/codefixes/addMissingDeclareProperty.ts index e08929b9dd132..f7b9369f95715 100644 --- a/src/services/codefixes/addMissingDeclareProperty.ts +++ b/src/services/codefixes/addMissingDeclareProperty.ts @@ -15,19 +15,19 @@ namespace ts.codefix { }, fixIds: [fixId], getAllCodeActions: context => { - const fixedNodes = new NodeSet(); + const fixedNodes = new Set(); return codeFixAll(context, errorCodes, (changes, diag) => makeChange(changes, diag.file, diag.start, fixedNodes)); }, }); - function makeChange(changeTracker: textChanges.ChangeTracker, sourceFile: SourceFile, pos: number, fixedNodes?: NodeSet) { + function makeChange(changeTracker: textChanges.ChangeTracker, sourceFile: SourceFile, pos: number, fixedNodes?: Set) { const token = getTokenAtPosition(sourceFile, pos); if (!isIdentifier(token)) { return; } const declaration = token.parent; if (declaration.kind === SyntaxKind.PropertyDeclaration && - (!fixedNodes || fixedNodes.tryAdd(declaration))) { + (!fixedNodes || tryAddToSet(fixedNodes, declaration))) { changeTracker.insertModifierBefore(sourceFile, SyntaxKind.DeclareKeyword, declaration); } } diff --git a/src/services/codefixes/convertToAsyncFunction.ts b/src/services/codefixes/convertToAsyncFunction.ts index 03a7f167cff91..556ab6c1d4750 100644 --- a/src/services/codefixes/convertToAsyncFunction.ts +++ b/src/services/codefixes/convertToAsyncFunction.ts @@ -61,7 +61,7 @@ namespace ts.codefix { return; } - const synthNamesMap: Map = createMap(); + const synthNamesMap: Map = new Map(); const isInJavascript = isInJSFile(functionToConvert); const setOfExpressionsToReturn = getAllPromiseExpressionsToReturn(functionToConvert, checker); const functionToConvertRenamed = renameCollidingVarNames(functionToConvert, checker, synthNamesMap, context.sourceFile); @@ -149,7 +149,7 @@ namespace ts.codefix { It then checks for any collisions and renames them through getSynthesizedDeepClone */ function renameCollidingVarNames(nodeToRename: FunctionLikeDeclaration, checker: TypeChecker, synthNamesMap: Map, sourceFile: SourceFile): FunctionLikeDeclaration { - const identsToRenameMap = createMap(); // key is the symbol id + const identsToRenameMap = new Map(); // key is the symbol id const collidingSymbolMap = createMultiMap(); forEachChild(nodeToRename, function visit(node: Node) { if (!isIdentifier(node)) { diff --git a/src/services/codefixes/convertToEs6Module.ts b/src/services/codefixes/convertToEs6Module.ts index 77f18a8b5cefa..ea334c9ed48d1 100644 --- a/src/services/codefixes/convertToEs6Module.ts +++ b/src/services/codefixes/convertToEs6Module.ts @@ -63,7 +63,7 @@ namespace ts.codefix { type ExportRenames = ReadonlyMap; function collectExportRenames(sourceFile: SourceFile, checker: TypeChecker, identifiers: Identifiers): ExportRenames { - const res = createMap(); + const res = new Map(); forEachExportReference(sourceFile, node => { const { text, originalKeywordKind } = node.name; if (!res.has(text) && (originalKeywordKind !== undefined && isNonContextualKeyword(originalKeywordKind) @@ -274,9 +274,9 @@ namespace ts.codefix { // `module.exports = require("x");` ==> `export * from "x"; export { default } from "x";` const moduleSpecifier = reExported.text; const moduleSymbol = checker.getSymbolAtLocation(reExported); - const exports = moduleSymbol ? moduleSymbol.exports! : emptyUnderscoreEscapedMap; - return exports.has("export=" as __String) ? [[reExportDefault(moduleSpecifier)], true] : - !exports.has("default" as __String) ? [[reExportStar(moduleSpecifier)], false] : + const exports = moduleSymbol ? moduleSymbol.exports! : emptyMap as ReadonlyCollection<__String>; + return exports.has(InternalSymbolName.ExportEquals) ? [[reExportDefault(moduleSpecifier)], true] : + !exports.has(InternalSymbolName.Default) ? [[reExportStar(moduleSpecifier)], false] : // If there's some non-default export, must include both `export *` and `export default`. exports.size > 1 ? [[reExportStar(moduleSpecifier), reExportDefault(moduleSpecifier)], true] : [[reExportDefault(moduleSpecifier)], true]; } @@ -388,7 +388,7 @@ namespace ts.codefix { function convertSingleIdentifierImport(file: SourceFile, name: Identifier, moduleSpecifier: StringLiteralLike, changes: textChanges.ChangeTracker, checker: TypeChecker, identifiers: Identifiers, quotePreference: QuotePreference): readonly Node[] { const nameSymbol = checker.getSymbolAtLocation(name); // Maps from module property name to name actually used. (The same if there isn't shadowing.) - const namedBindingsNames = createMap(); + const namedBindingsNames = new Map(); // True if there is some non-property use like `x()` or `f(x)`. let needDefaultImport = false; diff --git a/src/services/codefixes/convertToTypeOnlyExport.ts b/src/services/codefixes/convertToTypeOnlyExport.ts index 35510249927a9..cc36a7e7a8608 100644 --- a/src/services/codefixes/convertToTypeOnlyExport.ts +++ b/src/services/codefixes/convertToTypeOnlyExport.ts @@ -12,7 +12,7 @@ namespace ts.codefix { }, fixIds: [fixId], getAllCodeActions: context => { - const fixedExportDeclarations = createMap(); + const fixedExportDeclarations = new Map(); return codeFixAll(context, errorCodes, (changes, diag) => { const exportSpecifier = getExportSpecifierForDiagnosticSpan(diag, context.sourceFile); if (exportSpecifier && !addToSeen(fixedExportDeclarations, getNodeId(exportSpecifier.parent.parent))) { diff --git a/src/services/codefixes/fixAddMissingMember.ts b/src/services/codefixes/fixAddMissingMember.ts index 9d48f054226b9..28bc1da2d6bdc 100644 --- a/src/services/codefixes/fixAddMissingMember.ts +++ b/src/services/codefixes/fixAddMissingMember.ts @@ -27,9 +27,9 @@ namespace ts.codefix { getAllCodeActions: context => { const { program } = context; const checker = program.getTypeChecker(); - const seen = createMap(); + const seen = new Map(); - const typeDeclToMembers = new NodeMap(); + const typeDeclToMembers = new Map(); return createCombinedCodeActions(textChanges.ChangeTracker.with(context, changes => { eachDiagnostic(context, errorCodes, diag => { @@ -44,7 +44,7 @@ namespace ts.codefix { } else { const { parentDeclaration, token } = info; - const infos = typeDeclToMembers.getOrUpdate(parentDeclaration, () => []); + const infos = getOrUpdate(typeDeclToMembers, parentDeclaration, () => []); if (!infos.some(i => i.token.text === token.text)) infos.push(info); } }); diff --git a/src/services/codefixes/fixAwaitInSyncFunction.ts b/src/services/codefixes/fixAwaitInSyncFunction.ts index f09b204de64b7..c47ff6e71650d 100644 --- a/src/services/codefixes/fixAwaitInSyncFunction.ts +++ b/src/services/codefixes/fixAwaitInSyncFunction.ts @@ -16,7 +16,7 @@ namespace ts.codefix { }, fixIds: [fixId], getAllCodeActions: context => { - const seen = createMap(); + const seen = new Map(); return codeFixAll(context, errorCodes, (changes, diag) => { const nodes = getNodes(diag.file, diag.start); if (!nodes || !addToSeen(seen, getNodeId(nodes.insertBefore))) return; diff --git a/src/services/codefixes/fixClassDoesntImplementInheritedAbstractMember.ts b/src/services/codefixes/fixClassDoesntImplementInheritedAbstractMember.ts index eac02f0d7135a..449093203c6dc 100644 --- a/src/services/codefixes/fixClassDoesntImplementInheritedAbstractMember.ts +++ b/src/services/codefixes/fixClassDoesntImplementInheritedAbstractMember.ts @@ -15,7 +15,7 @@ namespace ts.codefix { }, fixIds: [fixId], getAllCodeActions: context => { - const seenClassDeclarations = createMap(); + const seenClassDeclarations = new Map(); return codeFixAll(context, errorCodes, (changes, diag) => { const classDeclaration = getClass(diag.file, diag.start); if (addToSeen(seenClassDeclarations, getNodeId(classDeclaration))) { diff --git a/src/services/codefixes/fixClassIncorrectlyImplementsInterface.ts b/src/services/codefixes/fixClassIncorrectlyImplementsInterface.ts index 954a64ef53dcd..56ef05bf453f6 100644 --- a/src/services/codefixes/fixClassIncorrectlyImplementsInterface.ts +++ b/src/services/codefixes/fixClassIncorrectlyImplementsInterface.ts @@ -17,7 +17,7 @@ namespace ts.codefix { }, fixIds: [fixId], getAllCodeActions(context) { - const seenClassDeclarations = createMap(); + const seenClassDeclarations = new Map(); return codeFixAll(context, errorCodes, (changes, diag) => { const classDeclaration = getClass(diag.file, diag.start); if (addToSeen(seenClassDeclarations, getNodeId(classDeclaration))) { diff --git a/src/services/codefixes/fixClassSuperMustPrecedeThisAccess.ts b/src/services/codefixes/fixClassSuperMustPrecedeThisAccess.ts index 1c26c39b10c1a..dc8f261cc266b 100644 --- a/src/services/codefixes/fixClassSuperMustPrecedeThisAccess.ts +++ b/src/services/codefixes/fixClassSuperMustPrecedeThisAccess.ts @@ -15,7 +15,7 @@ namespace ts.codefix { fixIds: [fixId], getAllCodeActions(context) { const { sourceFile } = context; - const seenClasses = createMap(); // Ensure we only do this once per class. + const seenClasses = new Map(); // Ensure we only do this once per class. return codeFixAll(context, errorCodes, (changes, diag) => { const nodes = getNodes(diag.file, diag.start); if (!nodes) return; diff --git a/src/services/codefixes/importFixes.ts b/src/services/codefixes/importFixes.ts index f1d2996d7e662..7ac2fff75f5c3 100644 --- a/src/services/codefixes/importFixes.ts +++ b/src/services/codefixes/importFixes.ts @@ -47,8 +47,8 @@ namespace ts.codefix { const addToNamespace: FixUseNamespaceImport[] = []; const importType: FixUseImportType[] = []; // Keys are import clause node IDs. - const addToExisting = createMap<{ readonly importClauseOrBindingPattern: ImportClause | ObjectBindingPattern, defaultImport: string | undefined; readonly namedImports: string[], canUseTypeOnlyImport: boolean }>(); - const newImports = createMap>(); + const addToExisting = new Map(); + const newImports = new Map>(); return { addImportFromDiagnostic, addImportFromExportedSymbol, writeFixes }; function addImportFromDiagnostic(diagnostic: DiagnosticWithLocation, context: CodeFixContextBase) { diff --git a/src/services/codefixes/inferFromUsage.ts b/src/services/codefixes/inferFromUsage.ts index bd5782d7a0fe5..d986b81c88439 100644 --- a/src/services/codefixes/inferFromUsage.ts +++ b/src/services/codefixes/inferFromUsage.ts @@ -501,7 +501,7 @@ namespace ts.codefix { } function combineUsages(usages: Usage[]): Usage { - const combinedProperties = createUnderscoreEscapedMap(); + const combinedProperties = new Map<__String, Usage[]>(); for (const u of usages) { if (u.properties) { u.properties.forEach((p, name) => { @@ -512,7 +512,7 @@ namespace ts.codefix { }); } } - const properties = createUnderscoreEscapedMap(); + const properties = new Map<__String, Usage>(); combinedProperties.forEach((ps, name) => { properties.set(name, combineUsages(ps)); }); @@ -821,7 +821,7 @@ namespace ts.codefix { function inferTypeFromPropertyAccessExpression(parent: PropertyAccessExpression, usage: Usage): void { const name = escapeLeadingUnderscores(parent.name.text); if (!usage.properties) { - usage.properties = createUnderscoreEscapedMap(); + usage.properties = new Map(); } const propertyUsage = usage.properties.get(name) || createEmptyUsage(); calculateUsageOfNode(parent, propertyUsage); @@ -975,7 +975,7 @@ namespace ts.codefix { } function inferStructuralType(usage: Usage) { - const members = createUnderscoreEscapedMap(); + const members = new Map<__String, Symbol>(); if (usage.properties) { usage.properties.forEach((u, name) => { const symbol = checker.createSymbol(SymbolFlags.Property, name); diff --git a/src/services/completions.ts b/src/services/completions.ts index 989aff628bdf8..5698454b0339b 100644 --- a/src/services/completions.ts +++ b/src/services/completions.ts @@ -293,7 +293,7 @@ namespace ts.Completions { } if (keywordFilters !== KeywordCompletionFilters.None) { - const entryNames = arrayToSet(entries, e => e.name); + const entryNames = new Set(entries.map(e => e.name)); for (const keywordEntry of getKeywordCompletions(keywordFilters, !insideJsDocTagTypeExpression && isSourceFileJS(sourceFile))) { if (!entryNames.has(keywordEntry.name)) { entries.push(keywordEntry); @@ -491,7 +491,7 @@ namespace ts.Completions { // Value is set to false for global variables or completions from external module exports, because we can have multiple of those; // true otherwise. Based on the order we add things we will always see locals first, then globals, then module exports. // So adding a completion for a local will prevent us from adding completions for external module exports sharing the same name. - const uniques = createMap(); + const uniques = new Map(); for (const symbol of symbols) { const origin = symbolToOriginInfoMap ? symbolToOriginInfoMap[getSymbolId(symbol)] : undefined; const info = getCompletionEntryDisplayNameForSymbol(symbol, target, origin, kind, !!jsxIdentifierExpected); @@ -549,7 +549,7 @@ namespace ts.Completions { function getLabelStatementCompletions(node: Node): CompletionEntry[] { const entries: CompletionEntry[] = []; - const uniques = createMap(); + const uniques = new Map(); let current = node; while (current) { @@ -1541,7 +1541,7 @@ namespace ts.Completions { } /** True if symbol is a type or a module containing at least one type. */ - function symbolCanBeReferencedAtTypeLocation(symbol: Symbol, seenModules = createMap()): boolean { + function symbolCanBeReferencedAtTypeLocation(symbol: Symbol, seenModules = new Map()): boolean { const sym = skipAlias(symbol.exportSymbol || symbol, typeChecker); return !!(sym.flags & SymbolFlags.Type) || !!(sym.flags & SymbolFlags.Module) && @@ -1609,16 +1609,16 @@ namespace ts.Completions { const startTime = timestamp(); log(`getSymbolsFromOtherSourceFileExports: Recomputing list${detailsEntryId ? " for details entry" : ""}`); - const seenResolvedModules = createMap(); - const seenExports = createMap(); + const seenResolvedModules = new Map(); + const seenExports = new Map(); /** Bucket B */ - const aliasesToAlreadyIncludedSymbols = createMap(); + const aliasesToAlreadyIncludedSymbols = new Map(); /** Bucket C */ - const aliasesToReturnIfOriginalsAreMissing = createMap<{ alias: Symbol, moduleSymbol: Symbol, isFromPackageJson: boolean }>(); + const aliasesToReturnIfOriginalsAreMissing = new Map(); /** Bucket A */ const results: AutoImportSuggestion[] = []; /** Ids present in `results` for faster lookup */ - const resultSymbolIds = createMap(); + const resultSymbolIds = new Map(); codefix.forEachExternalModuleToImportFrom(program, host, sourceFile, !detailsEntryId, /*useAutoImportProvider*/ true, (moduleSymbol, _, program, isFromPackageJson) => { // Perf -- ignore other modules if this is a request for details @@ -1944,8 +1944,8 @@ namespace ts.Completions { completionKind = CompletionKind.MemberLike; isNewIdentifierLocation = false; const exports = typeChecker.getExportsAndPropertiesOfModule(moduleSpecifierSymbol); - const existing = arrayToSet(namedImportsOrExports.elements, n => isCurrentlyEditingNode(n) ? undefined : (n.propertyName || n.name).escapedText); - symbols = exports.filter(e => e.escapedName !== InternalSymbolName.Default && !existing.get(e.escapedName)); + const existing = new Set((namedImportsOrExports.elements as NodeArray).filter(n => !isCurrentlyEditingNode(n)).map(n => (n.propertyName || n.name).escapedText)); + symbols = exports.filter(e => e.escapedName !== InternalSymbolName.Default && !existing.has(e.escapedName)); return GlobalsSearch.Success; } @@ -2316,7 +2316,7 @@ namespace ts.Completions { } const membersDeclaredBySpreadAssignment = new Set(); - const existingMemberNames = createUnderscoreEscapedMap(); + const existingMemberNames = new Set<__String>(); for (const m of existingMembers) { // Ignore omitted expressions for missing members if (m.kind !== SyntaxKind.PropertyAssignment && @@ -2353,10 +2353,12 @@ namespace ts.Completions { existingName = name && isPropertyNameLiteral(name) ? getEscapedTextOfIdentifierOrLiteral(name) : undefined; } - existingMemberNames.set(existingName!, true); // TODO: GH#18217 + if (existingName !== undefined) { + existingMemberNames.add(existingName); + } } - const filteredSymbols = contextualMemberSymbols.filter(m => !existingMemberNames.get(m.escapedName)); + const filteredSymbols = contextualMemberSymbols.filter(m => !existingMemberNames.has(m.escapedName)); setSortTextToMemberDeclaredBySpreadAssignment(membersDeclaredBySpreadAssignment, filteredSymbols); return filteredSymbols; @@ -2401,7 +2403,7 @@ namespace ts.Completions { * @returns Symbols to be suggested in an class element depending on existing memebers and symbol flags */ function filterClassMembersList(baseSymbols: readonly Symbol[], existingMembers: readonly ClassElement[], currentClassElementModifierFlags: ModifierFlags): Symbol[] { - const existingMemberNames = createUnderscoreEscapedMap(); + const existingMemberNames = new Set<__String>(); for (const m of existingMembers) { // Ignore omitted expressions for missing members if (m.kind !== SyntaxKind.PropertyDeclaration && @@ -2428,7 +2430,7 @@ namespace ts.Completions { const existingName = getPropertyNameForPropertyNameNode(m.name!); if (existingName) { - existingMemberNames.set(existingName, true); + existingMemberNames.add(existingName); } } @@ -2446,7 +2448,7 @@ namespace ts.Completions { * do not occur at the current position and have not otherwise been typed. */ function filterJsxAttributes(symbols: Symbol[], attributes: NodeArray): Symbol[] { - const seenNames = createUnderscoreEscapedMap(); + const seenNames = new Set<__String>(); const membersDeclaredBySpreadAssignment = new Set(); for (const attr of attributes) { // If this is the current item we are editing right now, do not filter it out @@ -2455,13 +2457,13 @@ namespace ts.Completions { } if (attr.kind === SyntaxKind.JsxAttribute) { - seenNames.set(attr.name.escapedText, true); + seenNames.add(attr.name.escapedText); } else if (isJsxSpreadAttribute(attr)) { setMembersDeclaredBySpreadAssignment(attr, membersDeclaredBySpreadAssignment); } } - const filteredSymbols = symbols.filter(a => !seenNames.get(a.escapedName)); + const filteredSymbols = symbols.filter(a => !seenNames.has(a.escapedName)); setSortTextToMemberDeclaredBySpreadAssignment(membersDeclaredBySpreadAssignment, filteredSymbols); diff --git a/src/services/documentRegistry.ts b/src/services/documentRegistry.ts index 2e97689bfbf9a..6d3836b1b6974 100644 --- a/src/services/documentRegistry.ts +++ b/src/services/documentRegistry.ts @@ -170,7 +170,7 @@ namespace ts { acquiring: boolean, scriptKind?: ScriptKind): SourceFile { - const bucket = getOrUpdate>(buckets, key, createMap); + const bucket = getOrUpdate(buckets, key, () => new Map()); let entry = bucket.get(path); const scriptTarget = scriptKind === ScriptKind.JSON ? ScriptTarget.JSON : compilationSettings.target || ScriptTarget.ES5; if (!entry && externalCache) { diff --git a/src/services/findAllReferences.ts b/src/services/findAllReferences.ts index b1e98f240bd69..61d7c44812d52 100644 --- a/src/services/findAllReferences.ts +++ b/src/services/findAllReferences.ts @@ -229,7 +229,7 @@ namespace ts.FindAllReferences { } else { const queue = entries && [...entries]; - const seenNodes = createMap(); + const seenNodes = new Map(); while (queue && queue.length) { const entry = queue.shift() as NodeEntry; if (!addToSeen(seenNodes, getNodeId(entry.node))) { @@ -946,7 +946,7 @@ namespace ts.FindAllReferences { */ class State { /** Cache for `explicitlyinheritsFrom`. */ - readonly inheritsFromCache = createMap(); + readonly inheritsFromCache = new Map(); /** * Type nodes can contain multiple references to the same type. For example: diff --git a/src/services/importTracker.ts b/src/services/importTracker.ts index b783532b85976..7f5979b1aa858 100644 --- a/src/services/importTracker.ts +++ b/src/services/importTracker.ts @@ -369,7 +369,7 @@ namespace ts.FindAllReferences { /** Returns a map from a module symbol Id to all import statements that directly reference the module. */ function getDirectImportsMap(sourceFiles: readonly SourceFile[], checker: TypeChecker, cancellationToken: CancellationToken | undefined): Map { - const map = createMap(); + const map = new Map(); for (const sourceFile of sourceFiles) { if (cancellationToken) cancellationToken.throwIfCancellationRequested(); diff --git a/src/services/navigationBar.ts b/src/services/navigationBar.ts index 9e8cc060d42dd..7cdfe5204fe20 100644 --- a/src/services/navigationBar.ts +++ b/src/services/navigationBar.ts @@ -128,7 +128,7 @@ namespace ts.NavigationBar { function addTrackedEs5Class(name: string) { if (!trackedEs5Classes) { - trackedEs5Classes = createMap(); + trackedEs5Classes = new Map(); } trackedEs5Classes.set(name, true); } @@ -443,7 +443,7 @@ namespace ts.NavigationBar { /** Merge declarations of the same kind. */ function mergeChildren(children: NavigationBarNode[], node: NavigationBarNode): void { - const nameToItems = createMap(); + const nameToItems = new Map(); filterMutate(children, (child, index) => { const declName = child.name || getNameOfDeclaration(child.node); const name = declName && nodeText(declName); diff --git a/src/services/patternMatcher.ts b/src/services/patternMatcher.ts index e6fda18ab3c9c..f35b83b376984 100644 --- a/src/services/patternMatcher.ts +++ b/src/services/patternMatcher.ts @@ -102,7 +102,7 @@ namespace ts { // we see the name of a module that is used everywhere, or the name of an overload). As // such, we cache the information we compute about the candidate for the life of this // pattern matcher so we don't have to compute it multiple times. - const stringToWordSpans = createMap(); + const stringToWordSpans = new Map(); const dotSeparatedSegments = pattern.trim().split(".").map(p => createSegment(p.trim())); // A segment is considered invalid if we couldn't find any words in it. diff --git a/src/services/refactorProvider.ts b/src/services/refactorProvider.ts index f88613ecea7f6..120f33962ebec 100644 --- a/src/services/refactorProvider.ts +++ b/src/services/refactorProvider.ts @@ -2,7 +2,7 @@ namespace ts.refactor { // A map with the refactor code as key, the refactor itself as value // e.g. nonSuggestableRefactors[refactorCode] -> the refactor you want - const refactors: Map = createMap(); + const refactors: Map = new Map(); /** @param name An unique code associated with each refactor. Does not have to be human-readable. */ export function registerRefactor(name: string, refactor: Refactor) { diff --git a/src/services/refactors/convertImport.ts b/src/services/refactors/convertImport.ts index 5ab2b316d5cc8..1ad43126d5d20 100644 --- a/src/services/refactors/convertImport.ts +++ b/src/services/refactors/convertImport.ts @@ -74,7 +74,7 @@ namespace ts.refactor { let usedAsNamespaceOrDefault = false; const nodesToReplace: PropertyAccessExpression[] = []; - const conflictingNames = createMap(); + const conflictingNames = new Map(); FindAllReferences.Core.eachSymbolReferenceInFile(toConvert.name, checker, sourceFile, id => { if (!isPropertyAccessExpression(id.parent)) { @@ -92,7 +92,7 @@ namespace ts.refactor { }); // We may need to change `mod.x` to `_x` to avoid a name conflict. - const exportNameToImportName = createMap(); + const exportNameToImportName = new Map(); for (const propertyAccess of nodesToReplace) { const exportName = propertyAccess.name.text; diff --git a/src/services/refactors/extractSymbol.ts b/src/services/refactors/extractSymbol.ts index 451ac6359b9ab..d37032d71cd85 100644 --- a/src/services/refactors/extractSymbol.ts +++ b/src/services/refactors/extractSymbol.ts @@ -43,11 +43,11 @@ namespace ts.refactor.extractSymbol { } const functionActions: RefactorActionInfo[] = []; - const usedFunctionNames: Map = createMap(); + const usedFunctionNames: Map = new Map(); let innermostErrorFunctionAction: RefactorActionInfo | undefined; const constantActions: RefactorActionInfo[] = []; - const usedConstantNames: Map = createMap(); + const usedConstantNames: Map = new Map(); let innermostErrorConstantAction: RefactorActionInfo | undefined; let i = 0; @@ -1545,13 +1545,13 @@ namespace ts.refactor.extractSymbol { checker: TypeChecker, cancellationToken: CancellationToken): ReadsAndWrites { - const allTypeParameterUsages = createMap(); // Key is type ID + const allTypeParameterUsages = new Map(); // Key is type ID const usagesPerScope: ScopeUsages[] = []; const substitutionsPerScope: Map[] = []; const functionErrorsPerScope: Diagnostic[][] = []; const constantErrorsPerScope: Diagnostic[][] = []; const visibleDeclarationsInExtractedRange: NamedDeclaration[] = []; - const exposedVariableSymbolSet = createMap(); // Key is symbol ID + const exposedVariableSymbolSet = new Map(); // Key is symbol ID const exposedVariableDeclarations: VariableDeclaration[] = []; let firstExposedNonVariableDeclaration: NamedDeclaration | undefined; @@ -1574,8 +1574,8 @@ namespace ts.refactor.extractSymbol { // initialize results for (const scope of scopes) { - usagesPerScope.push({ usages: createMap(), typeParameterUsages: createMap(), substitutions: createMap() }); - substitutionsPerScope.push(createMap()); + usagesPerScope.push({ usages: new Map(), typeParameterUsages: new Map(), substitutions: new Map() }); + substitutionsPerScope.push(new Map()); functionErrorsPerScope.push( isFunctionLikeDeclaration(scope) && scope.kind !== SyntaxKind.FunctionDeclaration @@ -1596,7 +1596,7 @@ namespace ts.refactor.extractSymbol { constantErrorsPerScope.push(constantErrors); } - const seenUsages = createMap(); + const seenUsages = new Map(); const target = isReadonlyArray(targetRange.range) ? factory.createBlock(targetRange.range) : targetRange.range; const unmodifiedNode = isReadonlyArray(targetRange.range) ? first(targetRange.range) : targetRange.range; @@ -1613,7 +1613,7 @@ namespace ts.refactor.extractSymbol { } if (allTypeParameterUsages.size > 0) { - const seenTypeParameterUsages = createMap(); // Key is type ID + const seenTypeParameterUsages = new Map(); // Key is type ID let i = 0; for (let curr: Node = unmodifiedNode; curr !== undefined && i < scopes.length; curr = curr.parent) { diff --git a/src/services/refactors/extractType.ts b/src/services/refactors/extractType.ts index ef922bce633b8..6f144cfe40b42 100644 --- a/src/services/refactors/extractType.ts +++ b/src/services/refactors/extractType.ts @@ -105,7 +105,7 @@ namespace ts.refactor { if (!node) return undefined; if (isIntersectionTypeNode(node)) { const result: TypeElement[] = []; - const seen = createMap(); + const seen = new Map(); for (const type of node.types) { const flattenedTypeMembers = flattenTypeLiteralNodeReference(checker, type); if (!flattenedTypeMembers || !flattenedTypeMembers.every(type => type.name && addToSeen(seen, getNameFromPropertyName(type.name) as string))) { diff --git a/src/services/refactors/moveToNewFile.ts b/src/services/refactors/moveToNewFile.ts index f4984fe18bde9..f4daab7fcf3b6 100644 --- a/src/services/refactors/moveToNewFile.ts +++ b/src/services/refactors/moveToNewFile.ts @@ -610,7 +610,7 @@ namespace ts.refactor { forEachEntry(cb: (symbol: Symbol) => T | undefined): T | undefined; } class SymbolSet implements ReadonlySymbolSet { - private map = createMap(); + private map = new Map(); add(symbol: Symbol): void { this.map.set(String(getSymbolId(symbol)), symbol); } diff --git a/src/services/services.ts b/src/services/services.ts index 75c9bfdba71df..2409af2f241d1 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -1831,12 +1831,12 @@ namespace ts { return OutliningElementsCollector.collectElements(sourceFile, cancellationToken); } - const braceMatching = createMapFromTemplate({ + const braceMatching = new Map(getEntries({ [SyntaxKind.OpenBraceToken]: SyntaxKind.CloseBraceToken, [SyntaxKind.OpenParenToken]: SyntaxKind.CloseParenToken, [SyntaxKind.OpenBracketToken]: SyntaxKind.CloseBracketToken, [SyntaxKind.GreaterThanToken]: SyntaxKind.LessThanToken, - }); + })); braceMatching.forEach((value, key) => braceMatching.set(value.toString(), Number(key) as SyntaxKind)); function getBraceMatchingAtPosition(fileName: string, position: number): TextSpan[] { @@ -2299,7 +2299,7 @@ namespace ts { } function initializeNameTable(sourceFile: SourceFile): void { - const nameTable = sourceFile.nameTable = createUnderscoreEscapedMap(); + const nameTable = sourceFile.nameTable = new Map(); sourceFile.forEachChild(function walk(node) { if (isIdentifier(node) && !isTagName(node) && node.escapedText || isStringOrNumericLiteralLike(node) && literalIsName(node)) { const text = getEscapedTextOfIdentifierOrLiteral(node); diff --git a/src/services/sourcemaps.ts b/src/services/sourcemaps.ts index e095708ed94d0..ed4bb7c892822 100644 --- a/src/services/sourcemaps.ts +++ b/src/services/sourcemaps.ts @@ -23,8 +23,8 @@ namespace ts { export function getSourceMapper(host: SourceMapperHost): SourceMapper { const getCanonicalFileName = createGetCanonicalFileName(host.useCaseSensitiveFileNames()); const currentDirectory = host.getCurrentDirectory(); - const sourceFileLike = createMap(); - const documentPositionMappers = createMap(); + const sourceFileLike = new Map(); + const documentPositionMappers = new Map(); return { tryGetSourcePosition, tryGetGeneratedPosition, toLineColumnOffset, clearCache }; function toPath(fileName: string) { diff --git a/src/services/stringCompletions.ts b/src/services/stringCompletions.ts index 27db312c5212f..c3473b6251eae 100644 --- a/src/services/stringCompletions.ts +++ b/src/services/stringCompletions.ts @@ -207,7 +207,7 @@ namespace ts.Completions.StringCompletions { function getStringLiteralCompletionsFromSignature(argumentInfo: SignatureHelp.ArgumentInfoForCompletions, checker: TypeChecker): StringLiteralCompletionsFromTypes { let isNewIdentifier = false; - const uniques = createMap(); + const uniques = new Map(); const candidates: Signature[] = []; checker.getResolvedSignature(argumentInfo.invocation, candidates, argumentInfo.argumentCount); const types = flatMap(candidates, candidate => { @@ -228,7 +228,7 @@ namespace ts.Completions.StringCompletions { }; } - function getStringLiteralTypes(type: Type | undefined, uniques = createMap()): readonly StringLiteralType[] { + function getStringLiteralTypes(type: Type | undefined, uniques = new Map()): readonly StringLiteralType[] { if (!type) return emptyArray; type = skipConstraint(type); return type.isUnion() ? flatMap(type.types, t => getStringLiteralTypes(t, uniques)) : @@ -363,7 +363,7 @@ namespace ts.Completions.StringCompletions { * * both foo.ts and foo.tsx become foo */ - const foundFiles = createMap(); // maps file to its extension + const foundFiles = new Map(); // maps file to its extension for (let filePath of files) { filePath = normalizePath(filePath); if (exclude && comparePaths(filePath, exclude, scriptPath, ignoreCase) === Comparison.EqualTo) { @@ -595,7 +595,7 @@ namespace ts.Completions.StringCompletions { function getCompletionEntriesFromTypings(host: LanguageServiceHost, options: CompilerOptions, scriptPath: string, fragmentDirectory: string | undefined, extensionOptions: ExtensionOptions, result: NameAndKind[] = []): readonly NameAndKind[] { // Check for typings specified in compiler options - const seen = createMap(); + const seen = new Map(); const typeRoots = tryAndIgnoreErrors(() => getEffectiveTypeRoots(options, host)) || emptyArray; diff --git a/src/services/suggestionDiagnostics.ts b/src/services/suggestionDiagnostics.ts index 09607d8ab8a00..a8c50322522a1 100644 --- a/src/services/suggestionDiagnostics.ts +++ b/src/services/suggestionDiagnostics.ts @@ -1,6 +1,6 @@ /* @internal */ namespace ts { - const visitedNestedConvertibleFunctions = createMap(); + const visitedNestedConvertibleFunctions = new Map(); export function computeSuggestionDiagnostics(sourceFile: SourceFile, program: Program, cancellationToken: CancellationToken): DiagnosticWithLocation[] { program.getSemanticDiagnostics(sourceFile, cancellationToken); diff --git a/src/services/textChanges.ts b/src/services/textChanges.ts index 1acce25574bfb..b70cb537df9d1 100644 --- a/src/services/textChanges.ts +++ b/src/services/textChanges.ts @@ -250,7 +250,7 @@ namespace ts.textChanges { export class ChangeTracker { private readonly changes: Change[] = []; private readonly newFiles: { readonly oldFile: SourceFile | undefined, readonly fileName: string, readonly statements: readonly Statement[] }[] = []; - private readonly classesWithNodesInsertedAtStart = createMap<{ readonly node: ClassDeclaration | InterfaceDeclaration | ObjectLiteralExpression, readonly sourceFile: SourceFile }>(); // Set implemented as Map + private readonly classesWithNodesInsertedAtStart = new Map(); // Set implemented as Map private readonly deletedNodes: { readonly sourceFile: SourceFile, readonly node: Node | NodeArray }[] = []; public static fromContext(context: TextChangesContext): ChangeTracker { @@ -824,7 +824,7 @@ namespace ts.textChanges { } private finishDeleteDeclarations(): void { - const deletedNodesInLists = new NodeSet(); // Stores nodes in lists that we already deleted. Used to avoid deleting `, ` twice in `a, b`. + const deletedNodesInLists = new Set(); // Stores nodes in lists that we already deleted. Used to avoid deleting `, ` twice in `a, b`. for (const { sourceFile, node } of this.deletedNodes) { if (!this.deletedNodes.some(d => d.sourceFile === sourceFile && rangeContainsRangeExclusive(d.node, node))) { if (isArray(node)) { @@ -1275,7 +1275,7 @@ namespace ts.textChanges { } namespace deleteDeclaration { - export function deleteDeclaration(changes: ChangeTracker, deletedNodesInLists: NodeSet, sourceFile: SourceFile, node: Node): void { + export function deleteDeclaration(changes: ChangeTracker, deletedNodesInLists: Set, sourceFile: SourceFile, node: Node): void { switch (node.kind) { case SyntaxKind.Parameter: { const oldFunction = node.parent; @@ -1397,7 +1397,7 @@ namespace ts.textChanges { } } - function deleteVariableDeclaration(changes: ChangeTracker, deletedNodesInLists: NodeSet, sourceFile: SourceFile, node: VariableDeclaration): void { + function deleteVariableDeclaration(changes: ChangeTracker, deletedNodesInLists: Set, sourceFile: SourceFile, node: VariableDeclaration): void { const { parent } = node; if (parent.kind === SyntaxKind.CatchClause) { @@ -1440,7 +1440,7 @@ namespace ts.textChanges { changes.deleteRange(sourceFile, { pos: startPosition, end: endPosition }); } - function deleteNodeInList(changes: ChangeTracker, deletedNodesInLists: NodeSet, sourceFile: SourceFile, node: Node): void { + function deleteNodeInList(changes: ChangeTracker, deletedNodesInLists: Set, sourceFile: SourceFile, node: Node): void { const containingList = Debug.checkDefined(formatting.SmartIndenter.getContainingList(node, sourceFile)); const index = indexOfNode(containingList, node); Debug.assert(index !== -1); diff --git a/src/services/transpile.ts b/src/services/transpile.ts index c739c8394f2c3..103c7dc503bbb 100644 --- a/src/services/transpile.ts +++ b/src/services/transpile.ts @@ -54,7 +54,7 @@ namespace ts { } if (transpileOptions.renamedDependencies) { - sourceFile.renamedDependencies = createMapFromTemplate(transpileOptions.renamedDependencies); + sourceFile.renamedDependencies = new Map(getEntries(transpileOptions.renamedDependencies)); } const newLine = getNewLineCharacter(options); diff --git a/src/services/utilities.ts b/src/services/utilities.ts index 4e56757abee19..0e6db8abb8843 100644 --- a/src/services/utilities.ts +++ b/src/services/utilities.ts @@ -1828,7 +1828,7 @@ namespace ts { * The value of previousIterationSymbol is undefined when the function is first called. */ export function getPropertySymbolsFromBaseTypes(symbol: Symbol, propertyName: string, checker: TypeChecker, cb: (symbol: Symbol) => T | undefined): T | undefined { - const seen = createMap(); + const seen = new Map(); return recur(symbol); function recur(symbol: Symbol): T | undefined { @@ -2696,7 +2696,7 @@ namespace ts { if (!dependencies) { continue; } - const dependencyMap = createMap(); + const dependencyMap = new Map(); for (const packageName in dependencies) { dependencyMap.set(packageName, dependencies[packageName]); } diff --git a/src/testRunner/parallel/host.ts b/src/testRunner/parallel/host.ts index bb4b31b9f058d..d1db63e2f5ae1 100644 --- a/src/testRunner/parallel/host.ts +++ b/src/testRunner/parallel/host.ts @@ -24,7 +24,7 @@ namespace Harness.Parallel.Host { let totalCost = 0; class RemoteSuite extends Mocha.Suite { - suiteMap = ts.createMap(); + suiteMap = new ts.Map(); constructor(title: string) { super(title); this.pending = false; diff --git a/src/testRunner/parallel/worker.ts b/src/testRunner/parallel/worker.ts index 2e985ec8bed5c..524bc08c66a5f 100644 --- a/src/testRunner/parallel/worker.ts +++ b/src/testRunner/parallel/worker.ts @@ -146,13 +146,13 @@ namespace Harness.Parallel.Worker { function executeUnitTests(task: UnitTestTask, fn: (payload: TaskResult) => void) { if (!unitTestSuiteMap && unitTestSuite.suites.length) { - unitTestSuiteMap = ts.createMap(); + unitTestSuiteMap = new ts.Map(); for (const suite of unitTestSuite.suites) { unitTestSuiteMap.set(suite.title, suite); } } if (!unitTestTestMap && unitTestSuite.tests.length) { - unitTestTestMap = ts.createMap(); + unitTestTestMap = new ts.Map(); for (const test of unitTestSuite.tests) { unitTestTestMap.set(test.title, test); } @@ -297,7 +297,7 @@ namespace Harness.Parallel.Worker { } // A cache of test harness Runner instances. - const runners = ts.createMap(); + const runners = new ts.Map(); // The root suite for all unit tests. let unitTestSuite: Suite; diff --git a/src/testRunner/rwcRunner.ts b/src/testRunner/rwcRunner.ts index a50447b2d0065..7f6e5f78ebb19 100644 --- a/src/testRunner/rwcRunner.ts +++ b/src/testRunner/rwcRunner.ts @@ -83,7 +83,7 @@ namespace RWC { } // Deduplicate files so they are only printed once in baselines (they are deduplicated within the compiler already) - const uniqueNames = ts.createMap(); + const uniqueNames = new ts.Map(); for (const fileName of fileNames) { // Must maintain order, build result list while checking map const normalized = ts.normalizeSlashes(Harness.IO.resolvePath(fileName)!); diff --git a/src/testRunner/unittests/config/commandLineParsing.ts b/src/testRunner/unittests/config/commandLineParsing.ts index 97de804b5ab91..8d70f0de1684f 100644 --- a/src/testRunner/unittests/config/commandLineParsing.ts +++ b/src/testRunner/unittests/config/commandLineParsing.ts @@ -571,10 +571,10 @@ namespace ts { describe("option of type Map", () => { verifyNullNonIncludedOption({ - type: () => createMapFromTemplate({ + type: () => new Map(getEntries({ node: ModuleResolutionKind.NodeJs, classic: ModuleResolutionKind.Classic, - }), + })), nonNullValue: "node" }); }); diff --git a/src/testRunner/unittests/config/projectReferences.ts b/src/testRunner/unittests/config/projectReferences.ts index 6f9d3b3b24951..a70329a8db8a2 100644 --- a/src/testRunner/unittests/config/projectReferences.ts +++ b/src/testRunner/unittests/config/projectReferences.ts @@ -43,7 +43,7 @@ namespace ts { } function testProjectReferences(spec: TestSpecification, entryPointConfigFileName: string, checkResult: (prog: Program, host: fakes.CompilerHost) => void) { - const files = createMap(); + const files = new Map(); for (const key in spec) { const sp = spec[key]; const configFileName = combineAllPaths("/", key, sp.configFileName || "tsconfig.json"); diff --git a/src/testRunner/unittests/createMapShim.ts b/src/testRunner/unittests/createMapShim.ts index 039372ab2746c..a83a6f006310b 100644 --- a/src/testRunner/unittests/createMapShim.ts +++ b/src/testRunner/unittests/createMapShim.ts @@ -139,11 +139,11 @@ namespace ts { const expectedResult = "1:1;3:3;2:Y2;4:X4;0:X0;3:Y3;999:999;A:A;Z:Z;X:X;Y:Y;"; // First, ensure the test actually has the same behavior as a native Map. - let nativeMap = createMap(); + let nativeMap = new Map(); const nativeMapForEachResult = testMapIterationAddedValues(stringKeys, nativeMap, /* useForEach */ true); assert.equal(nativeMapForEachResult, expectedResult, "nativeMap-forEach"); - nativeMap = createMap(); + nativeMap = new Map(); const nativeMapIteratorResult = testMapIterationAddedValues(stringKeys, nativeMap, /* useForEach */ false); assert.equal(nativeMapIteratorResult, expectedResult, "nativeMap-iterator"); @@ -161,11 +161,11 @@ namespace ts { const expectedResult = "true:1;3:3;2:Y2;4:X4;false:X0;3:Y3;null:999;undefined:A;Z:Z;X:X;Y:Y;"; // First, ensure the test actually has the same behavior as a native Map. - let nativeMap = createMap(); + let nativeMap = new Map(); const nativeMapForEachResult = testMapIterationAddedValues(mixedKeys, nativeMap, /* useForEach */ true); assert.equal(nativeMapForEachResult, expectedResult, "nativeMap-forEach"); - nativeMap = createMap(); + nativeMap = new Map(); const nativeMapIteratorResult = testMapIterationAddedValues(mixedKeys, nativeMap, /* useForEach */ false); assert.equal(nativeMapIteratorResult, expectedResult, "nativeMap-iterator"); diff --git a/src/testRunner/unittests/customTransforms.ts b/src/testRunner/unittests/customTransforms.ts index f346ea47dd658..7992f8a9c559f 100644 --- a/src/testRunner/unittests/customTransforms.ts +++ b/src/testRunner/unittests/customTransforms.ts @@ -4,7 +4,7 @@ namespace ts { it(name, () => { const roots = sources.map(source => createSourceFile(source.file, source.text, ScriptTarget.ES2015)); const fileMap = arrayToMap(roots, file => file.fileName); - const outputs = createMap(); + const outputs = new Map(); const host: CompilerHost = { getSourceFile: (fileName) => fileMap.get(fileName), getDefaultLibFileName: () => "lib.d.ts", diff --git a/src/testRunner/unittests/moduleResolution.ts b/src/testRunner/unittests/moduleResolution.ts index bd4e888c28453..af145e86a0bd4 100644 --- a/src/testRunner/unittests/moduleResolution.ts +++ b/src/testRunner/unittests/moduleResolution.ts @@ -35,7 +35,7 @@ namespace ts { } function createModuleResolutionHost(hasDirectoryExists: boolean, ...files: File[]): ModuleResolutionHost { - const map = createMap(); + const map = new Map(); for (const file of files) { map.set(file.name, file); if (file.symlinks) { @@ -46,7 +46,7 @@ namespace ts { } if (hasDirectoryExists) { - const directories = createMap(); + const directories = new Map(); for (const f of files) { let name = getDirectoryPath(f.name); while (true) { @@ -495,7 +495,7 @@ namespace ts { } it("should find all modules", () => { - const files = createMapFromTemplate({ + const files = new Map(getEntries({ "/a/b/c/first/shared.ts": ` class A {} export = A`, @@ -509,23 +509,23 @@ import Shared = require('../first/shared'); class C {} export = C; ` - }); + })); test(files, "/a/b/c/first/second", ["class_a.ts"], 3, ["../../../c/third/class_c.ts"]); }); it("should find modules in node_modules", () => { - const files = createMapFromTemplate({ + const files = new Map(getEntries({ "/parent/node_modules/mod/index.d.ts": "export var x", "/parent/app/myapp.ts": `import {x} from "mod"` - }); + })); test(files, "/parent/app", ["myapp.ts"], 2, []); }); it("should find file referenced via absolute and relative names", () => { - const files = createMapFromTemplate({ + const files = new Map(getEntries({ "/a/b/c.ts": `/// `, "/a/b/b.ts": "var x" - }); + })); test(files, "/a/b", ["c.ts", "/a/b/b.ts"], 2, []); }); }); @@ -543,7 +543,7 @@ export = C; const getCanonicalFileName = createGetCanonicalFileName(useCaseSensitiveFileNames); if (!useCaseSensitiveFileNames) { const oldFiles = files; - files = createMap(); + files = new Map(); oldFiles.forEach((file, fileName) => { files.set(getCanonicalFileName(fileName), file); }); @@ -580,10 +580,10 @@ export = C; } it("should succeed when the same file is referenced using absolute and relative names", () => { - const files = createMapFromTemplate({ + const files = new Map(getEntries({ "/a/b/c.ts": `/// `, "/a/b/d.ts": "var x" - }); + })); test( files, { module: ModuleKind.AMD }, @@ -595,10 +595,10 @@ export = C; }); it("should fail when two files used in program differ only in casing (tripleslash references)", () => { - const files = createMapFromTemplate({ + const files = new Map(getEntries({ "/a/b/c.ts": `/// `, "/a/b/d.ts": "var x" - }); + })); test( files, { module: ModuleKind.AMD, forceConsistentCasingInFileNames: true }, @@ -622,10 +622,10 @@ export = C; }); it("should fail when two files used in program differ only in casing (imports)", () => { - const files = createMapFromTemplate({ + const files = new Map(getEntries({ "/a/b/c.ts": `import {x} from "D"`, "/a/b/d.ts": "export var x" - }); + })); test( files, { module: ModuleKind.AMD, forceConsistentCasingInFileNames: true }, @@ -649,10 +649,10 @@ export = C; }); it("should fail when two files used in program differ only in casing (imports, relative module names)", () => { - const files = createMapFromTemplate({ + const files = new Map(getEntries({ "moduleA.ts": `import {x} from "./ModuleB"`, "moduleB.ts": "export var x" - }); + })); test( files, { module: ModuleKind.CommonJS, forceConsistentCasingInFileNames: true }, @@ -676,11 +676,11 @@ export = C; }); it("should fail when two files exist on disk that differs only in casing", () => { - const files = createMapFromTemplate({ + const files = new Map(getEntries({ "/a/b/c.ts": `import {x} from "D"`, "/a/b/D.ts": "export var x", "/a/b/d.ts": "export var y" - }); + })); test( files, { module: ModuleKind.AMD }, @@ -704,11 +704,11 @@ export = C; }); it("should fail when module name in 'require' calls has inconsistent casing", () => { - const files = createMapFromTemplate({ + const files = new Map(getEntries({ "moduleA.ts": `import a = require("./ModuleC")`, "moduleB.ts": `import a = require("./moduleC")`, "moduleC.ts": "export var x" - }); + })); test( files, { module: ModuleKind.CommonJS, forceConsistentCasingInFileNames: true }, @@ -747,7 +747,7 @@ export = C; }); it("should fail when module names in 'require' calls has inconsistent casing and current directory has uppercase chars", () => { - const files = createMapFromTemplate({ + const files = new Map(getEntries({ "/a/B/c/moduleA.ts": `import a = require("./ModuleC")`, "/a/B/c/moduleB.ts": `import a = require("./moduleC")`, "/a/B/c/moduleC.ts": "export var x", @@ -755,7 +755,7 @@ export = C; import a = require("./moduleA"); import b = require("./moduleB"); ` - }); + })); test( files, { module: ModuleKind.CommonJS, forceConsistentCasingInFileNames: true }, @@ -778,7 +778,7 @@ import b = require("./moduleB"); ); }); it("should not fail when module names in 'require' calls has consistent casing and current directory has uppercase chars", () => { - const files = createMapFromTemplate({ + const files = new Map(getEntries({ "/a/B/c/moduleA.ts": `import a = require("./moduleC")`, "/a/B/c/moduleB.ts": `import a = require("./moduleC")`, "/a/B/c/moduleC.ts": "export var x", @@ -786,7 +786,7 @@ import b = require("./moduleB"); import a = require("./moduleA"); import b = require("./moduleB"); ` - }); + })); test( files, { module: ModuleKind.CommonJS, forceConsistentCasingInFileNames: true }, @@ -798,11 +798,11 @@ import b = require("./moduleB"); }); it("should succeed when the two files in program differ only in drive letter in their names", () => { - const files = createMapFromTemplate({ + const files = new Map(getEntries({ "d:/someFolder/moduleA.ts": `import a = require("D:/someFolder/moduleC")`, "d:/someFolder/moduleB.ts": `import a = require("./moduleC")`, "D:/someFolder/moduleC.ts": "export const x = 10", - }); + })); test( files, { module: ModuleKind.CommonJS, forceConsistentCasingInFileNames: true }, diff --git a/src/testRunner/unittests/programApi.ts b/src/testRunner/unittests/programApi.ts index 170235b8308a1..63c33deb59560 100644 --- a/src/testRunner/unittests/programApi.ts +++ b/src/testRunner/unittests/programApi.ts @@ -1,13 +1,13 @@ namespace ts { function verifyMissingFilePaths(missingPaths: readonly Path[], expected: readonly string[]) { assert.isDefined(missingPaths); - const map = arrayToSet(expected) as Map; + const map = new Set(expected); for (const missing of missingPaths) { - const value = map.get(missing); + const value = map.has(missing); assert.isTrue(value, `${missing} to be ${value === undefined ? "not present" : "present only once"}, in actual: ${missingPaths} expected: ${expected}`); - map.set(missing, false); + map.delete(missing); } - const notFound = arrayFrom(mapDefinedIterator(map.keys(), k => map.get(k) === true ? k : undefined)); + const notFound = arrayFrom(mapDefinedIterator(map.keys(), k => map.has(k) ? k : undefined)); assert.equal(notFound.length, 0, `Not found ${notFound} in actual: ${missingPaths} expected: ${expected}`); } diff --git a/src/testRunner/unittests/reuseProgramStructure.ts b/src/testRunner/unittests/reuseProgramStructure.ts index 9ae4de199e212..6b81403b2cd39 100644 --- a/src/testRunner/unittests/reuseProgramStructure.ts +++ b/src/testRunner/unittests/reuseProgramStructure.ts @@ -344,7 +344,7 @@ namespace ts { const options: CompilerOptions = { target }; const program1 = newProgram(files, ["a.ts"], options); - checkResolvedModulesCache(program1, "a.ts", createMapFromTemplate({ b: createResolvedModule("b.ts") })); + checkResolvedModulesCache(program1, "a.ts", new Map(getEntries({ b: createResolvedModule("b.ts") }))); checkResolvedModulesCache(program1, "b.ts", /*expectedContent*/ undefined); const program2 = updateProgram(program1, ["a.ts"], options, files => { @@ -353,7 +353,7 @@ namespace ts { assert.equal(program1.structureIsReused, StructureIsReused.Completely); // content of resolution cache should not change - checkResolvedModulesCache(program1, "a.ts", createMapFromTemplate({ b: createResolvedModule("b.ts") })); + checkResolvedModulesCache(program1, "a.ts", new Map(getEntries({ b: createResolvedModule("b.ts") }))); checkResolvedModulesCache(program1, "b.ts", /*expectedContent*/ undefined); // imports has changed - program is not reused @@ -370,7 +370,7 @@ namespace ts { files[0].text = files[0].text.updateImportsAndExports(newImports); }); assert.equal(program3.structureIsReused, StructureIsReused.SafeModules); - checkResolvedModulesCache(program4, "a.ts", createMapFromTemplate({ b: createResolvedModule("b.ts"), c: undefined })); + checkResolvedModulesCache(program4, "a.ts", new Map(getEntries({ b: createResolvedModule("b.ts"), c: undefined }))); }); it("set the resolvedImports after re-using an ambient external module declaration", () => { @@ -418,7 +418,7 @@ namespace ts { const options: CompilerOptions = { target, typeRoots: ["/types"] }; const program1 = newProgram(files, ["/a.ts"], options); - checkResolvedTypeDirectivesCache(program1, "/a.ts", createMapFromTemplate({ typedefs: { resolvedFileName: "/types/typedefs/index.d.ts", primary: true } })); + checkResolvedTypeDirectivesCache(program1, "/a.ts", new Map(getEntries({ typedefs: { resolvedFileName: "/types/typedefs/index.d.ts", primary: true } }))); checkResolvedTypeDirectivesCache(program1, "/types/typedefs/index.d.ts", /*expectedContent*/ undefined); const program2 = updateProgram(program1, ["/a.ts"], options, files => { @@ -427,7 +427,7 @@ namespace ts { assert.equal(program1.structureIsReused, StructureIsReused.Completely); // content of resolution cache should not change - checkResolvedTypeDirectivesCache(program1, "/a.ts", createMapFromTemplate({ typedefs: { resolvedFileName: "/types/typedefs/index.d.ts", primary: true } })); + checkResolvedTypeDirectivesCache(program1, "/a.ts", new Map(getEntries({ typedefs: { resolvedFileName: "/types/typedefs/index.d.ts", primary: true } }))); checkResolvedTypeDirectivesCache(program1, "/types/typedefs/index.d.ts", /*expectedContent*/ undefined); // type reference directives has changed - program is not reused @@ -445,7 +445,7 @@ namespace ts { files[0].text = files[0].text.updateReferences(newReferences); }); assert.equal(program3.structureIsReused, StructureIsReused.SafeModules); - checkResolvedTypeDirectivesCache(program1, "/a.ts", createMapFromTemplate({ typedefs: { resolvedFileName: "/types/typedefs/index.d.ts", primary: true } })); + checkResolvedTypeDirectivesCache(program1, "/a.ts", new Map(getEntries({ typedefs: { resolvedFileName: "/types/typedefs/index.d.ts", primary: true } }))); }); it("fetches imports after npm install", () => { diff --git a/src/testRunner/unittests/services/extract/helpers.ts b/src/testRunner/unittests/services/extract/helpers.ts index 69148896ef74a..0967ecfd4953b 100644 --- a/src/testRunner/unittests/services/extract/helpers.ts +++ b/src/testRunner/unittests/services/extract/helpers.ts @@ -15,7 +15,7 @@ namespace ts { let text = ""; let lastPos = 0; let pos = 0; - const ranges = createMap(); + const ranges = new Map(); while (pos < source.length) { if (source.charCodeAt(pos) === CharacterCodes.openBracket && diff --git a/src/testRunner/unittests/services/languageService.ts b/src/testRunner/unittests/services/languageService.ts index 0cc4d1acd294a..6aba1018062d6 100644 --- a/src/testRunner/unittests/services/languageService.ts +++ b/src/testRunner/unittests/services/languageService.ts @@ -86,7 +86,7 @@ export function Component(x: Config): any;` describe("detects program upto date correctly", () => { function verifyProgramUptoDate(useProjectVersion: boolean) { let projectVersion = "1"; - const files = createMap<{ version: string, text: string; }>(); + const files = new Map(); files.set("/project/root.ts", { version: "1", text: `import { foo } from "./other"` }); files.set("/project/other.ts", { version: "1", text: `export function foo() { }` }); files.set("/lib/lib.d.ts", { version: "1", text: projectSystem.libFile.content }); diff --git a/src/testRunner/unittests/tsbuild/sample.ts b/src/testRunner/unittests/tsbuild/sample.ts index 4550595ded23c..42dc6eaef6d45 100644 --- a/src/testRunner/unittests/tsbuild/sample.ts +++ b/src/testRunner/unittests/tsbuild/sample.ts @@ -316,7 +316,7 @@ namespace ts { tick(); appendText(fs, "/src/logic/index.ts", "function foo() {}"); const originalWriteFile = fs.writeFileSync; - const writtenFiles = createMap(); + const writtenFiles = new Map(); fs.writeFileSync = (path, data, encoding) => { writtenFiles.set(path, true); originalWriteFile.call(fs, path, data, encoding); diff --git a/src/testRunner/unittests/tscWatch/watchEnvironment.ts b/src/testRunner/unittests/tscWatch/watchEnvironment.ts index 20dabc4194789..ff33daefa3053 100644 --- a/src/testRunner/unittests/tscWatch/watchEnvironment.ts +++ b/src/testRunner/unittests/tscWatch/watchEnvironment.ts @@ -12,7 +12,7 @@ namespace ts.tscWatch { path: `${projectFolder}/typescript.ts`, content: "var z = 10;" }; - const environmentVariables = createMap(); + const environmentVariables = new Map(); environmentVariables.set("TSC_WATCHFILE", TestFSWithWatch.Tsc_WatchFile.DynamicPolling); return createWatchedSystem([file1, libFile], { environmentVariables }); }, @@ -88,7 +88,7 @@ namespace ts.tscWatch { commandLineArgs: ["--w", "-p", configFile.path], sys: () => { const files = [file, configFile, libFile]; - const environmentVariables = createMap(); + const environmentVariables = new Map(); environmentVariables.set("TSC_WATCHDIRECTORY", tscWatchDirectory); return createWatchedSystem(files, { environmentVariables }); }, @@ -156,7 +156,7 @@ namespace ts.tscWatch { symLink: `${cwd}/node_modules/a` }; const files = [libFile, file1, tsconfig, realA, realB, symLinkA, symLinkB, symLinkBInA, symLinkAInB]; - const environmentVariables = createMap(); + const environmentVariables = new Map(); environmentVariables.set("TSC_WATCHDIRECTORY", Tsc_WatchDirectory.NonRecursiveWatchDirectory); return createWatchedSystem(files, { environmentVariables, currentDirectory: cwd }); }, diff --git a/src/testRunner/unittests/tsserver/cachingFileSystemInformation.ts b/src/testRunner/unittests/tsserver/cachingFileSystemInformation.ts index e8fdd4bbc3fc8..9011eead59fa1 100644 --- a/src/testRunner/unittests/tsserver/cachingFileSystemInformation.ts +++ b/src/testRunner/unittests/tsserver/cachingFileSystemInformation.ts @@ -204,7 +204,7 @@ namespace ts.projectSystem { } function getLocationsForDirectoryLookup() { - const result = createMap(); + const result = new Map(); forEachAncestorDirectory(getDirectoryPath(root.path), ancestor => { // To resolve modules result.set(ancestor, 2); diff --git a/src/testRunner/unittests/tsserver/events/projectUpdatedInBackground.ts b/src/testRunner/unittests/tsserver/events/projectUpdatedInBackground.ts index 918c817857ce0..0ac5ffdb5f50b 100644 --- a/src/testRunner/unittests/tsserver/events/projectUpdatedInBackground.ts +++ b/src/testRunner/unittests/tsserver/events/projectUpdatedInBackground.ts @@ -2,7 +2,7 @@ namespace ts.projectSystem { describe("unittests:: tsserver:: events:: ProjectsUpdatedInBackground", () => { function verifyFiles(caption: string, actual: readonly string[], expected: readonly string[]) { assert.equal(actual.length, expected.length, `Incorrect number of ${caption}. Actual: ${actual} Expected: ${expected}`); - const seen = createMap(); + const seen = new Map(); forEach(actual, f => { assert.isFalse(seen.has(f), `${caption}: Found duplicate ${f}. Actual: ${actual} Expected: ${expected}`); seen.set(f, true); diff --git a/src/testRunner/unittests/tsserver/helpers.ts b/src/testRunner/unittests/tsserver/helpers.ts index 5a1cdee81d654..2851ca8949fcf 100644 --- a/src/testRunner/unittests/tsserver/helpers.ts +++ b/src/testRunner/unittests/tsserver/helpers.ts @@ -101,7 +101,7 @@ namespace ts.projectSystem { readonly globalTypingsCacheLocation: string, throttleLimit: number, installTypingHost: server.ServerHost, - readonly typesRegistry = createMap>(), + readonly typesRegistry = new Map>(), log?: TI.Log) { super(installTypingHost, globalTypingsCacheLocation, TestFSWithWatch.safeList.path, customTypesMap.path, throttleLimit, log); } @@ -177,7 +177,7 @@ namespace ts.projectSystem { "ts2.6": "1.3.0", "ts2.7": "1.3.0" }; - const map = createMap>(); + const map = new Map>(); for (const l of list) { map.set(l, versionMap); } diff --git a/src/testRunner/unittests/tsserver/inferredProjects.ts b/src/testRunner/unittests/tsserver/inferredProjects.ts index 57689637dbdf6..8676e2a62794f 100644 --- a/src/testRunner/unittests/tsserver/inferredProjects.ts +++ b/src/testRunner/unittests/tsserver/inferredProjects.ts @@ -365,8 +365,8 @@ namespace ts.projectSystem { const projectService = createProjectService(host); const originalSet = projectService.configuredProjects.set; const originalDelete = projectService.configuredProjects.delete; - const configuredCreated = createMap(); - const configuredRemoved = createMap(); + const configuredCreated = new Map(); + const configuredRemoved = new Map(); projectService.configuredProjects.set = (key, value) => { assert.isFalse(configuredCreated.has(key)); configuredCreated.set(key, true); diff --git a/src/testRunner/unittests/tsserver/resolutionCache.ts b/src/testRunner/unittests/tsserver/resolutionCache.ts index 73a2467aa21fe..7a88d42da050e 100644 --- a/src/testRunner/unittests/tsserver/resolutionCache.ts +++ b/src/testRunner/unittests/tsserver/resolutionCache.ts @@ -551,7 +551,7 @@ namespace ts.projectSystem { } function verifyWatchesWithConfigFile(host: TestServerHost, files: File[], openFile: File, extraExpectedDirectories?: readonly string[]) { - const expectedRecursiveDirectories = arrayToSet([tscWatch.projectRoot, `${tscWatch.projectRoot}/${nodeModulesAtTypes}`, ...(extraExpectedDirectories || emptyArray)]); + const expectedRecursiveDirectories = new Set([tscWatch.projectRoot, `${tscWatch.projectRoot}/${nodeModulesAtTypes}`, ...(extraExpectedDirectories || emptyArray)]); checkWatchedFiles(host, mapDefined(files, f => { if (f === openFile) { return undefined; @@ -560,11 +560,11 @@ namespace ts.projectSystem { if (indexOfNodeModules === -1) { return f.path; } - expectedRecursiveDirectories.set(f.path.substr(0, indexOfNodeModules + "/node_modules".length), true); + expectedRecursiveDirectories.add(f.path.substr(0, indexOfNodeModules + "/node_modules".length)); return undefined; })); checkWatchedDirectories(host, [], /*recursive*/ false); - checkWatchedDirectories(host, arrayFrom(expectedRecursiveDirectories.keys()), /*recursive*/ true); + checkWatchedDirectories(host, arrayFrom(expectedRecursiveDirectories.values()), /*recursive*/ true); } describe("from files in same folder", () => { @@ -850,7 +850,7 @@ export const x = 10;` else { checkWatchedDirectoriesDetailed(host, [`${tscWatch.projectRoot}`, `${tscWatch.projectRoot}/src`], 1, /*recursive*/ false); // failed lookup for fs } - const expectedWatchedDirectories = createMap(); + const expectedWatchedDirectories = new Map(); expectedWatchedDirectories.set(`${tscWatch.projectRoot}/src`, 1); // Wild card expectedWatchedDirectories.set(`${tscWatch.projectRoot}/src/somefolder`, 1); // failedLookup for somefolder/module2 expectedWatchedDirectories.set(`${tscWatch.projectRoot}/src/node_modules`, 1); // failed lookup for somefolder/module2 diff --git a/src/testRunner/unittests/tsserver/session.ts b/src/testRunner/unittests/tsserver/session.ts index b41df99f4a2c6..7a144945340fa 100644 --- a/src/testRunner/unittests/tsserver/session.ts +++ b/src/testRunner/unittests/tsserver/session.ts @@ -621,7 +621,7 @@ namespace ts.server { private server: InProcSession | undefined; private seq = 0; private callbacks: ((resp: protocol.Response) => void)[] = []; - private eventHandlers = createMap<(args: any) => void>(); + private eventHandlers = new Map void>(); handle(msg: protocol.Message): void { if (msg.type === "response") { diff --git a/src/testRunner/unittests/tsserver/symLinks.ts b/src/testRunner/unittests/tsserver/symLinks.ts index 9b79e1e58609b..5c6b526b1eb65 100644 --- a/src/testRunner/unittests/tsserver/symLinks.ts +++ b/src/testRunner/unittests/tsserver/symLinks.ts @@ -188,7 +188,7 @@ new C();` if (!withPathMapping) { watchedDirectoriesWithResolvedModule.set(`${recognizersDateTime}/node_modules`, 1); // failed lookups } - const watchedDirectoriesWithUnresolvedModule = cloneMap(watchedDirectoriesWithResolvedModule); + const watchedDirectoriesWithUnresolvedModule = new Map(watchedDirectoriesWithResolvedModule); watchedDirectoriesWithUnresolvedModule.set(`${recognizersDateTime}/src`, 2); // wild card + failed lookups [`${recognizersDateTime}/node_modules`, ...(withPathMapping ? [recognizersText] : emptyArray), ...getNodeModuleDirectories(packages)].forEach(d => { watchedDirectoriesWithUnresolvedModule.set(d, 1); diff --git a/src/testRunner/unittests/tsserver/typingsInstaller.ts b/src/testRunner/unittests/tsserver/typingsInstaller.ts index e2d194dc1151f..505beac645b81 100644 --- a/src/testRunner/unittests/tsserver/typingsInstaller.ts +++ b/src/testRunner/unittests/tsserver/typingsInstaller.ts @@ -137,7 +137,7 @@ namespace ts.projectSystem { const p = configuredProjectAt(projectService, 0); checkProjectActualFiles(p, [file1.path, tsconfig.path]); - const expectedWatchedFiles = createMap(); + const expectedWatchedFiles = new Map(); expectedWatchedFiles.set(tsconfig.path, 1); // tsserver expectedWatchedFiles.set(libFile.path, 1); // tsserver expectedWatchedFiles.set(packageJson.path, 1); // typing installer @@ -145,7 +145,7 @@ namespace ts.projectSystem { checkWatchedDirectories(host, emptyArray, /*recursive*/ false); - const expectedWatchedDirectoriesRecursive = createMap(); + const expectedWatchedDirectoriesRecursive = new Map(); expectedWatchedDirectoriesRecursive.set("/a/b", 1); // wild card expectedWatchedDirectoriesRecursive.set("/a/b/node_modules/@types", 1); // type root watch expectedWatchedDirectoriesRecursive.set("/a/b/node_modules", 1); // TypingInstaller @@ -838,7 +838,7 @@ namespace ts.projectSystem { const p = configuredProjectAt(projectService, 0); checkProjectActualFiles(p, [app.path, jsconfig.path]); - const watchedFilesExpected = createMap(); + const watchedFilesExpected = new Map(); watchedFilesExpected.set(jsconfig.path, 1); // project files watchedFilesExpected.set(libFile.path, 1); // project files watchedFilesExpected.set(combinePaths(installer.globalTypingsCacheLocation, "package.json"), 1); @@ -1361,7 +1361,7 @@ namespace ts.projectSystem { content: "" }; - const safeList = createMapFromTemplate({ jquery: "jquery", chroma: "chroma-js" }); + const safeList = new Map(getEntries({ jquery: "jquery", chroma: "chroma-js" })); const host = createServerHost([app, jquery, chroma]); const logger = trackingLogger(); @@ -1381,7 +1381,7 @@ namespace ts.projectSystem { content: "" }; const host = createServerHost([f]); - const cache = createMap(); + const cache = new Map(); for (const name of JsTyping.nodeCoreModuleList) { const logger = trackingLogger(); @@ -1404,7 +1404,7 @@ namespace ts.projectSystem { content: "" }; const host = createServerHost([f, node]); - const cache = createMapFromTemplate({ node: { typingLocation: node.path, version: new Version("1.3.0") } }); + const cache = new Map(getEntries({ node: { typingLocation: node.path, version: new Version("1.3.0") } })); const registry = createTypesRegistry("node"); const logger = trackingLogger(); const result = JsTyping.discoverTypings(host, logger.log, [f.path], getDirectoryPath(f.path), emptySafeList, cache, { enable: true }, ["fs", "bar"], registry); @@ -1426,7 +1426,7 @@ namespace ts.projectSystem { content: "" }; const host = createServerHost([f, node]); - const cache = createMapFromTemplate({ node: { typingLocation: node.path, version: new Version("1.3.0") } }); + const cache = new Map(getEntries({ node: { typingLocation: node.path, version: new Version("1.3.0") } })); const logger = trackingLogger(); const result = JsTyping.discoverTypings(host, logger.log, [f.path], getDirectoryPath(f.path), emptySafeList, cache, { enable: true }, ["fs", "bar"], emptyMap); assert.deepEqual(logger.finish(), [ @@ -1451,7 +1451,7 @@ namespace ts.projectSystem { content: JSON.stringify({ name: "b" }), }; const host = createServerHost([app, a, b]); - const cache = createMap(); + const cache = new Map(); const logger = trackingLogger(); const result = JsTyping.discoverTypings(host, logger.log, [app.path], getDirectoryPath(app.path), emptySafeList, cache, { enable: true }, /*unresolvedImports*/ [], emptyMap); assert.deepEqual(logger.finish(), [ @@ -1482,10 +1482,10 @@ namespace ts.projectSystem { content: "export let y: number" }; const host = createServerHost([app]); - const cache = createMapFromTemplate({ + const cache = new Map(getEntries({ node: { typingLocation: node.path, version: new Version("1.3.0") }, commander: { typingLocation: commander.path, version: new Version("1.0.0") } - }); + })); const registry = createTypesRegistry("node", "commander"); const logger = trackingLogger(); const result = JsTyping.discoverTypings(host, logger.log, [app.path], getDirectoryPath(app.path), emptySafeList, cache, { enable: true }, ["http", "commander"], registry); @@ -1508,9 +1508,9 @@ namespace ts.projectSystem { content: "export let y: number" }; const host = createServerHost([app]); - const cache = createMapFromTemplate({ + const cache = new Map(getEntries({ node: { typingLocation: node.path, version: new Version("1.0.0") } - }); + })); const registry = createTypesRegistry("node"); registry.delete(`ts${versionMajorMinor}`); const logger = trackingLogger(); @@ -1539,10 +1539,10 @@ namespace ts.projectSystem { content: "export let y: number" }; const host = createServerHost([app]); - const cache = createMapFromTemplate({ + const cache = new Map(getEntries({ node: { typingLocation: node.path, version: new Version("1.3.0-next.0") }, commander: { typingLocation: commander.path, version: new Version("1.3.0-next.0") } - }); + })); const registry = createTypesRegistry("node", "commander"); registry.get("node")![`ts${versionMajorMinor}`] = "1.3.0-next.1"; const logger = trackingLogger(); diff --git a/src/testRunner/unittests/tsserver/watchEnvironment.ts b/src/testRunner/unittests/tsserver/watchEnvironment.ts index 1bda288495033..49fc0b237f65e 100644 --- a/src/testRunner/unittests/tsserver/watchEnvironment.ts +++ b/src/testRunner/unittests/tsserver/watchEnvironment.ts @@ -25,12 +25,12 @@ namespace ts.projectSystem { const fileNames = files.map(file => file.path); // All closed files(files other than index), project folder, project/src folder and project/node_modules/@types folder const expectedWatchedFiles = arrayToMap(fileNames.slice(1), s => s, () => 1); - const expectedWatchedDirectories = createMap(); + const expectedWatchedDirectories = new Map(); const mapOfDirectories = tscWatchDirectory === Tsc_WatchDirectory.NonRecursiveWatchDirectory ? expectedWatchedDirectories : tscWatchDirectory === Tsc_WatchDirectory.WatchFile ? expectedWatchedFiles : - createMap(); + new Map(); // For failed resolution lookup and tsconfig files => cached so only watched only once mapOfDirectories.set(projectFolder, 1); // Through above recursive watches @@ -39,7 +39,7 @@ namespace ts.projectSystem { mapOfDirectories.set(`${projectFolder}/${nodeModulesAtTypes}`, 1); const expectedCompletions = ["file1"]; const completionPosition = index.content.lastIndexOf('"'); - const environmentVariables = createMap(); + const environmentVariables = new Map(); environmentVariables.set("TSC_WATCHDIRECTORY", tscWatchDirectory); const host = createServerHost(files, { environmentVariables }); const projectService = createProjectService(host); @@ -161,7 +161,7 @@ namespace ts.projectSystem { const expectedWatchedFiles = arrayToMap(fileNames.slice(1), identity, () => 1); const expectedWatchedDirectories = arrayToMap([projectFolder, projectSrcFolder, `${projectFolder}/${nodeModules}`, `${projectFolder}/${nodeModulesAtTypes}`], identity, () => 1); - const environmentVariables = createMap(); + const environmentVariables = new Map(); environmentVariables.set("TSC_WATCHDIRECTORY", Tsc_WatchDirectory.NonRecursiveWatchDirectory); const host = createServerHost([index, file1, configFile, libFile, nodeModulesExistingUnusedFile], { environmentVariables }); const projectService = createProjectService(host); diff --git a/src/tsserver/server.ts b/src/tsserver/server.ts index 43961eb0ba597..54673ee7f05e6 100644 --- a/src/tsserver/server.ts +++ b/src/tsserver/server.ts @@ -230,7 +230,7 @@ namespace ts.server { private projectService!: ProjectService; private activeRequestCount = 0; private requestQueue: QueuedOperation[] = []; - private requestMap = createMap(); // Maps operation ID to newest requestQueue entry with that ID + private requestMap = new Map(); // Maps operation ID to newest requestQueue entry with that ID /** We will lazily request the types registry on the first call to `isKnownTypesPackageName` and store it in `typesRegistryCache`. */ private requestedRegistry = false; private typesRegistryCache: Map> | undefined; @@ -374,7 +374,7 @@ namespace ts.server { switch (response.kind) { case EventTypesRegistry: - this.typesRegistryCache = createMapFromTemplate(response.typesRegistry); + this.typesRegistryCache = new Map(getEntries(response.typesRegistry)); break; case ActionPackageInstalled: { const { success, message } = response; @@ -838,7 +838,7 @@ namespace ts.server { if (useWatchGuard) { const currentDrive = extractWatchDirectoryCacheKey(sys.resolvePath(sys.getCurrentDirectory()), /*currentDriveKey*/ undefined); - const statusCache = createMap(); + const statusCache = new Map(); sys.watchDirectory = (path, callback, recursive, options) => { const cacheKey = extractWatchDirectoryCacheKey(path, currentDrive); let status = cacheKey && statusCache.get(cacheKey); diff --git a/src/typingsInstaller/nodeTypingsInstaller.ts b/src/typingsInstaller/nodeTypingsInstaller.ts index cac11df704336..ce0c4929ed29b 100644 --- a/src/typingsInstaller/nodeTypingsInstaller.ts +++ b/src/typingsInstaller/nodeTypingsInstaller.ts @@ -51,17 +51,17 @@ namespace ts.server.typingsInstaller { if (log.isEnabled()) { log.writeLine(`Types registry file '${typesRegistryFilePath}' does not exist`); } - return createMap>(); + return new Map>(); } try { const content = JSON.parse(host.readFile(typesRegistryFilePath)!); - return createMapFromTemplate(content.entries); + return new Map(getEntries(content.entries)); } catch (e) { if (log.isEnabled()) { log.writeLine(`Error when loading types registry file '${typesRegistryFilePath}': ${(e).message}, ${(e).stack}`); } - return createMap>(); + return new Map>(); } } diff --git a/src/typingsInstallerCore/typingsInstaller.ts b/src/typingsInstallerCore/typingsInstaller.ts index 75aa4b58cad94..9e9bec6c5462e 100644 --- a/src/typingsInstallerCore/typingsInstaller.ts +++ b/src/typingsInstallerCore/typingsInstaller.ts @@ -87,10 +87,10 @@ namespace ts.server.typingsInstaller { type ProjectWatchers = Map & { isInvoked?: boolean; }; export abstract class TypingsInstaller { - private readonly packageNameToTypingLocation: Map = createMap(); + private readonly packageNameToTypingLocation: Map = new Map(); private readonly missingTypingsSet = new Set(); private readonly knownCachesSet = new Set(); - private readonly projectWatchers = createMap(); + private readonly projectWatchers = new Map(); private safeList: JsTyping.SafeList | undefined; readonly pendingRunRequests: PendingRequest[] = []; private readonly toCanonicalFileName: GetCanonicalFileName; @@ -407,9 +407,9 @@ namespace ts.server.typingsInstaller { } let watchers = this.projectWatchers.get(projectName)!; - const toRemove = createMap(); + const toRemove = new Map(); if (!watchers) { - watchers = createMap(); + watchers = new Map(); this.projectWatchers.set(projectName, watchers); } else { diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 72100cfc28940..df8549996e659 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -2405,11 +2405,9 @@ declare namespace ts { __escapedIdentifier: void; }) | InternalSymbolName; /** ReadonlyMap where keys are `__String`s. */ - export interface ReadonlyUnderscoreEscapedMap extends ReadonlyMap<__String, T> { - } + export type ReadonlyUnderscoreEscapedMap = ReadonlyMap<__String, T>; /** Map where keys are `__String`s. */ - export interface UnderscoreEscapedMap extends Map<__String, T>, ReadonlyUnderscoreEscapedMap { - } + export type UnderscoreEscapedMap = Map<__String, T>; /** SymbolTable based on ES6 Map interface. */ export type SymbolTable = UnderscoreEscapedMap; export enum TypeFlags { diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 8ed116b6b1d38..6a33a3fe66931 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -2405,11 +2405,9 @@ declare namespace ts { __escapedIdentifier: void; }) | InternalSymbolName; /** ReadonlyMap where keys are `__String`s. */ - export interface ReadonlyUnderscoreEscapedMap extends ReadonlyMap<__String, T> { - } + export type ReadonlyUnderscoreEscapedMap = ReadonlyMap<__String, T>; /** Map where keys are `__String`s. */ - export interface UnderscoreEscapedMap extends Map<__String, T>, ReadonlyUnderscoreEscapedMap { - } + export type UnderscoreEscapedMap = Map<__String, T>; /** SymbolTable based on ES6 Map interface. */ export type SymbolTable = UnderscoreEscapedMap; export enum TypeFlags { From 189e883cb9bef106a5e9163917f5463c2d2c272d Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Tue, 7 Jul 2020 13:59:21 -0700 Subject: [PATCH 2/2] Move deprecated jsdoc tags to compat/deprecations.ts --- src/compat/deprecations.ts | 20 +++++++++++++++++++ src/compiler/corePublic.ts | 2 -- .../reference/api/tsserverlibrary.d.ts | 12 +++++++++-- tests/baselines/reference/api/typescript.d.ts | 12 +++++++++-- 4 files changed, 40 insertions(+), 6 deletions(-) diff --git a/src/compat/deprecations.ts b/src/compat/deprecations.ts index e9a6dc3b9a878..ed1034b7e6a1b 100644 --- a/src/compat/deprecations.ts +++ b/src/compat/deprecations.ts @@ -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` instead. + */ + export interface ReadonlyMap extends ReadonlyESMap { + } + + /** + * @deprecated Use `ts.ESMap` instead. + */ + export interface Map extends ESMap { } + + // #endregion } \ No newline at end of file diff --git a/src/compiler/corePublic.ts b/src/compiler/corePublic.ts index 13ef334670914..dad59377900e1 100644 --- a/src/compiler/corePublic.ts +++ b/src/compiler/corePublic.ts @@ -45,7 +45,6 @@ namespace ts { /** * ES6 Map interface, only read methods included. - * @deprecated Use `ts.ReadonlyESMap` instead. */ export interface ReadonlyMap extends ReadonlyESMap { } @@ -57,7 +56,6 @@ namespace ts { /** * ES6 Map interface. - * @deprecated Use `ts.ESMap` instead. */ export interface Map extends ESMap { } diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 83b03093da4b0..c185cfdb8af85 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -51,7 +51,6 @@ declare namespace ts { } /** * ES6 Map interface, only read methods included. - * @deprecated Use `ts.ReadonlyESMap` instead. */ interface ReadonlyMap extends ReadonlyESMap { } @@ -61,7 +60,6 @@ declare namespace ts { } /** * ES6 Map interface. - * @deprecated Use `ts.ESMap` instead. */ interface Map extends ESMap { } @@ -10672,6 +10670,16 @@ declare namespace ts { const getMutableClone: (node: T) => T; /** @deprecated Use `isTypeAssertionExpression` instead. */ const isTypeAssertion: (node: Node) => node is TypeAssertion; + /** + * @deprecated Use `ts.ReadonlyESMap` instead. + */ + interface ReadonlyMap extends ReadonlyESMap { + } + /** + * @deprecated Use `ts.ESMap` instead. + */ + interface Map extends ESMap { + } } export = ts; diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index e85e4a8bf70b2..b97e67b16dba7 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -51,7 +51,6 @@ declare namespace ts { } /** * ES6 Map interface, only read methods included. - * @deprecated Use `ts.ReadonlyESMap` instead. */ interface ReadonlyMap extends ReadonlyESMap { } @@ -61,7 +60,6 @@ declare namespace ts { } /** * ES6 Map interface. - * @deprecated Use `ts.ESMap` instead. */ interface Map extends ESMap { } @@ -7092,6 +7090,16 @@ declare namespace ts { const getMutableClone: (node: T) => T; /** @deprecated Use `isTypeAssertionExpression` instead. */ const isTypeAssertion: (node: Node) => node is TypeAssertion; + /** + * @deprecated Use `ts.ReadonlyESMap` instead. + */ + interface ReadonlyMap extends ReadonlyESMap { + } + /** + * @deprecated Use `ts.ESMap` instead. + */ + interface Map extends ESMap { + } } export = ts; \ No newline at end of file