Merge pull request #10270 from Microsoft/optimizeMaps
Optimize performance of maps
This commit is contained in:
commit
5bdde3b284
|
@ -69,7 +69,7 @@ function checkForUniqueCodes(messages: string[], diagnosticTable: InputDiagnosti
|
|||
}
|
||||
|
||||
function buildUniqueNameMap(names: string[]): ts.Map<string> {
|
||||
var nameMap: ts.Map<string> = {};
|
||||
var nameMap = ts.createMap<string>();
|
||||
|
||||
var uniqueNames = NameGenerator.ensureUniqueness(names, /* isCaseSensitive */ false, /* isFixed */ undefined);
|
||||
|
||||
|
|
|
@ -135,7 +135,7 @@ namespace ts {
|
|||
options = opts;
|
||||
languageVersion = getEmitScriptTarget(options);
|
||||
inStrictMode = !!file.externalModuleIndicator;
|
||||
classifiableNames = {};
|
||||
classifiableNames = createMap<string>();
|
||||
symbolCount = 0;
|
||||
|
||||
Symbol = objectAllocator.getSymbolConstructor();
|
||||
|
@ -183,11 +183,11 @@ namespace ts {
|
|||
symbol.declarations.push(node);
|
||||
|
||||
if (symbolFlags & SymbolFlags.HasExports && !symbol.exports) {
|
||||
symbol.exports = {};
|
||||
symbol.exports = createMap<Symbol>();
|
||||
}
|
||||
|
||||
if (symbolFlags & SymbolFlags.HasMembers && !symbol.members) {
|
||||
symbol.members = {};
|
||||
symbol.members = createMap<Symbol>();
|
||||
}
|
||||
|
||||
if (symbolFlags & SymbolFlags.Value) {
|
||||
|
@ -318,9 +318,7 @@ namespace ts {
|
|||
// Otherwise, we'll be merging into a compatible existing symbol (for example when
|
||||
// you have multiple 'vars' with the same name in the same container). In this case
|
||||
// just add this node into the declarations list of the symbol.
|
||||
symbol = hasProperty(symbolTable, name)
|
||||
? symbolTable[name]
|
||||
: (symbolTable[name] = createSymbol(SymbolFlags.None, name));
|
||||
symbol = symbolTable[name] || (symbolTable[name] = createSymbol(SymbolFlags.None, name));
|
||||
|
||||
if (name && (includes & SymbolFlags.Classifiable)) {
|
||||
classifiableNames[name] = name;
|
||||
|
@ -434,7 +432,7 @@ namespace ts {
|
|||
if (containerFlags & ContainerFlags.IsContainer) {
|
||||
container = blockScopeContainer = node;
|
||||
if (containerFlags & ContainerFlags.HasLocals) {
|
||||
container.locals = {};
|
||||
container.locals = createMap<Symbol>();
|
||||
}
|
||||
addToContainerChain(container);
|
||||
}
|
||||
|
@ -1399,7 +1397,8 @@ namespace ts {
|
|||
|
||||
const typeLiteralSymbol = createSymbol(SymbolFlags.TypeLiteral, "__type");
|
||||
addDeclarationToSymbol(typeLiteralSymbol, node, SymbolFlags.TypeLiteral);
|
||||
typeLiteralSymbol.members = { [symbol.name]: symbol };
|
||||
typeLiteralSymbol.members = createMap<Symbol>();
|
||||
typeLiteralSymbol.members[symbol.name] = symbol;
|
||||
}
|
||||
|
||||
function bindObjectLiteralExpression(node: ObjectLiteralExpression) {
|
||||
|
@ -1409,7 +1408,7 @@ namespace ts {
|
|||
}
|
||||
|
||||
if (inStrictMode) {
|
||||
const seen: Map<ElementKind> = {};
|
||||
const seen = createMap<ElementKind>();
|
||||
|
||||
for (const prop of node.properties) {
|
||||
if (prop.name.kind !== SyntaxKind.Identifier) {
|
||||
|
@ -1465,7 +1464,7 @@ namespace ts {
|
|||
// fall through.
|
||||
default:
|
||||
if (!blockScopeContainer.locals) {
|
||||
blockScopeContainer.locals = {};
|
||||
blockScopeContainer.locals = createMap<Symbol>();
|
||||
addToContainerChain(blockScopeContainer);
|
||||
}
|
||||
declareSymbol(blockScopeContainer.locals, undefined, node, symbolFlags, symbolExcludes);
|
||||
|
@ -1924,7 +1923,7 @@ namespace ts {
|
|||
}
|
||||
}
|
||||
|
||||
file.symbol.globalExports = file.symbol.globalExports || {};
|
||||
file.symbol.globalExports = file.symbol.globalExports || createMap<Symbol>();
|
||||
declareSymbol(file.symbol.globalExports, file.symbol, node, SymbolFlags.Alias, SymbolFlags.AliasExcludes);
|
||||
}
|
||||
|
||||
|
@ -1977,7 +1976,7 @@ namespace ts {
|
|||
else {
|
||||
return;
|
||||
}
|
||||
assignee.symbol.members = assignee.symbol.members || {};
|
||||
assignee.symbol.members = assignee.symbol.members || createMap<Symbol>();
|
||||
// It's acceptable for multiple 'this' assignments of the same identifier to occur
|
||||
declareSymbol(assignee.symbol.members, assignee.symbol, node, SymbolFlags.Property, SymbolFlags.PropertyExcludes & ~SymbolFlags.Property);
|
||||
}
|
||||
|
@ -2003,7 +2002,7 @@ namespace ts {
|
|||
|
||||
// Set up the members collection if it doesn't exist already
|
||||
if (!funcSymbol.members) {
|
||||
funcSymbol.members = {};
|
||||
funcSymbol.members = createMap<Symbol>();
|
||||
}
|
||||
|
||||
// Declare the method/property
|
||||
|
@ -2052,7 +2051,7 @@ namespace ts {
|
|||
// module might have an exported variable called 'prototype'. We can't allow that as
|
||||
// that would clash with the built-in 'prototype' for the class.
|
||||
const prototypeSymbol = createSymbol(SymbolFlags.Property | SymbolFlags.Prototype, "prototype");
|
||||
if (hasProperty(symbol.exports, prototypeSymbol.name)) {
|
||||
if (symbol.exports[prototypeSymbol.name]) {
|
||||
if (node.name) {
|
||||
node.name.parent = node;
|
||||
}
|
||||
|
|
|
@ -44,7 +44,7 @@ namespace ts {
|
|||
let symbolCount = 0;
|
||||
|
||||
const emptyArray: any[] = [];
|
||||
const emptySymbols: SymbolTable = {};
|
||||
const emptySymbols = createMap<Symbol>();
|
||||
|
||||
const compilerOptions = host.getCompilerOptions();
|
||||
const languageVersion = compilerOptions.target || ScriptTarget.ES3;
|
||||
|
@ -106,11 +106,11 @@ namespace ts {
|
|||
isOptionalParameter
|
||||
};
|
||||
|
||||
const tupleTypes: Map<TupleType> = {};
|
||||
const unionTypes: Map<UnionType> = {};
|
||||
const intersectionTypes: Map<IntersectionType> = {};
|
||||
const stringLiteralTypes: Map<LiteralType> = {};
|
||||
const numericLiteralTypes: Map<LiteralType> = {};
|
||||
const tupleTypes = createMap<TupleType>();
|
||||
const unionTypes = createMap<UnionType>();
|
||||
const intersectionTypes = createMap<IntersectionType>();
|
||||
const stringLiteralTypes = createMap<LiteralType>();
|
||||
const numericLiteralTypes = createMap<LiteralType>();
|
||||
|
||||
const unknownSymbol = createSymbol(SymbolFlags.Property | SymbolFlags.Transient, "unknown");
|
||||
const resolvingSymbol = createSymbol(SymbolFlags.Transient, "__resolving__");
|
||||
|
@ -132,7 +132,7 @@ namespace ts {
|
|||
|
||||
const emptyObjectType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, undefined, undefined);
|
||||
const emptyGenericType = <GenericType><ObjectType>createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, undefined, undefined);
|
||||
emptyGenericType.instantiations = {};
|
||||
emptyGenericType.instantiations = createMap<TypeReference>();
|
||||
|
||||
const anyFunctionType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, undefined, undefined);
|
||||
// The anyFunctionType contains the anyFunctionType by definition. The flag is further propagated
|
||||
|
@ -146,7 +146,7 @@ namespace ts {
|
|||
|
||||
const enumNumberIndexInfo = createIndexInfo(stringType, /*isReadonly*/ true);
|
||||
|
||||
const globals: SymbolTable = {};
|
||||
const globals = createMap<Symbol>();
|
||||
/**
|
||||
* List of every ambient module with a "*" wildcard.
|
||||
* Unlike other ambient modules, these can't be stored in `globals` because symbol tables only deal with exact matches.
|
||||
|
@ -284,7 +284,7 @@ namespace ts {
|
|||
NullFacts = TypeofEQObject | TypeofNEString | TypeofNENumber | TypeofNEBoolean | TypeofNESymbol | TypeofNEFunction | TypeofNEHostObject | EQNull | EQUndefinedOrNull | NEUndefined | Falsy,
|
||||
}
|
||||
|
||||
const typeofEQFacts: Map<TypeFacts> = {
|
||||
const typeofEQFacts: MapLike<TypeFacts> = {
|
||||
"string": TypeFacts.TypeofEQString,
|
||||
"number": TypeFacts.TypeofEQNumber,
|
||||
"boolean": TypeFacts.TypeofEQBoolean,
|
||||
|
@ -294,7 +294,7 @@ namespace ts {
|
|||
"function": TypeFacts.TypeofEQFunction
|
||||
};
|
||||
|
||||
const typeofNEFacts: Map<TypeFacts> = {
|
||||
const typeofNEFacts: MapLike<TypeFacts> = {
|
||||
"string": TypeFacts.TypeofNEString,
|
||||
"number": TypeFacts.TypeofNENumber,
|
||||
"boolean": TypeFacts.TypeofNEBoolean,
|
||||
|
@ -304,7 +304,7 @@ namespace ts {
|
|||
"function": TypeFacts.TypeofNEFunction
|
||||
};
|
||||
|
||||
const typeofTypesByName: Map<Type> = {
|
||||
const typeofTypesByName: MapLike<Type> = {
|
||||
"string": stringType,
|
||||
"number": numberType,
|
||||
"boolean": booleanType,
|
||||
|
@ -314,7 +314,7 @@ namespace ts {
|
|||
|
||||
let jsxElementType: ObjectType;
|
||||
/** Things we lazy load from the JSX namespace */
|
||||
const jsxTypes: Map<ObjectType> = {};
|
||||
const jsxTypes = createMap<ObjectType>();
|
||||
const JsxNames = {
|
||||
JSX: "JSX",
|
||||
IntrinsicElements: "IntrinsicElements",
|
||||
|
@ -325,10 +325,10 @@ namespace ts {
|
|||
IntrinsicClassAttributes: "IntrinsicClassAttributes"
|
||||
};
|
||||
|
||||
const subtypeRelation: Map<RelationComparisonResult> = {};
|
||||
const assignableRelation: Map<RelationComparisonResult> = {};
|
||||
const comparableRelation: Map<RelationComparisonResult> = {};
|
||||
const identityRelation: Map<RelationComparisonResult> = {};
|
||||
const subtypeRelation = createMap<RelationComparisonResult>();
|
||||
const assignableRelation = createMap<RelationComparisonResult>();
|
||||
const comparableRelation = createMap<RelationComparisonResult>();
|
||||
const identityRelation = createMap<RelationComparisonResult>();
|
||||
|
||||
// This is for caching the result of getSymbolDisplayBuilder. Do not access directly.
|
||||
let _displayBuilder: SymbolDisplayBuilder;
|
||||
|
@ -342,9 +342,8 @@ namespace ts {
|
|||
ResolvedReturnType
|
||||
}
|
||||
|
||||
const builtinGlobals: SymbolTable = {
|
||||
[undefinedSymbol.name]: undefinedSymbol
|
||||
};
|
||||
const builtinGlobals = createMap<Symbol>();
|
||||
builtinGlobals[undefinedSymbol.name] = undefinedSymbol;
|
||||
|
||||
initializeTypeChecker();
|
||||
|
||||
|
@ -427,11 +426,11 @@ namespace ts {
|
|||
target.declarations.push(node);
|
||||
});
|
||||
if (source.members) {
|
||||
if (!target.members) target.members = {};
|
||||
if (!target.members) target.members = createMap<Symbol>();
|
||||
mergeSymbolTable(target.members, source.members);
|
||||
}
|
||||
if (source.exports) {
|
||||
if (!target.exports) target.exports = {};
|
||||
if (!target.exports) target.exports = createMap<Symbol>();
|
||||
mergeSymbolTable(target.exports, source.exports);
|
||||
}
|
||||
recordMergedSymbol(target, source);
|
||||
|
@ -449,28 +448,24 @@ namespace ts {
|
|||
}
|
||||
|
||||
function cloneSymbolTable(symbolTable: SymbolTable): SymbolTable {
|
||||
const result: SymbolTable = {};
|
||||
const result = createMap<Symbol>();
|
||||
for (const id in symbolTable) {
|
||||
if (hasProperty(symbolTable, id)) {
|
||||
result[id] = symbolTable[id];
|
||||
}
|
||||
result[id] = symbolTable[id];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function mergeSymbolTable(target: SymbolTable, source: SymbolTable) {
|
||||
for (const id in source) {
|
||||
if (hasProperty(source, id)) {
|
||||
if (!hasProperty(target, id)) {
|
||||
target[id] = source[id];
|
||||
}
|
||||
else {
|
||||
let symbol = target[id];
|
||||
if (!(symbol.flags & SymbolFlags.Merged)) {
|
||||
target[id] = symbol = cloneSymbol(symbol);
|
||||
}
|
||||
mergeSymbol(symbol, source[id]);
|
||||
let targetSymbol = target[id];
|
||||
if (!targetSymbol) {
|
||||
target[id] = source[id];
|
||||
}
|
||||
else {
|
||||
if (!(targetSymbol.flags & SymbolFlags.Merged)) {
|
||||
target[id] = targetSymbol = cloneSymbol(targetSymbol);
|
||||
}
|
||||
mergeSymbol(targetSymbol, source[id]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -514,14 +509,12 @@ namespace ts {
|
|||
|
||||
function addToSymbolTable(target: SymbolTable, source: SymbolTable, message: DiagnosticMessage) {
|
||||
for (const id in source) {
|
||||
if (hasProperty(source, id)) {
|
||||
if (hasProperty(target, id)) {
|
||||
// Error on redeclarations
|
||||
forEach(target[id].declarations, addDeclarationDiagnostic(id, message));
|
||||
}
|
||||
else {
|
||||
target[id] = source[id];
|
||||
}
|
||||
if (target[id]) {
|
||||
// Error on redeclarations
|
||||
forEach(target[id].declarations, addDeclarationDiagnostic(id, message));
|
||||
}
|
||||
else {
|
||||
target[id] = source[id];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -546,18 +539,20 @@ namespace ts {
|
|||
}
|
||||
|
||||
function getSymbol(symbols: SymbolTable, name: string, meaning: SymbolFlags): Symbol {
|
||||
if (meaning && hasProperty(symbols, name)) {
|
||||
if (meaning) {
|
||||
const symbol = symbols[name];
|
||||
Debug.assert((symbol.flags & SymbolFlags.Instantiated) === 0, "Should never get an instantiated symbol here.");
|
||||
if (symbol.flags & meaning) {
|
||||
return symbol;
|
||||
}
|
||||
if (symbol.flags & SymbolFlags.Alias) {
|
||||
const target = resolveAlias(symbol);
|
||||
// Unknown symbol means an error occurred in alias resolution, treat it as positive answer to avoid cascading errors
|
||||
if (target === unknownSymbol || target.flags & meaning) {
|
||||
if (symbol) {
|
||||
Debug.assert((symbol.flags & SymbolFlags.Instantiated) === 0, "Should never get an instantiated symbol here.");
|
||||
if (symbol.flags & meaning) {
|
||||
return symbol;
|
||||
}
|
||||
if (symbol.flags & SymbolFlags.Alias) {
|
||||
const target = resolveAlias(symbol);
|
||||
// Unknown symbol means an error occurred in alias resolution, treat it as positive answer to avoid cascading errors
|
||||
if (target === unknownSymbol || target.flags & meaning) {
|
||||
return symbol;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// return undefined if we can't find a symbol.
|
||||
|
@ -745,7 +740,7 @@ namespace ts {
|
|||
// 2. We check === SymbolFlags.Alias in order to check that the symbol is *purely*
|
||||
// an alias. If we used &, we'd be throwing out symbols that have non alias aspects,
|
||||
// which is not the desired behavior.
|
||||
if (hasProperty(moduleExports, name) &&
|
||||
if (moduleExports[name] &&
|
||||
moduleExports[name].flags === SymbolFlags.Alias &&
|
||||
getDeclarationOfKind(moduleExports[name], SyntaxKind.ExportSpecifier)) {
|
||||
break;
|
||||
|
@ -1105,9 +1100,9 @@ namespace ts {
|
|||
|
||||
function getExportOfModule(symbol: Symbol, name: string): Symbol {
|
||||
if (symbol.flags & SymbolFlags.Module) {
|
||||
const exports = getExportsOfSymbol(symbol);
|
||||
if (hasProperty(exports, name)) {
|
||||
return resolveSymbol(exports[name]);
|
||||
const exportedSymbol = getExportsOfSymbol(symbol)[name];
|
||||
if (exportedSymbol) {
|
||||
return resolveSymbol(exportedSymbol);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1425,7 +1420,7 @@ namespace ts {
|
|||
*/
|
||||
function extendExportSymbols(target: SymbolTable, source: SymbolTable, lookupTable?: Map<ExportCollisionTracker>, exportNode?: ExportDeclaration) {
|
||||
for (const id in source) {
|
||||
if (id !== "default" && !hasProperty(target, id)) {
|
||||
if (id !== "default" && !target[id]) {
|
||||
target[id] = source[id];
|
||||
if (lookupTable && exportNode) {
|
||||
lookupTable[id] = {
|
||||
|
@ -1433,7 +1428,7 @@ namespace ts {
|
|||
} as ExportCollisionTracker;
|
||||
}
|
||||
}
|
||||
else if (lookupTable && exportNode && id !== "default" && hasProperty(target, id) && resolveSymbol(target[id]) !== resolveSymbol(source[id])) {
|
||||
else if (lookupTable && exportNode && id !== "default" && target[id] && resolveSymbol(target[id]) !== resolveSymbol(source[id])) {
|
||||
if (!lookupTable[id].exportsWithDuplicate) {
|
||||
lookupTable[id].exportsWithDuplicate = [exportNode];
|
||||
}
|
||||
|
@ -1459,8 +1454,8 @@ namespace ts {
|
|||
// All export * declarations are collected in an __export symbol by the binder
|
||||
const exportStars = symbol.exports["__export"];
|
||||
if (exportStars) {
|
||||
const nestedSymbols: SymbolTable = {};
|
||||
const lookupTable: Map<ExportCollisionTracker> = {};
|
||||
const nestedSymbols = createMap<Symbol>();
|
||||
const lookupTable = createMap<ExportCollisionTracker>();
|
||||
for (const node of exportStars.declarations) {
|
||||
const resolvedModule = resolveExternalModuleName(node, (node as ExportDeclaration).moduleSpecifier);
|
||||
const exportedSymbols = visit(resolvedModule);
|
||||
|
@ -1474,7 +1469,7 @@ namespace ts {
|
|||
for (const id in lookupTable) {
|
||||
const { exportsWithDuplicate } = lookupTable[id];
|
||||
// It's not an error if the file with multiple `export *`s with duplicate names exports a member with that name itself
|
||||
if (id === "export=" || !(exportsWithDuplicate && exportsWithDuplicate.length) || hasProperty(symbols, id)) {
|
||||
if (id === "export=" || !(exportsWithDuplicate && exportsWithDuplicate.length) || symbols[id]) {
|
||||
continue;
|
||||
}
|
||||
for (const node of exportsWithDuplicate) {
|
||||
|
@ -1580,13 +1575,11 @@ namespace ts {
|
|||
function getNamedMembers(members: SymbolTable): Symbol[] {
|
||||
let result: Symbol[];
|
||||
for (const id in members) {
|
||||
if (hasProperty(members, id)) {
|
||||
if (!isReservedMemberName(id)) {
|
||||
if (!result) result = [];
|
||||
const symbol = members[id];
|
||||
if (symbolIsValue(symbol)) {
|
||||
result.push(symbol);
|
||||
}
|
||||
if (!isReservedMemberName(id)) {
|
||||
if (!result) result = [];
|
||||
const symbol = members[id];
|
||||
if (symbolIsValue(symbol)) {
|
||||
result.push(symbol);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1702,12 +1695,12 @@ namespace ts {
|
|||
let qualify = false;
|
||||
forEachSymbolTableInScope(enclosingDeclaration, symbolTable => {
|
||||
// If symbol of this name is not available in the symbol table we are ok
|
||||
if (!hasProperty(symbolTable, symbol.name)) {
|
||||
let symbolFromSymbolTable = symbolTable[symbol.name];
|
||||
if (!symbolFromSymbolTable) {
|
||||
// Continue to the next symbol table
|
||||
return false;
|
||||
}
|
||||
// If the symbol with this name is present it should refer to the symbol
|
||||
let symbolFromSymbolTable = symbolTable[symbol.name];
|
||||
if (symbolFromSymbolTable === symbol) {
|
||||
// No need to qualify
|
||||
return true;
|
||||
|
@ -3125,7 +3118,7 @@ namespace ts {
|
|||
|
||||
// Return the type implied by an object binding pattern
|
||||
function getTypeFromObjectBindingPattern(pattern: BindingPattern, includePatternInType: boolean): Type {
|
||||
const members: SymbolTable = {};
|
||||
const members = createMap<Symbol>();
|
||||
let hasComputedProperties = false;
|
||||
forEach(pattern.elements, e => {
|
||||
const name = e.propertyName || <Identifier>e.name;
|
||||
|
@ -3713,7 +3706,7 @@ namespace ts {
|
|||
type.typeParameters = concatenate(outerTypeParameters, localTypeParameters);
|
||||
type.outerTypeParameters = outerTypeParameters;
|
||||
type.localTypeParameters = localTypeParameters;
|
||||
(<GenericType>type).instantiations = {};
|
||||
(<GenericType>type).instantiations = createMap<TypeReference>();
|
||||
(<GenericType>type).instantiations[getTypeListId(type.typeParameters)] = <GenericType>type;
|
||||
(<GenericType>type).target = <GenericType>type;
|
||||
(<GenericType>type).typeArguments = type.typeParameters;
|
||||
|
@ -3755,7 +3748,7 @@ namespace ts {
|
|||
if (typeParameters) {
|
||||
// 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.instantiations = {};
|
||||
links.instantiations = createMap<Type>();
|
||||
links.instantiations[getTypeListId(links.typeParameters)] = type;
|
||||
}
|
||||
}
|
||||
|
@ -3776,7 +3769,7 @@ namespace ts {
|
|||
return expr.kind === SyntaxKind.NumericLiteral ||
|
||||
expr.kind === SyntaxKind.PrefixUnaryExpression && (<PrefixUnaryExpression>expr).operator === SyntaxKind.MinusToken &&
|
||||
(<PrefixUnaryExpression>expr).operand.kind === SyntaxKind.NumericLiteral ||
|
||||
expr.kind === SyntaxKind.Identifier && hasProperty(symbol.exports, (<Identifier>expr).text);
|
||||
expr.kind === SyntaxKind.Identifier && !!symbol.exports[(<Identifier>expr).text];
|
||||
}
|
||||
|
||||
function enumHasLiteralMembers(symbol: Symbol) {
|
||||
|
@ -3799,7 +3792,7 @@ namespace ts {
|
|||
enumType.symbol = symbol;
|
||||
if (enumHasLiteralMembers(symbol)) {
|
||||
const memberTypeList: Type[] = [];
|
||||
const memberTypes: Map<EnumLiteralType> = {};
|
||||
const memberTypes = createMap<EnumLiteralType>();
|
||||
for (const declaration of enumType.symbol.declarations) {
|
||||
if (declaration.kind === SyntaxKind.EnumDeclaration) {
|
||||
computeEnumMemberValues(<EnumDeclaration>declaration);
|
||||
|
@ -3962,7 +3955,7 @@ namespace ts {
|
|||
}
|
||||
|
||||
function createSymbolTable(symbols: Symbol[]): SymbolTable {
|
||||
const result: SymbolTable = {};
|
||||
const result = createMap<Symbol>();
|
||||
for (const symbol of symbols) {
|
||||
result[symbol.name] = symbol;
|
||||
}
|
||||
|
@ -3972,7 +3965,7 @@ namespace ts {
|
|||
// The mappingThisOnly flag indicates that the only type parameter being mapped is "this". When the flag is true,
|
||||
// we check symbols to see if we can quickly conclude they are free of "this" references, thus needing no instantiation.
|
||||
function createInstantiatedSymbolTable(symbols: Symbol[], mapper: TypeMapper, mappingThisOnly: boolean): SymbolTable {
|
||||
const result: SymbolTable = {};
|
||||
const result = createMap<Symbol>();
|
||||
for (const symbol of symbols) {
|
||||
result[symbol.name] = mappingThisOnly && isIndependentMember(symbol) ? symbol : instantiateSymbol(symbol, mapper);
|
||||
}
|
||||
|
@ -3981,7 +3974,7 @@ namespace ts {
|
|||
|
||||
function addInheritedMembers(symbols: SymbolTable, baseSymbols: Symbol[]) {
|
||||
for (const s of baseSymbols) {
|
||||
if (!hasProperty(symbols, s.name)) {
|
||||
if (!symbols[s.name]) {
|
||||
symbols[s.name] = s;
|
||||
}
|
||||
}
|
||||
|
@ -4098,7 +4091,7 @@ namespace ts {
|
|||
}
|
||||
|
||||
function createTupleTypeMemberSymbols(memberTypes: Type[]): SymbolTable {
|
||||
const members: SymbolTable = {};
|
||||
const members = createMap<Symbol>();
|
||||
for (let i = 0; i < memberTypes.length; i++) {
|
||||
const symbol = <TransientSymbol>createSymbol(SymbolFlags.Property | SymbolFlags.Transient, "" + i);
|
||||
symbol.type = memberTypes[i];
|
||||
|
@ -4321,11 +4314,9 @@ namespace ts {
|
|||
function getPropertyOfObjectType(type: Type, name: string): Symbol {
|
||||
if (type.flags & TypeFlags.ObjectType) {
|
||||
const resolved = resolveStructuredTypeMembers(<ObjectType>type);
|
||||
if (hasProperty(resolved.members, name)) {
|
||||
const symbol = resolved.members[name];
|
||||
if (symbolIsValue(symbol)) {
|
||||
return symbol;
|
||||
}
|
||||
const symbol = resolved.members[name];
|
||||
if (symbol && symbolIsValue(symbol)) {
|
||||
return symbol;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4454,13 +4445,13 @@ namespace ts {
|
|||
}
|
||||
|
||||
function getPropertyOfUnionOrIntersectionType(type: UnionOrIntersectionType, name: string): Symbol {
|
||||
const properties = type.resolvedProperties || (type.resolvedProperties = {});
|
||||
if (hasProperty(properties, name)) {
|
||||
return properties[name];
|
||||
}
|
||||
const property = createUnionOrIntersectionProperty(type, name);
|
||||
if (property) {
|
||||
properties[name] = property;
|
||||
const properties = type.resolvedProperties || (type.resolvedProperties = createMap<Symbol>());
|
||||
let property = properties[name];
|
||||
if (!property) {
|
||||
property = createUnionOrIntersectionProperty(type, name);
|
||||
if (property) {
|
||||
properties[name] = property;
|
||||
}
|
||||
}
|
||||
return property;
|
||||
}
|
||||
|
@ -4477,11 +4468,9 @@ namespace ts {
|
|||
type = getApparentType(type);
|
||||
if (type.flags & TypeFlags.ObjectType) {
|
||||
const resolved = resolveStructuredTypeMembers(type);
|
||||
if (hasProperty(resolved.members, name)) {
|
||||
const symbol = resolved.members[name];
|
||||
if (symbolIsValue(symbol)) {
|
||||
return symbol;
|
||||
}
|
||||
const symbol = resolved.members[name];
|
||||
if (symbol && symbolIsValue(symbol)) {
|
||||
return symbol;
|
||||
}
|
||||
if (resolved === anyFunctionType || resolved.callSignatures.length || resolved.constructSignatures.length) {
|
||||
const symbol = getPropertyOfObjectType(globalFunctionType, name);
|
||||
|
@ -5487,7 +5476,7 @@ namespace ts {
|
|||
|
||||
function getLiteralTypeForText(flags: TypeFlags, text: string) {
|
||||
const map = flags & TypeFlags.StringLiteral ? stringLiteralTypes : numericLiteralTypes;
|
||||
return hasProperty(map, text) ? map[text] : map[text] = createLiteralType(flags, text);
|
||||
return map[text] || (map[text] = createLiteralType(flags, text));
|
||||
}
|
||||
|
||||
function getTypeFromLiteralTypeNode(node: LiteralTypeNode): Type {
|
||||
|
@ -6602,7 +6591,7 @@ namespace ts {
|
|||
}
|
||||
sourceStack[depth] = source;
|
||||
targetStack[depth] = target;
|
||||
maybeStack[depth] = {};
|
||||
maybeStack[depth] = createMap<RelationComparisonResult>();
|
||||
maybeStack[depth][id] = RelationComparisonResult.Succeeded;
|
||||
depth++;
|
||||
const saveExpandingFlags = expandingFlags;
|
||||
|
@ -7243,7 +7232,7 @@ namespace ts {
|
|||
}
|
||||
|
||||
function transformTypeOfMembers(type: Type, f: (propertyType: Type) => Type) {
|
||||
const members: SymbolTable = {};
|
||||
const members = createMap<Symbol>();
|
||||
for (const property of getPropertiesOfObjectType(type)) {
|
||||
const original = getTypeOfSymbol(property);
|
||||
const updated = f(original);
|
||||
|
@ -7467,7 +7456,7 @@ namespace ts {
|
|||
let targetStack: Type[];
|
||||
let depth = 0;
|
||||
let inferiority = 0;
|
||||
const visited: Map<boolean> = {};
|
||||
const visited = createMap<boolean>();
|
||||
inferFromTypes(source, target);
|
||||
|
||||
function isInProcess(source: Type, target: Type) {
|
||||
|
@ -7601,7 +7590,7 @@ namespace ts {
|
|||
return;
|
||||
}
|
||||
const key = source.id + "," + target.id;
|
||||
if (hasProperty(visited, key)) {
|
||||
if (visited[key]) {
|
||||
return;
|
||||
}
|
||||
visited[key] = true;
|
||||
|
@ -8356,7 +8345,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] = {});
|
||||
const cache = flowLoopCaches[id] || (flowLoopCaches[id] = createMap<Type>());
|
||||
if (!key) {
|
||||
key = getFlowCacheKey(reference);
|
||||
}
|
||||
|
@ -9951,7 +9940,7 @@ namespace ts {
|
|||
// Grammar checking
|
||||
checkGrammarObjectLiteralExpression(node, inDestructuringPattern);
|
||||
|
||||
const propertiesTable: SymbolTable = {};
|
||||
const propertiesTable = createMap<Symbol>();
|
||||
const propertiesArray: Symbol[] = [];
|
||||
const contextualType = getApparentTypeOfContextualType(node);
|
||||
const contextualTypeHasPattern = contextualType && contextualType.pattern &&
|
||||
|
@ -10042,7 +10031,7 @@ namespace ts {
|
|||
// type with those properties for which the binding pattern specifies a default value.
|
||||
if (contextualTypeHasPattern) {
|
||||
for (const prop of getPropertiesOfType(contextualType)) {
|
||||
if (!hasProperty(propertiesTable, prop.name)) {
|
||||
if (!propertiesTable[prop.name]) {
|
||||
if (!(prop.flags & SymbolFlags.Optional)) {
|
||||
error(prop.valueDeclaration || (<TransientSymbol>prop).bindingElement,
|
||||
Diagnostics.Initializer_provides_no_value_for_this_binding_element_and_the_binding_element_has_no_default_value);
|
||||
|
@ -10170,7 +10159,7 @@ namespace ts {
|
|||
for (const prop of props) {
|
||||
// Is there a corresponding property in the element attributes type? Skip checking of properties
|
||||
// that have already been assigned to, as these are not actually pushed into the resulting type
|
||||
if (!hasProperty(nameTable, prop.name)) {
|
||||
if (!nameTable[prop.name]) {
|
||||
const targetPropSym = getPropertyOfType(elementAttributesType, prop.name);
|
||||
if (targetPropSym) {
|
||||
const msg = chainDiagnosticMessages(undefined, Diagnostics.Property_0_of_JSX_spread_attribute_is_not_assignable_to_target_property, prop.name);
|
||||
|
@ -10492,7 +10481,7 @@ namespace ts {
|
|||
|
||||
const targetAttributesType = getJsxElementAttributesType(node);
|
||||
|
||||
const nameTable: Map<boolean> = {};
|
||||
const nameTable = createMap<boolean>();
|
||||
// Process this array in right-to-left order so we know which
|
||||
// attributes (mostly from spreads) are being overwritten and
|
||||
// thus should have their types ignored
|
||||
|
@ -10516,7 +10505,7 @@ namespace ts {
|
|||
const targetProperties = getPropertiesOfType(targetAttributesType);
|
||||
for (let i = 0; i < targetProperties.length; i++) {
|
||||
if (!(targetProperties[i].flags & SymbolFlags.Optional) &&
|
||||
!hasProperty(nameTable, targetProperties[i].name)) {
|
||||
!nameTable[targetProperties[i].name]) {
|
||||
|
||||
error(node, Diagnostics.Property_0_is_missing_in_type_1, targetProperties[i].name, typeToString(targetAttributesType));
|
||||
}
|
||||
|
@ -13800,8 +13789,8 @@ namespace ts {
|
|||
function checkClassForDuplicateDeclarations(node: ClassLikeDeclaration) {
|
||||
const getter = 1, setter = 2, property = getter | setter;
|
||||
|
||||
const instanceNames: Map<number> = {};
|
||||
const staticNames: Map<number> = {};
|
||||
const instanceNames = createMap<number>();
|
||||
const staticNames = createMap<number>();
|
||||
for (const member of node.members) {
|
||||
if (member.kind === SyntaxKind.Constructor) {
|
||||
for (const param of (member as ConstructorDeclaration).parameters) {
|
||||
|
@ -13834,8 +13823,8 @@ namespace ts {
|
|||
}
|
||||
|
||||
function addName(names: Map<number>, location: Node, name: string, meaning: number) {
|
||||
if (hasProperty(names, name)) {
|
||||
const prev = names[name];
|
||||
const prev = names[name];
|
||||
if (prev) {
|
||||
if (prev & meaning) {
|
||||
error(location, Diagnostics.Duplicate_identifier_0, getTextOfNode(location));
|
||||
}
|
||||
|
@ -13850,7 +13839,7 @@ namespace ts {
|
|||
}
|
||||
|
||||
function checkObjectTypeForDuplicateDeclarations(node: TypeLiteralNode | InterfaceDeclaration) {
|
||||
const names: Map<boolean> = {};
|
||||
const names = createMap<boolean>();
|
||||
for (const member of node.members) {
|
||||
if (member.kind == SyntaxKind.PropertySignature) {
|
||||
let memberName: string;
|
||||
|
@ -13864,7 +13853,7 @@ namespace ts {
|
|||
continue;
|
||||
}
|
||||
|
||||
if (hasProperty(names, memberName)) {
|
||||
if (names[memberName]) {
|
||||
error(member.symbol.valueDeclaration.name, Diagnostics.Duplicate_identifier_0, memberName);
|
||||
error(member.name, Diagnostics.Duplicate_identifier_0, memberName);
|
||||
}
|
||||
|
@ -15076,22 +15065,20 @@ namespace ts {
|
|||
function checkUnusedLocalsAndParameters(node: Node): void {
|
||||
if (node.parent.kind !== SyntaxKind.InterfaceDeclaration && noUnusedIdentifiers && !isInAmbientContext(node)) {
|
||||
for (const key in node.locals) {
|
||||
if (hasProperty(node.locals, key)) {
|
||||
const local = node.locals[key];
|
||||
if (!local.isReferenced) {
|
||||
if (local.valueDeclaration && local.valueDeclaration.kind === SyntaxKind.Parameter) {
|
||||
const parameter = <ParameterDeclaration>local.valueDeclaration;
|
||||
if (compilerOptions.noUnusedParameters &&
|
||||
!isParameterPropertyDeclaration(parameter) &&
|
||||
!parameterIsThisKeyword(parameter) &&
|
||||
!parameterNameStartsWithUnderscore(parameter)) {
|
||||
error(local.valueDeclaration.name, Diagnostics._0_is_declared_but_never_used, local.name);
|
||||
}
|
||||
}
|
||||
else if (compilerOptions.noUnusedLocals) {
|
||||
forEach(local.declarations, d => error(d.name || d, Diagnostics._0_is_declared_but_never_used, local.name));
|
||||
const local = node.locals[key];
|
||||
if (!local.isReferenced) {
|
||||
if (local.valueDeclaration && local.valueDeclaration.kind === SyntaxKind.Parameter) {
|
||||
const parameter = <ParameterDeclaration>local.valueDeclaration;
|
||||
if (compilerOptions.noUnusedParameters &&
|
||||
!isParameterPropertyDeclaration(parameter) &&
|
||||
!parameterIsThisKeyword(parameter) &&
|
||||
!parameterNameStartsWithUnderscore(parameter)) {
|
||||
error(local.valueDeclaration.name, Diagnostics._0_is_declared_but_never_used, local.name);
|
||||
}
|
||||
}
|
||||
else if (compilerOptions.noUnusedLocals) {
|
||||
forEach(local.declarations, d => error(d.name || d, Diagnostics._0_is_declared_but_never_used, local.name));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -15148,13 +15135,11 @@ namespace ts {
|
|||
function checkUnusedModuleMembers(node: ModuleDeclaration | SourceFile): void {
|
||||
if (compilerOptions.noUnusedLocals && !isInAmbientContext(node)) {
|
||||
for (const key in node.locals) {
|
||||
if (hasProperty(node.locals, key)) {
|
||||
const local = node.locals[key];
|
||||
if (!local.isReferenced && !local.exportSymbol) {
|
||||
for (const declaration of local.declarations) {
|
||||
if (!isAmbientModule(declaration)) {
|
||||
error(declaration.name, Diagnostics._0_is_declared_but_never_used, local.name);
|
||||
}
|
||||
const local = node.locals[key];
|
||||
if (!local.isReferenced && !local.exportSymbol) {
|
||||
for (const declaration of local.declarations) {
|
||||
if (!isAmbientModule(declaration)) {
|
||||
error(declaration.name, Diagnostics._0_is_declared_but_never_used, local.name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -16163,7 +16148,7 @@ namespace ts {
|
|||
else {
|
||||
const identifierName = (<Identifier>catchClause.variableDeclaration.name).text;
|
||||
const locals = catchClause.block.locals;
|
||||
if (locals && hasProperty(locals, identifierName)) {
|
||||
if (locals) {
|
||||
const localSymbol = locals[identifierName];
|
||||
if (localSymbol && (localSymbol.flags & SymbolFlags.BlockScopedVariable) !== 0) {
|
||||
grammarErrorOnNode(localSymbol.valueDeclaration, Diagnostics.Cannot_redeclare_identifier_0_in_catch_clause, identifierName);
|
||||
|
@ -16584,18 +16569,18 @@ namespace ts {
|
|||
return true;
|
||||
}
|
||||
|
||||
const seen: Map<{ prop: Symbol; containingType: Type }> = {};
|
||||
const seen = createMap<{ prop: Symbol; containingType: Type }>();
|
||||
forEach(resolveDeclaredMembers(type).declaredProperties, p => { seen[p.name] = { prop: p, containingType: type }; });
|
||||
let ok = true;
|
||||
|
||||
for (const base of baseTypes) {
|
||||
const properties = getPropertiesOfObjectType(getTypeWithThisArgument(base, type.thisType));
|
||||
for (const prop of properties) {
|
||||
if (!hasProperty(seen, prop.name)) {
|
||||
const existing = seen[prop.name];
|
||||
if (!existing) {
|
||||
seen[prop.name] = { prop: prop, containingType: base };
|
||||
}
|
||||
else {
|
||||
const existing = seen[prop.name];
|
||||
const isInheritedProperty = existing.containingType !== type;
|
||||
if (isInheritedProperty && !isPropertyIdenticalTo(existing.prop, prop)) {
|
||||
ok = false;
|
||||
|
@ -17654,7 +17639,7 @@ namespace ts {
|
|||
}
|
||||
|
||||
function getSymbolsInScope(location: Node, meaning: SymbolFlags): Symbol[] {
|
||||
const symbols: SymbolTable = {};
|
||||
const symbols = createMap<Symbol>();
|
||||
let memberFlags: NodeFlags = 0;
|
||||
|
||||
if (isInsideWithStatementBody(location)) {
|
||||
|
@ -17732,7 +17717,7 @@ namespace ts {
|
|||
// We will copy all symbol regardless of its reserved name because
|
||||
// symbolsToArray will check whether the key is a reserved name and
|
||||
// it will not copy symbol with reserved name to the array
|
||||
if (!hasProperty(symbols, id)) {
|
||||
if (!symbols[id]) {
|
||||
symbols[id] = symbol;
|
||||
}
|
||||
}
|
||||
|
@ -18151,7 +18136,7 @@ namespace ts {
|
|||
const propsByName = createSymbolTable(getPropertiesOfType(type));
|
||||
if (getSignaturesOfType(type, SignatureKind.Call).length || getSignaturesOfType(type, SignatureKind.Construct).length) {
|
||||
forEach(getPropertiesOfType(globalFunctionType), p => {
|
||||
if (!hasProperty(propsByName, p.name)) {
|
||||
if (!propsByName[p.name]) {
|
||||
propsByName[p.name] = p;
|
||||
}
|
||||
});
|
||||
|
@ -18499,7 +18484,7 @@ namespace ts {
|
|||
}
|
||||
|
||||
function hasGlobalName(name: string): boolean {
|
||||
return hasProperty(globals, name);
|
||||
return !!globals[name];
|
||||
}
|
||||
|
||||
function getReferencedValueSymbol(reference: Identifier): Symbol {
|
||||
|
@ -18523,9 +18508,6 @@ namespace ts {
|
|||
// populate reverse mapping: file path -> type reference directive that was resolved to this file
|
||||
fileToDirective = createFileMap<string>();
|
||||
for (const key in resolvedTypeReferenceDirectives) {
|
||||
if (!hasProperty(resolvedTypeReferenceDirectives, key)) {
|
||||
continue;
|
||||
}
|
||||
const resolvedDirective = resolvedTypeReferenceDirectives[key];
|
||||
if (!resolvedDirective) {
|
||||
continue;
|
||||
|
@ -19314,7 +19296,7 @@ namespace ts {
|
|||
}
|
||||
|
||||
function checkGrammarObjectLiteralExpression(node: ObjectLiteralExpression, inDestructuring: boolean) {
|
||||
const seen: Map<SymbolFlags> = {};
|
||||
const seen = createMap<SymbolFlags>();
|
||||
const Property = 1;
|
||||
const GetAccessor = 2;
|
||||
const SetAccessor = 4;
|
||||
|
@ -19376,7 +19358,7 @@ namespace ts {
|
|||
continue;
|
||||
}
|
||||
|
||||
if (!hasProperty(seen, effectiveName)) {
|
||||
if (!seen[effectiveName]) {
|
||||
seen[effectiveName] = currentKind;
|
||||
}
|
||||
else {
|
||||
|
@ -19400,7 +19382,7 @@ namespace ts {
|
|||
}
|
||||
|
||||
function checkGrammarJsxElement(node: JsxOpeningLikeElement) {
|
||||
const seen: Map<boolean> = {};
|
||||
const seen = createMap<boolean>();
|
||||
for (const attr of node.attributes) {
|
||||
if (attr.kind === SyntaxKind.JsxSpreadAttribute) {
|
||||
continue;
|
||||
|
@ -19408,7 +19390,7 @@ namespace ts {
|
|||
|
||||
const jsxAttr = (<JsxAttribute>attr);
|
||||
const name = jsxAttr.name;
|
||||
if (!hasProperty(seen, name.text)) {
|
||||
if (!seen[name.text]) {
|
||||
seen[name.text] = true;
|
||||
}
|
||||
else {
|
||||
|
|
|
@ -470,8 +470,8 @@ namespace ts {
|
|||
return optionNameMapCache;
|
||||
}
|
||||
|
||||
const optionNameMap: Map<CommandLineOption> = {};
|
||||
const shortOptionNames: Map<string> = {};
|
||||
const optionNameMap = createMap<CommandLineOption>();
|
||||
const shortOptionNames = createMap<string>();
|
||||
forEach(optionDeclarations, option => {
|
||||
optionNameMap[option.name.toLowerCase()] = option;
|
||||
if (option.shortName) {
|
||||
|
@ -958,12 +958,12 @@ 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: Map<string> = {};
|
||||
const literalFileMap = createMap<string>();
|
||||
|
||||
// Wildcard paths (provided via the "includes" array in tsconfig.json) are stored in a
|
||||
// file map with a possibly case insensitive key. We use this map to store paths matched
|
||||
// via wildcard, and to handle extension priority.
|
||||
const wildcardFileMap: Map<string> = {};
|
||||
const wildcardFileMap = createMap<string>();
|
||||
|
||||
if (include) {
|
||||
include = validateSpecs(include, errors, /*allowTrailingRecursion*/ false);
|
||||
|
@ -1063,7 +1063,7 @@ namespace ts {
|
|||
// /a/b/a?z - Watch /a/b directly to catch any new file matching a?z
|
||||
const rawExcludeRegex = getRegularExpressionForWildcard(exclude, path, "exclude");
|
||||
const excludeRegex = rawExcludeRegex && new RegExp(rawExcludeRegex, useCaseSensitiveFileNames ? "" : "i");
|
||||
const wildcardDirectories: Map<WatchDirectoryFlags> = {};
|
||||
const wildcardDirectories = createMap<WatchDirectoryFlags>();
|
||||
if (include !== undefined) {
|
||||
const recursiveKeys: string[] = [];
|
||||
for (const file of include) {
|
||||
|
|
|
@ -19,8 +19,24 @@ namespace ts {
|
|||
True = -1
|
||||
}
|
||||
|
||||
const createObject = Object.create;
|
||||
|
||||
export function createMap<T>(): Map<T> {
|
||||
/* tslint:disable:no-null-keyword */
|
||||
const map: Map<T> = createObject(null);
|
||||
/* tslint:enable:no-null-keyword */
|
||||
|
||||
// Using 'delete' on an object causes V8 to put the object in dictionary mode.
|
||||
// This disables creation of hidden classes, which are expensive when an object is
|
||||
// constantly changing shape.
|
||||
map["__"] = undefined;
|
||||
delete map["__"];
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
export function createFileMap<T>(keyMapper?: (key: string) => string): FileMap<T> {
|
||||
let files: Map<T> = {};
|
||||
let files = createMap<T>();
|
||||
return {
|
||||
get,
|
||||
set,
|
||||
|
@ -55,7 +71,7 @@ namespace ts {
|
|||
}
|
||||
|
||||
function clear() {
|
||||
files = {};
|
||||
files = createMap<T>();
|
||||
}
|
||||
|
||||
function toKey(path: Path): string {
|
||||
|
@ -334,11 +350,11 @@ namespace ts {
|
|||
|
||||
const hasOwnProperty = Object.prototype.hasOwnProperty;
|
||||
|
||||
export function hasProperty<T>(map: Map<T>, key: string): boolean {
|
||||
export function hasProperty<T>(map: MapLike<T>, key: string): boolean {
|
||||
return hasOwnProperty.call(map, key);
|
||||
}
|
||||
|
||||
export function getKeys<T>(map: Map<T>): string[] {
|
||||
export function getKeys<T>(map: MapLike<T>): string[] {
|
||||
const keys: string[] = [];
|
||||
for (const key in map) {
|
||||
keys.push(key);
|
||||
|
@ -346,15 +362,15 @@ namespace ts {
|
|||
return keys;
|
||||
}
|
||||
|
||||
export function getProperty<T>(map: Map<T>, key: string): T | undefined {
|
||||
export function getProperty<T>(map: MapLike<T>, key: string): T | undefined {
|
||||
return hasProperty(map, key) ? map[key] : undefined;
|
||||
}
|
||||
|
||||
export function getOrUpdateProperty<T>(map: Map<T>, key: string, makeValue: () => T): T {
|
||||
export function getOrUpdateProperty<T>(map: MapLike<T>, key: string, makeValue: () => T): T {
|
||||
return hasProperty(map, key) ? map[key] : map[key] = makeValue();
|
||||
}
|
||||
|
||||
export function isEmpty<T>(map: Map<T>) {
|
||||
export function isEmpty<T>(map: MapLike<T>) {
|
||||
for (const id in map) {
|
||||
if (hasProperty(map, id)) {
|
||||
return false;
|
||||
|
@ -371,7 +387,7 @@ namespace ts {
|
|||
return <T>result;
|
||||
}
|
||||
|
||||
export function extend<T1 extends Map<{}>, T2 extends Map<{}>>(first: T1 , second: T2): T1 & T2 {
|
||||
export function extend<T1 extends MapLike<{}>, T2 extends MapLike<{}>>(first: T1 , second: T2): T1 & T2 {
|
||||
const result: T1 & T2 = <any>{};
|
||||
for (const id in first) {
|
||||
(result as any)[id] = first[id];
|
||||
|
@ -384,7 +400,7 @@ namespace ts {
|
|||
return result;
|
||||
}
|
||||
|
||||
export function forEachValue<T, U>(map: Map<T>, callback: (value: T) => U): U {
|
||||
export function forEachValue<T, U>(map: MapLike<T>, callback: (value: T) => U): U {
|
||||
let result: U;
|
||||
for (const id in map) {
|
||||
if (result = callback(map[id])) break;
|
||||
|
@ -392,7 +408,7 @@ namespace ts {
|
|||
return result;
|
||||
}
|
||||
|
||||
export function forEachKey<T, U>(map: Map<T>, callback: (key: string) => U): U {
|
||||
export function forEachKey<T, U>(map: MapLike<T>, callback: (key: string) => U): U {
|
||||
let result: U;
|
||||
for (const id in map) {
|
||||
if (result = callback(id)) break;
|
||||
|
@ -400,11 +416,11 @@ namespace ts {
|
|||
return result;
|
||||
}
|
||||
|
||||
export function lookUp<T>(map: Map<T>, key: string): T {
|
||||
export function lookUp<T>(map: MapLike<T>, key: string): T {
|
||||
return hasProperty(map, key) ? map[key] : undefined;
|
||||
}
|
||||
|
||||
export function copyMap<T>(source: Map<T>, target: Map<T>): void {
|
||||
export function copyMap<T>(source: MapLike<T>, target: MapLike<T>): void {
|
||||
for (const p in source) {
|
||||
target[p] = source[p];
|
||||
}
|
||||
|
@ -421,7 +437,7 @@ namespace ts {
|
|||
* index in the array will be the one associated with the produced key.
|
||||
*/
|
||||
export function arrayToMap<T>(array: T[], makeKey: (value: T) => string): Map<T> {
|
||||
const result: Map<T> = {};
|
||||
const result = createMap<T>();
|
||||
|
||||
forEach(array, value => {
|
||||
result[makeKey(value)] = value;
|
||||
|
@ -437,7 +453,7 @@ namespace ts {
|
|||
* @param callback An aggregation function that is called for each entry in the map
|
||||
* @param initial The initial value for the reduction.
|
||||
*/
|
||||
export function reduceProperties<T, U>(map: Map<T>, callback: (aggregate: U, value: T, key: string) => U, initial: U): U {
|
||||
export function reduceProperties<T, U>(map: MapLike<T>, callback: (aggregate: U, value: T, key: string) => U, initial: U): U {
|
||||
let result = initial;
|
||||
if (map) {
|
||||
for (const key in map) {
|
||||
|
@ -477,9 +493,7 @@ namespace ts {
|
|||
export let localizedDiagnosticMessages: Map<string> = undefined;
|
||||
|
||||
export function getLocaleSpecificMessage(message: DiagnosticMessage) {
|
||||
return localizedDiagnosticMessages && localizedDiagnosticMessages[message.key]
|
||||
? localizedDiagnosticMessages[message.key]
|
||||
: message.message;
|
||||
return localizedDiagnosticMessages && localizedDiagnosticMessages[message.key] || message.message;
|
||||
}
|
||||
|
||||
export function createFileDiagnostic(file: SourceFile, start: number, length: number, message: DiagnosticMessage, ...args: any[]): Diagnostic;
|
||||
|
|
|
@ -269,7 +269,7 @@ namespace ts {
|
|||
}
|
||||
|
||||
if (!usedTypeDirectiveReferences) {
|
||||
usedTypeDirectiveReferences = {};
|
||||
usedTypeDirectiveReferences = createMap<string>();
|
||||
}
|
||||
for (const directive of typeReferenceDirectives) {
|
||||
if (!hasProperty(usedTypeDirectiveReferences, directive)) {
|
||||
|
|
|
@ -24,7 +24,7 @@ namespace ts {
|
|||
Return = 1 << 3
|
||||
}
|
||||
|
||||
const entities: Map<number> = {
|
||||
const entities: MapLike<number> = {
|
||||
"quot": 0x0022,
|
||||
"amp": 0x0026,
|
||||
"apos": 0x0027,
|
||||
|
@ -489,13 +489,13 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|||
function setLabeledJump(state: ConvertedLoopState, isBreak: boolean, labelText: string, labelMarker: string): void {
|
||||
if (isBreak) {
|
||||
if (!state.labeledNonLocalBreaks) {
|
||||
state.labeledNonLocalBreaks = {};
|
||||
state.labeledNonLocalBreaks = createMap<string>();
|
||||
}
|
||||
state.labeledNonLocalBreaks[labelText] = labelMarker;
|
||||
}
|
||||
else {
|
||||
if (!state.labeledNonLocalContinues) {
|
||||
state.labeledNonLocalContinues = {};
|
||||
state.labeledNonLocalContinues = createMap<string>();
|
||||
}
|
||||
state.labeledNonLocalContinues[labelText] = labelMarker;
|
||||
}
|
||||
|
@ -531,7 +531,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|||
let currentText: string;
|
||||
let currentLineMap: number[];
|
||||
let currentFileIdentifiers: Map<string>;
|
||||
let renamedDependencies: Map<string>;
|
||||
let renamedDependencies: MapLike<string>;
|
||||
let isEs6Module: boolean;
|
||||
let isCurrentFileExternalModule: boolean;
|
||||
|
||||
|
@ -577,7 +577,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|||
|
||||
const setSourceMapWriterEmit = compilerOptions.sourceMap || compilerOptions.inlineSourceMap ? changeSourceMapEmit : function (writer: SourceMapWriter) { };
|
||||
|
||||
const moduleEmitDelegates: Map<(node: SourceFile, emitRelativePathAsModuleName?: boolean) => void> = {
|
||||
const moduleEmitDelegates: MapLike<(node: SourceFile, emitRelativePathAsModuleName?: boolean) => void> = {
|
||||
[ModuleKind.ES6]: emitES6Module,
|
||||
[ModuleKind.AMD]: emitAMDModule,
|
||||
[ModuleKind.System]: emitSystemModule,
|
||||
|
@ -585,7 +585,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|||
[ModuleKind.CommonJS]: emitCommonJSModule,
|
||||
};
|
||||
|
||||
const bundleEmitDelegates: Map<(node: SourceFile, emitRelativePathAsModuleName?: boolean) => void> = {
|
||||
const bundleEmitDelegates: MapLike<(node: SourceFile, emitRelativePathAsModuleName?: boolean) => void> = {
|
||||
[ModuleKind.ES6]() {},
|
||||
[ModuleKind.AMD]: emitAMDModule,
|
||||
[ModuleKind.System]: emitSystemModule,
|
||||
|
@ -597,7 +597,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|||
|
||||
function doEmit(jsFilePath: string, sourceMapFilePath: string, sourceFiles: SourceFile[], isBundledEmit: boolean) {
|
||||
sourceMap.initialize(jsFilePath, sourceMapFilePath, sourceFiles, isBundledEmit);
|
||||
generatedNameSet = {};
|
||||
generatedNameSet = createMap<string>();
|
||||
nodeToGeneratedName = [];
|
||||
decoratedClassAliases = [];
|
||||
isOwnFileEmit = !isBundledEmit;
|
||||
|
@ -3257,7 +3257,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|||
// Don't initialize seen unless we have at least one element.
|
||||
// Emit a comma to separate for all but the first element.
|
||||
if (!seen) {
|
||||
seen = {};
|
||||
seen = createMap<string>();
|
||||
}
|
||||
else {
|
||||
write(", ");
|
||||
|
@ -3856,7 +3856,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|||
|
||||
if (convertedLoopState) {
|
||||
if (!convertedLoopState.labels) {
|
||||
convertedLoopState.labels = {};
|
||||
convertedLoopState.labels = createMap<string>();
|
||||
}
|
||||
convertedLoopState.labels[node.label.text] = node.label.text;
|
||||
}
|
||||
|
@ -6803,7 +6803,7 @@ const _super = (function (geti, seti) {
|
|||
|
||||
function collectExternalModuleInfo(sourceFile: SourceFile) {
|
||||
externalImports = [];
|
||||
exportSpecifiers = {};
|
||||
exportSpecifiers = createMap<ExportSpecifier[]>();
|
||||
exportEquals = undefined;
|
||||
hasExportStarsToExportValues = false;
|
||||
for (const node of sourceFile.statements) {
|
||||
|
@ -7081,7 +7081,7 @@ const _super = (function (geti, seti) {
|
|||
if (hoistedVars) {
|
||||
writeLine();
|
||||
write("var ");
|
||||
const seen: Map<string> = {};
|
||||
const seen = createMap<string>();
|
||||
for (let i = 0; i < hoistedVars.length; i++) {
|
||||
const local = hoistedVars[i];
|
||||
const name = local.kind === SyntaxKind.Identifier
|
||||
|
@ -7447,7 +7447,7 @@ const _super = (function (geti, seti) {
|
|||
writeModuleName(node, emitRelativePathAsModuleName);
|
||||
write("[");
|
||||
|
||||
const groupIndices: Map<number> = {};
|
||||
const groupIndices = createMap<number>();
|
||||
const dependencyGroups: DependencyGroup[] = [];
|
||||
|
||||
for (let i = 0; i < externalImports.length; i++) {
|
||||
|
|
|
@ -595,7 +595,7 @@ namespace ts {
|
|||
|
||||
parseDiagnostics = [];
|
||||
parsingContext = 0;
|
||||
identifiers = {};
|
||||
identifiers = createMap<string>();
|
||||
identifierCount = 0;
|
||||
nodeCount = 0;
|
||||
|
||||
|
@ -1084,7 +1084,7 @@ namespace ts {
|
|||
|
||||
function internIdentifier(text: string): string {
|
||||
text = escapeIdentifier(text);
|
||||
return hasProperty(identifiers, text) ? identifiers[text] : (identifiers[text] = text);
|
||||
return identifiers[text] || (identifiers[text] = text);
|
||||
}
|
||||
|
||||
// An identifier that starts with two underscores has an extra underscore character prepended to it to avoid issues
|
||||
|
|
|
@ -10,8 +10,8 @@ namespace ts.performance {
|
|||
/** Performance measurements for the compiler. */
|
||||
declare const onProfilerEvent: { (markName: string): void; profiler: boolean; };
|
||||
let profilerEvent: (markName: string) => void;
|
||||
let counters: Map<number>;
|
||||
let measures: Map<number>;
|
||||
let counters: MapLike<number>;
|
||||
let measures: MapLike<number>;
|
||||
|
||||
/**
|
||||
* Emit a performance event if ts-profiler is connected. This is primarily used
|
||||
|
|
|
@ -843,7 +843,7 @@ namespace ts {
|
|||
}
|
||||
|
||||
export function createCompilerHost(options: CompilerOptions, setParentNodes?: boolean): CompilerHost {
|
||||
const existingDirectories: Map<boolean> = {};
|
||||
const existingDirectories = createMap<boolean>();
|
||||
|
||||
function getCanonicalFileName(fileName: string): string {
|
||||
// if underlying system can distinguish between two files whose names differs only in cases then file name already in canonical form.
|
||||
|
@ -896,7 +896,7 @@ namespace ts {
|
|||
|
||||
function writeFileIfUpdated(fileName: string, data: string, writeByteOrderMark: boolean): void {
|
||||
if (!outputFingerprints) {
|
||||
outputFingerprints = {};
|
||||
outputFingerprints = createMap<OutputFingerprint>();
|
||||
}
|
||||
|
||||
const hash = sys.createHash(data);
|
||||
|
@ -1037,7 +1037,7 @@ namespace ts {
|
|||
return [];
|
||||
}
|
||||
const resolutions: T[] = [];
|
||||
const cache: Map<T> = {};
|
||||
const cache = createMap<T>();
|
||||
for (const name of names) {
|
||||
let result: T;
|
||||
if (hasProperty(cache, name)) {
|
||||
|
@ -1098,7 +1098,7 @@ namespace ts {
|
|||
let noDiagnosticsTypeChecker: TypeChecker;
|
||||
let classifiableNames: Map<string>;
|
||||
|
||||
let resolvedTypeReferenceDirectives: Map<ResolvedTypeReferenceDirective> = {};
|
||||
let resolvedTypeReferenceDirectives = createMap<ResolvedTypeReferenceDirective>();
|
||||
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.
|
||||
|
@ -1113,10 +1113,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: Map<boolean> = {};
|
||||
const modulesWithElidedImports = createMap<boolean>();
|
||||
|
||||
// Track source files that are source files found by searching under node_modules, as these shouldn't be compiled.
|
||||
const sourceFilesFoundSearchingNodeModules: Map<boolean> = {};
|
||||
const sourceFilesFoundSearchingNodeModules = createMap<boolean>();
|
||||
|
||||
const start = performance.mark();
|
||||
|
||||
|
@ -1244,7 +1244,7 @@ namespace ts {
|
|||
if (!classifiableNames) {
|
||||
// Initialize a checker so that all our files are bound.
|
||||
getTypeChecker();
|
||||
classifiableNames = {};
|
||||
classifiableNames = createMap<string>();
|
||||
|
||||
for (const sourceFile of files) {
|
||||
copyMap(sourceFile.classifiableNames, classifiableNames);
|
||||
|
@ -2085,7 +2085,7 @@ namespace ts {
|
|||
function processImportedModules(file: SourceFile, basePath: string) {
|
||||
collectExternalModuleReferences(file);
|
||||
if (file.imports.length || file.moduleAugmentations.length) {
|
||||
file.resolvedModules = {};
|
||||
file.resolvedModules = createMap<ResolvedModule>();
|
||||
const moduleNames = map(concatenate(file.imports, file.moduleAugmentations), getTextOfLiteral);
|
||||
const resolutions = resolveModuleNamesWorker(moduleNames, getNormalizedAbsolutePath(file.fileName, currentDirectory));
|
||||
for (let i = 0; i < moduleNames.length; i++) {
|
||||
|
|
|
@ -55,7 +55,7 @@ namespace ts {
|
|||
tryScan<T>(callback: () => T): T;
|
||||
}
|
||||
|
||||
const textToToken: Map<SyntaxKind> = {
|
||||
const textToToken: MapLike<SyntaxKind> = {
|
||||
"abstract": SyntaxKind.AbstractKeyword,
|
||||
"any": SyntaxKind.AnyKeyword,
|
||||
"as": SyntaxKind.AsKeyword,
|
||||
|
@ -271,7 +271,7 @@ namespace ts {
|
|||
lookupInUnicodeMap(code, unicodeES3IdentifierPart);
|
||||
}
|
||||
|
||||
function makeReverseMap(source: Map<number>): string[] {
|
||||
function makeReverseMap(source: MapLike<number>): string[] {
|
||||
const result: string[] = [];
|
||||
for (const name in source) {
|
||||
if (source.hasOwnProperty(name)) {
|
||||
|
|
|
@ -233,15 +233,15 @@ namespace ts {
|
|||
const useNonPollingWatchers = process.env["TSC_NONPOLLING_WATCHER"];
|
||||
|
||||
function createWatchedFileSet() {
|
||||
const dirWatchers: Map<DirectoryWatcher> = {};
|
||||
const dirWatchers = createMap<DirectoryWatcher>();
|
||||
// One file can have multiple watchers
|
||||
const fileWatcherCallbacks: Map<FileWatcherCallback[]> = {};
|
||||
const fileWatcherCallbacks = createMap<FileWatcherCallback[]>();
|
||||
return { addFile, removeFile };
|
||||
|
||||
function reduceDirWatcherRefCountForFile(fileName: string) {
|
||||
const dirName = getDirectoryPath(fileName);
|
||||
if (hasProperty(dirWatchers, dirName)) {
|
||||
const watcher = dirWatchers[dirName];
|
||||
const watcher = dirWatchers[dirName];
|
||||
if (watcher) {
|
||||
watcher.referenceCount -= 1;
|
||||
if (watcher.referenceCount <= 0) {
|
||||
watcher.close();
|
||||
|
@ -251,13 +251,12 @@ namespace ts {
|
|||
}
|
||||
|
||||
function addDirWatcher(dirPath: string): void {
|
||||
if (hasProperty(dirWatchers, dirPath)) {
|
||||
const watcher = dirWatchers[dirPath];
|
||||
let watcher = dirWatchers[dirPath];
|
||||
if (watcher) {
|
||||
watcher.referenceCount += 1;
|
||||
return;
|
||||
}
|
||||
|
||||
const watcher: DirectoryWatcher = _fs.watch(
|
||||
watcher = _fs.watch(
|
||||
dirPath,
|
||||
{ persistent: true },
|
||||
(eventName: string, relativeFileName: string) => fileEventHandler(eventName, relativeFileName, dirPath)
|
||||
|
@ -268,12 +267,7 @@ namespace ts {
|
|||
}
|
||||
|
||||
function addFileWatcherCallback(filePath: string, callback: FileWatcherCallback): void {
|
||||
if (hasProperty(fileWatcherCallbacks, filePath)) {
|
||||
fileWatcherCallbacks[filePath].push(callback);
|
||||
}
|
||||
else {
|
||||
fileWatcherCallbacks[filePath] = [callback];
|
||||
}
|
||||
(fileWatcherCallbacks[filePath] || (fileWatcherCallbacks[filePath] = [])).push(callback);
|
||||
}
|
||||
|
||||
function addFile(fileName: string, callback: FileWatcherCallback): WatchedFile {
|
||||
|
@ -289,8 +283,9 @@ namespace ts {
|
|||
}
|
||||
|
||||
function removeFileWatcherCallback(filePath: string, callback: FileWatcherCallback) {
|
||||
if (hasProperty(fileWatcherCallbacks, filePath)) {
|
||||
const newCallbacks = copyListRemovingItem(callback, fileWatcherCallbacks[filePath]);
|
||||
const callbacks = fileWatcherCallbacks[filePath];
|
||||
if (callbacks) {
|
||||
const newCallbacks = copyListRemovingItem(callback, callbacks);
|
||||
if (newCallbacks.length === 0) {
|
||||
delete fileWatcherCallbacks[filePath];
|
||||
}
|
||||
|
@ -306,7 +301,7 @@ namespace ts {
|
|||
? undefined
|
||||
: ts.getNormalizedAbsolutePath(relativeFileName, baseDirPath);
|
||||
// Some applications save a working file via rename operations
|
||||
if ((eventName === "change" || eventName === "rename") && hasProperty(fileWatcherCallbacks, fileName)) {
|
||||
if ((eventName === "change" || eventName === "rename") && fileWatcherCallbacks[fileName]) {
|
||||
for (const fileCallback of fileWatcherCallbacks[fileName]) {
|
||||
fileCallback(fileName);
|
||||
}
|
||||
|
|
|
@ -122,7 +122,7 @@ namespace ts {
|
|||
const gutterSeparator = " ";
|
||||
const resetEscapeSequence = "\u001b[0m";
|
||||
const ellipsis = "...";
|
||||
const categoryFormatMap: Map<string> = {
|
||||
const categoryFormatMap: MapLike<string> = {
|
||||
[DiagnosticCategory.Warning]: yellowForegroundEscapeSequence,
|
||||
[DiagnosticCategory.Error]: redForegroundEscapeSequence,
|
||||
[DiagnosticCategory.Message]: blueForegroundEscapeSequence,
|
||||
|
@ -432,7 +432,7 @@ namespace ts {
|
|||
}
|
||||
|
||||
// reset the cache of existing files
|
||||
cachedExistingFiles = {};
|
||||
cachedExistingFiles = createMap<boolean>();
|
||||
|
||||
const compileResult = compile(rootFileNames, compilerOptions, compilerHost);
|
||||
|
||||
|
@ -676,7 +676,7 @@ namespace ts {
|
|||
const usageColumn: string[] = []; // Things like "-d, --declaration" go in here.
|
||||
const descriptionColumn: string[] = [];
|
||||
|
||||
const optionsDescriptionMap: Map<string[]> = {}; // Map between option.description and list of option.type if it is a kind
|
||||
const optionsDescriptionMap = createMap<string[]>(); // Map between option.description and list of option.type if it is a kind
|
||||
|
||||
for (let i = 0; i < optsList.length; i++) {
|
||||
const option = optsList[i];
|
||||
|
@ -786,7 +786,7 @@ namespace ts {
|
|||
return;
|
||||
|
||||
function serializeCompilerOptions(options: CompilerOptions): Map<string | number | boolean> {
|
||||
const result: Map<string | number | boolean> = {};
|
||||
const result = createMap<string | number | boolean>();
|
||||
const optionsNameMap = getOptionNameMap().optionNameMap;
|
||||
|
||||
for (const name in options) {
|
||||
|
|
|
@ -1,9 +1,13 @@
|
|||
|
||||
namespace ts {
|
||||
export interface Map<T> {
|
||||
|
||||
export interface MapLike<T> {
|
||||
[index: string]: T;
|
||||
}
|
||||
|
||||
export interface Map<T> extends MapLike<T> {
|
||||
__mapBrand: any;
|
||||
}
|
||||
|
||||
// branded string type used to store absolute, normalized and canonicalized paths
|
||||
// arbitrary file name can be converted to Path via toPath function
|
||||
export type Path = string & { __pathBrand: any };
|
||||
|
@ -1646,7 +1650,7 @@ namespace ts {
|
|||
|
||||
// this map is used by transpiler to supply alternative names for dependencies (i.e. in case of bundling)
|
||||
/* @internal */
|
||||
renamedDependencies?: Map<string>;
|
||||
renamedDependencies?: MapLike<string>;
|
||||
|
||||
/**
|
||||
* lib.d.ts should have a reference comment like
|
||||
|
@ -2178,9 +2182,7 @@ namespace ts {
|
|||
/* @internal */
|
||||
export interface TransientSymbol extends Symbol, SymbolLinks { }
|
||||
|
||||
export interface SymbolTable {
|
||||
[index: string]: Symbol;
|
||||
}
|
||||
export type SymbolTable = Map<Symbol>;
|
||||
|
||||
/** Represents a "prefix*suffix" pattern. */
|
||||
/* @internal */
|
||||
|
@ -2564,7 +2566,7 @@ namespace ts {
|
|||
}
|
||||
|
||||
export type RootPaths = string[];
|
||||
export type PathSubstitutions = Map<string[]>;
|
||||
export type PathSubstitutions = MapLike<string[]>;
|
||||
export type TsConfigOnlyOptions = RootPaths | PathSubstitutions;
|
||||
|
||||
export type CompilerOptionsValue = string | number | boolean | (string | number)[] | TsConfigOnlyOptions;
|
||||
|
@ -2724,7 +2726,7 @@ namespace ts {
|
|||
fileNames: string[];
|
||||
raw?: any;
|
||||
errors: Diagnostic[];
|
||||
wildcardDirectories?: Map<WatchDirectoryFlags>;
|
||||
wildcardDirectories?: MapLike<WatchDirectoryFlags>;
|
||||
}
|
||||
|
||||
export const enum WatchDirectoryFlags {
|
||||
|
@ -2734,13 +2736,13 @@ namespace ts {
|
|||
|
||||
export interface ExpandResult {
|
||||
fileNames: string[];
|
||||
wildcardDirectories: Map<WatchDirectoryFlags>;
|
||||
wildcardDirectories: MapLike<WatchDirectoryFlags>;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export interface CommandLineOptionBase {
|
||||
name: string;
|
||||
type: "string" | "number" | "boolean" | "object" | "list" | Map<number | string>; // a value of a primitive type, or an object literal mapping named values to actual values
|
||||
type: "string" | "number" | "boolean" | "object" | "list" | MapLike<number | string>; // a value of a primitive type, or an object literal mapping named values to actual values
|
||||
isFilePath?: boolean; // True if option value is a path or fileName
|
||||
shortName?: string; // A short mnemonic for convenience - for instance, 'h' can be used in place of 'help'
|
||||
description?: DiagnosticMessage; // The message describing what the command line switch does
|
||||
|
@ -2756,7 +2758,7 @@ namespace ts {
|
|||
|
||||
/* @internal */
|
||||
export interface CommandLineOptionOfCustomType extends CommandLineOptionBase {
|
||||
type: Map<number | string>; // an object literal mapping named values to actual values
|
||||
type: MapLike<number | string>; // an object literal mapping named values to actual values
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
|
|
|
@ -87,14 +87,14 @@ namespace ts {
|
|||
return node.end - node.pos;
|
||||
}
|
||||
|
||||
export function mapIsEqualTo<T>(map1: Map<T>, map2: Map<T>): boolean {
|
||||
export function mapIsEqualTo<T>(map1: MapLike<T>, map2: MapLike<T>): boolean {
|
||||
if (!map1 || !map2) {
|
||||
return map1 === map2;
|
||||
}
|
||||
return containsAll(map1, map2) && containsAll(map2, map1);
|
||||
}
|
||||
|
||||
function containsAll<T>(map: Map<T>, other: Map<T>): boolean {
|
||||
function containsAll<T>(map: MapLike<T>, other: MapLike<T>): boolean {
|
||||
for (const key in map) {
|
||||
if (!hasProperty(map, key)) {
|
||||
continue;
|
||||
|
@ -126,7 +126,7 @@ namespace ts {
|
|||
}
|
||||
|
||||
export function hasResolvedModule(sourceFile: SourceFile, moduleNameText: string): boolean {
|
||||
return sourceFile.resolvedModules && hasProperty(sourceFile.resolvedModules, moduleNameText);
|
||||
return !!(sourceFile.resolvedModules && sourceFile.resolvedModules[moduleNameText]);
|
||||
}
|
||||
|
||||
export function getResolvedModule(sourceFile: SourceFile, moduleNameText: string): ResolvedModule {
|
||||
|
@ -135,7 +135,7 @@ namespace ts {
|
|||
|
||||
export function setResolvedModule(sourceFile: SourceFile, moduleNameText: string, resolvedModule: ResolvedModule): void {
|
||||
if (!sourceFile.resolvedModules) {
|
||||
sourceFile.resolvedModules = {};
|
||||
sourceFile.resolvedModules = createMap<ResolvedModule>();
|
||||
}
|
||||
|
||||
sourceFile.resolvedModules[moduleNameText] = resolvedModule;
|
||||
|
@ -143,7 +143,7 @@ namespace ts {
|
|||
|
||||
export function setResolvedTypeReferenceDirective(sourceFile: SourceFile, typeReferenceDirectiveName: string, resolvedTypeReferenceDirective: ResolvedTypeReferenceDirective): void {
|
||||
if (!sourceFile.resolvedTypeReferenceDirectiveNames) {
|
||||
sourceFile.resolvedTypeReferenceDirectiveNames = {};
|
||||
sourceFile.resolvedTypeReferenceDirectiveNames = createMap<ResolvedTypeReferenceDirective>();
|
||||
}
|
||||
|
||||
sourceFile.resolvedTypeReferenceDirectiveNames[typeReferenceDirectiveName] = resolvedTypeReferenceDirective;
|
||||
|
@ -166,7 +166,7 @@ namespace ts {
|
|||
}
|
||||
for (let i = 0; i < names.length; i++) {
|
||||
const newResolution = newResolutions[i];
|
||||
const oldResolution = oldResolutions && hasProperty(oldResolutions, names[i]) ? oldResolutions[names[i]] : undefined;
|
||||
const oldResolution = oldResolutions && oldResolutions[names[i]];
|
||||
const changed =
|
||||
oldResolution
|
||||
? !newResolution || !comparer(oldResolution, newResolution)
|
||||
|
@ -1970,7 +1970,7 @@ namespace ts {
|
|||
|
||||
export function createDiagnosticCollection(): DiagnosticCollection {
|
||||
let nonFileDiagnostics: Diagnostic[] = [];
|
||||
const fileDiagnostics: Map<Diagnostic[]> = {};
|
||||
const fileDiagnostics = createMap<Diagnostic[]>();
|
||||
|
||||
let diagnosticsModified = false;
|
||||
let modificationCount = 0;
|
||||
|
@ -1988,12 +1988,11 @@ namespace ts {
|
|||
}
|
||||
|
||||
function reattachFileDiagnostics(newFile: SourceFile): void {
|
||||
if (!hasProperty(fileDiagnostics, newFile.fileName)) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (const diagnostic of fileDiagnostics[newFile.fileName]) {
|
||||
diagnostic.file = newFile;
|
||||
const diagnostics = fileDiagnostics[newFile.fileName];
|
||||
if (diagnostics) {
|
||||
for (const diagnostic of diagnostics) {
|
||||
diagnostic.file = newFile;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2034,9 +2033,7 @@ namespace ts {
|
|||
forEach(nonFileDiagnostics, pushDiagnostic);
|
||||
|
||||
for (const key in fileDiagnostics) {
|
||||
if (hasProperty(fileDiagnostics, key)) {
|
||||
forEach(fileDiagnostics[key], pushDiagnostic);
|
||||
}
|
||||
forEach(fileDiagnostics[key], pushDiagnostic);
|
||||
}
|
||||
|
||||
return sortAndDeduplicateDiagnostics(allDiagnostics);
|
||||
|
@ -2051,9 +2048,7 @@ namespace ts {
|
|||
nonFileDiagnostics = sortAndDeduplicateDiagnostics(nonFileDiagnostics);
|
||||
|
||||
for (const key in fileDiagnostics) {
|
||||
if (hasProperty(fileDiagnostics, key)) {
|
||||
fileDiagnostics[key] = sortAndDeduplicateDiagnostics(fileDiagnostics[key]);
|
||||
}
|
||||
fileDiagnostics[key] = sortAndDeduplicateDiagnostics(fileDiagnostics[key]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2064,7 +2059,7 @@ namespace ts {
|
|||
// the map below must be updated. Note that this regexp *does not* include the 'delete' character.
|
||||
// There is no reason for this other than that JSON.stringify does not handle it either.
|
||||
const escapedCharsRegExp = /[\\\"\u0000-\u001f\t\v\f\b\r\n\u2028\u2029\u0085]/g;
|
||||
const escapedCharsMap: Map<string> = {
|
||||
const escapedCharsMap: MapLike<string> = {
|
||||
"\0": "\\0",
|
||||
"\t": "\\t",
|
||||
"\v": "\\v",
|
||||
|
|
|
@ -291,8 +291,8 @@ class CompilerBaselineRunner extends RunnerBase {
|
|||
|
||||
const fullWalker = new TypeWriterWalker(program, /*fullTypeCheck*/ true);
|
||||
|
||||
const fullResults: ts.Map<TypeWriterResult[]> = {};
|
||||
const pullResults: ts.Map<TypeWriterResult[]> = {};
|
||||
const fullResults: ts.MapLike<TypeWriterResult[]> = {};
|
||||
const pullResults: ts.MapLike<TypeWriterResult[]> = {};
|
||||
|
||||
for (const sourceFile of allFiles) {
|
||||
fullResults[sourceFile.unitName] = fullWalker.getTypeAndSymbols(sourceFile.unitName);
|
||||
|
@ -338,7 +338,7 @@ class CompilerBaselineRunner extends RunnerBase {
|
|||
}
|
||||
}
|
||||
|
||||
function generateBaseLine(typeWriterResults: ts.Map<TypeWriterResult[]>, isSymbolBaseline: boolean): string {
|
||||
function generateBaseLine(typeWriterResults: ts.MapLike<TypeWriterResult[]>, isSymbolBaseline: boolean): string {
|
||||
const typeLines: string[] = [];
|
||||
const typeMap: { [fileName: string]: { [lineNum: number]: string[]; } } = {};
|
||||
|
||||
|
|
|
@ -95,7 +95,7 @@ namespace FourSlash {
|
|||
|
||||
export import IndentStyle = ts.IndentStyle;
|
||||
|
||||
const entityMap: ts.Map<string> = {
|
||||
const entityMap: ts.MapLike<string> = {
|
||||
"&": "&",
|
||||
"\"": """,
|
||||
"'": "'",
|
||||
|
@ -204,7 +204,7 @@ namespace FourSlash {
|
|||
|
||||
public formatCodeOptions: ts.FormatCodeOptions;
|
||||
|
||||
private inputFiles: ts.Map<string> = {}; // Map between inputFile's fileName and its content for easily looking up when resolving references
|
||||
private inputFiles: ts.MapLike<string> = {}; // Map between inputFile's fileName and its content for easily looking up when resolving references
|
||||
|
||||
// Add input file which has matched file name with the given reference-file path.
|
||||
// This is necessary when resolveReference flag is specified
|
||||
|
@ -594,7 +594,7 @@ namespace FourSlash {
|
|||
|
||||
public noItemsWithSameNameButDifferentKind(): void {
|
||||
const completions = this.getCompletionListAtCaret();
|
||||
const uniqueItems: ts.Map<string> = {};
|
||||
const uniqueItems: ts.MapLike<string> = {};
|
||||
for (const item of completions.entries) {
|
||||
if (!ts.hasProperty(uniqueItems, item.name)) {
|
||||
uniqueItems[item.name] = item.kind;
|
||||
|
@ -1631,8 +1631,8 @@ namespace FourSlash {
|
|||
return this.testData.ranges;
|
||||
}
|
||||
|
||||
public rangesByText(): ts.Map<Range[]> {
|
||||
const result: ts.Map<Range[]> = {};
|
||||
public rangesByText(): ts.MapLike<Range[]> {
|
||||
const result: ts.MapLike<Range[]> = {};
|
||||
for (const range of this.getRanges()) {
|
||||
const text = this.rangeText(range);
|
||||
(ts.getProperty(result, text) || (result[text] = [])).push(range);
|
||||
|
@ -1890,7 +1890,7 @@ namespace FourSlash {
|
|||
|
||||
public verifyBraceCompletionAtPosition(negative: boolean, openingBrace: string) {
|
||||
|
||||
const openBraceMap: ts.Map<ts.CharacterCodes> = {
|
||||
const openBraceMap: ts.MapLike<ts.CharacterCodes> = {
|
||||
"(": ts.CharacterCodes.openParen,
|
||||
"{": ts.CharacterCodes.openBrace,
|
||||
"[": ts.CharacterCodes.openBracket,
|
||||
|
@ -2738,7 +2738,7 @@ namespace FourSlashInterface {
|
|||
return this.state.getRanges();
|
||||
}
|
||||
|
||||
public rangesByText(): ts.Map<FourSlash.Range[]> {
|
||||
public rangesByText(): ts.MapLike<FourSlash.Range[]> {
|
||||
return this.state.rangesByText();
|
||||
}
|
||||
|
||||
|
|
|
@ -848,7 +848,7 @@ namespace Harness {
|
|||
export const defaultLibFileName = "lib.d.ts";
|
||||
export const es2015DefaultLibFileName = "lib.es2015.d.ts";
|
||||
|
||||
const libFileNameSourceFileMap: ts.Map<ts.SourceFile> = {
|
||||
const libFileNameSourceFileMap: ts.MapLike<ts.SourceFile> = {
|
||||
[defaultLibFileName]: createSourceFileAndAssertInvariants(defaultLibFileName, IO.readFile(libFolder + "lib.es5.d.ts"), /*languageVersion*/ ts.ScriptTarget.Latest)
|
||||
};
|
||||
|
||||
|
@ -1002,7 +1002,7 @@ namespace Harness {
|
|||
{ name: "symlink", type: "string" }
|
||||
];
|
||||
|
||||
let optionsIndex: ts.Map<ts.CommandLineOption>;
|
||||
let optionsIndex: ts.MapLike<ts.CommandLineOption>;
|
||||
function getCommandLineOption(name: string): ts.CommandLineOption {
|
||||
if (!optionsIndex) {
|
||||
optionsIndex = {};
|
||||
|
|
|
@ -123,7 +123,7 @@ namespace Harness.LanguageService {
|
|||
}
|
||||
|
||||
export class LanguageServiceAdapterHost {
|
||||
protected fileNameToScript: ts.Map<ScriptInfo> = {};
|
||||
protected fileNameToScript: ts.MapLike<ScriptInfo> = {};
|
||||
|
||||
constructor(protected cancellationToken = DefaultHostCancellationToken.Instance,
|
||||
protected settings = ts.getDefaultCompilerOptions()) {
|
||||
|
@ -235,7 +235,7 @@ namespace Harness.LanguageService {
|
|||
this.getModuleResolutionsForFile = (fileName) => {
|
||||
const scriptInfo = this.getScriptInfo(fileName);
|
||||
const preprocessInfo = ts.preProcessFile(scriptInfo.content, /*readImportFiles*/ true);
|
||||
const imports: ts.Map<string> = {};
|
||||
const imports: ts.MapLike<string> = {};
|
||||
for (const module of preprocessInfo.importedFiles) {
|
||||
const resolutionInfo = ts.resolveModuleName(module.fileName, fileName, compilerOptions, moduleResolutionHost);
|
||||
if (resolutionInfo.resolvedModule) {
|
||||
|
@ -248,7 +248,7 @@ namespace Harness.LanguageService {
|
|||
const scriptInfo = this.getScriptInfo(fileName);
|
||||
if (scriptInfo) {
|
||||
const preprocessInfo = ts.preProcessFile(scriptInfo.content, /*readImportFiles*/ false);
|
||||
const resolutions: ts.Map<ts.ResolvedTypeReferenceDirective> = {};
|
||||
const resolutions: ts.MapLike<ts.ResolvedTypeReferenceDirective> = {};
|
||||
const settings = this.nativeHost.getCompilationSettings();
|
||||
for (const typeReferenceDirective of preprocessInfo.typeReferenceDirectives) {
|
||||
const resolutionInfo = ts.resolveTypeReferenceDirective(typeReferenceDirective.fileName, fileName, settings, moduleResolutionHost);
|
||||
|
|
|
@ -253,7 +253,7 @@ class ProjectRunner extends RunnerBase {
|
|||
moduleResolution: ts.ModuleResolutionKind.Classic, // currently all tests use classic module resolution kind, this will change in the future
|
||||
};
|
||||
// Set the values specified using json
|
||||
const optionNameMap: ts.Map<ts.CommandLineOption> = {};
|
||||
const optionNameMap: ts.MapLike<ts.CommandLineOption> = {};
|
||||
ts.forEach(ts.optionDeclarations, option => {
|
||||
optionNameMap[option.name] = option;
|
||||
});
|
||||
|
|
|
@ -6,8 +6,8 @@ namespace ts {
|
|||
content: string;
|
||||
}
|
||||
|
||||
function createDefaultServerHost(fileMap: Map<File>): server.ServerHost {
|
||||
const existingDirectories: Map<boolean> = {};
|
||||
function createDefaultServerHost(fileMap: MapLike<File>): server.ServerHost {
|
||||
const existingDirectories: MapLike<boolean> = {};
|
||||
forEachValue(fileMap, v => {
|
||||
let dir = getDirectoryPath(v.name);
|
||||
let previous: string;
|
||||
|
@ -193,7 +193,7 @@ namespace ts {
|
|||
content: `export var y = 1`
|
||||
};
|
||||
|
||||
const fileMap: Map<File> = { [root.name]: root };
|
||||
const fileMap: MapLike<File> = { [root.name]: root };
|
||||
const serverHost = createDefaultServerHost(fileMap);
|
||||
const originalFileExists = serverHost.fileExists;
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ namespace ts {
|
|||
const map = arrayToMap(files, f => f.name);
|
||||
|
||||
if (hasDirectoryExists) {
|
||||
const directories: Map<string> = {};
|
||||
const directories: MapLike<string> = {};
|
||||
for (const f of files) {
|
||||
let name = getDirectoryPath(f.name);
|
||||
while (true) {
|
||||
|
@ -282,7 +282,7 @@ namespace ts {
|
|||
});
|
||||
|
||||
describe("Module resolution - relative imports", () => {
|
||||
function test(files: Map<string>, currentDirectory: string, rootFiles: string[], expectedFilesCount: number, relativeNamesToCheck: string[]) {
|
||||
function test(files: MapLike<string>, currentDirectory: string, rootFiles: string[], expectedFilesCount: number, relativeNamesToCheck: string[]) {
|
||||
const options: CompilerOptions = { module: ModuleKind.CommonJS };
|
||||
const host: CompilerHost = {
|
||||
getSourceFile: (fileName: string, languageVersion: ScriptTarget) => {
|
||||
|
@ -318,7 +318,7 @@ namespace ts {
|
|||
}
|
||||
|
||||
it("should find all modules", () => {
|
||||
const files: Map<string> = {
|
||||
const files: MapLike<string> = {
|
||||
"/a/b/c/first/shared.ts": `
|
||||
class A {}
|
||||
export = A`,
|
||||
|
@ -337,7 +337,7 @@ export = C;
|
|||
});
|
||||
|
||||
it("should find modules in node_modules", () => {
|
||||
const files: Map<string> = {
|
||||
const files: MapLike<string> = {
|
||||
"/parent/node_modules/mod/index.d.ts": "export var x",
|
||||
"/parent/app/myapp.ts": `import {x} from "mod"`
|
||||
};
|
||||
|
@ -345,7 +345,7 @@ export = C;
|
|||
});
|
||||
|
||||
it("should find file referenced via absolute and relative names", () => {
|
||||
const files: Map<string> = {
|
||||
const files: MapLike<string> = {
|
||||
"/a/b/c.ts": `/// <reference path="b.ts"/>`,
|
||||
"/a/b/b.ts": "var x"
|
||||
};
|
||||
|
@ -355,10 +355,10 @@ export = C;
|
|||
|
||||
describe("Files with different casing", () => {
|
||||
const library = createSourceFile("lib.d.ts", "", ScriptTarget.ES5);
|
||||
function test(files: Map<string>, options: CompilerOptions, currentDirectory: string, useCaseSensitiveFileNames: boolean, rootFiles: string[], diagnosticCodes: number[]): void {
|
||||
function test(files: MapLike<string>, options: CompilerOptions, currentDirectory: string, useCaseSensitiveFileNames: boolean, rootFiles: string[], diagnosticCodes: number[]): void {
|
||||
const getCanonicalFileName = createGetCanonicalFileName(useCaseSensitiveFileNames);
|
||||
if (!useCaseSensitiveFileNames) {
|
||||
const f: Map<string> = {};
|
||||
const f: MapLike<string> = {};
|
||||
for (const fileName in files) {
|
||||
f[getCanonicalFileName(fileName)] = files[fileName];
|
||||
}
|
||||
|
@ -395,7 +395,7 @@ export = C;
|
|||
}
|
||||
|
||||
it("should succeed when the same file is referenced using absolute and relative names", () => {
|
||||
const files: Map<string> = {
|
||||
const files: MapLike<string> = {
|
||||
"/a/b/c.ts": `/// <reference path="d.ts"/>`,
|
||||
"/a/b/d.ts": "var x"
|
||||
};
|
||||
|
@ -403,7 +403,7 @@ export = C;
|
|||
});
|
||||
|
||||
it("should fail when two files used in program differ only in casing (tripleslash references)", () => {
|
||||
const files: Map<string> = {
|
||||
const files: MapLike<string> = {
|
||||
"/a/b/c.ts": `/// <reference path="D.ts"/>`,
|
||||
"/a/b/d.ts": "var x"
|
||||
};
|
||||
|
@ -411,7 +411,7 @@ export = C;
|
|||
});
|
||||
|
||||
it("should fail when two files used in program differ only in casing (imports)", () => {
|
||||
const files: Map<string> = {
|
||||
const files: MapLike<string> = {
|
||||
"/a/b/c.ts": `import {x} from "D"`,
|
||||
"/a/b/d.ts": "export var x"
|
||||
};
|
||||
|
@ -419,7 +419,7 @@ export = C;
|
|||
});
|
||||
|
||||
it("should fail when two files used in program differ only in casing (imports, relative module names)", () => {
|
||||
const files: Map<string> = {
|
||||
const files: MapLike<string> = {
|
||||
"moduleA.ts": `import {x} from "./ModuleB"`,
|
||||
"moduleB.ts": "export var x"
|
||||
};
|
||||
|
@ -427,7 +427,7 @@ export = C;
|
|||
});
|
||||
|
||||
it("should fail when two files exist on disk that differs only in casing", () => {
|
||||
const files: Map<string> = {
|
||||
const files: MapLike<string> = {
|
||||
"/a/b/c.ts": `import {x} from "D"`,
|
||||
"/a/b/D.ts": "export var x",
|
||||
"/a/b/d.ts": "export var y"
|
||||
|
@ -436,7 +436,7 @@ export = C;
|
|||
});
|
||||
|
||||
it("should fail when module name in 'require' calls has inconsistent casing", () => {
|
||||
const files: Map<string> = {
|
||||
const files: MapLike<string> = {
|
||||
"moduleA.ts": `import a = require("./ModuleC")`,
|
||||
"moduleB.ts": `import a = require("./moduleC")`,
|
||||
"moduleC.ts": "export var x"
|
||||
|
@ -445,7 +445,7 @@ export = C;
|
|||
});
|
||||
|
||||
it("should fail when module names in 'require' calls has inconsistent casing and current directory has uppercase chars", () => {
|
||||
const files: Map<string> = {
|
||||
const files: MapLike<string> = {
|
||||
"/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",
|
||||
|
@ -457,7 +457,7 @@ import b = require("./moduleB.ts");
|
|||
test(files, { module: ts.ModuleKind.CommonJS, forceConsistentCasingInFileNames: true }, "/a/B/c", /*useCaseSensitiveFileNames*/ false, ["moduleD.ts"], [1149]);
|
||||
});
|
||||
it("should not fail when module names in 'require' calls has consistent casing and current directory has uppercase chars", () => {
|
||||
const files: Map<string> = {
|
||||
const files: MapLike<string> = {
|
||||
"/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",
|
||||
|
|
|
@ -96,7 +96,7 @@ namespace ts {
|
|||
}
|
||||
|
||||
function createTestCompilerHost(texts: NamedSourceText[], target: ScriptTarget): CompilerHost {
|
||||
const files: Map<SourceFileWithText> = {};
|
||||
const files: MapLike<SourceFileWithText> = {};
|
||||
for (const t of texts) {
|
||||
const file = <SourceFileWithText>createSourceFile(t.name, t.text.getFullText(), target);
|
||||
file.sourceText = t.text;
|
||||
|
@ -152,7 +152,7 @@ namespace ts {
|
|||
return program;
|
||||
}
|
||||
|
||||
function getSizeOfMap(map: Map<any>): number {
|
||||
function getSizeOfMap(map: MapLike<any>): number {
|
||||
let size = 0;
|
||||
for (const id in map) {
|
||||
if (hasProperty(map, id)) {
|
||||
|
@ -174,7 +174,7 @@ namespace ts {
|
|||
assert.isTrue(expected.primary === actual.primary, `'primary': expected '${expected.primary}' to be equal to '${actual.primary}'`);
|
||||
}
|
||||
|
||||
function checkCache<T>(caption: string, program: Program, fileName: string, expectedContent: Map<T>, getCache: (f: SourceFile) => Map<T>, entryChecker: (expected: T, original: T) => void): void {
|
||||
function checkCache<T>(caption: string, program: Program, fileName: string, expectedContent: MapLike<T>, getCache: (f: SourceFile) => MapLike<T>, entryChecker: (expected: T, original: T) => void): void {
|
||||
const file = program.getSourceFile(fileName);
|
||||
assert.isTrue(file !== undefined, `cannot find file ${fileName}`);
|
||||
const cache = getCache(file);
|
||||
|
@ -203,11 +203,11 @@ namespace ts {
|
|||
}
|
||||
}
|
||||
|
||||
function checkResolvedModulesCache(program: Program, fileName: string, expectedContent: Map<ResolvedModule>): void {
|
||||
function checkResolvedModulesCache(program: Program, fileName: string, expectedContent: MapLike<ResolvedModule>): void {
|
||||
checkCache("resolved modules", program, fileName, expectedContent, f => f.resolvedModules, checkResolvedModule);
|
||||
}
|
||||
|
||||
function checkResolvedTypeDirectivesCache(program: Program, fileName: string, expectedContent: Map<ResolvedTypeReferenceDirective>): void {
|
||||
function checkResolvedTypeDirectivesCache(program: Program, fileName: string, expectedContent: MapLike<ResolvedTypeReferenceDirective>): void {
|
||||
checkCache("resolved type directives", program, fileName, expectedContent, f => f.resolvedTypeReferenceDirectiveNames, checkResolvedTypeDirective);
|
||||
}
|
||||
|
||||
|
|
|
@ -362,8 +362,8 @@ namespace ts.server {
|
|||
class InProcClient {
|
||||
private server: InProcSession;
|
||||
private seq = 0;
|
||||
private callbacks: ts.Map<(resp: protocol.Response) => void> = {};
|
||||
private eventHandlers: ts.Map<(args: any) => void> = {};
|
||||
private callbacks: ts.MapLike<(resp: protocol.Response) => void> = {};
|
||||
private eventHandlers: ts.MapLike<(args: any) => void> = {};
|
||||
|
||||
handle(msg: protocol.Message): void {
|
||||
if (msg.type === "response") {
|
||||
|
|
|
@ -68,7 +68,7 @@ namespace ts {
|
|||
return entry;
|
||||
}
|
||||
|
||||
function sizeOfMap(map: Map<any>): number {
|
||||
function sizeOfMap(map: MapLike<any>): number {
|
||||
let n = 0;
|
||||
for (const name in map) {
|
||||
if (hasProperty(map, name)) {
|
||||
|
@ -78,7 +78,7 @@ namespace ts {
|
|||
return n;
|
||||
}
|
||||
|
||||
function checkMapKeys(caption: string, map: Map<any>, expectedKeys: string[]) {
|
||||
function checkMapKeys(caption: string, map: MapLike<any>, expectedKeys: string[]) {
|
||||
assert.equal(sizeOfMap(map), expectedKeys.length, `${caption}: incorrect size of map`);
|
||||
for (const name of expectedKeys) {
|
||||
assert.isTrue(hasProperty(map, name), `${caption} is expected to contain ${name}, actual keys: ${getKeys(map)}`);
|
||||
|
@ -126,8 +126,8 @@ namespace ts {
|
|||
private getCanonicalFileName: (s: string) => string;
|
||||
private toPath: (f: string) => Path;
|
||||
private callbackQueue: TimeOutCallback[] = [];
|
||||
readonly watchedDirectories: Map<{ cb: DirectoryWatcherCallback, recursive: boolean }[]> = {};
|
||||
readonly watchedFiles: Map<FileWatcherCallback[]> = {};
|
||||
readonly watchedDirectories: MapLike<{ cb: DirectoryWatcherCallback, recursive: boolean }[]> = {};
|
||||
readonly watchedFiles: MapLike<FileWatcherCallback[]> = {};
|
||||
|
||||
constructor(public useCaseSensitiveFileNames: boolean, private executingFilePath: string, private currentDirectory: string, fileOrFolderList: FileOrFolder[]) {
|
||||
this.getCanonicalFileName = createGetCanonicalFileName(useCaseSensitiveFileNames);
|
||||
|
|
|
@ -21,7 +21,7 @@ namespace ts.server {
|
|||
|
||||
export class SessionClient implements LanguageService {
|
||||
private sequence: number = 0;
|
||||
private lineMaps: ts.Map<number[]> = {};
|
||||
private lineMaps: ts.Map<number[]> = ts.createMap<number[]>();
|
||||
private messages: string[] = [];
|
||||
private lastRenameEntry: RenameEntry;
|
||||
|
||||
|
|
|
@ -130,7 +130,7 @@ namespace ts.server {
|
|||
const path = toPath(containingFile, this.host.getCurrentDirectory(), this.getCanonicalFileName);
|
||||
const currentResolutionsInFile = cache.get(path);
|
||||
|
||||
const newResolutions: Map<T> = {};
|
||||
const newResolutions = createMap<T>();
|
||||
const resolvedModules: R[] = [];
|
||||
const compilerOptions = this.getCompilationSettings();
|
||||
|
||||
|
@ -378,7 +378,7 @@ namespace ts.server {
|
|||
export interface ProjectOptions {
|
||||
// these fields can be present in the project file
|
||||
files?: string[];
|
||||
wildcardDirectories?: ts.Map<ts.WatchDirectoryFlags>;
|
||||
wildcardDirectories?: ts.MapLike<ts.WatchDirectoryFlags>;
|
||||
compilerOptions?: ts.CompilerOptions;
|
||||
}
|
||||
|
||||
|
@ -391,7 +391,7 @@ namespace ts.server {
|
|||
// Used to keep track of what directories are watched for this project
|
||||
directoriesWatchedForTsconfig: string[] = [];
|
||||
program: ts.Program;
|
||||
filenameToSourceFile: ts.Map<ts.SourceFile> = {};
|
||||
filenameToSourceFile = ts.createMap<ts.SourceFile>();
|
||||
updateGraphSeq = 0;
|
||||
/** Used for configured projects which may have multiple open roots */
|
||||
openRefCount = 0;
|
||||
|
@ -504,7 +504,7 @@ namespace ts.server {
|
|||
return;
|
||||
}
|
||||
|
||||
this.filenameToSourceFile = {};
|
||||
this.filenameToSourceFile = createMap<SourceFile>();
|
||||
const sourceFiles = this.program.getSourceFiles();
|
||||
for (let i = 0, len = sourceFiles.length; i < len; i++) {
|
||||
const normFilename = ts.normalizePath(sourceFiles[i].fileName);
|
||||
|
@ -613,7 +613,7 @@ namespace ts.server {
|
|||
}
|
||||
|
||||
export class ProjectService {
|
||||
filenameToScriptInfo: ts.Map<ScriptInfo> = {};
|
||||
filenameToScriptInfo = ts.createMap<ScriptInfo>();
|
||||
// open, non-configured root files
|
||||
openFileRoots: ScriptInfo[] = [];
|
||||
// projects built from openFileRoots
|
||||
|
@ -625,12 +625,12 @@ namespace ts.server {
|
|||
// open files that are roots of a configured project
|
||||
openFileRootsConfigured: ScriptInfo[] = [];
|
||||
// a path to directory watcher map that detects added tsconfig files
|
||||
directoryWatchersForTsconfig: ts.Map<FileWatcher> = {};
|
||||
directoryWatchersForTsconfig = ts.createMap<FileWatcher>();
|
||||
// count of how many projects are using the directory watcher. If the
|
||||
// number becomes 0 for a watcher, then we should close it.
|
||||
directoryWatchersRefCount: ts.Map<number> = {};
|
||||
directoryWatchersRefCount = ts.createMap<number>();
|
||||
hostConfiguration: HostConfiguration;
|
||||
timerForDetectingProjectFileListChanges: Map<any> = {};
|
||||
timerForDetectingProjectFileListChanges = createMap<any>();
|
||||
|
||||
constructor(public host: ServerHost, public psLogger: Logger, public eventHandler?: ProjectServiceEventHandler) {
|
||||
// ts.disableIncrementalParsing = true;
|
||||
|
|
|
@ -1061,7 +1061,7 @@ namespace ts.server {
|
|||
return { response, responseRequired: true };
|
||||
}
|
||||
|
||||
private handlers: Map<(request: protocol.Request) => { response?: any, responseRequired?: boolean }> = {
|
||||
private handlers: MapLike<(request: protocol.Request) => { response?: any, responseRequired?: boolean }> = {
|
||||
[CommandNames.Exit]: () => {
|
||||
this.exit();
|
||||
return { responseRequired: false };
|
||||
|
|
|
@ -47,7 +47,7 @@ namespace ts.JsTyping {
|
|||
{ cachedTypingPaths: string[], newTypingNames: string[], filesToWatch: string[] } {
|
||||
|
||||
// A typing name to typing file path mapping
|
||||
const inferredTypings: Map<string> = {};
|
||||
const inferredTypings = createMap<string>();
|
||||
|
||||
if (!typingOptions || !typingOptions.enableAutoDiscovery) {
|
||||
return { cachedTypingPaths: [], newTypingNames: [], filesToWatch: [] };
|
||||
|
@ -62,7 +62,7 @@ namespace ts.JsTyping {
|
|||
safeList = result.config;
|
||||
}
|
||||
else {
|
||||
safeList = {};
|
||||
safeList = createMap<string>();
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -234,7 +234,7 @@ namespace ts.NavigationBar {
|
|||
|
||||
/** Merge declarations of the same kind. */
|
||||
function mergeChildren(children: NavigationBarNode[]): void {
|
||||
const nameToItems: Map<NavigationBarNode | NavigationBarNode[]> = {};
|
||||
const nameToItems = createMap<NavigationBarNode | NavigationBarNode[]>();
|
||||
filterMutate(children, child => {
|
||||
const decl = <Declaration>child.node;
|
||||
const name = decl.name && nodeText(decl.name);
|
||||
|
|
|
@ -113,7 +113,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: Map<TextSpan[]> = {};
|
||||
const stringToWordSpans = createMap<TextSpan[]>();
|
||||
|
||||
pattern = pattern.trim();
|
||||
|
||||
|
|
|
@ -975,7 +975,7 @@ namespace ts {
|
|||
}
|
||||
|
||||
private computeNamedDeclarations(): Map<Declaration[]> {
|
||||
const result: Map<Declaration[]> = {};
|
||||
const result = createMap<Declaration[]>();
|
||||
|
||||
forEachChild(this, visit);
|
||||
|
||||
|
@ -2025,7 +2025,7 @@ namespace ts {
|
|||
fileName?: string;
|
||||
reportDiagnostics?: boolean;
|
||||
moduleName?: string;
|
||||
renamedDependencies?: Map<string>;
|
||||
renamedDependencies?: MapLike<string>;
|
||||
}
|
||||
|
||||
export interface TranspileOutput {
|
||||
|
@ -2243,7 +2243,7 @@ namespace ts {
|
|||
export function createDocumentRegistry(useCaseSensitiveFileNames?: boolean, currentDirectory = ""): DocumentRegistry {
|
||||
// Maps from compiler setting target (ES3, ES5, etc.) to all the cached documents we have
|
||||
// for those settings.
|
||||
const buckets: Map<FileMap<DocumentRegistryEntry>> = {};
|
||||
const buckets = createMap<FileMap<DocumentRegistryEntry>>();
|
||||
const getCanonicalFileName = createGetCanonicalFileName(!!useCaseSensitiveFileNames);
|
||||
|
||||
function getKeyForCompilationSettings(settings: CompilerOptions): DocumentRegistryBucketKey {
|
||||
|
@ -4102,7 +4102,7 @@ namespace ts {
|
|||
* do not occur at the current position and have not otherwise been typed.
|
||||
*/
|
||||
function filterNamedImportOrExportCompletionItems(exportsOfModule: Symbol[], namedImportsOrExports: ImportOrExportSpecifier[]): Symbol[] {
|
||||
const existingImportsOrExports: Map<boolean> = {};
|
||||
const existingImportsOrExports = createMap<boolean>();
|
||||
|
||||
for (const element of namedImportsOrExports) {
|
||||
// If this is the current item we are editing right now, do not filter it out
|
||||
|
@ -4132,7 +4132,7 @@ namespace ts {
|
|||
return contextualMemberSymbols;
|
||||
}
|
||||
|
||||
const existingMemberNames: Map<boolean> = {};
|
||||
const existingMemberNames = createMap<boolean>();
|
||||
for (const m of existingMembers) {
|
||||
// Ignore omitted expressions for missing members
|
||||
if (m.kind !== SyntaxKind.PropertyAssignment &&
|
||||
|
@ -4175,7 +4175,7 @@ namespace ts {
|
|||
* do not occur at the current position and have not otherwise been typed.
|
||||
*/
|
||||
function filterJsxAttributes(symbols: Symbol[], attributes: NodeArray<JsxAttribute | JsxSpreadAttribute>): Symbol[] {
|
||||
const seenNames: Map<boolean> = {};
|
||||
const seenNames = createMap<boolean>();
|
||||
for (const attr of attributes) {
|
||||
// If this is the current item we are editing right now, do not filter it out
|
||||
if (attr.getStart() <= position && position <= attr.getEnd()) {
|
||||
|
@ -4317,7 +4317,7 @@ namespace ts {
|
|||
|
||||
function getCompletionEntriesFromSymbols(symbols: Symbol[], entries: CompletionEntry[], location: Node, performCharacterChecks: boolean): Map<string> {
|
||||
const start = timestamp();
|
||||
const uniqueNames: Map<string> = {};
|
||||
const uniqueNames = createMap<string>();
|
||||
if (symbols) {
|
||||
for (const symbol of symbols) {
|
||||
const entry = createCompletionEntry(symbol, location, performCharacterChecks);
|
||||
|
@ -5318,7 +5318,7 @@ namespace ts {
|
|||
return undefined;
|
||||
}
|
||||
|
||||
const fileNameToDocumentHighlights: Map<DocumentHighlights> = {};
|
||||
const fileNameToDocumentHighlights = createMap<DocumentHighlights>();
|
||||
const result: DocumentHighlights[] = [];
|
||||
for (const referencedSymbol of referencedSymbols) {
|
||||
for (const referenceEntry of referencedSymbol.references) {
|
||||
|
@ -6713,7 +6713,7 @@ namespace ts {
|
|||
|
||||
// Add symbol of properties/methods of the same name in base classes and implemented interfaces definitions
|
||||
if (rootSymbol.parent && rootSymbol.parent.flags & (SymbolFlags.Class | SymbolFlags.Interface)) {
|
||||
getPropertySymbolsFromBaseTypes(rootSymbol.parent, rootSymbol.getName(), result, /*previousIterationSymbolsCache*/ {});
|
||||
getPropertySymbolsFromBaseTypes(rootSymbol.parent, rootSymbol.getName(), result, /*previousIterationSymbolsCache*/ createMap<Symbol>());
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -6834,7 +6834,7 @@ namespace ts {
|
|||
// see if any is in the list
|
||||
if (rootSymbol.parent && rootSymbol.parent.flags & (SymbolFlags.Class | SymbolFlags.Interface)) {
|
||||
const result: Symbol[] = [];
|
||||
getPropertySymbolsFromBaseTypes(rootSymbol.parent, rootSymbol.getName(), result, /*previousIterationSymbolsCache*/ {});
|
||||
getPropertySymbolsFromBaseTypes(rootSymbol.parent, rootSymbol.getName(), result, /*previousIterationSymbolsCache*/ createMap<Symbol>());
|
||||
return forEach(result, s => searchSymbols.indexOf(s) >= 0 ? s : undefined);
|
||||
}
|
||||
|
||||
|
@ -8318,7 +8318,7 @@ namespace ts {
|
|||
}
|
||||
|
||||
function initializeNameTable(sourceFile: SourceFile): void {
|
||||
const nameTable: Map<number> = {};
|
||||
const nameTable = createMap<number>();
|
||||
|
||||
walk(sourceFile);
|
||||
sourceFile.nameTable = nameTable;
|
||||
|
|
|
@ -20,7 +20,7 @@ declare var path: any;
|
|||
import * as ts from "typescript";
|
||||
|
||||
function watch(rootFileNames: string[], options: ts.CompilerOptions) {
|
||||
const files: ts.Map<{ version: number }> = {};
|
||||
const files: ts.MapLike<{ version: number }> = {};
|
||||
|
||||
// initialize the list of files
|
||||
rootFileNames.forEach(fileName => {
|
||||
|
|
|
@ -23,7 +23,7 @@ declare var path: any;
|
|||
import * as ts from "typescript";
|
||||
|
||||
function watch(rootFileNames: string[], options: ts.CompilerOptions) {
|
||||
const files: ts.Map<{ version: number }> = {};
|
||||
const files: ts.MapLike<{ version: number }> = {};
|
||||
|
||||
// initialize the list of files
|
||||
rootFileNames.forEach(fileName => {
|
||||
|
|
Loading…
Reference in a new issue