mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
Use native maps when they're available
This commit is contained in:
@@ -27,7 +27,7 @@ function main(): void {
|
||||
|
||||
var inputFilePath = sys.args[0].replace(/\\/g, "/");
|
||||
var inputStr = sys.readFile(inputFilePath);
|
||||
|
||||
|
||||
var diagnosticMessages: InputDiagnosticMessageTable = JSON.parse(inputStr);
|
||||
|
||||
var names = Utilities.getObjectKeys(diagnosticMessages);
|
||||
@@ -44,7 +44,7 @@ function main(): void {
|
||||
function checkForUniqueCodes(messages: string[], diagnosticTable: InputDiagnosticMessageTable) {
|
||||
const originalMessageForCode: string[] = [];
|
||||
let numConflicts = 0;
|
||||
|
||||
|
||||
for (const currentMessage of messages) {
|
||||
const code = diagnosticTable[currentMessage].code;
|
||||
|
||||
@@ -74,7 +74,7 @@ function buildUniqueNameMap(names: string[]): ts.Map<string> {
|
||||
var uniqueNames = NameGenerator.ensureUniqueness(names, /* isCaseSensitive */ false, /* isFixed */ undefined);
|
||||
|
||||
for (var i = 0; i < names.length; i++) {
|
||||
nameMap[names[i]] = uniqueNames[i];
|
||||
nameMap.set(names[i], uniqueNames[i]);
|
||||
}
|
||||
|
||||
return nameMap;
|
||||
@@ -91,7 +91,7 @@ function buildInfoFileOutput(messageTable: InputDiagnosticMessageTable, nameMap:
|
||||
for (var i = 0; i < names.length; i++) {
|
||||
var name = names[i];
|
||||
var diagnosticDetails = messageTable[name];
|
||||
var propName = convertPropertyName(nameMap[name]);
|
||||
var propName = convertPropertyName(nameMap.get(name));
|
||||
|
||||
result +=
|
||||
' ' + propName +
|
||||
@@ -114,7 +114,7 @@ function buildDiagnosticMessageOutput(messageTable: InputDiagnosticMessageTable,
|
||||
for (var i = 0; i < names.length; i++) {
|
||||
var name = names[i];
|
||||
var diagnosticDetails = messageTable[name];
|
||||
var propName = convertPropertyName(nameMap[name]);
|
||||
var propName = convertPropertyName(nameMap.get(name));
|
||||
|
||||
result += '\r\n "' + createKey(propName, diagnosticDetails.code) + '"' + ' : "' + name.replace(/[\"]/g, '\\"') + '"';
|
||||
if (i !== names.length - 1) {
|
||||
|
||||
+12
-12
@@ -349,17 +349,17 @@ 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 = symbolTable[name] || (symbolTable[name] = createSymbol(SymbolFlags.None, name));
|
||||
symbol = symbolTable.get(name) || set(symbolTable, name, createSymbol(SymbolFlags.None, name));
|
||||
|
||||
if (name && (includes & SymbolFlags.Classifiable)) {
|
||||
classifiableNames[name] = name;
|
||||
classifiableNames.set(name, name);
|
||||
}
|
||||
|
||||
if (symbol.flags & excludes) {
|
||||
if (symbol.isReplaceableByMethod) {
|
||||
// Javascript constructor-declared symbols can be discarded in favor of
|
||||
// prototype symbols like methods.
|
||||
symbol = symbolTable[name] = createSymbol(SymbolFlags.None, name);
|
||||
symbol = set(symbolTable, name, createSymbol(SymbolFlags.None, name));
|
||||
}
|
||||
else {
|
||||
if (node.name) {
|
||||
@@ -1570,7 +1570,7 @@ namespace ts {
|
||||
const typeLiteralSymbol = createSymbol(SymbolFlags.TypeLiteral, "__type");
|
||||
addDeclarationToSymbol(typeLiteralSymbol, node, SymbolFlags.TypeLiteral);
|
||||
typeLiteralSymbol.members = createMap<Symbol>();
|
||||
typeLiteralSymbol.members[symbol.name] = symbol;
|
||||
typeLiteralSymbol.members.set(symbol.name, symbol);
|
||||
}
|
||||
|
||||
function bindObjectLiteralExpression(node: ObjectLiteralExpression) {
|
||||
@@ -1601,9 +1601,9 @@ namespace ts {
|
||||
? ElementKind.Property
|
||||
: ElementKind.Accessor;
|
||||
|
||||
const existingKind = seen[identifier.text];
|
||||
const existingKind = seen.get(identifier.text);
|
||||
if (!existingKind) {
|
||||
seen[identifier.text] = currentKind;
|
||||
seen.set(identifier.text, currentKind);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -2208,7 +2208,7 @@ namespace ts {
|
||||
constructorFunction.parent = classPrototype;
|
||||
classPrototype.parent = leftSideOfAssignment;
|
||||
|
||||
const funcSymbol = container.locals[constructorFunction.text];
|
||||
const funcSymbol = container.locals.get(constructorFunction.text);
|
||||
if (!funcSymbol || !(funcSymbol.flags & SymbolFlags.Function || isDeclarationOfFunctionExpression(funcSymbol))) {
|
||||
return;
|
||||
}
|
||||
@@ -2239,7 +2239,7 @@ namespace ts {
|
||||
bindAnonymousDeclaration(node, SymbolFlags.Class, bindingName);
|
||||
// Add name of class expression into the map for semantic classifier
|
||||
if (node.name) {
|
||||
classifiableNames[node.name.text] = node.name.text;
|
||||
classifiableNames.set(node.name.text, node.name.text);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2255,14 +2255,14 @@ 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 (symbol.exports[prototypeSymbol.name]) {
|
||||
const symbolExport = symbol.exports.get(prototypeSymbol.name);
|
||||
if (symbolExport) {
|
||||
if (node.name) {
|
||||
node.name.parent = node;
|
||||
}
|
||||
file.bindDiagnostics.push(createDiagnosticForNode(symbol.exports[prototypeSymbol.name].declarations[0],
|
||||
Diagnostics.Duplicate_identifier_0, prototypeSymbol.name));
|
||||
file.bindDiagnostics.push(createDiagnosticForNode(symbolExport.declarations[0], Diagnostics.Duplicate_identifier_0, prototypeSymbol.name));
|
||||
}
|
||||
symbol.exports[prototypeSymbol.name] = prototypeSymbol;
|
||||
symbol.exports.set(prototypeSymbol.name, prototypeSymbol);
|
||||
prototypeSymbol.parent = symbol;
|
||||
}
|
||||
|
||||
|
||||
+200
-197
File diff suppressed because it is too large
Load Diff
@@ -531,9 +531,9 @@ namespace ts {
|
||||
const optionNameMap = createMap<CommandLineOption>();
|
||||
const shortOptionNames = createMap<string>();
|
||||
forEach(optionDeclarations, option => {
|
||||
optionNameMap[option.name.toLowerCase()] = option;
|
||||
optionNameMap.set(option.name.toLowerCase(), option);
|
||||
if (option.shortName) {
|
||||
shortOptionNames[option.shortName] = option.name;
|
||||
shortOptionNames.set(option.shortName, option.name);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -543,7 +543,7 @@ namespace ts {
|
||||
|
||||
/* @internal */
|
||||
export function createCompilerDiagnosticForInvalidCustomType(opt: CommandLineOptionOfCustomType): Diagnostic {
|
||||
const namesOfType = Object.keys(opt.type).map(key => `'${key}'`).join(", ");
|
||||
const namesOfType = keysOfMap(opt.type).map(key => `'${key}'`).join(", ");
|
||||
return createCompilerDiagnostic(Diagnostics.Argument_for_0_option_must_be_Colon_1, `--${opt.name}`, namesOfType);
|
||||
}
|
||||
|
||||
@@ -598,13 +598,13 @@ namespace ts {
|
||||
s = s.slice(s.charCodeAt(1) === CharacterCodes.minus ? 2 : 1).toLowerCase();
|
||||
|
||||
// Try to translate short option names to their full equivalents.
|
||||
if (s in shortOptionNames) {
|
||||
s = shortOptionNames[s];
|
||||
const short = shortOptionNames.get(s);
|
||||
if (short !== undefined) {
|
||||
s = short;
|
||||
}
|
||||
|
||||
if (s in optionNameMap) {
|
||||
const opt = optionNameMap[s];
|
||||
|
||||
const opt = optionNameMap.get(s);
|
||||
if (opt) {
|
||||
if (opt.isTSConfigOnly) {
|
||||
errors.push(createCompilerDiagnostic(Diagnostics.Option_0_can_only_be_specified_in_tsconfig_json_file, opt.name));
|
||||
}
|
||||
@@ -727,7 +727,7 @@ namespace ts {
|
||||
* @param fileNames array of filenames to be generated into tsconfig.json
|
||||
*/
|
||||
/* @internal */
|
||||
export function generateTSConfig(options: CompilerOptions, fileNames: string[]): { compilerOptions: Map<CompilerOptionsValue> } {
|
||||
export function generateTSConfig(options: CompilerOptions, fileNames: string[]): { compilerOptions: MapLike<CompilerOptionsValue> } {
|
||||
const compilerOptions = extend(options, defaultInitCompilerOptions);
|
||||
const configurations: any = {
|
||||
compilerOptions: serializeCompilerOptions(compilerOptions)
|
||||
@@ -752,18 +752,17 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function getNameOfCompilerOptionValue(value: CompilerOptionsValue, customTypeMap: MapLike<string | number>): string | undefined {
|
||||
function getNameOfCompilerOptionValue(value: CompilerOptionsValue, customTypeMap: Map<string | number>): string | undefined {
|
||||
// There is a typeMap associated with this command-line option so use it to map value back to its name
|
||||
for (const key in customTypeMap) {
|
||||
if (customTypeMap[key] === value) {
|
||||
return forEachInMap(customTypeMap, (mapValue, key) => {
|
||||
if (mapValue === value) {
|
||||
return key;
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
});
|
||||
}
|
||||
|
||||
function serializeCompilerOptions(options: CompilerOptions): Map<CompilerOptionsValue> {
|
||||
const result = createMap<CompilerOptionsValue>();
|
||||
function serializeCompilerOptions(options: CompilerOptions): MapLike<CompilerOptionsValue> {
|
||||
const result = createMapLike<CompilerOptionsValue>();
|
||||
const optionsNameMap = getOptionNameMap().optionNameMap;
|
||||
|
||||
for (const name in options) {
|
||||
@@ -779,7 +778,7 @@ namespace ts {
|
||||
break;
|
||||
default:
|
||||
const value = options[name];
|
||||
let optionDefinition = optionsNameMap[name.toLowerCase()];
|
||||
let optionDefinition = optionsNameMap.get(name.toLowerCase());
|
||||
if (optionDefinition) {
|
||||
const customTypeMap = getCustomTypeMapOfCommandLineOption(optionDefinition);
|
||||
if (!customTypeMap) {
|
||||
@@ -1049,8 +1048,8 @@ namespace ts {
|
||||
const optionNameMap = arrayToMap(optionDeclarations, opt => opt.name);
|
||||
|
||||
for (const id in jsonOptions) {
|
||||
if (id in optionNameMap) {
|
||||
const opt = optionNameMap[id];
|
||||
const opt = optionNameMap.get(id);
|
||||
if (opt) {
|
||||
defaultOptions[opt.name] = convertJsonOption(opt, jsonOptions[id], basePath, errors);
|
||||
}
|
||||
else {
|
||||
@@ -1086,8 +1085,9 @@ namespace ts {
|
||||
|
||||
function convertJsonOptionOfCustomType(opt: CommandLineOptionOfCustomType, value: string, errors: Diagnostic[]) {
|
||||
const key = value.toLowerCase();
|
||||
if (key in opt.type) {
|
||||
return opt.type[key];
|
||||
const val = opt.type.get(key);
|
||||
if (val !== undefined) {
|
||||
return val;
|
||||
}
|
||||
else {
|
||||
errors.push(createCompilerDiagnosticForInvalidCustomType(opt));
|
||||
@@ -1215,7 +1215,7 @@ namespace ts {
|
||||
// file map that marks whether it was a regular wildcard match (with a `*` or `?` token),
|
||||
// or a recursive directory. This information is used by filesystem watchers to monitor for
|
||||
// new entries in these paths.
|
||||
const wildcardDirectories: Map<WatchDirectoryFlags> = getWildcardDirectories(include, exclude, basePath, host.useCaseSensitiveFileNames);
|
||||
const wildcardDirectories = getWildcardDirectories(include, exclude, basePath, host.useCaseSensitiveFileNames);
|
||||
|
||||
// Rather than requery this for each file and filespec, we query the supported extensions
|
||||
// once and store it on the expansion context.
|
||||
@@ -1226,7 +1226,7 @@ namespace ts {
|
||||
if (fileNames) {
|
||||
for (const fileName of fileNames) {
|
||||
const file = combinePaths(basePath, fileName);
|
||||
literalFileMap[keyMapper(file)] = file;
|
||||
literalFileMap.set(keyMapper(file), file);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1249,14 +1249,14 @@ namespace ts {
|
||||
removeWildcardFilesWithLowerPriorityExtension(file, wildcardFileMap, supportedExtensions, keyMapper);
|
||||
|
||||
const key = keyMapper(file);
|
||||
if (!(key in literalFileMap) && !(key in wildcardFileMap)) {
|
||||
wildcardFileMap[key] = file;
|
||||
if (!literalFileMap.has(key) && !wildcardFileMap.has(key)) {
|
||||
wildcardFileMap.set(key, file);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const literalFiles = reduceProperties(literalFileMap, addFileToOutput, []);
|
||||
const wildcardFiles = reduceProperties(wildcardFileMap, addFileToOutput, []);
|
||||
const literalFiles = valuesOfMap(literalFileMap);
|
||||
const wildcardFiles = valuesOfMap(wildcardFileMap);
|
||||
wildcardFiles.sort(host.useCaseSensitiveFileNames ? compareStrings : compareStringsCaseInsensitive);
|
||||
return {
|
||||
fileNames: literalFiles.concat(wildcardFiles),
|
||||
@@ -1287,7 +1287,7 @@ namespace ts {
|
||||
/**
|
||||
* Gets directories in a set of include patterns that should be watched for changes.
|
||||
*/
|
||||
function getWildcardDirectories(include: string[], exclude: string[], path: string, useCaseSensitiveFileNames: boolean): Map<WatchDirectoryFlags> {
|
||||
function getWildcardDirectories(include: string[], exclude: string[], path: string, useCaseSensitiveFileNames: boolean): MapLike<WatchDirectoryFlags> {
|
||||
// We watch a directory recursively if it contains a wildcard anywhere in a directory segment
|
||||
// of the pattern:
|
||||
//
|
||||
@@ -1302,7 +1302,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 = createMap<WatchDirectoryFlags>();
|
||||
const wildcardDirectories = createMapLike<WatchDirectoryFlags>();
|
||||
if (include !== undefined) {
|
||||
const recursiveKeys: string[] = [];
|
||||
for (const file of include) {
|
||||
@@ -1331,7 +1331,7 @@ namespace ts {
|
||||
delete wildcardDirectories[key];
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
return wildcardDirectories;
|
||||
@@ -1365,7 +1365,7 @@ namespace ts {
|
||||
for (let i = ExtensionPriority.Highest; i < adjustedExtensionPriority; i++) {
|
||||
const higherPriorityExtension = extensions[i];
|
||||
const higherPriorityPath = keyMapper(changeExtension(file, higherPriorityExtension));
|
||||
if (higherPriorityPath in literalFiles || higherPriorityPath in wildcardFiles) {
|
||||
if (literalFiles.has(higherPriorityPath) || wildcardFiles.has(higherPriorityPath)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -1387,21 +1387,10 @@ namespace ts {
|
||||
for (let i = nextExtensionPriority; i < extensions.length; i++) {
|
||||
const lowerPriorityExtension = extensions[i];
|
||||
const lowerPriorityPath = keyMapper(changeExtension(file, lowerPriorityExtension));
|
||||
delete wildcardFiles[lowerPriorityPath];
|
||||
wildcardFiles.delete(lowerPriorityPath);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a file to an array of files.
|
||||
*
|
||||
* @param output The output array.
|
||||
* @param file The file path.
|
||||
*/
|
||||
function addFileToOutput(output: string[], file: string) {
|
||||
output.push(file);
|
||||
return output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a case sensitive key.
|
||||
*
|
||||
|
||||
+234
-93
@@ -23,13 +23,13 @@ namespace ts {
|
||||
True = -1
|
||||
}
|
||||
|
||||
const createObject = Object.create;
|
||||
|
||||
// More efficient to create a collator once and use its `compare` than to call `a.localeCompare(b)` many times.
|
||||
export const collator: { compare(a: string, b: string): number } = typeof Intl === "object" && typeof Intl.Collator === "function" ? new Intl.Collator() : undefined;
|
||||
|
||||
export function createMap<T>(template?: MapLike<T>): Map<T> {
|
||||
const map: Map<T> = createObject(null); // tslint:disable-line:no-null-keyword
|
||||
const createObject = Object.create;
|
||||
/** Create a MapLike with good performance. Prefer this over a literal `{}`. */
|
||||
export function createMapLike<T>(): MapLike<T> {
|
||||
const map = createObject(null); // tslint:disable-line: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
|
||||
@@ -37,17 +37,141 @@ namespace ts {
|
||||
map["__"] = undefined;
|
||||
delete map["__"];
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
/** Create a new map. If a template object is provided, the map will copy entries from it. */
|
||||
export function createMap<T>(template?: MapLike<T>): Map<T> {
|
||||
const map: Map<T> = new MapCtr<T>();
|
||||
|
||||
// Copies keys/values from template. Note that for..in will not throw if
|
||||
// template is undefined, and instead will just exit the loop.
|
||||
for (const key in template) if (hasOwnProperty.call(template, key)) {
|
||||
map[key] = template[key];
|
||||
map.set(key, template[key]);
|
||||
}
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
/** Create a map from [key, value] pairs. This avoids casting keys to strings. */
|
||||
export function createMapFromPairs<T>(...pairs: [number, T][]): Map<T> {
|
||||
const map: Map<T> = new MapCtr<T>();
|
||||
|
||||
for (const [key, value] of pairs) {
|
||||
map.set(key, value);
|
||||
}
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
/** Methods on native maps but not on shim maps. Only used in this file. */
|
||||
interface ES6Map<T> extends Map<T> {
|
||||
readonly size: number;
|
||||
entries(): Iterator<[string, T]>;
|
||||
keys(): Iterator<string>;
|
||||
}
|
||||
|
||||
/** ES6 Iterator type. */
|
||||
interface Iterator<T> {
|
||||
next(): { value: T, done: false } | { value: never, done: true };
|
||||
}
|
||||
|
||||
/** Shim maps support certain methods directly. For native maps we use a function. */
|
||||
interface ShimMap<T> extends Map<T> {
|
||||
isEmpty(): boolean;
|
||||
forEachInMap<U>(callback: (value: T, key: string) => U | undefined): U | undefined;
|
||||
forEachKey<U>(callback: (key: string) => U | undefined): U | undefined;
|
||||
some(predicate: (value: T, key: string) => boolean): boolean;
|
||||
someKey(predicate: (key: string) => boolean): boolean;
|
||||
}
|
||||
|
||||
// The global Map object. This may not be available, so we must test for it.
|
||||
declare const Map: { new<T>(): Map<T> } | undefined;
|
||||
// Internet Explorer's Map doesn't support iteration, so don't use it.
|
||||
// tslint:disable-next-line:no-in-operator
|
||||
const usingNativeMaps = typeof Map !== "undefined" && "entries" in Map.prototype;
|
||||
const MapCtr = usingNativeMaps ? Map : shimMap();
|
||||
|
||||
// Keep the class inside a function so it doesn't get compiled if it's not used.
|
||||
function shimMap(): { new<T>(): Map<T> } {
|
||||
return class<T> implements ShimMap<T> {
|
||||
private data = createMapLike<T>();
|
||||
|
||||
get(key: MapKey): T {
|
||||
return this.data[key];
|
||||
}
|
||||
|
||||
set(key: MapKey, value: T): this {
|
||||
this.data[key] = value;
|
||||
return this;
|
||||
}
|
||||
|
||||
has(key: MapKey): boolean {
|
||||
// tslint:disable-next-line:no-in-operator
|
||||
return key in this.data;
|
||||
}
|
||||
|
||||
delete(key: MapKey): boolean {
|
||||
const had = this.has(key);
|
||||
if (had) {
|
||||
delete this.data[key];
|
||||
}
|
||||
return had;
|
||||
}
|
||||
|
||||
clear(): void {
|
||||
this.data = createMapLike<T>();
|
||||
}
|
||||
|
||||
forEach(action: (value: T, key: string) => void): void {
|
||||
for (const key in this.data) {
|
||||
action(this.data[key], key);
|
||||
}
|
||||
}
|
||||
|
||||
isEmpty(): boolean {
|
||||
return !this.someKey(() => true);
|
||||
}
|
||||
|
||||
forEachInMap<U>(callback: (value: T, key: string) => U | undefined): U | undefined {
|
||||
return this.forEachKey(key => callback(this.data[key], key));
|
||||
}
|
||||
|
||||
forEachKey<U>(callback: (key: string) => U | undefined): U | undefined {
|
||||
for (const key in this.data) {
|
||||
const result = callback(key);
|
||||
if (result !== undefined) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
some(predicate: (value: T, key: string) => boolean): boolean {
|
||||
return this.someKey(key => predicate(this.data[key], key));
|
||||
}
|
||||
|
||||
someKey(predicate: (key: string) => boolean): boolean {
|
||||
for (const key in this.data) {
|
||||
if (predicate(key)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Unlike `map.set(key, value)`, this returns the value, making it useful as an expression.
|
||||
* Prefer `map.set(key, value)` for statements.
|
||||
*/
|
||||
export function set<T>(map: Map<T>, key: MapKey, value: T): T {
|
||||
map.set(key, value);
|
||||
return value;
|
||||
}
|
||||
|
||||
export function createFileMap<T>(keyMapper?: (key: string) => string): FileMap<T> {
|
||||
let files = createMap<T>();
|
||||
const files = createMap<T>();
|
||||
return {
|
||||
get,
|
||||
set,
|
||||
@@ -59,39 +183,34 @@ namespace ts {
|
||||
};
|
||||
|
||||
function forEachValueInMap(f: (key: Path, value: T) => void) {
|
||||
for (const key in files) {
|
||||
f(<Path>key, files[key]);
|
||||
}
|
||||
files.forEach((file, key) => {
|
||||
f(<Path>key, file);
|
||||
});
|
||||
}
|
||||
|
||||
function getKeys() {
|
||||
const keys: Path[] = [];
|
||||
for (const key in files) {
|
||||
keys.push(<Path>key);
|
||||
}
|
||||
return keys;
|
||||
return keysOfMap(files) as Path[];
|
||||
}
|
||||
|
||||
// path should already be well-formed so it does not need to be normalized
|
||||
function get(path: Path): T {
|
||||
return files[toKey(path)];
|
||||
return files.get(toKey(path));
|
||||
}
|
||||
|
||||
function set(path: Path, value: T) {
|
||||
files[toKey(path)] = value;
|
||||
files.set(toKey(path), value);
|
||||
}
|
||||
|
||||
function contains(path: Path) {
|
||||
return toKey(path) in files;
|
||||
return files.has(toKey(path));
|
||||
}
|
||||
|
||||
function remove(path: Path) {
|
||||
const key = toKey(path);
|
||||
delete files[key];
|
||||
files.delete(toKey(path));
|
||||
}
|
||||
|
||||
function clear() {
|
||||
files = createMap<T>();
|
||||
files.clear();
|
||||
}
|
||||
|
||||
function toKey(path: Path): string {
|
||||
@@ -748,9 +867,6 @@ namespace ts {
|
||||
/**
|
||||
* Indicates whether a map-like contains an own property with the specified key.
|
||||
*
|
||||
* NOTE: This is intended for use only with MapLike<T> objects. For Map<T> objects, use
|
||||
* the 'in' operator.
|
||||
*
|
||||
* @param map A map-like.
|
||||
* @param key A property key.
|
||||
*/
|
||||
@@ -761,9 +877,6 @@ namespace ts {
|
||||
/**
|
||||
* Gets the value of an owned property in a map-like.
|
||||
*
|
||||
* NOTE: This is intended for use only with MapLike<T> objects. For Map<T> objects, use
|
||||
* an indexer.
|
||||
*
|
||||
* @param map A map-like.
|
||||
* @param key A property key.
|
||||
*/
|
||||
@@ -788,49 +901,86 @@ namespace ts {
|
||||
}
|
||||
|
||||
/**
|
||||
* Enumerates the properties of a Map<T>, invoking a callback and returning the first truthy result.
|
||||
*
|
||||
* @param map A map for which properties should be enumerated.
|
||||
* @param callback A callback to invoke for each property.
|
||||
* Array of every key in a map.
|
||||
* May not actually return string[] if numbers were put into the map.
|
||||
*/
|
||||
export function forEachProperty<T, U>(map: Map<T>, callback: (value: T, key: string) => U): U {
|
||||
let result: U;
|
||||
for (const key in map) {
|
||||
if (result = callback(map[key], key)) break;
|
||||
}
|
||||
return result;
|
||||
export function keysOfMap<T>(map: Map<T>): string[] {
|
||||
const keys: string[] = [];
|
||||
forEachKeyInMap(map, key => {
|
||||
keys.push(key);
|
||||
});
|
||||
return keys;
|
||||
}
|
||||
|
||||
/** Array of every value in a map. */
|
||||
export function valuesOfMap<T>(map: Map<T>): T[] {
|
||||
const values: T[] = [];
|
||||
map.forEach(value => {
|
||||
values.push(value);
|
||||
});
|
||||
return values;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if a Map<T> has some matching property.
|
||||
*
|
||||
* @param map A map whose properties should be tested.
|
||||
* @param predicate An optional callback used to test each property.
|
||||
* Calls `callback` for each entry in the map, returning the first defined result.
|
||||
* Use `map.forEach` instead for normal iteration.
|
||||
*/
|
||||
export function someProperties<T>(map: Map<T>, predicate?: (value: T, key: string) => boolean) {
|
||||
for (const key in map) {
|
||||
if (!predicate || predicate(map[key], key)) return true;
|
||||
export const forEachInMap: <T, U>(map: Map<T>, callback: (value: T, key: string) => U | undefined) => U | undefined = usingNativeMaps
|
||||
? <T, U>(map: ES6Map<T>, callback: (value: T, key: string) => U | undefined) => {
|
||||
const iterator = map.entries();
|
||||
while (true) {
|
||||
const { value: pair, done } = iterator.next();
|
||||
if (done) return undefined;
|
||||
const [key, value] = pair;
|
||||
const result = callback(value, key);
|
||||
if (result !== undefined) return result;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
: <T, U>(map: ShimMap<T>, callback: (value: T, key: string) => U | undefined) => map.forEachInMap(callback);
|
||||
|
||||
/**
|
||||
* Performs a shallow copy of the properties from a source Map<T> to a target MapLike<T>
|
||||
*
|
||||
* @param source A map from which properties should be copied.
|
||||
* @param target A map to which properties should be copied.
|
||||
*/
|
||||
export function copyProperties<T>(source: Map<T>, target: MapLike<T>): void {
|
||||
for (const key in source) {
|
||||
target[key] = source[key];
|
||||
/** `forEachInMap` for just keys. */
|
||||
export const forEachKeyInMap: <T>(map: Map<{}>, callback: (key: string) => T | undefined) => T | undefined = usingNativeMaps
|
||||
? <T>(map: ES6Map<T>, callback: (key: string) => T | undefined) => {
|
||||
const iterator = map.keys();
|
||||
while (true) {
|
||||
const { value: key, done } = iterator.next();
|
||||
if (done) return undefined;
|
||||
const result = callback(key);
|
||||
if (result !== undefined) return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
: <T>(map: ShimMap<T>, callback: (key: string) => T | undefined) => map.forEachKey(callback);
|
||||
|
||||
export function appendProperty<T>(map: Map<T>, key: string | number, value: T): Map<T> {
|
||||
if (key === undefined || value === undefined) return map;
|
||||
if (map === undefined) map = createMap<T>();
|
||||
map[key] = value;
|
||||
return map;
|
||||
/** Whether `predicate` is true for some entry in the map. */
|
||||
export const someInMap: <T>(map: Map<T>, predicate: (value: T, key: string) => boolean) => boolean = usingNativeMaps
|
||||
? <T>(map: ES6Map<T>, predicate: (value: T, key: string) => boolean) => {
|
||||
const iterator = map.entries();
|
||||
while (true) {
|
||||
const { value: pair, done } = iterator.next();
|
||||
if (done) return false;
|
||||
const [key, value] = pair;
|
||||
if (predicate(value, key)) return true;
|
||||
}
|
||||
}
|
||||
: <T>(map: ShimMap<T>, predicate: (value: T, key: string) => boolean) => map.some(predicate);
|
||||
|
||||
/** Whether `predicate` is true for some key in the map. */
|
||||
export const someKeyInMap: (map: Map<{}>, predicate: (key: string) => boolean) => boolean = usingNativeMaps
|
||||
? (map: ES6Map<{}>, predicate: (key: string) => boolean) => {
|
||||
const iterator = map.keys();
|
||||
while (true) {
|
||||
const { value: key, done } = iterator.next();
|
||||
if (done) return false;
|
||||
if (predicate(key)) return true;
|
||||
}
|
||||
}
|
||||
: (map: ShimMap<{}>, predicate: (key: string) => boolean) => map.someKey(predicate);
|
||||
|
||||
/** Copy entries from `source` to `target`. */
|
||||
export function copyMapEntries<T>(source: Map<T>, target: Map<T>): void {
|
||||
source.forEach((value, key) => {
|
||||
target.set(key, value);
|
||||
});
|
||||
}
|
||||
|
||||
export function assign<T1 extends MapLike<{}>, T2, T3>(t: T1, arg1: T2, arg2: T3): T1 & T2 & T3;
|
||||
@@ -845,24 +995,6 @@ namespace ts {
|
||||
return t;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reduce the properties of a map.
|
||||
*
|
||||
* NOTE: This is intended for use with Map<T> objects. For MapLike<T> objects, use
|
||||
* reduceOwnProperties instead as it offers better runtime safety.
|
||||
*
|
||||
* @param map The map to reduce
|
||||
* @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 {
|
||||
let result = initial;
|
||||
for (const key in map) {
|
||||
result = callback(result, map[key], String(key));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs a shallow equality comparison of the contents of two map-likes.
|
||||
*
|
||||
@@ -882,6 +1014,20 @@ namespace ts {
|
||||
return true;
|
||||
}
|
||||
|
||||
/** True if the maps have the same keys and values. */
|
||||
export function mapsAreEqual<T>(left: Map<T>, right: Map<T>, valuesAreEqual?: (left: T, right: T) => boolean): boolean {
|
||||
if (left === right) return true;
|
||||
if (!left || !right) return false;
|
||||
const someInLeftHasNoMatch = someInMap(left, (leftValue, leftKey) => {
|
||||
if (!right.has(leftKey)) return true;
|
||||
const rightValue = right.get(leftKey);
|
||||
return !(valuesAreEqual ? valuesAreEqual(leftValue, rightValue) : leftValue === rightValue);
|
||||
});
|
||||
if (someInLeftHasNoMatch) return false;
|
||||
const someInRightHasNoMatch = someKeyInMap(right, rightKey => !left.has(rightKey));
|
||||
return !someInRightHasNoMatch;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a map from the elements of an array.
|
||||
*
|
||||
@@ -897,23 +1043,18 @@ namespace ts {
|
||||
export function arrayToMap<T, U>(array: T[], makeKey: (value: T) => string, makeValue?: (value: T) => U): Map<T | U> {
|
||||
const result = createMap<T | U>();
|
||||
for (const value of array) {
|
||||
result[makeKey(value)] = makeValue ? makeValue(value) : value;
|
||||
result.set(makeKey(value), makeValue ? makeValue(value) : value);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
export function isEmpty<T>(map: Map<T>) {
|
||||
for (const id in map) {
|
||||
if (hasProperty(map, id)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
export const mapIsEmpty: (map: Map<{}>) => boolean = usingNativeMaps
|
||||
? (map: ES6Map<{}>) => map.size === 0
|
||||
: (map: ShimMap<{}>) => map.isEmpty();
|
||||
|
||||
export function cloneMap<T>(map: Map<T>) {
|
||||
const clone = createMap<T>();
|
||||
copyProperties(map, clone);
|
||||
copyMapEntries(map, clone);
|
||||
return clone;
|
||||
}
|
||||
|
||||
@@ -943,13 +1084,13 @@ namespace ts {
|
||||
* Creates the array if it does not already exist.
|
||||
*/
|
||||
export function multiMapAdd<V>(map: Map<V[]>, key: string | number, value: V): V[] {
|
||||
const values = map[key];
|
||||
const values = map.get(key);
|
||||
if (values) {
|
||||
values.push(value);
|
||||
return values;
|
||||
}
|
||||
else {
|
||||
return map[key] = [value];
|
||||
return set(map, key, [value]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -959,11 +1100,11 @@ namespace ts {
|
||||
* Does nothing if `key` is not in `map`, or `value` is not in `map[key]`.
|
||||
*/
|
||||
export function multiMapRemove<V>(map: Map<V[]>, key: string, value: V): void {
|
||||
const values = map[key];
|
||||
const values = map.get(key);
|
||||
if (values) {
|
||||
unorderedRemoveItem(values, value);
|
||||
if (!values.length) {
|
||||
delete map[key];
|
||||
map.delete(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1066,7 +1207,7 @@ namespace ts {
|
||||
return text.replace(/{(\d+)}/g, (_match, index?) => args[+index + baseIndex]);
|
||||
}
|
||||
|
||||
export let localizedDiagnosticMessages: Map<string> = undefined;
|
||||
export let localizedDiagnosticMessages: MapLike<string> = undefined;
|
||||
|
||||
export function getLocaleSpecificMessage(message: DiagnosticMessage) {
|
||||
return localizedDiagnosticMessages && localizedDiagnosticMessages[message.key] || message.message;
|
||||
|
||||
@@ -156,9 +156,9 @@ namespace ts {
|
||||
});
|
||||
|
||||
if (usedTypeDirectiveReferences) {
|
||||
for (const directive in usedTypeDirectiveReferences) {
|
||||
forEachKeyInMap(usedTypeDirectiveReferences, directive => {
|
||||
referencesOutput += `/// <reference types="${directive}" />${newLine}`;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
@@ -271,8 +271,8 @@ namespace ts {
|
||||
usedTypeDirectiveReferences = createMap<string>();
|
||||
}
|
||||
for (const directive of typeReferenceDirectives) {
|
||||
if (!(directive in usedTypeDirectiveReferences)) {
|
||||
usedTypeDirectiveReferences[directive] = directive;
|
||||
if (!usedTypeDirectiveReferences.has(directive)) {
|
||||
usedTypeDirectiveReferences.set(directive, directive);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -581,14 +581,14 @@ namespace ts {
|
||||
// do not need to keep track of created temp names.
|
||||
function getExportDefaultTempVariableName(): string {
|
||||
const baseName = "_default";
|
||||
if (!(baseName in currentIdentifiers)) {
|
||||
if (!currentIdentifiers.has(baseName)) {
|
||||
return baseName;
|
||||
}
|
||||
let count = 0;
|
||||
while (true) {
|
||||
count++;
|
||||
const name = baseName + "_" + count;
|
||||
if (!(name in currentIdentifiers)) {
|
||||
if (!currentIdentifiers.has(name)) {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2031,11 +2031,11 @@ namespace ts {
|
||||
// Skip the helper if it can be bundled but hasn't already been emitted and we
|
||||
// are emitting a bundled module.
|
||||
if (shouldBundle) {
|
||||
if (bundledHelpers[helper.name]) {
|
||||
if (bundledHelpers.get(helper.name)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
bundledHelpers[helper.name] = true;
|
||||
bundledHelpers.set(helper.name, true);
|
||||
}
|
||||
}
|
||||
else if (isBundle) {
|
||||
@@ -2487,15 +2487,16 @@ namespace ts {
|
||||
|
||||
function isUniqueName(name: string): boolean {
|
||||
return !resolver.hasGlobalName(name) &&
|
||||
!hasProperty(currentFileIdentifiers, name) &&
|
||||
!hasProperty(generatedNameSet, name);
|
||||
!currentFileIdentifiers.has(name) &&
|
||||
!generatedNameSet.has(name);
|
||||
}
|
||||
|
||||
function isUniqueLocalName(name: string, container: Node): boolean {
|
||||
for (let node = container; isNodeDescendantOf(node, container); node = node.nextContainer) {
|
||||
if (node.locals && hasProperty(node.locals, name)) {
|
||||
if (node.locals) {
|
||||
const local = node.locals.get(name);
|
||||
// We conservatively include alias symbols to cover cases where they're emitted as locals
|
||||
if (node.locals[name].flags & (SymbolFlags.Value | SymbolFlags.ExportValue | SymbolFlags.Alias)) {
|
||||
if (local && local.flags & (SymbolFlags.Value | SymbolFlags.ExportValue | SymbolFlags.Alias)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -2544,7 +2545,7 @@ namespace ts {
|
||||
while (true) {
|
||||
const generatedName = baseName + i;
|
||||
if (isUniqueName(generatedName)) {
|
||||
return generatedNameSet[generatedName] = generatedName;
|
||||
return set(generatedNameSet, generatedName, generatedName);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
+13
-15
@@ -2643,7 +2643,7 @@ namespace ts {
|
||||
|
||||
function mergeTokenSourceMapRanges(sourceRanges: Map<TextRange>, destRanges: Map<TextRange>) {
|
||||
if (!destRanges) destRanges = createMap<TextRange>();
|
||||
copyProperties(sourceRanges, destRanges);
|
||||
copyMapEntries(sourceRanges, destRanges);
|
||||
return destRanges;
|
||||
}
|
||||
|
||||
@@ -2745,7 +2745,7 @@ namespace ts {
|
||||
export function getTokenSourceMapRange(node: Node, token: SyntaxKind) {
|
||||
const emitNode = node.emitNode;
|
||||
const tokenSourceMapRanges = emitNode && emitNode.tokenSourceMapRanges;
|
||||
return tokenSourceMapRanges && tokenSourceMapRanges[token];
|
||||
return tokenSourceMapRanges && tokenSourceMapRanges.get(token);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2758,7 +2758,7 @@ namespace ts {
|
||||
export function setTokenSourceMapRange<T extends Node>(node: T, token: SyntaxKind, range: TextRange) {
|
||||
const emitNode = getOrCreateEmitNode(node);
|
||||
const tokenSourceMapRanges = emitNode.tokenSourceMapRanges || (emitNode.tokenSourceMapRanges = createMap<TextRange>());
|
||||
tokenSourceMapRanges[token] = range;
|
||||
tokenSourceMapRanges.set(token, range);
|
||||
return node;
|
||||
}
|
||||
|
||||
@@ -2969,10 +2969,8 @@ namespace ts {
|
||||
* Here we check if alternative name was provided for a given moduleName and return it if possible.
|
||||
*/
|
||||
function tryRenameExternalModule(moduleName: LiteralExpression, sourceFile: SourceFile) {
|
||||
if (sourceFile.renamedDependencies && hasProperty(sourceFile.renamedDependencies, moduleName.text)) {
|
||||
return createLiteral(sourceFile.renamedDependencies[moduleName.text]);
|
||||
}
|
||||
return undefined;
|
||||
const rename = sourceFile.renamedDependencies && sourceFile.renamedDependencies.get(moduleName.text);
|
||||
return rename && createLiteral(rename);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -3332,7 +3330,7 @@ namespace ts {
|
||||
else {
|
||||
// export { x, y }
|
||||
for (const specifier of (<ExportDeclaration>node).exportClause.elements) {
|
||||
if (!uniqueExports[specifier.name.text]) {
|
||||
if (!uniqueExports.get(specifier.name.text)) {
|
||||
const name = specifier.propertyName || specifier.name;
|
||||
multiMapAdd(exportSpecifiers, name.text, specifier);
|
||||
|
||||
@@ -3343,7 +3341,7 @@ namespace ts {
|
||||
multiMapAdd(exportedBindings, getOriginalNodeId(decl), specifier.name);
|
||||
}
|
||||
|
||||
uniqueExports[specifier.name.text] = true;
|
||||
uniqueExports.set(specifier.name.text, true);
|
||||
exportedNames = append(exportedNames, specifier.name);
|
||||
}
|
||||
}
|
||||
@@ -3377,9 +3375,9 @@ namespace ts {
|
||||
else {
|
||||
// export function x() { }
|
||||
const name = (<FunctionDeclaration>node).name;
|
||||
if (!uniqueExports[name.text]) {
|
||||
if (!uniqueExports.get(name.text)) {
|
||||
multiMapAdd(exportedBindings, getOriginalNodeId(node), name);
|
||||
uniqueExports[name.text] = true;
|
||||
uniqueExports.set(name.text, true);
|
||||
exportedNames = append(exportedNames, name);
|
||||
}
|
||||
}
|
||||
@@ -3398,9 +3396,9 @@ namespace ts {
|
||||
else {
|
||||
// export class x { }
|
||||
const name = (<ClassDeclaration>node).name;
|
||||
if (!uniqueExports[name.text]) {
|
||||
if (!uniqueExports.get(name.text)) {
|
||||
multiMapAdd(exportedBindings, getOriginalNodeId(node), name);
|
||||
uniqueExports[name.text] = true;
|
||||
uniqueExports.set(name.text, true);
|
||||
exportedNames = append(exportedNames, name);
|
||||
}
|
||||
}
|
||||
@@ -3421,8 +3419,8 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
else if (!isGeneratedIdentifier(decl.name)) {
|
||||
if (!uniqueExports[decl.name.text]) {
|
||||
uniqueExports[decl.name.text] = true;
|
||||
if (!uniqueExports.get(decl.name.text)) {
|
||||
uniqueExports.set(decl.name.text, true);
|
||||
exportedNames = append(exportedNames, decl.name);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1131,7 +1131,7 @@ namespace ts {
|
||||
|
||||
function internIdentifier(text: string): string {
|
||||
text = escapeIdentifier(text);
|
||||
return identifiers[text] || (identifiers[text] = text);
|
||||
return identifiers.get(text) || set(identifiers, text, text);
|
||||
}
|
||||
|
||||
// An identifier that starts with two underscores has an extra underscore character prepended to it to avoid issues
|
||||
|
||||
+10
-10
@@ -27,8 +27,8 @@ namespace ts.performance {
|
||||
*/
|
||||
export function mark(markName: string) {
|
||||
if (enabled) {
|
||||
marks[markName] = timestamp();
|
||||
counts[markName] = (counts[markName] || 0) + 1;
|
||||
marks.set(markName, timestamp());
|
||||
counts.set(markName, (counts.get(markName) || 0) + 1);
|
||||
profilerEvent(markName);
|
||||
}
|
||||
}
|
||||
@@ -44,9 +44,9 @@ namespace ts.performance {
|
||||
*/
|
||||
export function measure(measureName: string, startMarkName?: string, endMarkName?: string) {
|
||||
if (enabled) {
|
||||
const end = endMarkName && marks[endMarkName] || timestamp();
|
||||
const start = startMarkName && marks[startMarkName] || profilerStart;
|
||||
measures[measureName] = (measures[measureName] || 0) + (end - start);
|
||||
const end = endMarkName && marks.get(endMarkName) || timestamp();
|
||||
const start = startMarkName && marks.get(startMarkName) || profilerStart;
|
||||
measures.set(measureName, (measures.get(measureName) || 0) + (end - start));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,7 +56,7 @@ namespace ts.performance {
|
||||
* @param markName The name of the mark.
|
||||
*/
|
||||
export function getCount(markName: string) {
|
||||
return counts && counts[markName] || 0;
|
||||
return counts && counts.get(markName) || 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -65,7 +65,7 @@ namespace ts.performance {
|
||||
* @param measureName The name of the measure whose durations should be accumulated.
|
||||
*/
|
||||
export function getDuration(measureName: string) {
|
||||
return measures && measures[measureName] || 0;
|
||||
return measures && measures.get(measureName) || 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -74,9 +74,9 @@ namespace ts.performance {
|
||||
* @param cb The action to perform for each measure
|
||||
*/
|
||||
export function forEachMeasure(cb: (measureName: string, duration: number) => void) {
|
||||
for (const key in measures) {
|
||||
cb(key, measures[key]);
|
||||
}
|
||||
measures.forEach((measure, key) => {
|
||||
cb(key, measure);
|
||||
});
|
||||
}
|
||||
|
||||
/** Enables (and resets) performance measurements for the compiler. */
|
||||
|
||||
+22
-22
@@ -110,11 +110,11 @@ namespace ts {
|
||||
}
|
||||
|
||||
function directoryExists(directoryPath: string): boolean {
|
||||
if (directoryPath in existingDirectories) {
|
||||
if (existingDirectories.has(directoryPath)) {
|
||||
return true;
|
||||
}
|
||||
if (sys.directoryExists(directoryPath)) {
|
||||
existingDirectories[directoryPath] = true;
|
||||
existingDirectories.set(directoryPath, true);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -138,11 +138,11 @@ namespace ts {
|
||||
const hash = sys.createHash(data);
|
||||
const mtimeBefore = sys.getModifiedTime(fileName);
|
||||
|
||||
if (mtimeBefore && fileName in outputFingerprints) {
|
||||
const fingerprint = outputFingerprints[fileName];
|
||||
|
||||
if (mtimeBefore) {
|
||||
const fingerprint = outputFingerprints.get(fileName);
|
||||
// If output has not been changed, and the file has no external modification
|
||||
if (fingerprint.byteOrderMark === writeByteOrderMark &&
|
||||
if (fingerprint &&
|
||||
fingerprint.byteOrderMark === writeByteOrderMark &&
|
||||
fingerprint.hash === hash &&
|
||||
fingerprint.mtime.getTime() === mtimeBefore.getTime()) {
|
||||
return;
|
||||
@@ -153,11 +153,11 @@ namespace ts {
|
||||
|
||||
const mtimeAfter = sys.getModifiedTime(fileName);
|
||||
|
||||
outputFingerprints[fileName] = {
|
||||
outputFingerprints.set(fileName, {
|
||||
hash,
|
||||
byteOrderMark: writeByteOrderMark,
|
||||
mtime: mtimeAfter
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
function writeFile(fileName: string, data: string, writeByteOrderMark: boolean, onError?: (message: string) => void) {
|
||||
@@ -277,9 +277,9 @@ namespace ts {
|
||||
const resolutions: T[] = [];
|
||||
const cache = createMap<T>();
|
||||
for (const name of names) {
|
||||
const result = name in cache
|
||||
? cache[name]
|
||||
: cache[name] = loader(name, containingFile);
|
||||
const result = cache.has(name)
|
||||
? cache.get(name)
|
||||
: set(cache, name, loader(name, containingFile));
|
||||
resolutions.push(result);
|
||||
}
|
||||
return resolutions;
|
||||
@@ -454,7 +454,7 @@ namespace ts {
|
||||
classifiableNames = createMap<string>();
|
||||
|
||||
for (const sourceFile of files) {
|
||||
copyProperties(sourceFile.classifiableNames, classifiableNames);
|
||||
copyMapEntries(sourceFile.classifiableNames, classifiableNames);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -729,7 +729,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function isSourceFileFromExternalLibrary(file: SourceFile): boolean {
|
||||
return sourceFilesFoundSearchingNodeModules[file.path];
|
||||
return sourceFilesFoundSearchingNodeModules.get(file.path);
|
||||
}
|
||||
|
||||
function getDiagnosticsProducingTypeChecker() {
|
||||
@@ -1292,20 +1292,20 @@ namespace ts {
|
||||
|
||||
// If the file was previously found via a node_modules search, but is now being processed as a root file,
|
||||
// then everything it sucks in may also be marked incorrectly, and needs to be checked again.
|
||||
if (file && sourceFilesFoundSearchingNodeModules[file.path] && currentNodeModulesDepth == 0) {
|
||||
sourceFilesFoundSearchingNodeModules[file.path] = false;
|
||||
if (file && sourceFilesFoundSearchingNodeModules.get(file.path) && currentNodeModulesDepth == 0) {
|
||||
sourceFilesFoundSearchingNodeModules.set(file.path, false);
|
||||
if (!options.noResolve) {
|
||||
processReferencedFiles(file, isDefaultLib);
|
||||
processTypeReferenceDirectives(file);
|
||||
}
|
||||
|
||||
modulesWithElidedImports[file.path] = false;
|
||||
modulesWithElidedImports.set(file.path, false);
|
||||
processImportedModules(file);
|
||||
}
|
||||
// See if we need to reprocess the imports due to prior skipped imports
|
||||
else if (file && modulesWithElidedImports[file.path]) {
|
||||
else if (file && modulesWithElidedImports.get(file.path)) {
|
||||
if (currentNodeModulesDepth < maxNodeModuleJsDepth) {
|
||||
modulesWithElidedImports[file.path] = false;
|
||||
modulesWithElidedImports.set(file.path, false);
|
||||
processImportedModules(file);
|
||||
}
|
||||
}
|
||||
@@ -1326,7 +1326,7 @@ namespace ts {
|
||||
|
||||
filesByName.set(path, file);
|
||||
if (file) {
|
||||
sourceFilesFoundSearchingNodeModules[path] = (currentNodeModulesDepth > 0);
|
||||
sourceFilesFoundSearchingNodeModules.set(path, currentNodeModulesDepth > 0);
|
||||
file.path = path;
|
||||
|
||||
if (host.useCaseSensitiveFileNames()) {
|
||||
@@ -1387,7 +1387,7 @@ namespace ts {
|
||||
refFile?: SourceFile, refPos?: number, refEnd?: number): void {
|
||||
|
||||
// If we already found this library as a primary reference - nothing to do
|
||||
const previousResolution = resolvedTypeReferenceDirectives[typeReferenceDirective];
|
||||
const previousResolution = resolvedTypeReferenceDirectives.get(typeReferenceDirective);
|
||||
if (previousResolution && previousResolution.primary) {
|
||||
return;
|
||||
}
|
||||
@@ -1427,7 +1427,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
if (saveResolution) {
|
||||
resolvedTypeReferenceDirectives[typeReferenceDirective] = resolvedTypeReferenceDirective;
|
||||
resolvedTypeReferenceDirectives.set(typeReferenceDirective, resolvedTypeReferenceDirective);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1480,7 +1480,7 @@ namespace ts {
|
||||
const shouldAddFile = resolvedFileName && !getResolutionDiagnostic(options, resolution) && !options.noResolve && i < file.imports.length && !elideImport;
|
||||
|
||||
if (elideImport) {
|
||||
modulesWithElidedImports[file.path] = true;
|
||||
modulesWithElidedImports.set(file.path, true);
|
||||
}
|
||||
else if (shouldAddFile) {
|
||||
const path = toPath(resolvedFileName, currentDirectory, getCanonicalFileName);
|
||||
|
||||
@@ -275,9 +275,9 @@ namespace ts {
|
||||
|
||||
function makeReverseMap(source: Map<number>): string[] {
|
||||
const result: string[] = [];
|
||||
for (const name in source) {
|
||||
result[source[name]] = name;
|
||||
}
|
||||
source.forEach((value, name) => {
|
||||
result[value] = name;
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -289,7 +289,7 @@ namespace ts {
|
||||
|
||||
/* @internal */
|
||||
export function stringToToken(s: string): SyntaxKind {
|
||||
return textToToken[s];
|
||||
return textToToken.get(s);
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
@@ -363,8 +363,6 @@ namespace ts {
|
||||
return computeLineAndCharacterOfPosition(getLineStarts(sourceFile), position);
|
||||
}
|
||||
|
||||
const hasOwnProperty = Object.prototype.hasOwnProperty;
|
||||
|
||||
export function isWhiteSpace(ch: number): boolean {
|
||||
return isWhiteSpaceSingleLine(ch) || isLineBreak(ch);
|
||||
}
|
||||
@@ -1183,8 +1181,11 @@ namespace ts {
|
||||
const len = tokenValue.length;
|
||||
if (len >= 2 && len <= 11) {
|
||||
const ch = tokenValue.charCodeAt(0);
|
||||
if (ch >= CharacterCodes.a && ch <= CharacterCodes.z && hasOwnProperty.call(textToToken, tokenValue)) {
|
||||
return token = textToToken[tokenValue];
|
||||
if (ch >= CharacterCodes.a && ch <= CharacterCodes.z) {
|
||||
token = textToToken.get(tokenValue);
|
||||
if (token !== undefined) {
|
||||
return token;
|
||||
}
|
||||
}
|
||||
}
|
||||
return token = SyntaxKind.Identifier;
|
||||
|
||||
@@ -362,7 +362,7 @@ namespace ts {
|
||||
|
||||
const emitNode = node && node.emitNode;
|
||||
const emitFlags = emitNode && emitNode.flags;
|
||||
const range = emitNode && emitNode.tokenSourceMapRanges && emitNode.tokenSourceMapRanges[token];
|
||||
const range = emitNode && emitNode.tokenSourceMapRanges && emitNode.tokenSourceMapRanges.get(token);
|
||||
|
||||
tokenPos = skipTrivia(currentSourceText, range ? range.pos : tokenPos);
|
||||
if ((emitFlags & EmitFlags.NoTokenLeadingSourceMaps) === 0 && tokenPos >= 0) {
|
||||
|
||||
+11
-8
@@ -18,7 +18,7 @@ namespace ts {
|
||||
getFileSize?(path: string): number;
|
||||
writeFile(path: string, data: string, writeByteOrderMark?: boolean): void;
|
||||
/**
|
||||
* @pollingInterval - this parameter is used in polling-based watchers and ignored in watchers that
|
||||
* @pollingInterval - this parameter is used in polling-based watchers and ignored in watchers that
|
||||
* use native OS file watching
|
||||
*/
|
||||
watchFile?(path: string, callback: FileWatcherCallback, pollingInterval?: number): FileWatcher;
|
||||
@@ -248,18 +248,18 @@ namespace ts {
|
||||
|
||||
function reduceDirWatcherRefCountForFile(fileName: string) {
|
||||
const dirName = getDirectoryPath(fileName);
|
||||
const watcher = dirWatchers[dirName];
|
||||
const watcher = dirWatchers.get(dirName);
|
||||
if (watcher) {
|
||||
watcher.referenceCount -= 1;
|
||||
if (watcher.referenceCount <= 0) {
|
||||
watcher.close();
|
||||
delete dirWatchers[dirName];
|
||||
dirWatchers.delete(dirName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function addDirWatcher(dirPath: string): void {
|
||||
let watcher = dirWatchers[dirPath];
|
||||
let watcher = dirWatchers.get(dirPath);
|
||||
if (watcher) {
|
||||
watcher.referenceCount += 1;
|
||||
return;
|
||||
@@ -270,7 +270,7 @@ namespace ts {
|
||||
(eventName: string, relativeFileName: string) => fileEventHandler(eventName, relativeFileName, dirPath)
|
||||
);
|
||||
watcher.referenceCount = 1;
|
||||
dirWatchers[dirPath] = watcher;
|
||||
dirWatchers.set(dirPath, watcher);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -300,9 +300,12 @@ namespace ts {
|
||||
? undefined
|
||||
: ts.getNormalizedAbsolutePath(relativeFileName, baseDirPath);
|
||||
// Some applications save a working file via rename operations
|
||||
if ((eventName === "change" || eventName === "rename") && fileWatcherCallbacks[fileName]) {
|
||||
for (const fileCallback of fileWatcherCallbacks[fileName]) {
|
||||
fileCallback(fileName);
|
||||
if ((eventName === "change" || eventName === "rename")) {
|
||||
const callbacks = fileWatcherCallbacks.get(fileName);
|
||||
if (callbacks) {
|
||||
for (const fileCallback of callbacks) {
|
||||
fileCallback(fileName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,14 +13,14 @@
|
||||
|
||||
/* @internal */
|
||||
namespace ts {
|
||||
const moduleTransformerMap = createMap<Transformer>({
|
||||
[ModuleKind.ES2015]: transformES2015Module,
|
||||
[ModuleKind.System]: transformSystemModule,
|
||||
[ModuleKind.AMD]: transformModule,
|
||||
[ModuleKind.CommonJS]: transformModule,
|
||||
[ModuleKind.UMD]: transformModule,
|
||||
[ModuleKind.None]: transformModule,
|
||||
});
|
||||
const moduleTransformerMap = createMapFromPairs<Transformer>(
|
||||
[ModuleKind.ES2015, transformES2015Module],
|
||||
[ModuleKind.System, transformSystemModule],
|
||||
[ModuleKind.AMD, transformModule],
|
||||
[ModuleKind.CommonJS, transformModule],
|
||||
[ModuleKind.UMD, transformModule],
|
||||
[ModuleKind.None, transformModule],
|
||||
);
|
||||
|
||||
const enum SyntaxKindFeatureFlags {
|
||||
Substitution = 1 << 0,
|
||||
@@ -56,7 +56,7 @@ namespace ts {
|
||||
transformers.push(transformGenerators);
|
||||
}
|
||||
|
||||
transformers.push(moduleTransformerMap[moduleKind] || moduleTransformerMap[ModuleKind.None]);
|
||||
transformers.push(moduleTransformerMap.get(moduleKind) || moduleTransformerMap.get(ModuleKind.None));
|
||||
|
||||
// The ES5 transformer is last so that it can substitute expressions like `exports.default`
|
||||
// for ES3.
|
||||
|
||||
@@ -561,7 +561,7 @@ namespace ts {
|
||||
// - break/continue is non-labeled and located in non-converted loop/switch statement
|
||||
const jump = node.kind === SyntaxKind.BreakStatement ? Jump.Break : Jump.Continue;
|
||||
const canUseBreakOrContinue =
|
||||
(node.label && convertedLoopState.labels && convertedLoopState.labels[node.label.text]) ||
|
||||
(node.label && convertedLoopState.labels && convertedLoopState.labels.get(node.label.text)) ||
|
||||
(!node.label && (convertedLoopState.allowedNonLabeledJumps & jump));
|
||||
|
||||
if (!canUseBreakOrContinue) {
|
||||
@@ -1929,7 +1929,7 @@ namespace ts {
|
||||
if (!convertedLoopState.labels) {
|
||||
convertedLoopState.labels = createMap<string>();
|
||||
}
|
||||
convertedLoopState.labels[node.label.text] = node.label.text;
|
||||
convertedLoopState.labels.set(node.label.text, node.label.text);
|
||||
}
|
||||
|
||||
let result: VisitResult<Statement>;
|
||||
@@ -1941,7 +1941,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
if (convertedLoopState) {
|
||||
convertedLoopState.labels[node.label.text] = undefined;
|
||||
convertedLoopState.labels.set(node.label.text, undefined);
|
||||
}
|
||||
|
||||
return result;
|
||||
@@ -2548,13 +2548,13 @@ namespace ts {
|
||||
if (!state.labeledNonLocalBreaks) {
|
||||
state.labeledNonLocalBreaks = createMap<string>();
|
||||
}
|
||||
state.labeledNonLocalBreaks[labelText] = labelMarker;
|
||||
state.labeledNonLocalBreaks.set(labelText, labelMarker);
|
||||
}
|
||||
else {
|
||||
if (!state.labeledNonLocalContinues) {
|
||||
state.labeledNonLocalContinues = createMap<string>();
|
||||
}
|
||||
state.labeledNonLocalContinues[labelText] = labelMarker;
|
||||
state.labeledNonLocalContinues.set(labelText, labelMarker);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2562,13 +2562,12 @@ namespace ts {
|
||||
if (!table) {
|
||||
return;
|
||||
}
|
||||
for (const labelText in table) {
|
||||
const labelMarker = table[labelText];
|
||||
table.forEach((labelMarker, labelText) => {
|
||||
const statements: Statement[] = [];
|
||||
// if there are no outer converted loop or outer label in question is located inside outer converted loop
|
||||
// then emit labeled break\continue
|
||||
// otherwise propagate pair 'label -> marker' to outer converted loop and emit 'return labelMarker' so outer loop can later decide what to do
|
||||
if (!outerLoop || (outerLoop.labels && outerLoop.labels[labelText])) {
|
||||
if (!outerLoop || (outerLoop.labels && outerLoop.labels.get(labelText))) {
|
||||
const label = createIdentifier(labelText);
|
||||
statements.push(isBreak ? createBreak(label) : createContinue(label));
|
||||
}
|
||||
@@ -2577,7 +2576,7 @@ namespace ts {
|
||||
statements.push(createReturn(loopResultName));
|
||||
}
|
||||
caseClauses.push(createCaseClause(createLiteral(labelMarker), statements));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function processLoopVariableDeclaration(decl: VariableDeclaration | BindingElement, loopParameters: ParameterDeclaration[], loopOutParameters: LoopOutParameter[]) {
|
||||
|
||||
@@ -217,13 +217,13 @@ namespace ts {
|
||||
Endfinally = 7,
|
||||
}
|
||||
|
||||
const instructionNames = createMap<string>({
|
||||
[Instruction.Return]: "return",
|
||||
[Instruction.Break]: "break",
|
||||
[Instruction.Yield]: "yield",
|
||||
[Instruction.YieldStar]: "yield*",
|
||||
[Instruction.Endfinally]: "endfinally",
|
||||
});
|
||||
const instructionNames = createMapFromPairs<string>(
|
||||
[Instruction.Return, "return"],
|
||||
[Instruction.Break, "break"],
|
||||
[Instruction.Yield, "yield"],
|
||||
[Instruction.YieldStar, "yield*"],
|
||||
[Instruction.Endfinally, "endfinally"],
|
||||
);
|
||||
|
||||
export function transformGenerators(context: TransformationContext) {
|
||||
const {
|
||||
@@ -1921,12 +1921,12 @@ namespace ts {
|
||||
}
|
||||
|
||||
function substituteExpressionIdentifier(node: Identifier) {
|
||||
if (renamedCatchVariables && hasProperty(renamedCatchVariables, node.text)) {
|
||||
if (renamedCatchVariables && renamedCatchVariables.has(node.text)) {
|
||||
const original = getOriginalNode(node);
|
||||
if (isIdentifier(original) && original.parent) {
|
||||
const declaration = resolver.getReferencedValueDeclaration(original);
|
||||
if (declaration) {
|
||||
const name = getProperty(renamedCatchVariableDeclarations, String(getOriginalNodeId(declaration)));
|
||||
const name = renamedCatchVariableDeclarations.get(getOriginalNodeId(declaration));
|
||||
if (name) {
|
||||
const clone = getMutableClone(name);
|
||||
setSourceMapRange(clone, node);
|
||||
@@ -2096,8 +2096,8 @@ namespace ts {
|
||||
context.enableSubstitution(SyntaxKind.Identifier);
|
||||
}
|
||||
|
||||
renamedCatchVariables[text] = true;
|
||||
renamedCatchVariableDeclarations[getOriginalNodeId(variable)] = name;
|
||||
renamedCatchVariables.set(text, true);
|
||||
renamedCatchVariableDeclarations.set(getOriginalNodeId(variable), name);
|
||||
|
||||
const exception = <ExceptionBlock>peekBlock();
|
||||
Debug.assert(exception.state < ExceptionBlockState.Catch);
|
||||
@@ -2401,7 +2401,7 @@ namespace ts {
|
||||
*/
|
||||
function createInstruction(instruction: Instruction): NumericLiteral {
|
||||
const literal = createLiteral(instruction);
|
||||
literal.trailingComment = instructionNames[instruction];
|
||||
literal.trailingComment = instructionNames.get(instruction);
|
||||
return literal;
|
||||
}
|
||||
|
||||
|
||||
@@ -229,7 +229,7 @@ namespace ts {
|
||||
return String.fromCharCode(parseInt(hex, 16));
|
||||
}
|
||||
else {
|
||||
const ch = entities[word];
|
||||
const ch = entities.get(word);
|
||||
// If this is not a valid entity, then just use `match` (replace it with itself, i.e. don't replace)
|
||||
return ch ? String.fromCharCode(ch) : match;
|
||||
}
|
||||
|
||||
@@ -10,12 +10,12 @@ namespace ts {
|
||||
importAliasNames: ParameterDeclaration[];
|
||||
}
|
||||
|
||||
const transformModuleDelegates = createMap<(node: SourceFile) => SourceFile>({
|
||||
[ModuleKind.None]: transformCommonJSModule,
|
||||
[ModuleKind.CommonJS]: transformCommonJSModule,
|
||||
[ModuleKind.AMD]: transformAMDModule,
|
||||
[ModuleKind.UMD]: transformUMDModule,
|
||||
});
|
||||
const transformModuleDelegates = createMapFromPairs<(node: SourceFile) => SourceFile>(
|
||||
[ModuleKind.None, transformCommonJSModule],
|
||||
[ModuleKind.CommonJS, transformCommonJSModule],
|
||||
[ModuleKind.AMD, transformAMDModule],
|
||||
[ModuleKind.UMD, transformUMDModule],
|
||||
);
|
||||
|
||||
const {
|
||||
startLexicalEnvironment,
|
||||
@@ -60,10 +60,10 @@ namespace ts {
|
||||
}
|
||||
|
||||
currentSourceFile = node;
|
||||
currentModuleInfo = moduleInfoMap[getOriginalNodeId(node)] = collectExternalModuleInfo(node, resolver, compilerOptions);
|
||||
currentModuleInfo = set(moduleInfoMap, getOriginalNodeId(node), collectExternalModuleInfo(node, resolver, compilerOptions));
|
||||
|
||||
// Perform the transformation.
|
||||
const transformModule = transformModuleDelegates[moduleKind] || transformModuleDelegates[ModuleKind.None];
|
||||
const transformModule = transformModuleDelegates.get(moduleKind) || transformModuleDelegates.get(ModuleKind.None);
|
||||
const updated = transformModule(node);
|
||||
|
||||
currentSourceFile = undefined;
|
||||
@@ -444,7 +444,7 @@ namespace ts {
|
||||
if (hasAssociatedEndOfDeclarationMarker(node)) {
|
||||
// Defer exports until we encounter an EndOfDeclarationMarker node
|
||||
const id = getOriginalNodeId(node);
|
||||
deferredExports[id] = appendExportsOfImportDeclaration(deferredExports[id], node);
|
||||
deferredExports.set(id, appendExportsOfImportDeclaration(deferredExports.get(id), node));
|
||||
}
|
||||
else {
|
||||
statements = appendExportsOfImportDeclaration(statements, node);
|
||||
@@ -523,7 +523,7 @@ namespace ts {
|
||||
if (hasAssociatedEndOfDeclarationMarker(node)) {
|
||||
// Defer exports until we encounter an EndOfDeclarationMarker node
|
||||
const id = getOriginalNodeId(node);
|
||||
deferredExports[id] = appendExportsOfImportEqualsDeclaration(deferredExports[id], node);
|
||||
deferredExports.set(id, appendExportsOfImportEqualsDeclaration(deferredExports.get(id), node));
|
||||
}
|
||||
else {
|
||||
statements = appendExportsOfImportEqualsDeclaration(statements, node);
|
||||
@@ -610,7 +610,7 @@ namespace ts {
|
||||
if (original && hasAssociatedEndOfDeclarationMarker(original)) {
|
||||
// Defer exports until we encounter an EndOfDeclarationMarker node
|
||||
const id = getOriginalNodeId(node);
|
||||
deferredExports[id] = appendExportStatement(deferredExports[id], createIdentifier("default"), node.expression, /*location*/ node, /*allowComments*/ true);
|
||||
deferredExports.set(id, appendExportStatement(deferredExports.get(id), createIdentifier("default"), node.expression, /*location*/ node, /*allowComments*/ true));
|
||||
}
|
||||
else {
|
||||
statements = appendExportStatement(statements, createIdentifier("default"), node.expression, /*location*/ node, /*allowComments*/ true);
|
||||
@@ -651,7 +651,7 @@ namespace ts {
|
||||
if (hasAssociatedEndOfDeclarationMarker(node)) {
|
||||
// Defer exports until we encounter an EndOfDeclarationMarker node
|
||||
const id = getOriginalNodeId(node);
|
||||
deferredExports[id] = appendExportsOfHoistedDeclaration(deferredExports[id], node);
|
||||
deferredExports.set(id, appendExportsOfHoistedDeclaration(deferredExports.get(id), node));
|
||||
}
|
||||
else {
|
||||
statements = appendExportsOfHoistedDeclaration(statements, node);
|
||||
@@ -690,7 +690,7 @@ namespace ts {
|
||||
if (hasAssociatedEndOfDeclarationMarker(node)) {
|
||||
// Defer exports until we encounter an EndOfDeclarationMarker node
|
||||
const id = getOriginalNodeId(node);
|
||||
deferredExports[id] = appendExportsOfHoistedDeclaration(deferredExports[id], node);
|
||||
deferredExports.set(id, appendExportsOfHoistedDeclaration(deferredExports.get(id), node));
|
||||
}
|
||||
else {
|
||||
statements = appendExportsOfHoistedDeclaration(statements, node);
|
||||
@@ -741,7 +741,7 @@ namespace ts {
|
||||
if (hasAssociatedEndOfDeclarationMarker(node)) {
|
||||
// Defer exports until we encounter an EndOfDeclarationMarker node
|
||||
const id = getOriginalNodeId(node);
|
||||
deferredExports[id] = appendExportsOfVariableStatement(deferredExports[id], node);
|
||||
deferredExports.set(id, appendExportsOfVariableStatement(deferredExports.get(id), node));
|
||||
}
|
||||
else {
|
||||
statements = appendExportsOfVariableStatement(statements, node);
|
||||
@@ -794,7 +794,7 @@ namespace ts {
|
||||
// statement.
|
||||
if (hasAssociatedEndOfDeclarationMarker(node) && node.original.kind === SyntaxKind.VariableStatement) {
|
||||
const id = getOriginalNodeId(node);
|
||||
deferredExports[id] = appendExportsOfVariableStatement(deferredExports[id], <VariableStatement>node.original);
|
||||
deferredExports.set(id, appendExportsOfVariableStatement(deferredExports.get(id), <VariableStatement>node.original));
|
||||
}
|
||||
|
||||
return node;
|
||||
@@ -820,9 +820,9 @@ namespace ts {
|
||||
// end of the transformed declaration. We use this marker to emit any deferred exports
|
||||
// of the declaration.
|
||||
const id = getOriginalNodeId(node);
|
||||
const statements = deferredExports[id];
|
||||
const statements = deferredExports.get(id);
|
||||
if (statements) {
|
||||
delete deferredExports[id];
|
||||
deferredExports.delete(id);
|
||||
return append(statements, node);
|
||||
}
|
||||
|
||||
@@ -973,7 +973,7 @@ namespace ts {
|
||||
*/
|
||||
function appendExportsOfDeclaration(statements: Statement[] | undefined, decl: Declaration): Statement[] | undefined {
|
||||
const name = getDeclarationName(decl);
|
||||
const exportSpecifiers = currentModuleInfo.exportSpecifiers[name.text];
|
||||
const exportSpecifiers = currentModuleInfo.exportSpecifiers.get(name.text);
|
||||
if (exportSpecifiers) {
|
||||
for (const exportSpecifier of exportSpecifiers) {
|
||||
statements = appendExportStatement(statements, exportSpecifier.name, name, /*location*/ exportSpecifier.name);
|
||||
@@ -997,7 +997,7 @@ namespace ts {
|
||||
function appendExportStatement(statements: Statement[] | undefined, exportName: Identifier, expression: Expression, location?: TextRange, allowComments?: boolean): Statement[] | undefined {
|
||||
if (exportName.text === "default") {
|
||||
const sourceFile = getOriginalNode(currentSourceFile, isSourceFile);
|
||||
if (sourceFile && !sourceFile.symbol.exports["___esModule"]) {
|
||||
if (sourceFile && !sourceFile.symbol.exports.get("___esModule")) {
|
||||
if (languageVersion === ScriptTarget.ES3) {
|
||||
statements = append(statements,
|
||||
createStatement(
|
||||
@@ -1102,7 +1102,7 @@ namespace ts {
|
||||
function onEmitNode(emitContext: EmitContext, node: Node, emitCallback: (emitContext: EmitContext, node: Node) => void): void {
|
||||
if (node.kind === SyntaxKind.SourceFile) {
|
||||
currentSourceFile = <SourceFile>node;
|
||||
currentModuleInfo = moduleInfoMap[getOriginalNodeId(currentSourceFile)];
|
||||
currentModuleInfo = moduleInfoMap.get(getOriginalNodeId(currentSourceFile));
|
||||
noSubstitution = createMap<boolean>();
|
||||
|
||||
previousOnEmitNode(emitContext, node, emitCallback);
|
||||
@@ -1128,7 +1128,7 @@ namespace ts {
|
||||
*/
|
||||
function onSubstituteNode(emitContext: EmitContext, node: Node) {
|
||||
node = previousOnSubstituteNode(emitContext, node);
|
||||
if (node.id && noSubstitution[node.id]) {
|
||||
if (node.id && noSubstitution.get(node.id)) {
|
||||
return node;
|
||||
}
|
||||
|
||||
@@ -1254,7 +1254,7 @@ namespace ts {
|
||||
let expression: Expression = node;
|
||||
for (const exportName of exportedNames) {
|
||||
// Mark the node to prevent triggering this rule again.
|
||||
noSubstitution[getNodeId(expression)] = true;
|
||||
noSubstitution.set(getNodeId(expression), true);
|
||||
expression = createExportExpression(exportName, expression, /*location*/ node);
|
||||
}
|
||||
|
||||
@@ -1296,7 +1296,7 @@ namespace ts {
|
||||
: node;
|
||||
for (const exportName of exportedNames) {
|
||||
// Mark the node to prevent triggering this rule again.
|
||||
noSubstitution[getNodeId(expression)] = true;
|
||||
noSubstitution.set(getNodeId(expression), true);
|
||||
expression = createExportExpression(exportName, expression);
|
||||
}
|
||||
|
||||
@@ -1318,7 +1318,7 @@ namespace ts {
|
||||
|| resolver.getReferencedValueDeclaration(name);
|
||||
if (valueDeclaration) {
|
||||
return currentModuleInfo
|
||||
&& currentModuleInfo.exportedBindings[getOriginalNodeId(valueDeclaration)];
|
||||
&& currentModuleInfo.exportedBindings.get(getOriginalNodeId(valueDeclaration));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,11 +73,11 @@ namespace ts {
|
||||
// see comment to 'substitutePostfixUnaryExpression' for more details
|
||||
|
||||
// Collect information about the external module and dependency groups.
|
||||
moduleInfo = moduleInfoMap[id] = collectExternalModuleInfo(node, resolver, compilerOptions);
|
||||
moduleInfo = set(moduleInfoMap, id, collectExternalModuleInfo(node, resolver, compilerOptions));
|
||||
|
||||
// Make sure that the name of the 'exports' function does not conflict with
|
||||
// existing identifiers.
|
||||
exportFunction = exportFunctionsMap[id] = createUniqueName("exports");
|
||||
exportFunction = set(exportFunctionsMap, id, createUniqueName("exports"));
|
||||
contextObject = createUniqueName("context");
|
||||
|
||||
// Add the body of the module.
|
||||
@@ -121,7 +121,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
if (noSubstitution) {
|
||||
noSubstitutionMap[id] = noSubstitution;
|
||||
noSubstitutionMap.set(id, noSubstitution);
|
||||
noSubstitution = undefined;
|
||||
}
|
||||
|
||||
@@ -147,13 +147,13 @@ namespace ts {
|
||||
const externalImport = externalImports[i];
|
||||
const externalModuleName = getExternalModuleNameLiteral(externalImport, currentSourceFile, host, resolver, compilerOptions);
|
||||
const text = externalModuleName.text;
|
||||
if (hasProperty(groupIndices, text)) {
|
||||
const groupIndex = groupIndices.get(text);
|
||||
if (groupIndex !== undefined) {
|
||||
// deduplicate/group entries in dependency list by the dependency name
|
||||
const groupIndex = groupIndices[text];
|
||||
dependencyGroups[groupIndex].externalImports.push(externalImport);
|
||||
}
|
||||
else {
|
||||
groupIndices[text] = dependencyGroups.length;
|
||||
groupIndices.set(text, dependencyGroups.length);
|
||||
dependencyGroups.push({
|
||||
name: externalModuleName,
|
||||
externalImports: [externalImport]
|
||||
@@ -305,7 +305,7 @@ namespace ts {
|
||||
// this set is used to filter names brought by star expors.
|
||||
|
||||
// local names set should only be added if we have anything exported
|
||||
if (!moduleInfo.exportedNames && isEmpty(moduleInfo.exportSpecifiers)) {
|
||||
if (!moduleInfo.exportedNames && mapIsEmpty(moduleInfo.exportSpecifiers)) {
|
||||
// no exported declarations (export var ...) or export specifiers (export {x})
|
||||
// check if we have any non star export declarations.
|
||||
let hasExportDeclarationWithExportClause = false;
|
||||
@@ -608,7 +608,7 @@ namespace ts {
|
||||
if (hasAssociatedEndOfDeclarationMarker(node)) {
|
||||
// Defer exports until we encounter an EndOfDeclarationMarker node
|
||||
const id = getOriginalNodeId(node);
|
||||
deferredExports[id] = appendExportsOfImportDeclaration(deferredExports[id], node);
|
||||
deferredExports.set(id, appendExportsOfImportDeclaration(deferredExports.get(id), node));
|
||||
}
|
||||
else {
|
||||
statements = appendExportsOfImportDeclaration(statements, node);
|
||||
@@ -631,7 +631,7 @@ namespace ts {
|
||||
if (hasAssociatedEndOfDeclarationMarker(node)) {
|
||||
// Defer exports until we encounter an EndOfDeclarationMarker node
|
||||
const id = getOriginalNodeId(node);
|
||||
deferredExports[id] = appendExportsOfImportEqualsDeclaration(deferredExports[id], node);
|
||||
deferredExports.set(id, appendExportsOfImportEqualsDeclaration(deferredExports.get(id), node));
|
||||
}
|
||||
else {
|
||||
statements = appendExportsOfImportEqualsDeclaration(statements, node);
|
||||
@@ -656,7 +656,7 @@ namespace ts {
|
||||
if (original && hasAssociatedEndOfDeclarationMarker(original)) {
|
||||
// Defer exports until we encounter an EndOfDeclarationMarker node
|
||||
const id = getOriginalNodeId(node);
|
||||
deferredExports[id] = appendExportStatement(deferredExports[id], createIdentifier("default"), expression, /*allowComments*/ true);
|
||||
deferredExports.set(id, appendExportStatement(deferredExports.get(id), createIdentifier("default"), expression, /*allowComments*/ true));
|
||||
}
|
||||
else {
|
||||
return createExportStatement(createIdentifier("default"), expression, /*allowComments*/ true);
|
||||
@@ -688,7 +688,7 @@ namespace ts {
|
||||
if (hasAssociatedEndOfDeclarationMarker(node)) {
|
||||
// Defer exports until we encounter an EndOfDeclarationMarker node
|
||||
const id = getOriginalNodeId(node);
|
||||
deferredExports[id] = appendExportsOfHoistedDeclaration(deferredExports[id], node);
|
||||
deferredExports.set(id, appendExportsOfHoistedDeclaration(deferredExports.get(id), node));
|
||||
}
|
||||
else {
|
||||
hoistedStatements = appendExportsOfHoistedDeclaration(hoistedStatements, node);
|
||||
@@ -730,7 +730,7 @@ namespace ts {
|
||||
if (hasAssociatedEndOfDeclarationMarker(node)) {
|
||||
// Defer exports until we encounter an EndOfDeclarationMarker node
|
||||
const id = getOriginalNodeId(node);
|
||||
deferredExports[id] = appendExportsOfHoistedDeclaration(deferredExports[id], node);
|
||||
deferredExports.set(id, appendExportsOfHoistedDeclaration(deferredExports.get(id), node));
|
||||
}
|
||||
else {
|
||||
statements = appendExportsOfHoistedDeclaration(statements, node);
|
||||
@@ -770,7 +770,7 @@ namespace ts {
|
||||
if (isMarkedDeclaration) {
|
||||
// Defer exports until we encounter an EndOfDeclarationMarker node
|
||||
const id = getOriginalNodeId(node);
|
||||
deferredExports[id] = appendExportsOfVariableStatement(deferredExports[id], node, isExportedDeclaration);
|
||||
deferredExports.set(id, appendExportsOfVariableStatement(deferredExports.get(id), node, isExportedDeclaration));
|
||||
}
|
||||
else {
|
||||
statements = appendExportsOfVariableStatement(statements, node, /*exportSelf*/ false);
|
||||
@@ -883,7 +883,7 @@ namespace ts {
|
||||
if (hasAssociatedEndOfDeclarationMarker(node) && node.original.kind === SyntaxKind.VariableStatement) {
|
||||
const id = getOriginalNodeId(node);
|
||||
const isExportedDeclaration = hasModifier(node.original, ModifierFlags.Export);
|
||||
deferredExports[id] = appendExportsOfVariableStatement(deferredExports[id], <VariableStatement>node.original, isExportedDeclaration);
|
||||
deferredExports.set(id, appendExportsOfVariableStatement(deferredExports.get(id), <VariableStatement>node.original, isExportedDeclaration));
|
||||
}
|
||||
|
||||
return node;
|
||||
@@ -909,9 +909,9 @@ namespace ts {
|
||||
// end of the transformed declaration. We use this marker to emit any deferred exports
|
||||
// of the declaration.
|
||||
const id = getOriginalNodeId(node);
|
||||
const statements = deferredExports[id];
|
||||
const statements = deferredExports.get(id);
|
||||
if (statements) {
|
||||
delete deferredExports[id];
|
||||
deferredExports.delete(id);
|
||||
return append(statements, node);
|
||||
}
|
||||
|
||||
@@ -1080,7 +1080,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
const name = getDeclarationName(decl);
|
||||
const exportSpecifiers = moduleInfo.exportSpecifiers[name.text];
|
||||
const exportSpecifiers = moduleInfo.exportSpecifiers.get(name.text);
|
||||
if (exportSpecifiers) {
|
||||
for (const exportSpecifier of exportSpecifiers) {
|
||||
if (exportSpecifier.name.text !== excludeName) {
|
||||
@@ -1554,12 +1554,12 @@ namespace ts {
|
||||
if (node.kind === SyntaxKind.SourceFile) {
|
||||
const id = getOriginalNodeId(node);
|
||||
currentSourceFile = <SourceFile>node;
|
||||
moduleInfo = moduleInfoMap[id];
|
||||
exportFunction = exportFunctionsMap[id];
|
||||
noSubstitution = noSubstitutionMap[id];
|
||||
moduleInfo = moduleInfoMap.get(id);
|
||||
exportFunction = exportFunctionsMap.get(id);
|
||||
noSubstitution = noSubstitutionMap.get(id);
|
||||
|
||||
if (noSubstitution) {
|
||||
delete noSubstitutionMap[id];
|
||||
noSubstitutionMap.delete(id);
|
||||
}
|
||||
|
||||
previousOnEmitNode(emitContext, node, emitCallback);
|
||||
@@ -1756,7 +1756,7 @@ namespace ts {
|
||||
exportedNames = append(exportedNames, getDeclarationName(valueDeclaration));
|
||||
}
|
||||
|
||||
exportedNames = addRange(exportedNames, moduleInfo && moduleInfo.exportedBindings[getOriginalNodeId(valueDeclaration)]);
|
||||
exportedNames = addRange(exportedNames, moduleInfo && moduleInfo.exportedBindings.get(getOriginalNodeId(valueDeclaration)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1770,7 +1770,7 @@ namespace ts {
|
||||
*/
|
||||
function preventSubstitution<T extends Node>(node: T): T {
|
||||
if (noSubstitution === undefined) noSubstitution = createMap<boolean>();
|
||||
noSubstitution[getNodeId(node)] = true;
|
||||
noSubstitution.set(getNodeId(node), true);
|
||||
return node;
|
||||
}
|
||||
|
||||
@@ -1780,7 +1780,7 @@ namespace ts {
|
||||
* @param node The node to test.
|
||||
*/
|
||||
function isSubstitutionPrevented(node: Node) {
|
||||
return noSubstitution && node.id && noSubstitution[node.id];
|
||||
return noSubstitution && node.id && noSubstitution.get(node.id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -752,7 +752,7 @@ namespace ts {
|
||||
if (resolver.getNodeCheckFlags(node) & NodeCheckFlags.ClassWithConstructorReference) {
|
||||
// record an alias as the class name is not in scope for statics.
|
||||
enableSubstitutionForClassAliases();
|
||||
classAliases[getOriginalNodeId(node)] = getSynthesizedClone(temp);
|
||||
classAliases.set(getOriginalNodeId(node), getSynthesizedClone(temp));
|
||||
}
|
||||
|
||||
// To preserve the behavior of the old emitter, we explicitly indent
|
||||
@@ -1420,7 +1420,7 @@ namespace ts {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const classAlias = classAliases && classAliases[getOriginalNodeId(node)];
|
||||
const classAlias = classAliases && classAliases.get(getOriginalNodeId(node));
|
||||
const localName = getLocalName(node, /*allowComments*/ false, /*allowSourceMaps*/ true);
|
||||
const decorate = createDecorateHelper(context, decoratorExpressions, localName);
|
||||
const expression = createAssignment(localName, classAlias ? createAssignment(classAlias, decorate) : decorate);
|
||||
@@ -2530,8 +2530,8 @@ namespace ts {
|
||||
currentScopeFirstDeclarationsOfName = createMap<Node>();
|
||||
}
|
||||
|
||||
if (!(name in currentScopeFirstDeclarationsOfName)) {
|
||||
currentScopeFirstDeclarationsOfName[name] = node;
|
||||
if (!currentScopeFirstDeclarationsOfName.has(name)) {
|
||||
currentScopeFirstDeclarationsOfName.set(name, node);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2544,7 +2544,7 @@ namespace ts {
|
||||
if (currentScopeFirstDeclarationsOfName) {
|
||||
const name = node.symbol && node.symbol.name;
|
||||
if (name) {
|
||||
return currentScopeFirstDeclarationsOfName[name] === node;
|
||||
return currentScopeFirstDeclarationsOfName.get(name) === node;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3085,7 +3085,7 @@ namespace ts {
|
||||
if (resolver.getNodeCheckFlags(node) & NodeCheckFlags.ClassWithConstructorReference) {
|
||||
enableSubstitutionForClassAliases();
|
||||
const classAlias = createUniqueName(node.name && !isGeneratedIdentifier(node.name) ? node.name.text : "default");
|
||||
classAliases[getOriginalNodeId(node)] = classAlias;
|
||||
classAliases.set(getOriginalNodeId(node), classAlias);
|
||||
hoistVariableDeclaration(classAlias);
|
||||
return classAlias;
|
||||
}
|
||||
@@ -3230,7 +3230,7 @@ namespace ts {
|
||||
// constructor references in static property initializers.
|
||||
const declaration = resolver.getReferencedValueDeclaration(node);
|
||||
if (declaration) {
|
||||
const classAlias = classAliases[declaration.id];
|
||||
const classAlias = classAliases.get(declaration.id);
|
||||
if (classAlias) {
|
||||
const clone = getSynthesizedClone(classAlias);
|
||||
setSourceMapRange(clone, node);
|
||||
|
||||
+10
-15
@@ -67,11 +67,11 @@ namespace ts {
|
||||
const gutterSeparator = " ";
|
||||
const resetEscapeSequence = "\u001b[0m";
|
||||
const ellipsis = "...";
|
||||
const categoryFormatMap = createMap<string>({
|
||||
[DiagnosticCategory.Warning]: yellowForegroundEscapeSequence,
|
||||
[DiagnosticCategory.Error]: redForegroundEscapeSequence,
|
||||
[DiagnosticCategory.Message]: blueForegroundEscapeSequence,
|
||||
});
|
||||
const categoryFormatMap = createMapFromPairs<string>(
|
||||
[DiagnosticCategory.Warning, yellowForegroundEscapeSequence],
|
||||
[DiagnosticCategory.Error, redForegroundEscapeSequence],
|
||||
[DiagnosticCategory.Message, blueForegroundEscapeSequence],
|
||||
);
|
||||
|
||||
function formatAndReset(text: string, formatStyle: string) {
|
||||
return formatStyle + text + resetEscapeSequence;
|
||||
@@ -139,7 +139,7 @@ namespace ts {
|
||||
output += `${ relativeFileName }(${ firstLine + 1 },${ firstLineChar + 1 }): `;
|
||||
}
|
||||
|
||||
const categoryColor = categoryFormatMap[diagnostic.category];
|
||||
const categoryColor = categoryFormatMap.get(diagnostic.category);
|
||||
const category = DiagnosticCategory[diagnostic.category].toLowerCase();
|
||||
output += `${ formatAndReset(category, categoryColor) } TS${ diagnostic.code }: ${ flattenDiagnosticMessageText(diagnostic.messageText, sys.newLine) }`;
|
||||
output += sys.newLine + sys.newLine;
|
||||
@@ -378,9 +378,8 @@ namespace ts {
|
||||
}
|
||||
|
||||
function cachedFileExists(fileName: string): boolean {
|
||||
return fileName in cachedExistingFiles
|
||||
? cachedExistingFiles[fileName]
|
||||
: cachedExistingFiles[fileName] = hostFileExists(fileName);
|
||||
const fileExists = cachedExistingFiles.get(fileName);
|
||||
return fileExists !== undefined ? fileExists : set(cachedExistingFiles, fileName, hostFileExists(fileName));
|
||||
}
|
||||
|
||||
function getSourceFile(fileName: string, languageVersion: ScriptTarget, onError?: (message: string) => void) {
|
||||
@@ -674,13 +673,9 @@ namespace ts {
|
||||
|
||||
if (option.name === "lib") {
|
||||
description = getDiagnosticText(option.description);
|
||||
const options: string[] = [];
|
||||
const element = (<CommandLineOptionOfListType>option).element;
|
||||
const typeMap = <Map<number | string>>element.type;
|
||||
for (const key in typeMap) {
|
||||
options.push(`'${key}'`);
|
||||
}
|
||||
optionsDescriptionMap[description] = options;
|
||||
optionsDescriptionMap.set(description, keysOfMap(typeMap).map(key => `'${key}'`));
|
||||
}
|
||||
else {
|
||||
description = getDiagnosticText(option.description);
|
||||
@@ -702,7 +697,7 @@ namespace ts {
|
||||
for (let i = 0; i < usageColumn.length; i++) {
|
||||
const usage = usageColumn[i];
|
||||
const description = descriptionColumn[i];
|
||||
const kindsList = optionsDescriptionMap[description];
|
||||
const kindsList = optionsDescriptionMap.get(description);
|
||||
output.push(usage + makePadding(marginLength - usage.length + 2) + description + sys.newLine);
|
||||
|
||||
if (kindsList) {
|
||||
|
||||
+17
-3
@@ -1,11 +1,25 @@
|
||||
namespace ts {
|
||||
|
||||
/**
|
||||
* Type of objects whose values are all of the same type.
|
||||
* The `in` and `for-in` operators can *not* be safely used,
|
||||
* since `Object.prototype` may be modified by outside code.
|
||||
*/
|
||||
export interface MapLike<T> {
|
||||
[index: string]: T;
|
||||
}
|
||||
|
||||
export interface Map<T> extends MapLike<T> {
|
||||
__mapBrand: any;
|
||||
/** It's allowed to get/set into a map with numbers. However, when iterating, you may get strings back due to the shim being an ordinary object (which only allows string keys). */
|
||||
export type MapKey = string | number;
|
||||
|
||||
/** Minimal ES6 Map interface. */
|
||||
export interface Map<T> {
|
||||
get(key: MapKey): T;
|
||||
has(key: MapKey): boolean;
|
||||
set(key: MapKey, value: T): this;
|
||||
delete(key: MapKey): boolean;
|
||||
clear(): void;
|
||||
/** `key` may *not* be a string if it was set with a number and we are not using the shim. */
|
||||
forEach(action: (value: T, key: string) => void): void;
|
||||
}
|
||||
|
||||
// branded string type used to store absolute, normalized and canonicalized paths
|
||||
|
||||
+20
-25
@@ -70,11 +70,11 @@ namespace ts {
|
||||
}
|
||||
|
||||
export function hasResolvedModule(sourceFile: SourceFile, moduleNameText: string): boolean {
|
||||
return !!(sourceFile && sourceFile.resolvedModules && sourceFile.resolvedModules[moduleNameText]);
|
||||
return !!(sourceFile && sourceFile.resolvedModules && sourceFile.resolvedModules.get(moduleNameText));
|
||||
}
|
||||
|
||||
export function getResolvedModule(sourceFile: SourceFile, moduleNameText: string): ResolvedModuleFull {
|
||||
return hasResolvedModule(sourceFile, moduleNameText) ? sourceFile.resolvedModules[moduleNameText] : undefined;
|
||||
return hasResolvedModule(sourceFile, moduleNameText) ? sourceFile.resolvedModules.get(moduleNameText) : undefined;
|
||||
}
|
||||
|
||||
export function setResolvedModule(sourceFile: SourceFile, moduleNameText: string, resolvedModule: ResolvedModuleFull): void {
|
||||
@@ -82,7 +82,7 @@ namespace ts {
|
||||
sourceFile.resolvedModules = createMap<ResolvedModuleFull>();
|
||||
}
|
||||
|
||||
sourceFile.resolvedModules[moduleNameText] = resolvedModule;
|
||||
sourceFile.resolvedModules.set(moduleNameText, resolvedModule);
|
||||
}
|
||||
|
||||
export function setResolvedTypeReferenceDirective(sourceFile: SourceFile, typeReferenceDirectiveName: string, resolvedTypeReferenceDirective: ResolvedTypeReferenceDirective): void {
|
||||
@@ -90,7 +90,7 @@ namespace ts {
|
||||
sourceFile.resolvedTypeReferenceDirectiveNames = createMap<ResolvedTypeReferenceDirective>();
|
||||
}
|
||||
|
||||
sourceFile.resolvedTypeReferenceDirectiveNames[typeReferenceDirectiveName] = resolvedTypeReferenceDirective;
|
||||
sourceFile.resolvedTypeReferenceDirectiveNames.set(typeReferenceDirectiveName, resolvedTypeReferenceDirective);
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
@@ -112,7 +112,7 @@ namespace ts {
|
||||
}
|
||||
for (let i = 0; i < names.length; i++) {
|
||||
const newResolution = newResolutions[i];
|
||||
const oldResolution = oldResolutions && oldResolutions[names[i]];
|
||||
const oldResolution = oldResolutions && oldResolutions.get(names[i]);
|
||||
const changed =
|
||||
oldResolution
|
||||
? !newResolution || !comparer(oldResolution, newResolution)
|
||||
@@ -2217,22 +2217,16 @@ namespace ts {
|
||||
}
|
||||
|
||||
function reattachFileDiagnostics(newFile: SourceFile): void {
|
||||
if (!hasProperty(fileDiagnostics, newFile.fileName)) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (const diagnostic of fileDiagnostics[newFile.fileName]) {
|
||||
diagnostic.file = newFile;
|
||||
}
|
||||
forEach(fileDiagnostics.get(newFile.fileName), diagnostic => diagnostic.file = newFile);
|
||||
}
|
||||
|
||||
function add(diagnostic: Diagnostic): void {
|
||||
let diagnostics: Diagnostic[];
|
||||
if (diagnostic.file) {
|
||||
diagnostics = fileDiagnostics[diagnostic.file.fileName];
|
||||
diagnostics = fileDiagnostics.get(diagnostic.file.fileName);
|
||||
if (!diagnostics) {
|
||||
diagnostics = [];
|
||||
fileDiagnostics[diagnostic.file.fileName] = diagnostics;
|
||||
fileDiagnostics.set(diagnostic.file.fileName, diagnostics);
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -2252,7 +2246,7 @@ namespace ts {
|
||||
function getDiagnostics(fileName?: string): Diagnostic[] {
|
||||
sortAndDeduplicate();
|
||||
if (fileName) {
|
||||
return fileDiagnostics[fileName] || [];
|
||||
return fileDiagnostics.get(fileName) || [];
|
||||
}
|
||||
|
||||
const allDiagnostics: Diagnostic[] = [];
|
||||
@@ -2262,9 +2256,9 @@ namespace ts {
|
||||
|
||||
forEach(nonFileDiagnostics, pushDiagnostic);
|
||||
|
||||
for (const key in fileDiagnostics) {
|
||||
forEach(fileDiagnostics[key], pushDiagnostic);
|
||||
}
|
||||
fileDiagnostics.forEach(diagnostics => {
|
||||
forEach(diagnostics, pushDiagnostic);
|
||||
});
|
||||
|
||||
return sortAndDeduplicateDiagnostics(allDiagnostics);
|
||||
}
|
||||
@@ -2277,9 +2271,9 @@ namespace ts {
|
||||
diagnosticsModified = false;
|
||||
nonFileDiagnostics = sortAndDeduplicateDiagnostics(nonFileDiagnostics);
|
||||
|
||||
for (const key in fileDiagnostics) {
|
||||
fileDiagnostics[key] = sortAndDeduplicateDiagnostics(fileDiagnostics[key]);
|
||||
}
|
||||
fileDiagnostics.forEach((diagnostics, key) => {
|
||||
fileDiagnostics.set(key, sortAndDeduplicateDiagnostics(diagnostics));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2316,7 +2310,7 @@ namespace ts {
|
||||
return s;
|
||||
|
||||
function getReplacement(c: string) {
|
||||
return escapedCharsMap[c] || get16BitUnicodeEscapeSequence(c.charCodeAt(0));
|
||||
return escapedCharsMap.get(c) || get16BitUnicodeEscapeSequence(c.charCodeAt(0));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3322,13 +3316,14 @@ namespace ts {
|
||||
export function formatSyntaxKind(kind: SyntaxKind): string {
|
||||
const syntaxKindEnum = (<any>ts).SyntaxKind;
|
||||
if (syntaxKindEnum) {
|
||||
if (syntaxKindCache[kind]) {
|
||||
return syntaxKindCache[kind];
|
||||
const cached = syntaxKindCache.get(kind);
|
||||
if (cached !== undefined) {
|
||||
return cached;
|
||||
}
|
||||
|
||||
for (const name in syntaxKindEnum) {
|
||||
if (syntaxKindEnum[name] === kind) {
|
||||
return syntaxKindCache[kind] = kind.toString() + " (" + name + ")";
|
||||
return set(syntaxKindCache, kind, kind.toString() + " (" + name + ")");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+27
-27
@@ -46,54 +46,54 @@ namespace ts {
|
||||
* supplant the existing `forEachChild` implementation if performance is not
|
||||
* significantly impacted.
|
||||
*/
|
||||
const nodeEdgeTraversalMap = createMap<NodeTraversalPath>({
|
||||
[SyntaxKind.QualifiedName]: [
|
||||
const nodeEdgeTraversalMap = createMapFromPairs<NodeTraversalPath>(
|
||||
[SyntaxKind.QualifiedName, [
|
||||
{ name: "left", test: isEntityName },
|
||||
{ name: "right", test: isIdentifier }
|
||||
],
|
||||
[SyntaxKind.Decorator]: [
|
||||
]],
|
||||
[SyntaxKind.Decorator, [
|
||||
{ name: "expression", test: isLeftHandSideExpression }
|
||||
],
|
||||
[SyntaxKind.TypeAssertionExpression]: [
|
||||
]],
|
||||
[SyntaxKind.TypeAssertionExpression, [
|
||||
{ name: "type", test: isTypeNode },
|
||||
{ name: "expression", test: isUnaryExpression }
|
||||
],
|
||||
[SyntaxKind.AsExpression]: [
|
||||
]],
|
||||
[SyntaxKind.AsExpression, [
|
||||
{ name: "expression", test: isExpression },
|
||||
{ name: "type", test: isTypeNode }
|
||||
],
|
||||
[SyntaxKind.NonNullExpression]: [
|
||||
]],
|
||||
[SyntaxKind.NonNullExpression, [
|
||||
{ name: "expression", test: isLeftHandSideExpression }
|
||||
],
|
||||
[SyntaxKind.EnumDeclaration]: [
|
||||
]],
|
||||
[SyntaxKind.EnumDeclaration, [
|
||||
{ name: "decorators", test: isDecorator },
|
||||
{ name: "modifiers", test: isModifier },
|
||||
{ name: "name", test: isIdentifier },
|
||||
{ name: "members", test: isEnumMember }
|
||||
],
|
||||
[SyntaxKind.ModuleDeclaration]: [
|
||||
]],
|
||||
[SyntaxKind.ModuleDeclaration, [
|
||||
{ name: "decorators", test: isDecorator },
|
||||
{ name: "modifiers", test: isModifier },
|
||||
{ name: "name", test: isModuleName },
|
||||
{ name: "body", test: isModuleBody }
|
||||
],
|
||||
[SyntaxKind.ModuleBlock]: [
|
||||
]],
|
||||
[SyntaxKind.ModuleBlock, [
|
||||
{ name: "statements", test: isStatement }
|
||||
],
|
||||
[SyntaxKind.ImportEqualsDeclaration]: [
|
||||
]],
|
||||
[SyntaxKind.ImportEqualsDeclaration, [
|
||||
{ name: "decorators", test: isDecorator },
|
||||
{ name: "modifiers", test: isModifier },
|
||||
{ name: "name", test: isIdentifier },
|
||||
{ name: "moduleReference", test: isModuleReference }
|
||||
],
|
||||
[SyntaxKind.ExternalModuleReference]: [
|
||||
]],
|
||||
[SyntaxKind.ExternalModuleReference, [
|
||||
{ name: "expression", test: isExpression, optional: true }
|
||||
],
|
||||
[SyntaxKind.EnumMember]: [
|
||||
]],
|
||||
[SyntaxKind.EnumMember, [
|
||||
{ name: "name", test: isPropertyName },
|
||||
{ name: "initializer", test: isExpression, optional: true, parenthesize: parenthesizeExpressionForList }
|
||||
]
|
||||
});
|
||||
]]
|
||||
);
|
||||
|
||||
function reduceNode<T>(node: Node, f: (memo: T, node: Node) => T, initial: T) {
|
||||
return node ? f(initial, node) : initial;
|
||||
@@ -530,7 +530,7 @@ namespace ts {
|
||||
break;
|
||||
|
||||
default:
|
||||
const edgeTraversalPath = nodeEdgeTraversalMap[kind];
|
||||
const edgeTraversalPath = nodeEdgeTraversalMap.get(kind);
|
||||
if (edgeTraversalPath) {
|
||||
for (const edge of edgeTraversalPath) {
|
||||
const value = (<MapLike<any>>node)[edge.name];
|
||||
@@ -1188,10 +1188,10 @@ namespace ts {
|
||||
|
||||
default:
|
||||
let updated: Node & MapLike<any>;
|
||||
const edgeTraversalPath = nodeEdgeTraversalMap[kind];
|
||||
const edgeTraversalPath = nodeEdgeTraversalMap.get(kind);
|
||||
if (edgeTraversalPath) {
|
||||
for (const edge of edgeTraversalPath) {
|
||||
const value = <Node | NodeArray<Node>>(<Node & Map<any>>node)[edge.name];
|
||||
const value = <Node | NodeArray<Node>>(<Node & MapLike<any>>node)[edge.name];
|
||||
if (value !== undefined) {
|
||||
const visited = isArray(value)
|
||||
? visitNodes(value, visitor, edge.test, 0, value.length, edge.parenthesize, node)
|
||||
|
||||
+15
-13
@@ -96,7 +96,7 @@ namespace FourSlash {
|
||||
});
|
||||
|
||||
export function escapeXmlAttributeValue(s: string) {
|
||||
return s.replace(/[&<>"'\/]/g, ch => entityMap[ch]);
|
||||
return s.replace(/[&<>"'\/]/g, ch => entityMap.get(ch));
|
||||
}
|
||||
|
||||
// Name of testcase metadata including ts.CompilerOptions properties that will be used by globalOptions
|
||||
@@ -222,7 +222,7 @@ namespace FourSlash {
|
||||
}
|
||||
|
||||
function tryAdd(path: string) {
|
||||
const inputFile = inputFiles[path];
|
||||
const inputFile = inputFiles.get(path);
|
||||
if (inputFile && !Harness.isDefaultLibraryFile(path)) {
|
||||
languageServiceAdapterHost.addScript(path, inputFile, /*isRootFile*/ true);
|
||||
return true;
|
||||
@@ -256,7 +256,7 @@ namespace FourSlash {
|
||||
|
||||
ts.forEach(testData.files, file => {
|
||||
// Create map between fileName and its content for easily looking up when resolveReference flag is specified
|
||||
this.inputFiles[file.fileName] = file.content;
|
||||
this.inputFiles.set(file.fileName, file.content);
|
||||
|
||||
if (ts.getBaseFileName(file.fileName).toLowerCase() === "tsconfig.json") {
|
||||
const configJson = ts.parseConfigFileTextToJson(file.fileName, file.content);
|
||||
@@ -322,11 +322,11 @@ namespace FourSlash {
|
||||
}
|
||||
else {
|
||||
// resolveReference file-option is not specified then do not resolve any files and include all inputFiles
|
||||
for (const fileName in this.inputFiles) {
|
||||
this.inputFiles.forEach((file, fileName) => {
|
||||
if (!Harness.isDefaultLibraryFile(fileName)) {
|
||||
this.languageServiceAdapterHost.addScript(fileName, this.inputFiles[fileName], /*isRootFile*/ true);
|
||||
this.languageServiceAdapterHost.addScript(fileName, file, /*isRootFile*/ true);
|
||||
}
|
||||
}
|
||||
});
|
||||
this.languageServiceAdapterHost.addScript(Harness.Compiler.defaultLibFileName,
|
||||
Harness.Compiler.getDefaultLibrarySourceFile().text, /*isRootFile*/ false);
|
||||
}
|
||||
@@ -659,11 +659,12 @@ namespace FourSlash {
|
||||
const completions = this.getCompletionListAtCaret();
|
||||
const uniqueItems = ts.createMap<string>();
|
||||
for (const item of completions.entries) {
|
||||
if (!(item.name in uniqueItems)) {
|
||||
uniqueItems[item.name] = item.kind;
|
||||
const uniqueItem = uniqueItems.get(item.name);
|
||||
if (!uniqueItem) {
|
||||
uniqueItems.set(item.name, item.kind);
|
||||
}
|
||||
else {
|
||||
assert.equal(item.kind, uniqueItems[item.name], `Items should have the same kind, got ${item.kind} and ${uniqueItems[item.name]}`);
|
||||
assert.equal(item.kind, uniqueItem, `Items should have the same kind, got ${item.kind} and ${uniqueItem}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -831,7 +832,7 @@ namespace FourSlash {
|
||||
}
|
||||
|
||||
public verifyRangesWithSameTextReferenceEachOther() {
|
||||
ts.forEachProperty(this.rangesByText(), ranges => this.verifyRangesReferenceEachOther(ranges));
|
||||
this.rangesByText().forEach(ranges => this.verifyRangesReferenceEachOther(ranges));
|
||||
}
|
||||
|
||||
public verifyDisplayPartsOfReferencedSymbol(expected: ts.SymbolDisplayPart[]) {
|
||||
@@ -903,7 +904,8 @@ namespace FourSlash {
|
||||
}
|
||||
|
||||
public verifyQuickInfos(namesAndTexts: { [name: string]: string | [string, string] }) {
|
||||
ts.forEachProperty(ts.createMap(namesAndTexts), (text, name) => {
|
||||
for (const name in namesAndTexts) if (ts.hasProperty(namesAndTexts, name)) {
|
||||
const text = namesAndTexts[name];
|
||||
if (text instanceof Array) {
|
||||
assert(text.length === 2);
|
||||
const [expectedText, expectedDocumentation] = text;
|
||||
@@ -912,7 +914,7 @@ namespace FourSlash {
|
||||
else {
|
||||
this.verifyQuickInfoAt(name, text);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public verifyQuickInfoString(expectedText: string, expectedDocumentation?: string) {
|
||||
@@ -2087,7 +2089,7 @@ namespace FourSlash {
|
||||
"<": ts.CharacterCodes.lessThan
|
||||
});
|
||||
|
||||
const charCode = openBraceMap[openingBrace];
|
||||
const charCode = openBraceMap.get(openingBrace);
|
||||
|
||||
if (!charCode) {
|
||||
this.raiseError(`Invalid openingBrace '${openingBrace}' specified.`);
|
||||
|
||||
@@ -918,10 +918,9 @@ namespace Harness {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
if (!libFileNameSourceFileMap[fileName]) {
|
||||
libFileNameSourceFileMap[fileName] = createSourceFileAndAssertInvariants(fileName, IO.readFile(libFolder + fileName), ts.ScriptTarget.Latest);
|
||||
}
|
||||
return libFileNameSourceFileMap[fileName];
|
||||
const sourceFile = libFileNameSourceFileMap.get(fileName);
|
||||
return sourceFile || ts.set(libFileNameSourceFileMap, fileName,
|
||||
createSourceFileAndAssertInvariants(fileName, IO.readFile(libFolder + fileName), ts.ScriptTarget.Latest));
|
||||
}
|
||||
|
||||
export function getDefaultLibFileName(options: ts.CompilerOptions): string {
|
||||
@@ -1103,10 +1102,10 @@ namespace Harness {
|
||||
optionsIndex = ts.createMap<ts.CommandLineOption>();
|
||||
const optionDeclarations = harnessOptionDeclarations.concat(ts.optionDeclarations);
|
||||
for (const option of optionDeclarations) {
|
||||
optionsIndex[option.name.toLowerCase()] = option;
|
||||
optionsIndex.set(option.name.toLowerCase(), option);
|
||||
}
|
||||
}
|
||||
return optionsIndex[name.toLowerCase()];
|
||||
return optionsIndex.get(name.toLowerCase());
|
||||
}
|
||||
|
||||
export function setCompilerOptionsFromHarnessSetting(settings: Harness.TestCaseParser.CompilerSettings, options: ts.CompilerOptions & HarnessOptions): void {
|
||||
@@ -1466,7 +1465,7 @@ namespace Harness {
|
||||
const fullResults = ts.createMap<TypeWriterResult[]>();
|
||||
|
||||
for (const sourceFile of allFiles) {
|
||||
fullResults[sourceFile.unitName] = fullWalker.getTypeAndSymbols(sourceFile.unitName);
|
||||
fullResults.set(sourceFile.unitName, fullWalker.getTypeAndSymbols(sourceFile.unitName));
|
||||
}
|
||||
|
||||
// Produce baselines. The first gives the types for all expressions.
|
||||
@@ -1519,7 +1518,7 @@ namespace Harness {
|
||||
|
||||
allFiles.forEach(file => {
|
||||
const codeLines = file.content.split("\n");
|
||||
typeWriterResults[file.unitName].forEach(result => {
|
||||
typeWriterResults.get(file.unitName).forEach(result => {
|
||||
if (isSymbolBaseline && !result.symbol) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -262,7 +262,7 @@ namespace Harness.LanguageService {
|
||||
this.getModuleResolutionsForFile = (fileName) => {
|
||||
const scriptInfo = this.getScriptInfo(fileName);
|
||||
const preprocessInfo = ts.preProcessFile(scriptInfo.content, /*readImportFiles*/ true);
|
||||
const imports = ts.createMap<string>();
|
||||
const imports = ts.createMapLike<string>();
|
||||
for (const module of preprocessInfo.importedFiles) {
|
||||
const resolutionInfo = ts.resolveModuleName(module.fileName, fileName, compilerOptions, moduleResolutionHost);
|
||||
if (resolutionInfo.resolvedModule) {
|
||||
@@ -275,7 +275,7 @@ namespace Harness.LanguageService {
|
||||
const scriptInfo = this.getScriptInfo(fileName);
|
||||
if (scriptInfo) {
|
||||
const preprocessInfo = ts.preProcessFile(scriptInfo.content, /*readImportFiles*/ false);
|
||||
const resolutions = ts.createMap<ts.ResolvedTypeReferenceDirective>();
|
||||
const resolutions = ts.createMapLike<ts.ResolvedTypeReferenceDirective>();
|
||||
const settings = this.nativeHost.getCompilationSettings();
|
||||
for (const typeReferenceDirective of preprocessInfo.typeReferenceDirectives) {
|
||||
const resolutionInfo = ts.resolveTypeReferenceDirective(typeReferenceDirective.fileName, fileName, settings, moduleResolutionHost);
|
||||
|
||||
@@ -256,17 +256,20 @@ class ProjectRunner extends RunnerBase {
|
||||
// Set the values specified using json
|
||||
const optionNameMap = ts.arrayToMap(ts.optionDeclarations, option => option.name);
|
||||
for (const name in testCase) {
|
||||
if (name !== "mapRoot" && name !== "sourceRoot" && name in optionNameMap) {
|
||||
const option = optionNameMap[name];
|
||||
const optType = option.type;
|
||||
let value = <any>testCase[name];
|
||||
if (typeof optType !== "string") {
|
||||
const key = value.toLowerCase();
|
||||
if (key in optType) {
|
||||
value = optType[key];
|
||||
if (name !== "mapRoot" && name !== "sourceRoot") {
|
||||
const option = optionNameMap.get(name);
|
||||
if (option) {
|
||||
const optType = option.type;
|
||||
let value = <any>testCase[name];
|
||||
if (typeof optType !== "string") {
|
||||
const key = value.toLowerCase();
|
||||
const optTypeValue = optType.get(key);
|
||||
if (optTypeValue) {
|
||||
value = optTypeValue;
|
||||
}
|
||||
}
|
||||
compilerOptions[option.name] = value;
|
||||
}
|
||||
compilerOptions[option.name] = value;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -8,25 +8,28 @@ namespace ts {
|
||||
|
||||
function createDefaultServerHost(fileMap: Map<File>): server.ServerHost {
|
||||
const existingDirectories = createMap<boolean>();
|
||||
for (const name in fileMap) {
|
||||
forEachKeyInMap(fileMap, name => {
|
||||
let dir = getDirectoryPath(name);
|
||||
let previous: string;
|
||||
do {
|
||||
existingDirectories[dir] = true;
|
||||
existingDirectories.set(dir, true);
|
||||
previous = dir;
|
||||
dir = getDirectoryPath(dir);
|
||||
} while (dir !== previous);
|
||||
}
|
||||
});
|
||||
return {
|
||||
args: <string[]>[],
|
||||
newLine: "\r\n",
|
||||
useCaseSensitiveFileNames: false,
|
||||
write: noop,
|
||||
readFile: path => path in fileMap ? fileMap[path].content : undefined,
|
||||
readFile: path => {
|
||||
const file = fileMap.get(path);
|
||||
return file && file.content;
|
||||
},
|
||||
writeFile: notImplemented,
|
||||
resolvePath: notImplemented,
|
||||
fileExists: path => path in fileMap,
|
||||
directoryExists: path => existingDirectories[path] || false,
|
||||
fileExists: path => fileMap.has(path),
|
||||
directoryExists: path => existingDirectories.get(path) || false,
|
||||
createDirectory: noop,
|
||||
getExecutingFilePath: () => "",
|
||||
getCurrentDirectory: () => "",
|
||||
@@ -191,7 +194,7 @@ namespace ts {
|
||||
assert.isTrue(typeof diags[0].messageText === "string" && ((<string>diags[0].messageText).indexOf("Cannot find module") === 0), "should be 'cannot find module' message");
|
||||
|
||||
// assert that import will success once file appear on disk
|
||||
fileMap[imported.name] = imported;
|
||||
fileMap.set(imported.name, imported);
|
||||
fileExistsCalledForBar = false;
|
||||
rootScriptInfo.editContent(0, root.content.length, `import {y} from "bar"`);
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ namespace ts {
|
||||
for (const f of files) {
|
||||
let name = getDirectoryPath(f.name);
|
||||
while (true) {
|
||||
directories[name] = name;
|
||||
directories.set(name, name);
|
||||
const baseName = getDirectoryPath(name);
|
||||
if (baseName === name) {
|
||||
break;
|
||||
@@ -46,20 +46,19 @@ namespace ts {
|
||||
}
|
||||
return {
|
||||
readFile,
|
||||
directoryExists: path => {
|
||||
return path in directories;
|
||||
},
|
||||
directoryExists: path => directories.has(path),
|
||||
fileExists: path => {
|
||||
assert.isTrue(getDirectoryPath(path) in directories, `'fileExists' '${path}' request in non-existing directory`);
|
||||
return path in map;
|
||||
assert.isTrue(directories.has(getDirectoryPath(path)), `'fileExists' '${path}' request in non-existing directory`);
|
||||
return map.has(path);
|
||||
}
|
||||
};
|
||||
}
|
||||
else {
|
||||
return { readFile, fileExists: path => path in map, };
|
||||
return { readFile, fileExists: path => map.has(path) };
|
||||
}
|
||||
function readFile(path: string): string {
|
||||
return path in map ? map[path].content : undefined;
|
||||
const file = map.get(path);
|
||||
return file && file.content;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -300,7 +299,8 @@ namespace ts {
|
||||
const host: CompilerHost = {
|
||||
getSourceFile: (fileName: string, languageVersion: ScriptTarget) => {
|
||||
const path = normalizePath(combinePaths(currentDirectory, fileName));
|
||||
return path in files ? createSourceFile(fileName, files[path], languageVersion) : undefined;
|
||||
const file = files.get(path);
|
||||
return file && createSourceFile(fileName, file, languageVersion);
|
||||
},
|
||||
getDefaultLibFileName: () => "lib.d.ts",
|
||||
writeFile: notImplemented,
|
||||
@@ -311,7 +311,7 @@ namespace ts {
|
||||
useCaseSensitiveFileNames: () => false,
|
||||
fileExists: fileName => {
|
||||
const path = normalizePath(combinePaths(currentDirectory, fileName));
|
||||
return path in files;
|
||||
return files.has(path);
|
||||
},
|
||||
readFile: notImplemented
|
||||
};
|
||||
@@ -371,7 +371,11 @@ export = C;
|
||||
function test(files: Map<string>, options: CompilerOptions, currentDirectory: string, useCaseSensitiveFileNames: boolean, rootFiles: string[], diagnosticCodes: number[]): void {
|
||||
const getCanonicalFileName = createGetCanonicalFileName(useCaseSensitiveFileNames);
|
||||
if (!useCaseSensitiveFileNames) {
|
||||
files = reduceProperties(files, (files, file, fileName) => (files[getCanonicalFileName(fileName)] = file, files), createMap<string>());
|
||||
const oldFiles = files;
|
||||
files = createMap<string>();
|
||||
oldFiles.forEach((file, fileName) => {
|
||||
files.set(getCanonicalFileName(fileName), file);
|
||||
});
|
||||
}
|
||||
|
||||
const host: CompilerHost = {
|
||||
@@ -380,7 +384,8 @@ export = C;
|
||||
return library;
|
||||
}
|
||||
const path = getCanonicalFileName(normalizePath(combinePaths(currentDirectory, fileName)));
|
||||
return path in files ? createSourceFile(fileName, files[path], languageVersion) : undefined;
|
||||
const file = files.get(path);
|
||||
return file && createSourceFile(fileName, file, languageVersion);
|
||||
},
|
||||
getDefaultLibFileName: () => "lib.d.ts",
|
||||
writeFile: notImplemented,
|
||||
@@ -391,7 +396,7 @@ export = C;
|
||||
useCaseSensitiveFileNames: () => useCaseSensitiveFileNames,
|
||||
fileExists: fileName => {
|
||||
const path = getCanonicalFileName(normalizePath(combinePaths(currentDirectory, fileName)));
|
||||
return path in files;
|
||||
return files.has(path);
|
||||
},
|
||||
readFile: notImplemented
|
||||
};
|
||||
@@ -1020,8 +1025,8 @@ import b = require("./moduleB");
|
||||
const names = map(files, f => f.name);
|
||||
const sourceFiles = arrayToMap(map(files, f => createSourceFile(f.name, f.content, ScriptTarget.ES2015)), f => f.fileName);
|
||||
const compilerHost: CompilerHost = {
|
||||
fileExists : fileName => fileName in sourceFiles,
|
||||
getSourceFile: fileName => sourceFiles[fileName],
|
||||
fileExists : fileName => sourceFiles.has(fileName),
|
||||
getSourceFile: fileName => sourceFiles.get(fileName),
|
||||
getDefaultLibFileName: () => "lib.d.ts",
|
||||
writeFile: notImplemented,
|
||||
getCurrentDirectory: () => "/",
|
||||
@@ -1029,7 +1034,10 @@ import b = require("./moduleB");
|
||||
getCanonicalFileName: f => f.toLowerCase(),
|
||||
getNewLine: () => "\r\n",
|
||||
useCaseSensitiveFileNames: () => false,
|
||||
readFile: fileName => fileName in sourceFiles ? sourceFiles[fileName].text : undefined
|
||||
readFile: fileName => {
|
||||
const file = sourceFiles.get(fileName);
|
||||
return file && file.text;
|
||||
}
|
||||
};
|
||||
const program1 = createProgram(names, {}, compilerHost);
|
||||
const diagnostics1 = program1.getFileProcessingDiagnostics().getDiagnostics();
|
||||
|
||||
@@ -122,7 +122,7 @@ namespace ts {
|
||||
trace: s => trace.push(s),
|
||||
getTrace: () => trace,
|
||||
getSourceFile(fileName): SourceFile {
|
||||
return files[fileName];
|
||||
return files.get(fileName);
|
||||
},
|
||||
getDefaultLibFileName(): string {
|
||||
return "lib.d.ts";
|
||||
@@ -143,9 +143,10 @@ namespace ts {
|
||||
getNewLine(): string {
|
||||
return sys ? sys.newLine : newLine;
|
||||
},
|
||||
fileExists: fileName => fileName in files,
|
||||
fileExists: fileName => files.has(fileName),
|
||||
readFile: fileName => {
|
||||
return fileName in files ? files[fileName].text : undefined;
|
||||
const file = files.get(fileName);
|
||||
return file && file.text;
|
||||
},
|
||||
};
|
||||
}
|
||||
@@ -188,7 +189,7 @@ namespace ts {
|
||||
}
|
||||
else {
|
||||
assert.isTrue(cache !== undefined, `expected ${caption} to be set`);
|
||||
assert.isTrue(equalOwnProperties(expectedContent, cache, entryChecker), `contents of ${caption} did not match the expected contents.`);
|
||||
assert.isTrue(mapsAreEqual(expectedContent, cache, entryChecker), `contents of ${caption} did not match the expected contents.`);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -422,9 +422,10 @@ namespace ts.server {
|
||||
handle(msg: protocol.Message): void {
|
||||
if (msg.type === "response") {
|
||||
const response = <protocol.Response>msg;
|
||||
if (response.request_seq in this.callbacks) {
|
||||
this.callbacks[response.request_seq](response);
|
||||
delete this.callbacks[response.request_seq];
|
||||
const handler = this.callbacks.get(response.request_seq);
|
||||
if (handler) {
|
||||
handler(response);
|
||||
this.callbacks.delete(response.request_seq);
|
||||
}
|
||||
}
|
||||
else if (msg.type === "event") {
|
||||
@@ -434,13 +435,14 @@ namespace ts.server {
|
||||
}
|
||||
|
||||
emit(name: string, args: any): void {
|
||||
if (name in this.eventHandlers) {
|
||||
this.eventHandlers[name](args);
|
||||
const handler = this.eventHandlers.get(name);
|
||||
if (handler) {
|
||||
handler(args);
|
||||
}
|
||||
}
|
||||
|
||||
on(name: string, handler: (args: any) => void): void {
|
||||
this.eventHandlers[name] = handler;
|
||||
this.eventHandlers.set(name, handler);
|
||||
}
|
||||
|
||||
connect(session: InProcSession): void {
|
||||
@@ -458,7 +460,7 @@ namespace ts.server {
|
||||
command,
|
||||
arguments: args
|
||||
});
|
||||
this.callbacks[this.seq] = callback;
|
||||
this.callbacks.set(this.seq, callback);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -243,12 +243,18 @@ namespace ts.projectSystem {
|
||||
}
|
||||
|
||||
export function checkMapKeys(caption: string, map: Map<any>, expectedKeys: string[]) {
|
||||
assert.equal(reduceProperties(map, count => count + 1, 0), expectedKeys.length, `${caption}: incorrect size of map`);
|
||||
assert.equal(mapSize(map), expectedKeys.length, `${caption}: incorrect size of map`);
|
||||
for (const name of expectedKeys) {
|
||||
assert.isTrue(name in map, `${caption} is expected to contain ${name}, actual keys: ${Object.keys(map)}`);
|
||||
assert.isTrue(map.has(name), `${caption} is expected to contain ${name}, actual keys: ${keysOfMap(map)}`);
|
||||
}
|
||||
}
|
||||
|
||||
function mapSize<T>(map: Map<T>): number {
|
||||
let size = 0;
|
||||
map.forEach(() => { size++; });
|
||||
return size;
|
||||
}
|
||||
|
||||
export function checkFileNames(caption: string, actualFileNames: string[], expectedFileNames: string[]) {
|
||||
assert.equal(actualFileNames.length, expectedFileNames.length, `${caption}: incorrect actual number of files, expected ${JSON.stringify(expectedFileNames)}, got ${actualFileNames}`);
|
||||
for (const f of expectedFileNames) {
|
||||
@@ -291,38 +297,30 @@ namespace ts.projectSystem {
|
||||
}
|
||||
|
||||
export class Callbacks {
|
||||
private map: { [n: number]: TimeOutCallback } = {};
|
||||
private map = createMap<TimeOutCallback>();
|
||||
private nextId = 1;
|
||||
|
||||
register(cb: (...args: any[]) => void, args: any[]) {
|
||||
const timeoutId = this.nextId;
|
||||
this.nextId++;
|
||||
this.map[timeoutId] = cb.bind(undefined, ...args);
|
||||
this.map.set(timeoutId, cb.bind(undefined, ...args));
|
||||
return timeoutId;
|
||||
}
|
||||
unregister(id: any) {
|
||||
if (typeof id === "number") {
|
||||
delete this.map[id];
|
||||
this.map.delete(id);
|
||||
}
|
||||
}
|
||||
|
||||
count() {
|
||||
let n = 0;
|
||||
for (const _ in this.map) {
|
||||
// TODO: GH#11734
|
||||
_;
|
||||
n++;
|
||||
}
|
||||
return n;
|
||||
return mapSize(this.map);
|
||||
}
|
||||
|
||||
invoke() {
|
||||
for (const id in this.map) {
|
||||
if (hasProperty(this.map, id)) {
|
||||
this.map[id]();
|
||||
}
|
||||
}
|
||||
this.map = {};
|
||||
this.map.forEach(cb => {
|
||||
cb();
|
||||
});
|
||||
this.map.clear();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -439,7 +437,7 @@ namespace ts.projectSystem {
|
||||
|
||||
triggerDirectoryWatcherCallback(directoryName: string, fileName: string): void {
|
||||
const path = this.toPath(directoryName);
|
||||
const callbacks = this.watchedDirectories[path];
|
||||
const callbacks = this.watchedDirectories.get(path);
|
||||
if (callbacks) {
|
||||
for (const callback of callbacks) {
|
||||
callback.cb(fileName);
|
||||
@@ -449,7 +447,7 @@ namespace ts.projectSystem {
|
||||
|
||||
triggerFileWatcherCallback(fileName: string, removed?: boolean): void {
|
||||
const path = this.toPath(fileName);
|
||||
const callbacks = this.watchedFiles[path];
|
||||
const callbacks = this.watchedFiles.get(path);
|
||||
if (callbacks) {
|
||||
for (const callback of callbacks) {
|
||||
callback(path, removed);
|
||||
|
||||
@@ -14,7 +14,7 @@ namespace ts.projectSystem {
|
||||
function createTypesRegistry(...list: string[]): Map<void> {
|
||||
const map = createMap<void>();
|
||||
for (const l of list) {
|
||||
map[l] = undefined;
|
||||
map.set(l, undefined);
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
@@ -336,24 +336,24 @@ namespace ts.server {
|
||||
// Use slice to clone the array to avoid manipulating in place
|
||||
const queue = fileInfo.referencedBy.slice(0);
|
||||
const fileNameSet = createMap<ScriptInfo>();
|
||||
fileNameSet[scriptInfo.fileName] = scriptInfo;
|
||||
fileNameSet.set(scriptInfo.fileName, scriptInfo);
|
||||
while (queue.length > 0) {
|
||||
const processingFileInfo = queue.pop();
|
||||
if (processingFileInfo.updateShapeSignature() && processingFileInfo.referencedBy.length > 0) {
|
||||
for (const potentialFileInfo of processingFileInfo.referencedBy) {
|
||||
if (!fileNameSet[potentialFileInfo.scriptInfo.fileName]) {
|
||||
if (!fileNameSet.has(potentialFileInfo.scriptInfo.fileName)) {
|
||||
queue.push(potentialFileInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
fileNameSet[processingFileInfo.scriptInfo.fileName] = processingFileInfo.scriptInfo;
|
||||
fileNameSet.set(processingFileInfo.scriptInfo.fileName, processingFileInfo.scriptInfo);
|
||||
}
|
||||
const result: string[] = [];
|
||||
for (const fileName in fileNameSet) {
|
||||
if (shouldEmitFile(fileNameSet[fileName])) {
|
||||
fileNameSet.forEach((scriptInfo, fileName) => {
|
||||
if (shouldEmitFile(scriptInfo)) {
|
||||
result.push(fileName);
|
||||
}
|
||||
}
|
||||
});
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,10 +31,10 @@ namespace ts.server {
|
||||
}
|
||||
|
||||
private getLineMap(fileName: string): number[] {
|
||||
let lineMap = this.lineMaps[fileName];
|
||||
let lineMap = this.lineMaps.get(fileName);
|
||||
if (!lineMap) {
|
||||
const scriptSnapshot = this.host.getScriptSnapshot(fileName);
|
||||
lineMap = this.lineMaps[fileName] = ts.computeLineStarts(scriptSnapshot.getText(0, scriptSnapshot.getLength()));
|
||||
lineMap = set(this.lineMaps, fileName, ts.computeLineStarts(scriptSnapshot.getText(0, scriptSnapshot.getLength())));
|
||||
}
|
||||
return lineMap;
|
||||
}
|
||||
@@ -140,7 +140,7 @@ namespace ts.server {
|
||||
|
||||
changeFile(fileName: string, start: number, end: number, newText: string): void {
|
||||
// clear the line map after an edit
|
||||
this.lineMaps[fileName] = undefined;
|
||||
this.lineMaps.set(fileName, undefined);
|
||||
|
||||
const lineOffset = this.positionToOneBasedLineOffset(fileName, start);
|
||||
const endLineOffset = this.positionToOneBasedLineOffset(fileName, end);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/// <reference path="..\compiler\commandLineParser.ts" />
|
||||
/// <reference path="..\compiler\commandLineParser.ts" />
|
||||
/// <reference path="..\services\services.ts" />
|
||||
/// <reference path="utilities.ts" />
|
||||
/// <reference path="session.ts" />
|
||||
@@ -41,10 +41,10 @@ namespace ts.server {
|
||||
if (typeof option.type === "object") {
|
||||
const optionMap = <Map<number>>option.type;
|
||||
// verify that map contains only numbers
|
||||
for (const id in optionMap) {
|
||||
Debug.assert(typeof optionMap[id] === "number");
|
||||
}
|
||||
map[option.name] = optionMap;
|
||||
optionMap.forEach(value => {
|
||||
Debug.assert(typeof value === "number");
|
||||
});
|
||||
map.set(option.name, optionMap);
|
||||
}
|
||||
}
|
||||
return map;
|
||||
@@ -59,20 +59,19 @@ namespace ts.server {
|
||||
|
||||
export function convertFormatOptions(protocolOptions: protocol.FormatCodeSettings): FormatCodeSettings {
|
||||
if (typeof protocolOptions.indentStyle === "string") {
|
||||
protocolOptions.indentStyle = indentStyle[protocolOptions.indentStyle.toLowerCase()];
|
||||
protocolOptions.indentStyle = indentStyle.get(protocolOptions.indentStyle.toLowerCase());
|
||||
Debug.assert(protocolOptions.indentStyle !== undefined);
|
||||
}
|
||||
return <any>protocolOptions;
|
||||
}
|
||||
|
||||
export function convertCompilerOptions(protocolOptions: protocol.ExternalProjectCompilerOptions): CompilerOptions & protocol.CompileOnSaveMixin {
|
||||
for (const id in compilerOptionConverters) {
|
||||
compilerOptionConverters.forEach((mappedValues, id) => {
|
||||
const propertyValue = protocolOptions[id];
|
||||
if (typeof propertyValue === "string") {
|
||||
const mappedValues = compilerOptionConverters[id];
|
||||
protocolOptions[id] = mappedValues[propertyValue.toLowerCase()];
|
||||
protocolOptions[id] = mappedValues.get(propertyValue.toLowerCase());
|
||||
}
|
||||
}
|
||||
});
|
||||
return <any>protocolOptions;
|
||||
}
|
||||
|
||||
@@ -189,11 +188,12 @@ namespace ts.server {
|
||||
|
||||
stopWatchingDirectory(directory: string) {
|
||||
// if the ref count for this directory watcher drops to 0, it's time to close it
|
||||
this.directoryWatchersRefCount[directory]--;
|
||||
if (this.directoryWatchersRefCount[directory] === 0) {
|
||||
const refCount = this.directoryWatchersRefCount.get(directory) - 1;
|
||||
this.directoryWatchersRefCount.set(directory, refCount);
|
||||
if (refCount === 0) {
|
||||
this.projectService.logger.info(`Close directory watcher for: ${directory}`);
|
||||
this.directoryWatchersForTsconfig[directory].close();
|
||||
delete this.directoryWatchersForTsconfig[directory];
|
||||
this.directoryWatchersForTsconfig.get(directory).close();
|
||||
this.directoryWatchersForTsconfig.delete(directory);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -201,13 +201,13 @@ namespace ts.server {
|
||||
let currentPath = getDirectoryPath(fileName);
|
||||
let parentPath = getDirectoryPath(currentPath);
|
||||
while (currentPath != parentPath) {
|
||||
if (!this.directoryWatchersForTsconfig[currentPath]) {
|
||||
if (!this.directoryWatchersForTsconfig.has(currentPath)) {
|
||||
this.projectService.logger.info(`Add watcher for: ${currentPath}`);
|
||||
this.directoryWatchersForTsconfig[currentPath] = this.projectService.host.watchDirectory(currentPath, callback);
|
||||
this.directoryWatchersRefCount[currentPath] = 1;
|
||||
this.directoryWatchersForTsconfig.set(currentPath, this.projectService.host.watchDirectory(currentPath, callback));
|
||||
this.directoryWatchersRefCount.set(currentPath, 1);
|
||||
}
|
||||
else {
|
||||
this.directoryWatchersRefCount[currentPath] += 1;
|
||||
this.directoryWatchersRefCount.set(currentPath, this.directoryWatchersRefCount.get(currentPath) + 1);
|
||||
}
|
||||
project.directoriesWatchedForTsconfig.push(currentPath);
|
||||
currentPath = parentPath;
|
||||
@@ -425,7 +425,7 @@ namespace ts.server {
|
||||
}
|
||||
else {
|
||||
if (info && (!info.isOpen)) {
|
||||
// file has been changed which might affect the set of referenced files in projects that include
|
||||
// file has been changed which might affect the set of referenced files in projects that include
|
||||
// this file and set of inferred projects
|
||||
info.reloadFromFile();
|
||||
this.updateProjectGraphs(info.containingProjects);
|
||||
@@ -444,7 +444,7 @@ namespace ts.server {
|
||||
this.filenameToScriptInfo.remove(info.path);
|
||||
this.lastDeletedFile = info;
|
||||
|
||||
// capture list of projects since detachAllProjects will wipe out original list
|
||||
// capture list of projects since detachAllProjects will wipe out original list
|
||||
const containingProjects = info.containingProjects.slice();
|
||||
|
||||
info.detachAllProjects();
|
||||
@@ -600,7 +600,7 @@ namespace ts.server {
|
||||
const inferredProject = this.createInferredProjectWithRootFileIfNecessary(info);
|
||||
if (!this.useSingleInferredProject) {
|
||||
// if useOneInferredProject is not set then try to fixup ownership of open files
|
||||
// check 'defaultProject !== inferredProject' is necessary to handle cases
|
||||
// check 'defaultProject !== inferredProject' is necessary to handle cases
|
||||
// when creation inferred project for some file has added other open files into this project (i.e. as referenced files)
|
||||
// we definitely don't want to delete the project that was just created
|
||||
for (const f of this.openFiles) {
|
||||
@@ -610,7 +610,7 @@ namespace ts.server {
|
||||
}
|
||||
const defaultProject = f.getDefaultProject();
|
||||
if (isRootFileInInferredProject(info) && defaultProject !== inferredProject && inferredProject.containsScriptInfo(f)) {
|
||||
// open file used to be root in inferred project,
|
||||
// open file used to be root in inferred project,
|
||||
// this inferred project is different from the one we've just created for current file
|
||||
// and new inferred project references this open file.
|
||||
// We should delete old inferred project and attach open file to the new one
|
||||
@@ -990,7 +990,7 @@ namespace ts.server {
|
||||
if (toAdd) {
|
||||
for (const f of toAdd) {
|
||||
if (f.isOpen && isRootFileInInferredProject(f)) {
|
||||
// if file is already root in some inferred project
|
||||
// if file is already root in some inferred project
|
||||
// - remove the file from that project and delete the project if necessary
|
||||
const inferredProject = f.containingProjects[0];
|
||||
inferredProject.removeFile(f);
|
||||
@@ -1143,7 +1143,7 @@ namespace ts.server {
|
||||
this.logger.info(`Host information ${args.hostInfo}`);
|
||||
}
|
||||
if (args.formatOptions) {
|
||||
mergeMaps(this.hostConfiguration.formatCodeOptions, convertFormatOptions(args.formatOptions));
|
||||
mergeMapLikes(this.hostConfiguration.formatCodeOptions, convertFormatOptions(args.formatOptions));
|
||||
this.logger.info("Format host information updated");
|
||||
}
|
||||
}
|
||||
@@ -1265,7 +1265,7 @@ namespace ts.server {
|
||||
for (const file of changedFiles) {
|
||||
const scriptInfo = this.getScriptInfo(file.fileName);
|
||||
Debug.assert(!!scriptInfo);
|
||||
// apply changes in reverse order
|
||||
// apply changes in reverse order
|
||||
for (let i = file.changes.length - 1; i >= 0; i--) {
|
||||
const change = file.changes[i];
|
||||
scriptInfo.editContent(change.span.start, change.span.start + change.span.length, change.newText);
|
||||
@@ -1302,7 +1302,7 @@ namespace ts.server {
|
||||
|
||||
closeExternalProject(uncheckedFileName: string, suppressRefresh = false): void {
|
||||
const fileName = toNormalizedPath(uncheckedFileName);
|
||||
const configFiles = this.externalProjectToConfiguredProjectMap[fileName];
|
||||
const configFiles = this.externalProjectToConfiguredProjectMap.get(fileName);
|
||||
if (configFiles) {
|
||||
let shouldRefreshInferredProjects = false;
|
||||
for (const configFile of configFiles) {
|
||||
@@ -1310,7 +1310,7 @@ namespace ts.server {
|
||||
shouldRefreshInferredProjects = true;
|
||||
}
|
||||
}
|
||||
delete this.externalProjectToConfiguredProjectMap[fileName];
|
||||
this.externalProjectToConfiguredProjectMap.delete(fileName);
|
||||
if (shouldRefreshInferredProjects && !suppressRefresh) {
|
||||
this.refreshInferredProjects();
|
||||
}
|
||||
@@ -1331,19 +1331,19 @@ namespace ts.server {
|
||||
// record project list before the update
|
||||
const projectsToClose = arrayToMap(this.externalProjects, p => p.getProjectName(), _ => true);
|
||||
for (const externalProjectName in this.externalProjectToConfiguredProjectMap) {
|
||||
projectsToClose[externalProjectName] = true;
|
||||
projectsToClose.set(externalProjectName, true);
|
||||
}
|
||||
|
||||
for (const externalProject of projects) {
|
||||
this.openExternalProject(externalProject, /*suppressRefreshOfInferredProjects*/ true);
|
||||
// delete project that is present in input list
|
||||
delete projectsToClose[externalProject.projectFileName];
|
||||
projectsToClose.delete(externalProject.projectFileName);
|
||||
}
|
||||
|
||||
// close projects that were missing in the input list
|
||||
for (const externalProjectName in projectsToClose) {
|
||||
forEachKeyInMap(projectsToClose, externalProjectName => {
|
||||
this.closeExternalProject(externalProjectName, /*suppressRefresh*/ true)
|
||||
}
|
||||
});
|
||||
|
||||
this.refreshInferredProjects();
|
||||
}
|
||||
@@ -1386,7 +1386,7 @@ namespace ts.server {
|
||||
// close existing project and later we'll open a set of configured projects for these files
|
||||
this.closeExternalProject(proj.projectFileName, /*suppressRefresh*/ true);
|
||||
}
|
||||
else if (this.externalProjectToConfiguredProjectMap[proj.projectFileName]) {
|
||||
else if (this.externalProjectToConfiguredProjectMap.get(proj.projectFileName)) {
|
||||
// this project used to include config files
|
||||
if (!tsConfigFiles) {
|
||||
// config files were removed from the project - close existing external project which in turn will close configured projects
|
||||
@@ -1394,7 +1394,7 @@ namespace ts.server {
|
||||
}
|
||||
else {
|
||||
// project previously had some config files - compare them with new set of files and close all configured projects that correspond to unused files
|
||||
const oldConfigFiles = this.externalProjectToConfiguredProjectMap[proj.projectFileName];
|
||||
const oldConfigFiles = this.externalProjectToConfiguredProjectMap.get(proj.projectFileName);
|
||||
let iNew = 0;
|
||||
let iOld = 0;
|
||||
while (iNew < tsConfigFiles.length && iOld < oldConfigFiles.length) {
|
||||
@@ -1422,7 +1422,7 @@ namespace ts.server {
|
||||
}
|
||||
if (tsConfigFiles) {
|
||||
// store the list of tsconfig files that belong to the external project
|
||||
this.externalProjectToConfiguredProjectMap[proj.projectFileName] = tsConfigFiles;
|
||||
this.externalProjectToConfiguredProjectMap.set(proj.projectFileName, tsConfigFiles);
|
||||
for (const tsconfigFile of tsConfigFiles) {
|
||||
let project = this.findConfiguredProjectByProjectName(tsconfigFile);
|
||||
if (!project) {
|
||||
@@ -1438,7 +1438,7 @@ namespace ts.server {
|
||||
}
|
||||
else {
|
||||
// no config files - remove the item from the collection
|
||||
delete this.externalProjectToConfiguredProjectMap[proj.projectFileName];
|
||||
this.externalProjectToConfiguredProjectMap.delete(proj.projectFileName);
|
||||
this.createAndAddExternalProject(proj.projectFileName, rootFiles, proj.options, proj.typeAcquisition);
|
||||
}
|
||||
if (!suppressRefreshOfInferredProjects) {
|
||||
|
||||
@@ -75,15 +75,16 @@ namespace ts.server {
|
||||
|
||||
for (const name of names) {
|
||||
// check if this is a duplicate entry in the list
|
||||
let resolution = newResolutions[name];
|
||||
let resolution = newResolutions.get(name);
|
||||
if (!resolution) {
|
||||
const existingResolution = currentResolutionsInFile && currentResolutionsInFile[name];
|
||||
const existingResolution = currentResolutionsInFile && currentResolutionsInFile.get(name);
|
||||
if (moduleResolutionIsValid(existingResolution)) {
|
||||
// ok, it is safe to use existing name resolution results
|
||||
resolution = existingResolution;
|
||||
}
|
||||
else {
|
||||
newResolutions[name] = resolution = loader(name, containingFile, compilerOptions, this);
|
||||
resolution = loader(name, containingFile, compilerOptions, this);
|
||||
newResolutions.set(name, resolution);
|
||||
}
|
||||
if (logChanges && this.filesWithChangedSetOfUnresolvedImports && !resolutionIsEqualTo(existingResolution, resolution)) {
|
||||
this.filesWithChangedSetOfUnresolvedImports.push(path);
|
||||
|
||||
+26
-26
@@ -495,9 +495,9 @@ namespace ts.server {
|
||||
}
|
||||
let unresolvedImports: string[];
|
||||
if (file.resolvedModules) {
|
||||
for (const name in file.resolvedModules) {
|
||||
file.resolvedModules.forEach((resolvedModule, name) => {
|
||||
// pick unresolved non-relative names
|
||||
if (!file.resolvedModules[name] && !isExternalModuleNameRelative(name)) {
|
||||
if (!resolvedModule && !isExternalModuleNameRelative(name)) {
|
||||
// for non-scoped names extract part up-to the first slash
|
||||
// for scoped names - extract up to the second slash
|
||||
let trimmed = name.trim();
|
||||
@@ -511,7 +511,7 @@ namespace ts.server {
|
||||
(unresolvedImports || (unresolvedImports = [])).push(trimmed);
|
||||
result.push(trimmed);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
this.cachedUnresolvedImportsPerFile.set(file.path, unresolvedImports || emptyArray);
|
||||
}
|
||||
@@ -537,7 +537,7 @@ namespace ts.server {
|
||||
}
|
||||
|
||||
// 1. no changes in structure, no changes in unresolved imports - do nothing
|
||||
// 2. no changes in structure, unresolved imports were changed - collect unresolved imports for all files
|
||||
// 2. no changes in structure, unresolved imports were changed - collect unresolved imports for all files
|
||||
// (can reuse cached imports for files that were not changed)
|
||||
// 3. new files were added/removed, but compilation settings stays the same - collect unresolved imports for all new/modified files
|
||||
// (can reuse cached imports for files that were not changed)
|
||||
@@ -679,16 +679,16 @@ namespace ts.server {
|
||||
|
||||
const added: string[] = [];
|
||||
const removed: string[] = [];
|
||||
for (const id in currentFiles) {
|
||||
if (!hasProperty(lastReportedFileNames, id)) {
|
||||
forEachKeyInMap(currentFiles, id => {
|
||||
if (!lastReportedFileNames.has(id)) {
|
||||
added.push(id);
|
||||
}
|
||||
}
|
||||
for (const id in lastReportedFileNames) {
|
||||
if (!hasProperty(currentFiles, id)) {
|
||||
});
|
||||
forEachKeyInMap(lastReportedFileNames, id => {
|
||||
if (!currentFiles.has(id)) {
|
||||
removed.push(id);
|
||||
}
|
||||
}
|
||||
});
|
||||
this.lastReportedFileNames = currentFiles;
|
||||
this.lastReportedVersion = this.projectStructureVersion;
|
||||
return { info, changes: { added, removed }, projectErrors: this.projectErrors };
|
||||
@@ -722,7 +722,7 @@ namespace ts.server {
|
||||
if (symbol && symbol.declarations && symbol.declarations[0]) {
|
||||
const declarationSourceFile = symbol.declarations[0].getSourceFile();
|
||||
if (declarationSourceFile) {
|
||||
referencedFiles[declarationSourceFile.path] = true;
|
||||
referencedFiles.set(declarationSourceFile.path, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -734,25 +734,24 @@ namespace ts.server {
|
||||
if (sourceFile.referencedFiles && sourceFile.referencedFiles.length > 0) {
|
||||
for (const referencedFile of sourceFile.referencedFiles) {
|
||||
const referencedPath = toPath(referencedFile.fileName, currentDirectory, getCanonicalFileName);
|
||||
referencedFiles[referencedPath] = true;
|
||||
referencedFiles.set(referencedPath, true);
|
||||
}
|
||||
}
|
||||
|
||||
// Handle type reference directives
|
||||
if (sourceFile.resolvedTypeReferenceDirectiveNames) {
|
||||
for (const typeName in sourceFile.resolvedTypeReferenceDirectiveNames) {
|
||||
const resolvedTypeReferenceDirective = sourceFile.resolvedTypeReferenceDirectiveNames[typeName];
|
||||
sourceFile.resolvedTypeReferenceDirectiveNames.forEach((resolvedTypeReferenceDirective) => {
|
||||
if (!resolvedTypeReferenceDirective) {
|
||||
continue;
|
||||
return;
|
||||
}
|
||||
|
||||
const fileName = resolvedTypeReferenceDirective.resolvedFileName;
|
||||
const typeFilePath = toPath(fileName, currentDirectory, getCanonicalFileName);
|
||||
referencedFiles[typeFilePath] = true;
|
||||
}
|
||||
referencedFiles.set(typeFilePath, true);
|
||||
})
|
||||
}
|
||||
|
||||
const allFileNames = map(Object.keys(referencedFiles), key => <Path>key);
|
||||
const allFileNames = keysOfMap(referencedFiles) as Path[];
|
||||
return filter(allFileNames, file => this.projectService.host.fileExists(file));
|
||||
}
|
||||
|
||||
@@ -888,18 +887,19 @@ namespace ts.server {
|
||||
return;
|
||||
}
|
||||
const configDirectoryPath = getDirectoryPath(this.getConfigFilePath());
|
||||
this.directoriesWatchedForWildcards = reduceProperties(this.wildcardDirectories, (watchers, flag, directory) => {
|
||||
|
||||
this.directoriesWatchedForWildcards = createMap<FileWatcher>();
|
||||
this.wildcardDirectories.forEach((flag, directory) => {
|
||||
if (comparePaths(configDirectoryPath, directory, ".", !this.projectService.host.useCaseSensitiveFileNames) !== Comparison.EqualTo) {
|
||||
const recursive = (flag & WatchDirectoryFlags.Recursive) !== 0;
|
||||
this.projectService.logger.info(`Add ${recursive ? "recursive " : ""}watcher for: ${directory}`);
|
||||
watchers[directory] = this.projectService.host.watchDirectory(
|
||||
this.directoriesWatchedForWildcards.set(directory, this.projectService.host.watchDirectory(
|
||||
directory,
|
||||
path => callback(this, path),
|
||||
recursive
|
||||
);
|
||||
));
|
||||
}
|
||||
return watchers;
|
||||
}, <Map<FileWatcher>>{});
|
||||
});
|
||||
}
|
||||
|
||||
stopWatchingDirectory() {
|
||||
@@ -923,9 +923,9 @@ namespace ts.server {
|
||||
this.typeRootsWatchers = undefined;
|
||||
}
|
||||
|
||||
for (const id in this.directoriesWatchedForWildcards) {
|
||||
this.directoriesWatchedForWildcards[id].close();
|
||||
}
|
||||
this.directoriesWatchedForWildcards.forEach(watcher => {
|
||||
watcher.close();
|
||||
});
|
||||
this.directoriesWatchedForWildcards = undefined;
|
||||
|
||||
this.stopWatchingDirectory();
|
||||
|
||||
@@ -95,7 +95,7 @@ namespace ts.server {
|
||||
if (!this.formatCodeSettings) {
|
||||
this.formatCodeSettings = getDefaultFormatCodeSettings(this.host);
|
||||
}
|
||||
mergeMaps(this.formatCodeSettings, formatSettings);
|
||||
mergeMapLikes(this.formatCodeSettings, formatSettings);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1607,14 +1607,14 @@ namespace ts.server {
|
||||
});
|
||||
|
||||
public addProtocolHandler(command: string, handler: (request: protocol.Request) => { response?: any, responseRequired: boolean }) {
|
||||
if (command in this.handlers) {
|
||||
if (this.handlers.has(command)) {
|
||||
throw new Error(`Protocol handler already exists for command "${command}"`);
|
||||
}
|
||||
this.handlers[command] = handler;
|
||||
this.handlers.set(command, handler);
|
||||
}
|
||||
|
||||
public executeCommand(request: protocol.Request): { response?: any, responseRequired?: boolean } {
|
||||
const handler = this.handlers[request.command];
|
||||
const handler = this.handlers.get(request.command);
|
||||
if (handler) {
|
||||
return handler(request);
|
||||
}
|
||||
|
||||
+13
-12
@@ -35,17 +35,18 @@ namespace ts.server {
|
||||
let unique = 0;
|
||||
|
||||
for (const v of arr1) {
|
||||
if (set[v] !== true) {
|
||||
set[v] = true;
|
||||
if (set.get(v) !== true) {
|
||||
set.set(v, true);
|
||||
unique++;
|
||||
}
|
||||
}
|
||||
for (const v of arr2) {
|
||||
if (!hasProperty(set, v)) {
|
||||
const isSet = set.get(v);
|
||||
if (isSet === undefined) {
|
||||
return false;
|
||||
}
|
||||
if (set[v] === true) {
|
||||
set[v] = false;
|
||||
if (isSet === true) {
|
||||
set.set(v, false);
|
||||
unique--;
|
||||
}
|
||||
}
|
||||
@@ -83,7 +84,7 @@ namespace ts.server {
|
||||
return <any>emptyArray;
|
||||
}
|
||||
|
||||
const entry = this.perProjectCache[project.getProjectName()];
|
||||
const entry = this.perProjectCache.get(project.getProjectName());
|
||||
const result: SortedReadonlyArray<string> = entry ? entry.typings : <any>emptyArray;
|
||||
if (forceRefresh ||
|
||||
!entry ||
|
||||
@@ -92,13 +93,13 @@ namespace ts.server {
|
||||
unresolvedImportsChanged(unresolvedImports, entry.unresolvedImports)) {
|
||||
// Note: entry is now poisoned since it does not really contain typings for a given combination of compiler options\typings options.
|
||||
// instead it acts as a placeholder to prevent issuing multiple requests
|
||||
this.perProjectCache[project.getProjectName()] = {
|
||||
this.perProjectCache.set(project.getProjectName(), {
|
||||
compilerOptions: project.getCompilerOptions(),
|
||||
typeAcquisition,
|
||||
typings: result,
|
||||
unresolvedImports,
|
||||
poisoned: true
|
||||
};
|
||||
});
|
||||
// something has been changed, issue a request to update typings
|
||||
this.installer.enqueueInstallTypingsRequest(project, typeAcquisition, unresolvedImports);
|
||||
}
|
||||
@@ -106,21 +107,21 @@ namespace ts.server {
|
||||
}
|
||||
|
||||
updateTypingsForProject(projectName: string, compilerOptions: CompilerOptions, typeAcquisition: TypeAcquisition, unresolvedImports: SortedReadonlyArray<string>, newTypings: string[]) {
|
||||
this.perProjectCache[projectName] = {
|
||||
this.perProjectCache.set(projectName, {
|
||||
compilerOptions,
|
||||
typeAcquisition,
|
||||
typings: toSortedReadonlyArray(newTypings),
|
||||
unresolvedImports,
|
||||
poisoned: false
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
deleteTypingsForProject(projectName: string) {
|
||||
delete this.perProjectCache[projectName];
|
||||
this.perProjectCache.delete(projectName);
|
||||
}
|
||||
|
||||
onProjectClosed(project: Project) {
|
||||
delete this.perProjectCache[project.getProjectName()];
|
||||
this.perProjectCache.delete(project.getProjectName());
|
||||
this.installer.onProjectClosed(project);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -112,7 +112,7 @@ namespace ts.server.typingsInstaller {
|
||||
if (this.log.isEnabled()) {
|
||||
this.log.writeLine(`Closing file watchers for project '${projectName}'`);
|
||||
}
|
||||
const watchers = this.projectWatchers[projectName];
|
||||
const watchers = this.projectWatchers.get(projectName);
|
||||
if (!watchers) {
|
||||
if (this.log.isEnabled()) {
|
||||
this.log.writeLine(`No watchers are registered for project '${projectName}'`);
|
||||
@@ -123,7 +123,7 @@ namespace ts.server.typingsInstaller {
|
||||
w.close();
|
||||
}
|
||||
|
||||
delete this.projectWatchers[projectName];
|
||||
this.projectWatchers.delete(projectName);
|
||||
|
||||
if (this.log.isEnabled()) {
|
||||
this.log.writeLine(`Closing file watchers for project '${projectName}' - done.`);
|
||||
@@ -177,7 +177,7 @@ namespace ts.server.typingsInstaller {
|
||||
if (this.log.isEnabled()) {
|
||||
this.log.writeLine(`Processing cache location '${cacheLocation}'`);
|
||||
}
|
||||
if (this.knownCachesSet[cacheLocation]) {
|
||||
if (this.knownCachesSet.get(cacheLocation)) {
|
||||
if (this.log.isEnabled()) {
|
||||
this.log.writeLine(`Cache location was already processed...`);
|
||||
}
|
||||
@@ -201,10 +201,10 @@ namespace ts.server.typingsInstaller {
|
||||
}
|
||||
const typingFile = typingToFileName(cacheLocation, packageName, this.installTypingHost, this.log);
|
||||
if (!typingFile) {
|
||||
this.missingTypingsSet[packageName] = true;
|
||||
this.missingTypingsSet.set(packageName, true);
|
||||
continue;
|
||||
}
|
||||
const existingTypingFile = this.packageNameToTypingLocation[packageName];
|
||||
const existingTypingFile = this.packageNameToTypingLocation.get(packageName);
|
||||
if (existingTypingFile === typingFile) {
|
||||
continue;
|
||||
}
|
||||
@@ -216,14 +216,14 @@ namespace ts.server.typingsInstaller {
|
||||
if (this.log.isEnabled()) {
|
||||
this.log.writeLine(`Adding entry into typings cache: '${packageName}' => '${typingFile}'`);
|
||||
}
|
||||
this.packageNameToTypingLocation[packageName] = typingFile;
|
||||
this.packageNameToTypingLocation.set(packageName, typingFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (this.log.isEnabled()) {
|
||||
this.log.writeLine(`Finished processing cache location '${cacheLocation}'`);
|
||||
}
|
||||
this.knownCachesSet[cacheLocation] = true;
|
||||
this.knownCachesSet.set(cacheLocation, true);
|
||||
}
|
||||
|
||||
private filterTypings(typingsToInstall: string[]) {
|
||||
@@ -232,12 +232,12 @@ namespace ts.server.typingsInstaller {
|
||||
}
|
||||
const result: string[] = [];
|
||||
for (const typing of typingsToInstall) {
|
||||
if (this.missingTypingsSet[typing] || this.packageNameToTypingLocation[typing]) {
|
||||
if (this.missingTypingsSet.get(typing) || this.packageNameToTypingLocation.get(typing)) {
|
||||
continue;
|
||||
}
|
||||
const validationResult = validatePackageName(typing);
|
||||
if (validationResult === PackageNameValidationResult.Ok) {
|
||||
if (typing in this.typesRegistry) {
|
||||
if (this.typesRegistry.has(typing)) {
|
||||
result.push(typing);
|
||||
}
|
||||
else {
|
||||
@@ -248,7 +248,7 @@ namespace ts.server.typingsInstaller {
|
||||
}
|
||||
else {
|
||||
// add typing name to missing set so we won't process it again
|
||||
this.missingTypingsSet[typing] = true;
|
||||
this.missingTypingsSet.set(typing, true);
|
||||
if (this.log.isEnabled()) {
|
||||
switch (validationResult) {
|
||||
case PackageNameValidationResult.EmptyName:
|
||||
@@ -323,7 +323,7 @@ namespace ts.server.typingsInstaller {
|
||||
this.log.writeLine(`install request failed, marking packages as missing to prevent repeated requests: ${JSON.stringify(filteredTypings)}`);
|
||||
}
|
||||
for (const typing of filteredTypings) {
|
||||
this.missingTypingsSet[typing] = true;
|
||||
this.missingTypingsSet.set(typing, true);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -336,11 +336,11 @@ namespace ts.server.typingsInstaller {
|
||||
for (const packageName of filteredTypings) {
|
||||
const typingFile = typingToFileName(cachePath, packageName, this.installTypingHost, this.log);
|
||||
if (!typingFile) {
|
||||
this.missingTypingsSet[packageName] = true;
|
||||
this.missingTypingsSet.set(packageName, true);
|
||||
continue;
|
||||
}
|
||||
if (!this.packageNameToTypingLocation[packageName]) {
|
||||
this.packageNameToTypingLocation[packageName] = typingFile;
|
||||
if (!this.packageNameToTypingLocation.has(packageName)) {
|
||||
this.packageNameToTypingLocation.set(packageName, typingFile);
|
||||
}
|
||||
installedTypingFiles.push(typingFile);
|
||||
}
|
||||
@@ -395,7 +395,7 @@ namespace ts.server.typingsInstaller {
|
||||
}, /*pollingInterval*/ 2000);
|
||||
watchers.push(w);
|
||||
}
|
||||
this.projectWatchers[projectName] = watchers;
|
||||
this.projectWatchers.set(projectName, watchers);
|
||||
}
|
||||
|
||||
private createSetTypings(request: DiscoverTypings, typings: string[]): SetTypings {
|
||||
|
||||
+11
-10
@@ -92,7 +92,7 @@ namespace ts.server {
|
||||
};
|
||||
}
|
||||
|
||||
export function mergeMaps(target: MapLike<any>, source: MapLike <any>): void {
|
||||
export function mergeMapLikes(target: MapLike<any>, source: MapLike <any>): void {
|
||||
for (const key in source) {
|
||||
if (hasProperty(source, key)) {
|
||||
target[key] = source[key];
|
||||
@@ -142,20 +142,20 @@ namespace ts.server {
|
||||
|
||||
export function createNormalizedPathMap<T>(): NormalizedPathMap<T> {
|
||||
/* tslint:disable:no-null-keyword */
|
||||
const map: Map<T> = Object.create(null);
|
||||
const map = createMap<T>();
|
||||
/* tslint:enable:no-null-keyword */
|
||||
return {
|
||||
get(path) {
|
||||
return map[path];
|
||||
return map.get(path);
|
||||
},
|
||||
set(path, value) {
|
||||
map[path] = value;
|
||||
map.set(path, value);
|
||||
},
|
||||
contains(path) {
|
||||
return hasProperty(map, path);
|
||||
return map.has(path);
|
||||
},
|
||||
remove(path) {
|
||||
delete map[path];
|
||||
map.delete(path);
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -195,16 +195,17 @@ namespace ts.server {
|
||||
}
|
||||
|
||||
public schedule(operationId: string, delay: number, cb: () => void) {
|
||||
if (hasProperty(this.pendingTimeouts, operationId)) {
|
||||
const pendingTimeout = this.pendingTimeouts.get(operationId);
|
||||
if (pendingTimeout) {
|
||||
// another operation was already scheduled for this id - cancel it
|
||||
this.host.clearTimeout(this.pendingTimeouts[operationId]);
|
||||
this.host.clearTimeout(pendingTimeout);
|
||||
}
|
||||
// schedule new operation, pass arguments
|
||||
this.pendingTimeouts[operationId] = this.host.setTimeout(ThrottledOperations.run, delay, this, operationId, cb);
|
||||
this.pendingTimeouts.set(operationId, this.host.setTimeout(ThrottledOperations.run, delay, this, operationId, cb));
|
||||
}
|
||||
|
||||
private static run(self: ThrottledOperations, operationId: string, cb: () => void) {
|
||||
delete self.pendingTimeouts[operationId];
|
||||
self.pendingTimeouts.delete(operationId);
|
||||
cb();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -557,7 +557,7 @@ namespace ts {
|
||||
// Only bother calling into the typechecker if this is an identifier that
|
||||
// could possibly resolve to a type name. This makes classification run
|
||||
// in a third of the time it would normally take.
|
||||
if (classifiableNames[identifier.text]) {
|
||||
if (classifiableNames.get(identifier.text)) {
|
||||
const symbol = typeChecker.getSymbolAtLocation(node);
|
||||
if (symbol) {
|
||||
const type = classifySymbol(symbol, getMeaningFromLocation(node));
|
||||
|
||||
@@ -20,21 +20,21 @@ namespace ts {
|
||||
|
||||
export function registerCodeFix(action: CodeFix) {
|
||||
forEach(action.errorCodes, error => {
|
||||
let fixes = codeFixes[error];
|
||||
let fixes = codeFixes.get(error);
|
||||
if (!fixes) {
|
||||
fixes = [];
|
||||
codeFixes[error] = fixes;
|
||||
codeFixes.set(error, fixes);
|
||||
}
|
||||
fixes.push(action);
|
||||
});
|
||||
}
|
||||
|
||||
export function getSupportedErrorCodes() {
|
||||
return Object.keys(codeFixes);
|
||||
return keysOfMap(codeFixes);
|
||||
}
|
||||
|
||||
export function getFixes(context: CodeFixContext): CodeAction[] {
|
||||
const fixes = codeFixes[context.errorCode];
|
||||
const fixes = codeFixes.get(context.errorCode);
|
||||
let allActions: CodeAction[] = [];
|
||||
|
||||
forEach(fixes, f => {
|
||||
|
||||
@@ -21,18 +21,19 @@ namespace ts.codefix {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this.symbolIdToActionMap[symbolId]) {
|
||||
this.symbolIdToActionMap[symbolId] = [newAction];
|
||||
const actions = this.symbolIdToActionMap.get(symbolId);
|
||||
if (!actions) {
|
||||
this.symbolIdToActionMap.set(symbolId, [newAction]);
|
||||
return;
|
||||
}
|
||||
|
||||
if (newAction.kind === "CodeChange") {
|
||||
this.symbolIdToActionMap[symbolId].push(newAction);
|
||||
actions.push(newAction);
|
||||
return;
|
||||
}
|
||||
|
||||
const updatedNewImports: ImportCodeAction[] = [];
|
||||
for (const existingAction of this.symbolIdToActionMap[symbolId]) {
|
||||
for (const existingAction of this.symbolIdToActionMap.get(symbolId)) {
|
||||
if (existingAction.kind === "CodeChange") {
|
||||
// only import actions should compare
|
||||
updatedNewImports.push(existingAction);
|
||||
@@ -62,7 +63,7 @@ namespace ts.codefix {
|
||||
}
|
||||
// if we reach here, it means the new one is better or equal to all of the existing ones.
|
||||
updatedNewImports.push(newAction);
|
||||
this.symbolIdToActionMap[symbolId] = updatedNewImports;
|
||||
this.symbolIdToActionMap.set(symbolId, updatedNewImports);
|
||||
}
|
||||
|
||||
addActions(symbolId: number, newActions: ImportCodeAction[]) {
|
||||
@@ -73,9 +74,9 @@ namespace ts.codefix {
|
||||
|
||||
getAllActions() {
|
||||
let result: ImportCodeAction[] = [];
|
||||
for (const symbolId in this.symbolIdToActionMap) {
|
||||
result = concatenate(result, this.symbolIdToActionMap[symbolId]);
|
||||
}
|
||||
this.symbolIdToActionMap.forEach(actions => {
|
||||
result = concatenate(result, actions);
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -162,8 +163,9 @@ namespace ts.codefix {
|
||||
function getImportDeclarations(moduleSymbol: Symbol) {
|
||||
const moduleSymbolId = getUniqueSymbolId(moduleSymbol);
|
||||
|
||||
if (cachedImportDeclarations[moduleSymbolId]) {
|
||||
return cachedImportDeclarations[moduleSymbolId];
|
||||
const cached = cachedImportDeclarations.get(moduleSymbolId);
|
||||
if (cached) {
|
||||
return cached;
|
||||
}
|
||||
|
||||
const existingDeclarations: (ImportDeclaration | ImportEqualsDeclaration)[] = [];
|
||||
@@ -173,7 +175,7 @@ namespace ts.codefix {
|
||||
existingDeclarations.push(getImportDeclaration(importModuleSpecifier));
|
||||
}
|
||||
}
|
||||
cachedImportDeclarations[moduleSymbolId] = existingDeclarations;
|
||||
cachedImportDeclarations.set(moduleSymbolId, existingDeclarations);
|
||||
return existingDeclarations;
|
||||
|
||||
function getImportDeclaration(moduleSpecifier: LiteralExpression) {
|
||||
|
||||
+19
-19
@@ -64,14 +64,14 @@ namespace ts.Completions {
|
||||
const entries: CompletionEntry[] = [];
|
||||
|
||||
const nameTable = getNameTable(sourceFile);
|
||||
for (const name in nameTable) {
|
||||
nameTable.forEach((namePosition, name) => {
|
||||
// Skip identifiers produced only from the current location
|
||||
if (nameTable[name] === position) {
|
||||
continue;
|
||||
if (namePosition === position) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!uniqueNames[name]) {
|
||||
uniqueNames[name] = name;
|
||||
if (!uniqueNames.get(name)) {
|
||||
uniqueNames.set(name, name);
|
||||
const displayName = getCompletionEntryDisplayName(unescapeIdentifier(name), compilerOptions.target, /*performCharacterChecks*/ true);
|
||||
if (displayName) {
|
||||
const entry = {
|
||||
@@ -83,7 +83,7 @@ namespace ts.Completions {
|
||||
entries.push(entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return entries;
|
||||
}
|
||||
@@ -122,9 +122,9 @@ namespace ts.Completions {
|
||||
const entry = createCompletionEntry(symbol, location, performCharacterChecks);
|
||||
if (entry) {
|
||||
const id = escapeIdentifier(entry.name);
|
||||
if (!uniqueNames[id]) {
|
||||
if (!uniqueNames.get(id)) {
|
||||
entries.push(entry);
|
||||
uniqueNames[id] = id;
|
||||
uniqueNames.set(id, id);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -373,14 +373,14 @@ namespace ts.Completions {
|
||||
|
||||
const foundFileName = includeExtensions ? getBaseFileName(filePath) : removeFileExtension(getBaseFileName(filePath));
|
||||
|
||||
if (!foundFiles[foundFileName]) {
|
||||
foundFiles[foundFileName] = true;
|
||||
if (!foundFiles.get(foundFileName)) {
|
||||
foundFiles.set(foundFileName, true);
|
||||
}
|
||||
}
|
||||
|
||||
for (const foundFile in foundFiles) {
|
||||
forEachKeyInMap(foundFiles, foundFile => {
|
||||
result.push(createCompletionEntryForModule(foundFile, ScriptElementKind.scriptElement, span));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// If possible, get folder completion as well
|
||||
@@ -1563,14 +1563,14 @@ namespace ts.Completions {
|
||||
}
|
||||
|
||||
const name = element.propertyName || element.name;
|
||||
existingImportsOrExports[name.text] = true;
|
||||
existingImportsOrExports.set(name.text, true);
|
||||
}
|
||||
|
||||
if (!someProperties(existingImportsOrExports)) {
|
||||
if (mapIsEmpty(existingImportsOrExports)) {
|
||||
return filter(exportsOfModule, e => e.name !== "default");
|
||||
}
|
||||
|
||||
return filter(exportsOfModule, e => e.name !== "default" && !existingImportsOrExports[e.name]);
|
||||
return filter(exportsOfModule, e => e.name !== "default" && !existingImportsOrExports.get(e.name));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1616,10 +1616,10 @@ namespace ts.Completions {
|
||||
existingName = (<Identifier>m.name).text;
|
||||
}
|
||||
|
||||
existingMemberNames[existingName] = true;
|
||||
existingMemberNames.set(existingName, true);
|
||||
}
|
||||
|
||||
return filter(contextualMemberSymbols, m => !existingMemberNames[m.name]);
|
||||
return filter(contextualMemberSymbols, m => !existingMemberNames.get(m.name));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1637,11 +1637,11 @@ namespace ts.Completions {
|
||||
}
|
||||
|
||||
if (attr.kind === SyntaxKind.JsxAttribute) {
|
||||
seenNames[(<JsxAttribute>attr).name.text] = true;
|
||||
seenNames.set((<JsxAttribute>attr).name.text, true);
|
||||
}
|
||||
}
|
||||
|
||||
return filter(symbols, a => !seenNames[a.name]);
|
||||
return filter(symbols, a => !seenNames.get(a.name));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -44,11 +44,11 @@ namespace ts.DocumentHighlights {
|
||||
for (const referencedSymbol of referencedSymbols) {
|
||||
for (const referenceEntry of referencedSymbol.references) {
|
||||
const fileName = referenceEntry.fileName;
|
||||
let documentHighlights = fileNameToDocumentHighlights[fileName];
|
||||
let documentHighlights = fileNameToDocumentHighlights.get(fileName);
|
||||
if (!documentHighlights) {
|
||||
documentHighlights = { fileName, highlightSpans: [] };
|
||||
|
||||
fileNameToDocumentHighlights[fileName] = documentHighlights;
|
||||
fileNameToDocumentHighlights.set(fileName, documentHighlights);
|
||||
result.push(documentHighlights);
|
||||
}
|
||||
|
||||
|
||||
@@ -113,16 +113,16 @@ namespace ts {
|
||||
}
|
||||
|
||||
function getBucketForCompilationSettings(key: DocumentRegistryBucketKey, createIfMissing: boolean): FileMap<DocumentRegistryEntry> {
|
||||
let bucket = buckets[key];
|
||||
let bucket = buckets.get(key);
|
||||
if (!bucket && createIfMissing) {
|
||||
buckets[key] = bucket = createFileMap<DocumentRegistryEntry>();
|
||||
buckets.set(key, bucket = createFileMap<DocumentRegistryEntry>());
|
||||
}
|
||||
return bucket;
|
||||
}
|
||||
|
||||
function reportStats() {
|
||||
const bucketInfoArray = Object.keys(buckets).filter(name => name && name.charAt(0) === "_").map(name => {
|
||||
const entries = buckets[name];
|
||||
const bucketInfoArray = keysOfMap(buckets).filter(name => name && name.charAt(0) === "_").map(name => {
|
||||
const entries = buckets.get(name);
|
||||
const sourceFiles: { name: string; refCount: number; references: string[]; }[] = [];
|
||||
entries.forEachValue((key, entry) => {
|
||||
sourceFiles.push({
|
||||
|
||||
@@ -96,7 +96,7 @@ namespace ts.FindAllReferences {
|
||||
|
||||
const nameTable = getNameTable(sourceFile);
|
||||
|
||||
if (nameTable[internedName] !== undefined) {
|
||||
if (nameTable.get(internedName) !== undefined) {
|
||||
result = result || [];
|
||||
getReferencesInNode(sourceFile, symbol, declaredName, node, searchMeaning, findInStrings, findInComments, result, symbolToIndex);
|
||||
}
|
||||
@@ -501,14 +501,14 @@ namespace ts.FindAllReferences {
|
||||
function findOwnConstructorCalls(classSymbol: Symbol): Node[] {
|
||||
const result: Node[] = [];
|
||||
|
||||
for (const decl of classSymbol.members["__constructor"].declarations) {
|
||||
for (const decl of classSymbol.members.get("__constructor").declarations) {
|
||||
Debug.assert(decl.kind === SyntaxKind.Constructor);
|
||||
const ctrKeyword = decl.getChildAt(0);
|
||||
Debug.assert(ctrKeyword.kind === SyntaxKind.ConstructorKeyword);
|
||||
result.push(ctrKeyword);
|
||||
}
|
||||
|
||||
forEachProperty(classSymbol.exports, member => {
|
||||
forEachInMap(classSymbol.exports, member => {
|
||||
const decl = member.valueDeclaration;
|
||||
if (decl && decl.kind === SyntaxKind.MethodDeclaration) {
|
||||
const body = (<MethodDeclaration>decl).body;
|
||||
@@ -528,7 +528,7 @@ namespace ts.FindAllReferences {
|
||||
/** Find references to `super` in the constructor of an extending class. */
|
||||
function superConstructorAccesses(cls: ClassLikeDeclaration): Node[] {
|
||||
const symbol = cls.symbol;
|
||||
const ctr = symbol.members["__constructor"];
|
||||
const ctr = symbol.members.get("__constructor");
|
||||
if (!ctr) {
|
||||
return [];
|
||||
}
|
||||
@@ -715,12 +715,13 @@ namespace ts.FindAllReferences {
|
||||
}
|
||||
|
||||
const key = getSymbolId(symbol) + "," + getSymbolId(parent);
|
||||
if (key in cachedResults) {
|
||||
return cachedResults[key];
|
||||
const cached = cachedResults.get(key);
|
||||
if (cached !== undefined) {
|
||||
return cached;
|
||||
}
|
||||
|
||||
// Set the key so that we don't infinitely recurse
|
||||
cachedResults[key] = false;
|
||||
cachedResults.set(key, false);
|
||||
|
||||
const inherits = forEach(symbol.getDeclarations(), declaration => {
|
||||
if (isClassLike(declaration)) {
|
||||
@@ -744,7 +745,7 @@ namespace ts.FindAllReferences {
|
||||
return false;
|
||||
});
|
||||
|
||||
cachedResults[key] = inherits;
|
||||
cachedResults.set(key, inherits);
|
||||
return inherits;
|
||||
}
|
||||
|
||||
@@ -1078,7 +1079,7 @@ namespace ts.FindAllReferences {
|
||||
// the function will add any found symbol of the property-name, then its sub-routine will call
|
||||
// getPropertySymbolsFromBaseTypes again to walk up any base types to prevent revisiting already
|
||||
// visited symbol, interface "C", the sub-routine will pass the current symbol as previousIterationSymbol.
|
||||
if (symbol.name in previousIterationSymbolsCache) {
|
||||
if (previousIterationSymbolsCache.has(symbol.name)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1105,7 +1106,7 @@ namespace ts.FindAllReferences {
|
||||
}
|
||||
|
||||
// Visit the typeReference as well to see if it directly or indirectly use that property
|
||||
previousIterationSymbolsCache[symbol.name] = symbol;
|
||||
previousIterationSymbolsCache.set(symbol.name, symbol);
|
||||
getPropertySymbolsFromBaseTypes(type.symbol, propertyName, result, previousIterationSymbolsCache);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
namespace ts.formatting {
|
||||
export class Rules {
|
||||
public getRuleName(rule: Rule) {
|
||||
const o: ts.Map<any> = <any>this;
|
||||
const o: ts.MapLike<any> = <any>this;
|
||||
for (const name in o) {
|
||||
if (o[name] === rule) {
|
||||
return name;
|
||||
|
||||
@@ -14,7 +14,7 @@ namespace ts.GoToDefinition {
|
||||
// Type reference directives
|
||||
const typeReferenceDirective = findReferenceInPosition(sourceFile.typeReferenceDirectives, position);
|
||||
if (typeReferenceDirective) {
|
||||
const referenceFile = program.getResolvedTypeReferenceDirectives()[typeReferenceDirective.fileName];
|
||||
const referenceFile = program.getResolvedTypeReferenceDirectives().get(typeReferenceDirective.fileName);
|
||||
if (referenceFile && referenceFile.resolvedFileName) {
|
||||
return [getDefinitionInfoForFileReference(typeReferenceDirective.fileName, referenceFile.resolvedFileName)];
|
||||
}
|
||||
|
||||
+20
-20
@@ -17,11 +17,11 @@ namespace ts.JsTyping {
|
||||
|
||||
interface PackageJson {
|
||||
_requiredBy?: string[];
|
||||
dependencies?: Map<string>;
|
||||
devDependencies?: Map<string>;
|
||||
dependencies?: MapLike<string>;
|
||||
devDependencies?: MapLike<string>;
|
||||
name?: string;
|
||||
optionalDependencies?: Map<string>;
|
||||
peerDependencies?: Map<string>;
|
||||
optionalDependencies?: MapLike<string>;
|
||||
peerDependencies?: MapLike<string>;
|
||||
typings?: string;
|
||||
};
|
||||
|
||||
@@ -107,34 +107,34 @@ namespace ts.JsTyping {
|
||||
// add typings for unresolved imports
|
||||
if (unresolvedImports) {
|
||||
for (const moduleId of unresolvedImports) {
|
||||
const typingName = moduleId in nodeCoreModules ? "node" : moduleId;
|
||||
if (!(typingName in inferredTypings)) {
|
||||
inferredTypings[typingName] = undefined;
|
||||
const typingName = nodeCoreModules.has(moduleId) ? "node" : moduleId;
|
||||
if (!inferredTypings.has(typingName)) {
|
||||
inferredTypings.set(typingName, undefined);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Add the cached typing locations for inferred typings that are already installed
|
||||
for (const name in packageNameToTypingLocation) {
|
||||
if (name in inferredTypings && !inferredTypings[name]) {
|
||||
inferredTypings[name] = packageNameToTypingLocation[name];
|
||||
packageNameToTypingLocation.forEach((typingLocation, name) => {
|
||||
if (inferredTypings.has(name) && inferredTypings.get(name) === undefined) {
|
||||
inferredTypings.set(name, typingLocation);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Remove typings that the user has added to the exclude list
|
||||
for (const excludeTypingName of exclude) {
|
||||
delete inferredTypings[excludeTypingName];
|
||||
inferredTypings.delete(excludeTypingName);
|
||||
}
|
||||
|
||||
const newTypingNames: string[] = [];
|
||||
const cachedTypingPaths: string[] = [];
|
||||
for (const typing in inferredTypings) {
|
||||
if (inferredTypings[typing] !== undefined) {
|
||||
cachedTypingPaths.push(inferredTypings[typing]);
|
||||
inferredTypings.forEach((inferred, typing) => {
|
||||
if (inferred !== undefined) {
|
||||
cachedTypingPaths.push(inferred);
|
||||
}
|
||||
else {
|
||||
newTypingNames.push(typing);
|
||||
}
|
||||
}
|
||||
});
|
||||
return { cachedTypingPaths, newTypingNames, filesToWatch };
|
||||
|
||||
/**
|
||||
@@ -146,8 +146,8 @@ namespace ts.JsTyping {
|
||||
}
|
||||
|
||||
for (const typing of typingNames) {
|
||||
if (!(typing in inferredTypings)) {
|
||||
inferredTypings[typing] = undefined;
|
||||
if (!inferredTypings.has(typing)) {
|
||||
inferredTypings.set(typing, undefined);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -189,7 +189,7 @@ namespace ts.JsTyping {
|
||||
const cleanedTypingNames = map(inferredTypingNames, f => f.replace(/((?:\.|-)min(?=\.|$))|((?:-|\.)\d+)/g, ""));
|
||||
|
||||
if (safeList !== EmptySafeList) {
|
||||
mergeTypings(filter(cleanedTypingNames, f => f in safeList));
|
||||
mergeTypings(filter(cleanedTypingNames, f => safeList.has(f)));
|
||||
}
|
||||
|
||||
const hasJsxFile = forEach(fileNames, f => ensureScriptKind(f, getScriptKindFromFileName(f)) === ScriptKind.JSX);
|
||||
@@ -236,7 +236,7 @@ namespace ts.JsTyping {
|
||||
}
|
||||
if (packageJson.typings) {
|
||||
const absolutePath = getNormalizedAbsolutePath(packageJson.typings, getDirectoryPath(normalizedFileName));
|
||||
inferredTypings[packageJson.name] = absolutePath;
|
||||
inferredTypings.set(packageJson.name, absolutePath);
|
||||
}
|
||||
else {
|
||||
typingNames.push(packageJson.name);
|
||||
|
||||
@@ -7,23 +7,21 @@ namespace ts.NavigateTo {
|
||||
let rawItems: RawNavigateToItem[] = [];
|
||||
|
||||
// Search the declarations in all files and output matched NavigateToItem into array of NavigateToItem[]
|
||||
forEach(sourceFiles, sourceFile => {
|
||||
for (const sourceFile of sourceFiles) {
|
||||
cancellationToken.throwIfCancellationRequested();
|
||||
|
||||
if (excludeDtsFiles && fileExtensionIs(sourceFile.fileName, ".d.ts")) {
|
||||
return;
|
||||
continue;
|
||||
}
|
||||
|
||||
const nameToDeclarations = sourceFile.getNamedDeclarations();
|
||||
for (const name in nameToDeclarations) {
|
||||
const declarations = nameToDeclarations[name];
|
||||
forEachInMap(sourceFile.getNamedDeclarations(), (declarations, name) => {
|
||||
if (declarations) {
|
||||
// First do a quick check to see if the name of the declaration matches the
|
||||
// last portion of the (possibly) dotted name they're searching for.
|
||||
let matches = patternMatcher.getMatchesForLastSegmentOfPattern(name);
|
||||
|
||||
if (!matches) {
|
||||
continue;
|
||||
return; // continue to next named declarations
|
||||
}
|
||||
|
||||
for (const declaration of declarations) {
|
||||
@@ -32,13 +30,13 @@ namespace ts.NavigateTo {
|
||||
if (patternMatcher.patternContainsDots) {
|
||||
const containers = getContainers(declaration);
|
||||
if (!containers) {
|
||||
return undefined;
|
||||
return true; // Break out of named declarations and go to the next source file.
|
||||
}
|
||||
|
||||
matches = patternMatcher.getMatches(containers, name);
|
||||
|
||||
if (!matches) {
|
||||
continue;
|
||||
return; // continue to next named declarations
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,8 +45,8 @@ namespace ts.NavigateTo {
|
||||
rawItems.push({ name, fileName, matchKind, isCaseSensitive: allMatchesAreCaseSensitive(matches), declaration });
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Remove imports when the imported declaration is already in the list and has the same name.
|
||||
rawItems = filter(rawItems, item => {
|
||||
|
||||
@@ -248,9 +248,9 @@ namespace ts.NavigationBar {
|
||||
return true;
|
||||
}
|
||||
|
||||
const itemsWithSameName = nameToItems[name];
|
||||
const itemsWithSameName = nameToItems.get(name);
|
||||
if (!itemsWithSameName) {
|
||||
nameToItems[name] = child;
|
||||
nameToItems.set(name, child);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -268,7 +268,7 @@ namespace ts.NavigationBar {
|
||||
if (tryMerge(itemWithSameName, child)) {
|
||||
return false;
|
||||
}
|
||||
nameToItems[name] = [itemWithSameName, child];
|
||||
nameToItems.set(name, [itemWithSameName, child]);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -626,15 +626,15 @@ namespace ts.NavigationBar {
|
||||
|
||||
/**
|
||||
* Matches all whitespace characters in a string. Eg:
|
||||
*
|
||||
*
|
||||
* "app.
|
||||
*
|
||||
*
|
||||
* onactivated"
|
||||
*
|
||||
*
|
||||
* matches because of the newline, whereas
|
||||
*
|
||||
*
|
||||
* "app.onactivated"
|
||||
*
|
||||
*
|
||||
* does not match.
|
||||
*/
|
||||
const whiteSpaceRegex = /\s+/g;
|
||||
|
||||
@@ -188,11 +188,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function getWordSpans(word: string): TextSpan[] {
|
||||
if (!(word in stringToWordSpans)) {
|
||||
stringToWordSpans[word] = breakIntoWordSpans(word);
|
||||
}
|
||||
|
||||
return stringToWordSpans[word];
|
||||
return stringToWordSpans.get(word) || set(stringToWordSpans, word, breakIntoWordSpans(word));
|
||||
}
|
||||
|
||||
function matchTextChunk(candidate: string, chunk: TextChunk, punctuationStripped: boolean): PatternMatch {
|
||||
|
||||
@@ -532,7 +532,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function getDeclarations(name: string) {
|
||||
return result[name] || (result[name] = []);
|
||||
return result.get(name) || set(result, name, []);
|
||||
}
|
||||
|
||||
function getDeclarationName(declaration: Declaration) {
|
||||
@@ -1956,9 +1956,11 @@ namespace ts {
|
||||
|
||||
function walk(node: Node) {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.Identifier:
|
||||
nameTable[(<Identifier>node).text] = nameTable[(<Identifier>node).text] === undefined ? node.pos : -1;
|
||||
case SyntaxKind.Identifier: {
|
||||
const text = (<Identifier>node).text;
|
||||
nameTable.set(text, nameTable.get(text) === undefined ? node.pos : -1);
|
||||
break;
|
||||
}
|
||||
case SyntaxKind.StringLiteral:
|
||||
case SyntaxKind.NumericLiteral:
|
||||
// We want to store any numbers/strings if they were a name that could be
|
||||
@@ -1970,7 +1972,8 @@ namespace ts {
|
||||
isArgumentOfElementAccessExpression(node) ||
|
||||
isLiteralComputedPropertyDeclarationName(node)) {
|
||||
|
||||
nameTable[(<LiteralExpression>node).text] = nameTable[(<LiteralExpression>node).text] === undefined ? node.pos : -1;
|
||||
const text = (<LiteralExpression>node).text;
|
||||
nameTable.set(text, nameTable.get(text) === undefined ? node.pos : -1);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
||||
@@ -237,7 +237,7 @@ namespace ts.SignatureHelp {
|
||||
const typeChecker = program.getTypeChecker();
|
||||
for (const sourceFile of program.getSourceFiles()) {
|
||||
const nameToDeclarations = sourceFile.getNamedDeclarations();
|
||||
const declarations = nameToDeclarations[name.text];
|
||||
const declarations = nameToDeclarations.get(name.text);
|
||||
|
||||
if (declarations) {
|
||||
for (const declaration of declarations) {
|
||||
|
||||
@@ -126,7 +126,7 @@ namespace ts {
|
||||
function fixupCompilerOptions(options: CompilerOptions, diagnostics: Diagnostic[]): CompilerOptions {
|
||||
// Lazily create this value to fix module loading errors.
|
||||
commandLineOptionsStringToEnum = commandLineOptionsStringToEnum || <CommandLineOptionOfCustomType[]>filter(optionDeclarations, o =>
|
||||
typeof o.type === "object" && !forEachProperty(o.type, v => typeof v !== "number"));
|
||||
typeof o.type === "object" && !forEachInMap(o.type, v => typeof v !== "number"));
|
||||
|
||||
options = clone(options);
|
||||
|
||||
@@ -142,7 +142,7 @@ namespace ts {
|
||||
options[opt.name] = parseCustomTypeOption(opt, value, diagnostics);
|
||||
}
|
||||
else {
|
||||
if (!forEachProperty(opt.type, v => v === value)) {
|
||||
if (!someInMap(opt.type, v => v === value)) {
|
||||
// Supplied value isn't a valid enum value.
|
||||
diagnostics.push(createCompilerDiagnosticForInvalidCustomType(opt));
|
||||
}
|
||||
|
||||
@@ -9,8 +9,8 @@ var a: any;
|
||||
>a : any
|
||||
|
||||
var v = {
|
||||
>v : { [x: string]: () => void; [x: number]: () => void; [0](): void; [""](): void; }
|
||||
>{ [s]() { }, [n]() { }, [s + s]() { }, [s + n]() { }, [+s]() { }, [""]() { }, [0]() { }, [a]() { }, [<any>true]() { }, [`hello bye`]() { }, [`hello ${a} bye`]() { }} : { [x: string]: () => void; [x: number]: () => void; [0](): void; [""](): void; }
|
||||
>v : { [x: string]: () => void; [x: number]: () => void; [""](): void; [0](): void; }
|
||||
>{ [s]() { }, [n]() { }, [s + s]() { }, [s + n]() { }, [+s]() { }, [""]() { }, [0]() { }, [a]() { }, [<any>true]() { }, [`hello bye`]() { }, [`hello ${a} bye`]() { }} : { [x: string]: () => void; [x: number]: () => void; [""](): void; [0](): void; }
|
||||
|
||||
[s]() { },
|
||||
>s : string
|
||||
|
||||
@@ -9,8 +9,8 @@ var a: any;
|
||||
>a : any
|
||||
|
||||
var v = {
|
||||
>v : { [x: string]: () => void; [x: number]: () => void; [0](): void; [""](): void; }
|
||||
>{ [s]() { }, [n]() { }, [s + s]() { }, [s + n]() { }, [+s]() { }, [""]() { }, [0]() { }, [a]() { }, [<any>true]() { }, [`hello bye`]() { }, [`hello ${a} bye`]() { }} : { [x: string]: () => void; [x: number]: () => void; [0](): void; [""](): void; }
|
||||
>v : { [x: string]: () => void; [x: number]: () => void; [""](): void; [0](): void; }
|
||||
>{ [s]() { }, [n]() { }, [s + s]() { }, [s + n]() { }, [+s]() { }, [""]() { }, [0]() { }, [a]() { }, [<any>true]() { }, [`hello bye`]() { }, [`hello ${a} bye`]() { }} : { [x: string]: () => void; [x: number]: () => void; [""](): void; [0](): void; }
|
||||
|
||||
[s]() { },
|
||||
>s : string
|
||||
|
||||
@@ -9,8 +9,8 @@ var a: any;
|
||||
>a : any
|
||||
|
||||
var v = {
|
||||
>v : { [x: string]: any; [x: number]: any; readonly [0]: number; [""]: any; }
|
||||
>{ get [s]() { return 0; }, set [n](v) { }, get [s + s]() { return 0; }, set [s + n](v) { }, get [+s]() { return 0; }, set [""](v) { }, get [0]() { return 0; }, set [a](v) { }, get [<any>true]() { return 0; }, set [`hello bye`](v) { }, get [`hello ${a} bye`]() { return 0; }} : { [x: string]: any; [x: number]: any; readonly [0]: number; [""]: any; }
|
||||
>v : { [x: string]: any; [x: number]: any; [""]: any; readonly [0]: number; }
|
||||
>{ get [s]() { return 0; }, set [n](v) { }, get [s + s]() { return 0; }, set [s + n](v) { }, get [+s]() { return 0; }, set [""](v) { }, get [0]() { return 0; }, set [a](v) { }, get [<any>true]() { return 0; }, set [`hello bye`](v) { }, get [`hello ${a} bye`]() { return 0; }} : { [x: string]: any; [x: number]: any; [""]: any; readonly [0]: number; }
|
||||
|
||||
get [s]() { return 0; },
|
||||
>s : string
|
||||
|
||||
@@ -9,8 +9,8 @@ var a: any;
|
||||
>a : any
|
||||
|
||||
var v = {
|
||||
>v : { [x: string]: any; [x: number]: any; readonly [0]: number; [""]: any; }
|
||||
>{ get [s]() { return 0; }, set [n](v) { }, get [s + s]() { return 0; }, set [s + n](v) { }, get [+s]() { return 0; }, set [""](v) { }, get [0]() { return 0; }, set [a](v) { }, get [<any>true]() { return 0; }, set [`hello bye`](v) { }, get [`hello ${a} bye`]() { return 0; }} : { [x: string]: any; [x: number]: any; readonly [0]: number; [""]: any; }
|
||||
>v : { [x: string]: any; [x: number]: any; [""]: any; readonly [0]: number; }
|
||||
>{ get [s]() { return 0; }, set [n](v) { }, get [s + s]() { return 0; }, set [s + n](v) { }, get [+s]() { return 0; }, set [""](v) { }, get [0]() { return 0; }, set [a](v) { }, get [<any>true]() { return 0; }, set [`hello bye`](v) { }, get [`hello ${a} bye`]() { return 0; }} : { [x: string]: any; [x: number]: any; [""]: any; readonly [0]: number; }
|
||||
|
||||
get [s]() { return 0; },
|
||||
>s : string
|
||||
|
||||
@@ -9,8 +9,8 @@ var a: any;
|
||||
>a : any
|
||||
|
||||
var v = {
|
||||
>v : { [x: string]: string | number; [x: number]: string | number; [0]: number; [""]: number; }
|
||||
>{ [s]: 0, [n]: n, [s + s]: 1, [s + n]: 2, [+s]: s, [""]: 0, [0]: 0, [a]: 1, [<any>true]: 0, [`hello bye`]: 0, [`hello ${a} bye`]: 0} : { [x: string]: string | number; [x: number]: string | number; [0]: number; [""]: number; }
|
||||
>v : { [x: string]: string | number; [x: number]: string | number; [""]: number; [0]: number; }
|
||||
>{ [s]: 0, [n]: n, [s + s]: 1, [s + n]: 2, [+s]: s, [""]: 0, [0]: 0, [a]: 1, [<any>true]: 0, [`hello bye`]: 0, [`hello ${a} bye`]: 0} : { [x: string]: string | number; [x: number]: string | number; [""]: number; [0]: number; }
|
||||
|
||||
[s]: 0,
|
||||
>s : string
|
||||
|
||||
@@ -9,8 +9,8 @@ var a: any;
|
||||
>a : any
|
||||
|
||||
var v = {
|
||||
>v : { [x: string]: string | number; [x: number]: string | number; [0]: number; [""]: number; }
|
||||
>{ [s]: 0, [n]: n, [s + s]: 1, [s + n]: 2, [+s]: s, [""]: 0, [0]: 0, [a]: 1, [<any>true]: 0, [`hello bye`]: 0, [`hello ${a} bye`]: 0} : { [x: string]: string | number; [x: number]: string | number; [0]: number; [""]: number; }
|
||||
>v : { [x: string]: string | number; [x: number]: string | number; [""]: number; [0]: number; }
|
||||
>{ [s]: 0, [n]: n, [s + s]: 1, [s + n]: 2, [+s]: s, [""]: 0, [0]: 0, [a]: 1, [<any>true]: 0, [`hello bye`]: 0, [`hello ${a} bye`]: 0} : { [x: string]: string | number; [x: number]: string | number; [""]: number; [0]: number; }
|
||||
|
||||
[s]: 0,
|
||||
>s : string
|
||||
|
||||
@@ -19,7 +19,7 @@ declare function foo<T>(obj: I<T>): T
|
||||
foo({
|
||||
>foo({ p: "", 0: () => { }, ["hi" + "bye"]: true, [0 + 1]: 0, [+"hi"]: [0]}) : string | number | boolean | (() => void) | number[]
|
||||
>foo : <T>(obj: I<T>) => T
|
||||
>{ p: "", 0: () => { }, ["hi" + "bye"]: true, [0 + 1]: 0, [+"hi"]: [0]} : { [x: string]: true | "" | (() => void) | 0 | number[]; [x: number]: (() => void) | 0 | number[]; 0: () => void; p: ""; }
|
||||
>{ p: "", 0: () => { }, ["hi" + "bye"]: true, [0 + 1]: 0, [+"hi"]: [0]} : { [x: string]: true | "" | (() => void) | 0 | number[]; [x: number]: (() => void) | 0 | number[]; p: ""; 0: () => void; }
|
||||
|
||||
p: "",
|
||||
>p : string
|
||||
|
||||
@@ -19,7 +19,7 @@ declare function foo<T>(obj: I<T>): T
|
||||
foo({
|
||||
>foo({ p: "", 0: () => { }, ["hi" + "bye"]: true, [0 + 1]: 0, [+"hi"]: [0]}) : string | number | boolean | (() => void) | number[]
|
||||
>foo : <T>(obj: I<T>) => T
|
||||
>{ p: "", 0: () => { }, ["hi" + "bye"]: true, [0 + 1]: 0, [+"hi"]: [0]} : { [x: string]: true | "" | (() => void) | 0 | number[]; [x: number]: (() => void) | 0 | number[]; 0: () => void; p: ""; }
|
||||
>{ p: "", 0: () => { }, ["hi" + "bye"]: true, [0 + 1]: 0, [+"hi"]: [0]} : { [x: string]: true | "" | (() => void) | 0 | number[]; [x: number]: (() => void) | 0 | number[]; p: ""; 0: () => void; }
|
||||
|
||||
p: "",
|
||||
>p : string
|
||||
|
||||
+8
-8
@@ -1,8 +1,8 @@
|
||||
=== tests/cases/conformance/es7/exponentiationOperator/emitCompoundExponentiationAssignmentWithIndexingOnLHS3.ts ===
|
||||
|
||||
var object = {
|
||||
>object : { 0: number; _0: number; }
|
||||
>{ _0: 2, get 0() { return this._0; }, set 0(x: number) { this._0 = x; },} : { 0: number; _0: number; }
|
||||
>object : { _0: number; 0: number; }
|
||||
>{ _0: 2, get 0() { return this._0; }, set 0(x: number) { this._0 = x; },} : { _0: number; 0: number; }
|
||||
|
||||
_0: 2,
|
||||
>_0 : number
|
||||
@@ -30,31 +30,31 @@ var object = {
|
||||
object[0] **= object[0];
|
||||
>object[0] **= object[0] : number
|
||||
>object[0] : number
|
||||
>object : { 0: number; _0: number; }
|
||||
>object : { _0: number; 0: number; }
|
||||
>0 : 0
|
||||
>object[0] : number
|
||||
>object : { 0: number; _0: number; }
|
||||
>object : { _0: number; 0: number; }
|
||||
>0 : 0
|
||||
|
||||
object[0] **= object[0] **= 2;
|
||||
>object[0] **= object[0] **= 2 : number
|
||||
>object[0] : number
|
||||
>object : { 0: number; _0: number; }
|
||||
>object : { _0: number; 0: number; }
|
||||
>0 : 0
|
||||
>object[0] **= 2 : number
|
||||
>object[0] : number
|
||||
>object : { 0: number; _0: number; }
|
||||
>object : { _0: number; 0: number; }
|
||||
>0 : 0
|
||||
>2 : 2
|
||||
|
||||
object[0] **= object[0] ** 2;
|
||||
>object[0] **= object[0] ** 2 : number
|
||||
>object[0] : number
|
||||
>object : { 0: number; _0: number; }
|
||||
>object : { _0: number; 0: number; }
|
||||
>0 : 0
|
||||
>object[0] ** 2 : number
|
||||
>object[0] : number
|
||||
>object : { 0: number; _0: number; }
|
||||
>object : { _0: number; 0: number; }
|
||||
>0 : 0
|
||||
>2 : 2
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ tests/cases/conformance/types/objectTypeLiteral/indexSignatures/numericIndexerCo
|
||||
tests/cases/conformance/types/objectTypeLiteral/indexSignatures/numericIndexerConstrainsPropertyDeclarations.ts(36,16): error TS1056: Accessors are only available when targeting ECMAScript 5 and higher.
|
||||
tests/cases/conformance/types/objectTypeLiteral/indexSignatures/numericIndexerConstrainsPropertyDeclarations.ts(50,5): error TS2412: Property '2.0' of type 'number' is not assignable to numeric index type 'string'.
|
||||
tests/cases/conformance/types/objectTypeLiteral/indexSignatures/numericIndexerConstrainsPropertyDeclarations.ts(68,5): error TS2412: Property '2.0' of type 'number' is not assignable to numeric index type 'string'.
|
||||
tests/cases/conformance/types/objectTypeLiteral/indexSignatures/numericIndexerConstrainsPropertyDeclarations.ts(79,5): error TS2322: Type '{ 1.0: string; 2.0: number; a: string; b: number; c: () => void; "d": string; "e": number; "3.0": string; "4.0": number; f: any; X: string; foo(): string; }' is not assignable to type '{ [x: number]: string; }'.
|
||||
tests/cases/conformance/types/objectTypeLiteral/indexSignatures/numericIndexerConstrainsPropertyDeclarations.ts(79,5): error TS2322: Type '{ a: string; b: number; c: () => void; "d": string; "e": number; 1.0: string; 2.0: number; "3.0": string; "4.0": number; f: any; X: string; foo(): string; }' is not assignable to type '{ [x: number]: string; }'.
|
||||
Object literal may only specify known properties, and 'a' does not exist in type '{ [x: number]: string; }'.
|
||||
tests/cases/conformance/types/objectTypeLiteral/indexSignatures/numericIndexerConstrainsPropertyDeclarations.ts(88,9): error TS2304: Cannot find name 'Myn'.
|
||||
tests/cases/conformance/types/objectTypeLiteral/indexSignatures/numericIndexerConstrainsPropertyDeclarations.ts(90,9): error TS1056: Accessors are only available when targeting ECMAScript 5 and higher.
|
||||
@@ -107,7 +107,7 @@ tests/cases/conformance/types/objectTypeLiteral/indexSignatures/numericIndexerCo
|
||||
var b: { [x: number]: string; } = {
|
||||
a: '',
|
||||
~~~~~
|
||||
!!! error TS2322: Type '{ 1.0: string; 2.0: number; a: string; b: number; c: () => void; "d": string; "e": number; "3.0": string; "4.0": number; f: any; X: string; foo(): string; }' is not assignable to type '{ [x: number]: string; }'.
|
||||
!!! error TS2322: Type '{ a: string; b: number; c: () => void; "d": string; "e": number; 1.0: string; 2.0: number; "3.0": string; "4.0": number; f: any; X: string; foo(): string; }' is not assignable to type '{ [x: number]: string; }'.
|
||||
!!! error TS2322: Object literal may only specify known properties, and 'a' does not exist in type '{ [x: number]: string; }'.
|
||||
b: 1,
|
||||
c: () => { },
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
tests/cases/conformance/types/objectTypeLiteral/indexSignatures/numericIndexerConstrainsPropertyDeclarations2.ts(16,5): error TS2412: Property '3.0' of type 'number' is not assignable to numeric index type 'A'.
|
||||
tests/cases/conformance/types/objectTypeLiteral/indexSignatures/numericIndexerConstrainsPropertyDeclarations2.ts(25,5): error TS2412: Property '3.0' of type 'number' is not assignable to numeric index type 'A'.
|
||||
tests/cases/conformance/types/objectTypeLiteral/indexSignatures/numericIndexerConstrainsPropertyDeclarations2.ts(34,5): error TS2412: Property '3.0' of type 'number' is not assignable to numeric index type 'A'.
|
||||
tests/cases/conformance/types/objectTypeLiteral/indexSignatures/numericIndexerConstrainsPropertyDeclarations2.ts(44,5): error TS2322: Type '{ 1.0: A; 2.0: B; 3.0: number; "2.5": B; "4.0": string; }' is not assignable to type '{ [x: number]: A; }'.
|
||||
tests/cases/conformance/types/objectTypeLiteral/indexSignatures/numericIndexerConstrainsPropertyDeclarations2.ts(44,5): error TS2322: Type '{ 1.0: A; 2.0: B; "2.5": B; 3.0: number; "4.0": string; }' is not assignable to type '{ [x: number]: A; }'.
|
||||
Object literal may only specify known properties, and '"4.0"' does not exist in type '{ [x: number]: A; }'.
|
||||
|
||||
|
||||
@@ -57,6 +57,6 @@ tests/cases/conformance/types/objectTypeLiteral/indexSignatures/numericIndexerCo
|
||||
3.0: 1,
|
||||
"4.0": ''
|
||||
~~~~~~~~~
|
||||
!!! error TS2322: Type '{ 1.0: A; 2.0: B; 3.0: number; "2.5": B; "4.0": string; }' is not assignable to type '{ [x: number]: A; }'.
|
||||
!!! error TS2322: Type '{ 1.0: A; 2.0: B; "2.5": B; 3.0: number; "4.0": string; }' is not assignable to type '{ [x: number]: A; }'.
|
||||
!!! error TS2322: Object literal may only specify known properties, and '"4.0"' does not exist in type '{ [x: number]: A; }'.
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
tests/cases/compiler/numericIndexerConstraint5.ts(2,5): error TS2322: Type '{ 0: Date; name: string; }' is not assignable to type '{ [name: number]: string; }'.
|
||||
tests/cases/compiler/numericIndexerConstraint5.ts(2,5): error TS2322: Type '{ name: string; 0: Date; }' is not assignable to type '{ [name: number]: string; }'.
|
||||
Property '0' is incompatible with index signature.
|
||||
Type 'Date' is not assignable to type 'string'.
|
||||
|
||||
@@ -7,6 +7,6 @@ tests/cases/compiler/numericIndexerConstraint5.ts(2,5): error TS2322: Type '{ 0:
|
||||
var x = { name: "x", 0: new Date() };
|
||||
var z: { [name: number]: string } = x;
|
||||
~
|
||||
!!! error TS2322: Type '{ 0: Date; name: string; }' is not assignable to type '{ [name: number]: string; }'.
|
||||
!!! error TS2322: Type '{ name: string; 0: Date; }' is not assignable to type '{ [name: number]: string; }'.
|
||||
!!! error TS2322: Property '0' is incompatible with index signature.
|
||||
!!! error TS2322: Type 'Date' is not assignable to type 'string'.
|
||||
@@ -1,8 +1,8 @@
|
||||
tests/cases/compiler/objectLiteralIndexerErrors.ts(13,5): error TS2322: Type '{ 0: A; x: B; }' is not assignable to type '{ [s: string]: A; [n: number]: B; }'.
|
||||
tests/cases/compiler/objectLiteralIndexerErrors.ts(13,5): error TS2322: Type '{ x: B; 0: A; }' is not assignable to type '{ [s: string]: A; [n: number]: B; }'.
|
||||
Property '0' is incompatible with index signature.
|
||||
Type 'A' is not assignable to type 'B'.
|
||||
Property 'y' is missing in type 'A'.
|
||||
tests/cases/compiler/objectLiteralIndexerErrors.ts(14,1): error TS2322: Type '{ 0: A; x: any; }' is not assignable to type '{ [s: string]: A; [n: number]: B; }'.
|
||||
tests/cases/compiler/objectLiteralIndexerErrors.ts(14,1): error TS2322: Type '{ x: any; 0: A; }' is not assignable to type '{ [s: string]: A; [n: number]: B; }'.
|
||||
Property '0' is incompatible with index signature.
|
||||
Type 'A' is not assignable to type 'B'.
|
||||
|
||||
@@ -22,12 +22,12 @@ tests/cases/compiler/objectLiteralIndexerErrors.ts(14,1): error TS2322: Type '{
|
||||
|
||||
var o1: { [s: string]: A;[n: number]: B; } = { x: b, 0: a }; // both indexers are A
|
||||
~~
|
||||
!!! error TS2322: Type '{ 0: A; x: B; }' is not assignable to type '{ [s: string]: A; [n: number]: B; }'.
|
||||
!!! error TS2322: Type '{ x: B; 0: A; }' is not assignable to type '{ [s: string]: A; [n: number]: B; }'.
|
||||
!!! error TS2322: Property '0' is incompatible with index signature.
|
||||
!!! error TS2322: Type 'A' is not assignable to type 'B'.
|
||||
!!! error TS2322: Property 'y' is missing in type 'A'.
|
||||
o1 = { x: c, 0: a }; // string indexer is any, number indexer is A
|
||||
~~
|
||||
!!! error TS2322: Type '{ 0: A; x: any; }' is not assignable to type '{ [s: string]: A; [n: number]: B; }'.
|
||||
!!! error TS2322: Type '{ x: any; 0: A; }' is not assignable to type '{ [s: string]: A; [n: number]: B; }'.
|
||||
!!! error TS2322: Property '0' is incompatible with index signature.
|
||||
!!! error TS2322: Type 'A' is not assignable to type 'B'.
|
||||
@@ -31,23 +31,23 @@ var o1: { [s: string]: A;[n: number]: B; } = { x: a, 0: b }; // string indexer i
|
||||
>A : A
|
||||
>n : number
|
||||
>B : B
|
||||
>{ x: a, 0: b } : { 0: B; x: A; }
|
||||
>{ x: a, 0: b } : { x: A; 0: B; }
|
||||
>x : A
|
||||
>a : A
|
||||
>b : B
|
||||
|
||||
o1 = { x: b, 0: c }; // both indexers are any
|
||||
>o1 = { x: b, 0: c } : { 0: any; x: B; }
|
||||
>o1 = { x: b, 0: c } : { x: B; 0: any; }
|
||||
>o1 : { [s: string]: A; [n: number]: B; }
|
||||
>{ x: b, 0: c } : { 0: any; x: B; }
|
||||
>{ x: b, 0: c } : { x: B; 0: any; }
|
||||
>x : B
|
||||
>b : B
|
||||
>c : any
|
||||
|
||||
o1 = { x: c, 0: b }; // string indexer is any, number indexer is B
|
||||
>o1 = { x: c, 0: b } : { 0: B; x: any; }
|
||||
>o1 = { x: c, 0: b } : { x: any; 0: B; }
|
||||
>o1 : { [s: string]: A; [n: number]: B; }
|
||||
>{ x: c, 0: b } : { 0: B; x: any; }
|
||||
>{ x: c, 0: b } : { x: any; 0: B; }
|
||||
>x : any
|
||||
>c : any
|
||||
>b : B
|
||||
|
||||
@@ -267,7 +267,7 @@ var r13 = i[-01]
|
||||
>01 : 1
|
||||
|
||||
var a: {
|
||||
>a : { "1": number; "0.1": void; ".1": Object; "1.": string; "1..": boolean; "1.0": Date; "-1.0": RegExp; "-1": Date; }
|
||||
>a : { "0.1": void; ".1": Object; "1": number; "1.": string; "1..": boolean; "1.0": Date; "-1.0": RegExp; "-1": Date; }
|
||||
|
||||
"0.1": void;
|
||||
".1": Object;
|
||||
@@ -289,19 +289,19 @@ var a: {
|
||||
var r1 = a['0.1'];
|
||||
>r1 : void
|
||||
>a['0.1'] : void
|
||||
>a : { "1": number; "0.1": void; ".1": Object; "1.": string; "1..": boolean; "1.0": Date; "-1.0": RegExp; "-1": Date; }
|
||||
>a : { "0.1": void; ".1": Object; "1": number; "1.": string; "1..": boolean; "1.0": Date; "-1.0": RegExp; "-1": Date; }
|
||||
>'0.1' : "0.1"
|
||||
|
||||
var r2 = a['.1'];
|
||||
>r2 : Object
|
||||
>a['.1'] : Object
|
||||
>a : { "1": number; "0.1": void; ".1": Object; "1.": string; "1..": boolean; "1.0": Date; "-1.0": RegExp; "-1": Date; }
|
||||
>a : { "0.1": void; ".1": Object; "1": number; "1.": string; "1..": boolean; "1.0": Date; "-1.0": RegExp; "-1": Date; }
|
||||
>'.1' : ".1"
|
||||
|
||||
var r3 = a['1'];
|
||||
>r3 : number
|
||||
>a['1'] : number
|
||||
>a : { "1": number; "0.1": void; ".1": Object; "1.": string; "1..": boolean; "1.0": Date; "-1.0": RegExp; "-1": Date; }
|
||||
>a : { "0.1": void; ".1": Object; "1": number; "1.": string; "1..": boolean; "1.0": Date; "-1.0": RegExp; "-1": Date; }
|
||||
>'1' : "1"
|
||||
|
||||
var r3 = c[1];
|
||||
@@ -313,7 +313,7 @@ var r3 = c[1];
|
||||
var r4 = a['1.'];
|
||||
>r4 : string
|
||||
>a['1.'] : string
|
||||
>a : { "1": number; "0.1": void; ".1": Object; "1.": string; "1..": boolean; "1.0": Date; "-1.0": RegExp; "-1": Date; }
|
||||
>a : { "0.1": void; ".1": Object; "1": number; "1.": string; "1..": boolean; "1.0": Date; "-1.0": RegExp; "-1": Date; }
|
||||
>'1.' : "1."
|
||||
|
||||
var r3 = c[1.]; // same as indexing by 1 when done numerically
|
||||
@@ -325,13 +325,13 @@ var r3 = c[1.]; // same as indexing by 1 when done numerically
|
||||
var r5 = a['1..'];
|
||||
>r5 : boolean
|
||||
>a['1..'] : boolean
|
||||
>a : { "1": number; "0.1": void; ".1": Object; "1.": string; "1..": boolean; "1.0": Date; "-1.0": RegExp; "-1": Date; }
|
||||
>a : { "0.1": void; ".1": Object; "1": number; "1.": string; "1..": boolean; "1.0": Date; "-1.0": RegExp; "-1": Date; }
|
||||
>'1..' : "1.."
|
||||
|
||||
var r6 = a['1.0'];
|
||||
>r6 : Date
|
||||
>a['1.0'] : Date
|
||||
>a : { "1": number; "0.1": void; ".1": Object; "1.": string; "1..": boolean; "1.0": Date; "-1.0": RegExp; "-1": Date; }
|
||||
>a : { "0.1": void; ".1": Object; "1": number; "1.": string; "1..": boolean; "1.0": Date; "-1.0": RegExp; "-1": Date; }
|
||||
>'1.0' : "1.0"
|
||||
|
||||
var r3 = c[1.0]; // same as indexing by 1 when done numerically
|
||||
@@ -394,8 +394,8 @@ var r13 = i[-01]
|
||||
>01 : 1
|
||||
|
||||
var b = {
|
||||
>b : { "1": number; "0.1": void; ".1": Object; "1.": string; "1..": boolean; "1.0": Date; "-1.0": RegExp; "-1": DateConstructor; }
|
||||
>{ "0.1": <void>null, ".1": new Object(), "1": 1, "1.": "", "1..": true, "1.0": new Date(), "-1.0": /123/, "-1": Date} : { "1": number; "0.1": void; ".1": Object; "1.": string; "1..": boolean; "1.0": Date; "-1.0": RegExp; "-1": DateConstructor; }
|
||||
>b : { "0.1": void; ".1": Object; "1": number; "1.": string; "1..": boolean; "1.0": Date; "-1.0": RegExp; "-1": DateConstructor; }
|
||||
>{ "0.1": <void>null, ".1": new Object(), "1": 1, "1.": "", "1..": true, "1.0": new Date(), "-1.0": /123/, "-1": Date} : { "0.1": void; ".1": Object; "1": number; "1.": string; "1..": boolean; "1.0": Date; "-1.0": RegExp; "-1": DateConstructor; }
|
||||
|
||||
"0.1": <void>null,
|
||||
><void>null : void
|
||||
@@ -429,19 +429,19 @@ var b = {
|
||||
var r1 = b['0.1'];
|
||||
>r1 : void
|
||||
>b['0.1'] : void
|
||||
>b : { "1": number; "0.1": void; ".1": Object; "1.": string; "1..": boolean; "1.0": Date; "-1.0": RegExp; "-1": DateConstructor; }
|
||||
>b : { "0.1": void; ".1": Object; "1": number; "1.": string; "1..": boolean; "1.0": Date; "-1.0": RegExp; "-1": DateConstructor; }
|
||||
>'0.1' : "0.1"
|
||||
|
||||
var r2 = b['.1'];
|
||||
>r2 : Object
|
||||
>b['.1'] : Object
|
||||
>b : { "1": number; "0.1": void; ".1": Object; "1.": string; "1..": boolean; "1.0": Date; "-1.0": RegExp; "-1": DateConstructor; }
|
||||
>b : { "0.1": void; ".1": Object; "1": number; "1.": string; "1..": boolean; "1.0": Date; "-1.0": RegExp; "-1": DateConstructor; }
|
||||
>'.1' : ".1"
|
||||
|
||||
var r3 = b['1'];
|
||||
>r3 : number
|
||||
>b['1'] : number
|
||||
>b : { "1": number; "0.1": void; ".1": Object; "1.": string; "1..": boolean; "1.0": Date; "-1.0": RegExp; "-1": DateConstructor; }
|
||||
>b : { "0.1": void; ".1": Object; "1": number; "1.": string; "1..": boolean; "1.0": Date; "-1.0": RegExp; "-1": DateConstructor; }
|
||||
>'1' : "1"
|
||||
|
||||
var r3 = c[1];
|
||||
@@ -453,7 +453,7 @@ var r3 = c[1];
|
||||
var r4 = b['1.'];
|
||||
>r4 : string
|
||||
>b['1.'] : string
|
||||
>b : { "1": number; "0.1": void; ".1": Object; "1.": string; "1..": boolean; "1.0": Date; "-1.0": RegExp; "-1": DateConstructor; }
|
||||
>b : { "0.1": void; ".1": Object; "1": number; "1.": string; "1..": boolean; "1.0": Date; "-1.0": RegExp; "-1": DateConstructor; }
|
||||
>'1.' : "1."
|
||||
|
||||
var r3 = c[1.]; // same as indexing by 1 when done numerically
|
||||
@@ -465,13 +465,13 @@ var r3 = c[1.]; // same as indexing by 1 when done numerically
|
||||
var r5 = b['1..'];
|
||||
>r5 : boolean
|
||||
>b['1..'] : boolean
|
||||
>b : { "1": number; "0.1": void; ".1": Object; "1.": string; "1..": boolean; "1.0": Date; "-1.0": RegExp; "-1": DateConstructor; }
|
||||
>b : { "0.1": void; ".1": Object; "1": number; "1.": string; "1..": boolean; "1.0": Date; "-1.0": RegExp; "-1": DateConstructor; }
|
||||
>'1..' : "1.."
|
||||
|
||||
var r6 = b['1.0'];
|
||||
>r6 : Date
|
||||
>b['1.0'] : Date
|
||||
>b : { "1": number; "0.1": void; ".1": Object; "1.": string; "1..": boolean; "1.0": Date; "-1.0": RegExp; "-1": DateConstructor; }
|
||||
>b : { "0.1": void; ".1": Object; "1": number; "1.": string; "1..": boolean; "1.0": Date; "-1.0": RegExp; "-1": DateConstructor; }
|
||||
>'1.0' : "1.0"
|
||||
|
||||
var r3 = c[1.0]; // same as indexing by 1 when done numerically
|
||||
|
||||
@@ -22,8 +22,8 @@ tests/cases/conformance/types/objectTypeLiteral/indexSignatures/stringIndexerCon
|
||||
tests/cases/conformance/types/objectTypeLiteral/indexSignatures/stringIndexerConstrainsPropertyDeclarations.ts(71,5): error TS2411: Property 'foo' of type '() => string' is not assignable to string index type 'string'.
|
||||
tests/cases/conformance/types/objectTypeLiteral/indexSignatures/stringIndexerConstrainsPropertyDeclarations.ts(73,5): error TS2411: Property '"4.0"' of type 'number' is not assignable to string index type 'string'.
|
||||
tests/cases/conformance/types/objectTypeLiteral/indexSignatures/stringIndexerConstrainsPropertyDeclarations.ts(74,5): error TS2411: Property 'f' of type 'MyString' is not assignable to string index type 'string'.
|
||||
tests/cases/conformance/types/objectTypeLiteral/indexSignatures/stringIndexerConstrainsPropertyDeclarations.ts(78,5): error TS2322: Type '{ 1.0: string; 2.0: number; a: string; b: number; c: () => void; "d": string; "e": number; "3.0": string; "4.0": number; f: MyString; X: string; foo(): string; }' is not assignable to type '{ [x: string]: string; }'.
|
||||
Property '2.0' is incompatible with index signature.
|
||||
tests/cases/conformance/types/objectTypeLiteral/indexSignatures/stringIndexerConstrainsPropertyDeclarations.ts(78,5): error TS2322: Type '{ a: string; b: number; c: () => void; "d": string; "e": number; 1.0: string; 2.0: number; "3.0": string; "4.0": number; f: MyString; X: string; foo(): string; }' is not assignable to type '{ [x: string]: string; }'.
|
||||
Property 'b' is incompatible with index signature.
|
||||
Type 'number' is not assignable to type 'string'.
|
||||
tests/cases/conformance/types/objectTypeLiteral/indexSignatures/stringIndexerConstrainsPropertyDeclarations.ts(90,9): error TS1056: Accessors are only available when targeting ECMAScript 5 and higher.
|
||||
tests/cases/conformance/types/objectTypeLiteral/indexSignatures/stringIndexerConstrainsPropertyDeclarations.ts(93,9): error TS1056: Accessors are only available when targeting ECMAScript 5 and higher.
|
||||
@@ -157,8 +157,8 @@ tests/cases/conformance/types/objectTypeLiteral/indexSignatures/stringIndexerCon
|
||||
// error
|
||||
var b: { [x: string]: string; } = {
|
||||
~
|
||||
!!! error TS2322: Type '{ 1.0: string; 2.0: number; a: string; b: number; c: () => void; "d": string; "e": number; "3.0": string; "4.0": number; f: MyString; X: string; foo(): string; }' is not assignable to type '{ [x: string]: string; }'.
|
||||
!!! error TS2322: Property '2.0' is incompatible with index signature.
|
||||
!!! error TS2322: Type '{ a: string; b: number; c: () => void; "d": string; "e": number; 1.0: string; 2.0: number; "3.0": string; "4.0": number; f: MyString; X: string; foo(): string; }' is not assignable to type '{ [x: string]: string; }'.
|
||||
!!! error TS2322: Property 'b' is incompatible with index signature.
|
||||
!!! error TS2322: Type 'number' is not assignable to type 'string'.
|
||||
a: '',
|
||||
b: 1,
|
||||
|
||||
@@ -43,6 +43,16 @@
|
||||
// TODO: figure out a better solution to the API exposure problem.
|
||||
|
||||
declare module ts {
|
||||
export type MapKey = string | number;
|
||||
export interface Map<T> {
|
||||
forEach(action: (value: T, key: string) => void): void;
|
||||
get(key: MapKey): T;
|
||||
has(key: MapKey): boolean;
|
||||
set(key: MapKey, value: T): this;
|
||||
delete(key: MapKey): boolean;
|
||||
clear(): void;
|
||||
}
|
||||
|
||||
interface SymbolDisplayPart {
|
||||
text: string;
|
||||
kind: string;
|
||||
@@ -103,7 +113,7 @@ declare namespace FourSlashInterface {
|
||||
markerNames(): string[];
|
||||
marker(name?: string): Marker;
|
||||
ranges(): Range[];
|
||||
rangesByText(): { [text: string]: Range[] };
|
||||
rangesByText(): ts.Map<Range[]>;
|
||||
markerByName(s: string): Marker;
|
||||
}
|
||||
class goTo {
|
||||
|
||||
@@ -202,15 +202,14 @@ goTo.marker("4");
|
||||
verify.referencesAre([]);
|
||||
|
||||
const rangesByText = test.rangesByText();
|
||||
for (const text in rangesByText) {
|
||||
const ranges = rangesByText[text];
|
||||
rangesByText.forEach((ranges, text) => {
|
||||
if (text === "globalVar") {
|
||||
verify.rangesReferenceEachOther(ranges.filter(isShadow));
|
||||
verify.rangesReferenceEachOther(ranges.filter(r => !isShadow(r)));
|
||||
} else {
|
||||
verify.rangesReferenceEachOther(ranges);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
function isShadow(r) {
|
||||
return r.marker && r.marker.data && r.marker.data.shadow;
|
||||
|
||||
+2
-1
@@ -46,6 +46,7 @@
|
||||
"prefer-const": true,
|
||||
"no-increment-decrement": true,
|
||||
"object-literal-surrounding-space": true,
|
||||
"no-type-assertion-whitespace": true
|
||||
"no-type-assertion-whitespace": true,
|
||||
"no-in-operator": true
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user