mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-05-22 12:03:44 -05:00
Use sparse arrays for number-keyed maps
This commit is contained in:
@@ -4054,16 +4054,15 @@ namespace ts {
|
||||
enumType.symbol = symbol;
|
||||
if (enumHasLiteralMembers(symbol)) {
|
||||
const memberTypeList: Type[] = [];
|
||||
const memberTypes = createMap<EnumLiteralType>();
|
||||
const memberTypes = sparseArray<EnumLiteralType>();
|
||||
for (const declaration of enumType.symbol.declarations) {
|
||||
if (declaration.kind === SyntaxKind.EnumDeclaration) {
|
||||
computeEnumMemberValues(<EnumDeclaration>declaration);
|
||||
for (const member of (<EnumDeclaration>declaration).members) {
|
||||
const memberSymbol = getSymbolOfNode(member);
|
||||
const value = getEnumMemberValue(member);
|
||||
if (!memberTypes.has(value)) {
|
||||
const memberType = createEnumLiteralType(memberSymbol, enumType, "" + value);
|
||||
memberTypes.set(value, memberType);
|
||||
if (!memberTypes[value]) {
|
||||
const memberType = memberTypes[value] = createEnumLiteralType(memberSymbol, enumType, "" + value);
|
||||
memberTypeList.push(memberType);
|
||||
}
|
||||
}
|
||||
@@ -4085,7 +4084,7 @@ namespace ts {
|
||||
if (!links.declaredType) {
|
||||
const enumType = <EnumType>getDeclaredTypeOfEnum(getParentOfSymbol(symbol));
|
||||
links.declaredType = enumType.flags & TypeFlags.Union ?
|
||||
enumType.memberTypes.get(getEnumMemberValue(<EnumMember>symbol.valueDeclaration)) :
|
||||
enumType.memberTypes[getEnumMemberValue(<EnumMember>symbol.valueDeclaration)] :
|
||||
enumType;
|
||||
}
|
||||
return links.declaredType;
|
||||
|
||||
@@ -39,6 +39,8 @@ namespace ts {
|
||||
return map;
|
||||
}
|
||||
|
||||
export const sparseArray: <T>() => SparseArray<T> = createMapLike;
|
||||
|
||||
/** 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>();
|
||||
@@ -52,17 +54,6 @@ namespace ts {
|
||||
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> {
|
||||
entries(): Iterator<[string, T]>;
|
||||
@@ -92,21 +83,21 @@ namespace ts {
|
||||
return class<T> implements ShimMap<T> {
|
||||
private data = createMapLike<T>();
|
||||
|
||||
get(key: MapKey): T {
|
||||
get(key: string): T {
|
||||
return this.data[key];
|
||||
}
|
||||
|
||||
set(key: MapKey, value: T): this {
|
||||
set(key: string, value: T): this {
|
||||
this.data[key] = value;
|
||||
return this;
|
||||
}
|
||||
|
||||
has(key: MapKey): boolean {
|
||||
has(key: string): boolean {
|
||||
// tslint:disable-next-line:no-in-operator
|
||||
return key in this.data;
|
||||
}
|
||||
|
||||
delete(key: MapKey): boolean {
|
||||
delete(key: string): boolean {
|
||||
const had = this.has(key);
|
||||
if (had) {
|
||||
delete this.data[key];
|
||||
@@ -890,7 +881,7 @@ namespace ts {
|
||||
* Array of every key in a map.
|
||||
* May not actually return string[] if numbers were put into the map.
|
||||
*/
|
||||
export function keysOfMap<T>(map: Map<T>): string[] {
|
||||
export function keysOfMap(map: Map<{}>): string[] {
|
||||
const keys: string[] = [];
|
||||
forEachKeyInMap(map, key => {
|
||||
keys.push(key);
|
||||
@@ -1040,7 +1031,7 @@ namespace ts {
|
||||
* Adds the value to an array of values associated with the key, and returns the array.
|
||||
* Creates the array if it does not already exist.
|
||||
*/
|
||||
export function multiMapAdd<V>(map: Map<V[]>, key: string | number, value: V): V[] {
|
||||
export function multiMapAdd<V>(map: Map<V[]>, key: string, value: V): V[] {
|
||||
let values = map.get(key);
|
||||
if (values) {
|
||||
values.push(value);
|
||||
@@ -1051,6 +1042,17 @@ namespace ts {
|
||||
return values;
|
||||
}
|
||||
|
||||
export function multiMapSparseArrayAdd<V>(map: SparseArray<V[]>, key: number, value: V): V[] {
|
||||
let values = map[key];
|
||||
if (values) {
|
||||
values.push(value);
|
||||
}
|
||||
else {
|
||||
map[key] = values = [value];
|
||||
}
|
||||
return values;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a value from an array of values associated with the key.
|
||||
* Does not preserve the order of those values.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/// <reference path="core.ts"/>
|
||||
/// <reference path="core.ts"/>
|
||||
/// <reference path="utilities.ts"/>
|
||||
|
||||
/* @internal */
|
||||
@@ -2641,9 +2641,11 @@ namespace ts {
|
||||
return destEmitNode;
|
||||
}
|
||||
|
||||
function mergeTokenSourceMapRanges(sourceRanges: Map<TextRange>, destRanges: Map<TextRange>) {
|
||||
if (!destRanges) destRanges = createMap<TextRange>();
|
||||
copyMapEntries(sourceRanges, destRanges);
|
||||
function mergeTokenSourceMapRanges(sourceRanges: SparseArray<TextRange>, destRanges: SparseArray<TextRange>) {
|
||||
if (!destRanges) destRanges = [];
|
||||
for (const key in sourceRanges) {
|
||||
destRanges[key] = sourceRanges[key];
|
||||
}
|
||||
return destRanges;
|
||||
}
|
||||
|
||||
@@ -2745,7 +2747,7 @@ namespace ts {
|
||||
export function getTokenSourceMapRange(node: Node, token: SyntaxKind) {
|
||||
const emitNode = node.emitNode;
|
||||
const tokenSourceMapRanges = emitNode && emitNode.tokenSourceMapRanges;
|
||||
return tokenSourceMapRanges && tokenSourceMapRanges.get(token);
|
||||
return tokenSourceMapRanges && tokenSourceMapRanges[token];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2757,8 +2759,8 @@ 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.set(token, range);
|
||||
const tokenSourceMapRanges = emitNode.tokenSourceMapRanges || (emitNode.tokenSourceMapRanges = []);
|
||||
tokenSourceMapRanges[token] = range;
|
||||
return node;
|
||||
}
|
||||
|
||||
@@ -3270,7 +3272,7 @@ namespace ts {
|
||||
externalImports: (ImportDeclaration | ImportEqualsDeclaration | ExportDeclaration)[]; // imports of other external modules
|
||||
externalHelpersImportDeclaration: ImportDeclaration | undefined; // import of external helpers
|
||||
exportSpecifiers: Map<ExportSpecifier[]>; // export specifiers by name
|
||||
exportedBindings: Map<Identifier[]>; // exported names of local declarations
|
||||
exportedBindings: SparseArray<Identifier[]>; // exported names of local declarations
|
||||
exportedNames: Identifier[]; // all exported names local to module
|
||||
exportEquals: ExportAssignment | undefined; // an export= declaration if one was present
|
||||
hasExportStarsToExportValues: boolean; // whether this module contains export*
|
||||
@@ -3279,7 +3281,7 @@ namespace ts {
|
||||
export function collectExternalModuleInfo(sourceFile: SourceFile, resolver: EmitResolver, compilerOptions: CompilerOptions): ExternalModuleInfo {
|
||||
const externalImports: (ImportDeclaration | ImportEqualsDeclaration | ExportDeclaration)[] = [];
|
||||
const exportSpecifiers = createMap<ExportSpecifier[]>();
|
||||
const exportedBindings = createMap<Identifier[]>();
|
||||
const exportedBindings = sparseArray<Identifier[]>();
|
||||
const uniqueExports = createMap<boolean>();
|
||||
let exportedNames: Identifier[];
|
||||
let hasExportDefault = false;
|
||||
@@ -3338,7 +3340,7 @@ namespace ts {
|
||||
|| resolver.getReferencedValueDeclaration(name);
|
||||
|
||||
if (decl) {
|
||||
multiMapAdd(exportedBindings, getOriginalNodeId(decl), specifier.name);
|
||||
multiMapSparseArrayAdd(exportedBindings, getOriginalNodeId(decl), specifier.name);
|
||||
}
|
||||
|
||||
uniqueExports.set(specifier.name.text, true);
|
||||
@@ -3368,7 +3370,7 @@ namespace ts {
|
||||
if (hasModifier(node, ModifierFlags.Default)) {
|
||||
// export default function() { }
|
||||
if (!hasExportDefault) {
|
||||
multiMapAdd(exportedBindings, getOriginalNodeId(node), getDeclarationName(<FunctionDeclaration>node));
|
||||
multiMapSparseArrayAdd(exportedBindings, getOriginalNodeId(node), getDeclarationName(<FunctionDeclaration>node));
|
||||
hasExportDefault = true;
|
||||
}
|
||||
}
|
||||
@@ -3376,7 +3378,7 @@ namespace ts {
|
||||
// export function x() { }
|
||||
const name = (<FunctionDeclaration>node).name;
|
||||
if (!uniqueExports.get(name.text)) {
|
||||
multiMapAdd(exportedBindings, getOriginalNodeId(node), name);
|
||||
multiMapSparseArrayAdd(exportedBindings, getOriginalNodeId(node), name);
|
||||
uniqueExports.set(name.text, true);
|
||||
exportedNames = append(exportedNames, name);
|
||||
}
|
||||
@@ -3389,7 +3391,7 @@ namespace ts {
|
||||
if (hasModifier(node, ModifierFlags.Default)) {
|
||||
// export default class { }
|
||||
if (!hasExportDefault) {
|
||||
multiMapAdd(exportedBindings, getOriginalNodeId(node), getDeclarationName(<ClassDeclaration>node));
|
||||
multiMapSparseArrayAdd(exportedBindings, getOriginalNodeId(node), getDeclarationName(<ClassDeclaration>node));
|
||||
hasExportDefault = true;
|
||||
}
|
||||
}
|
||||
@@ -3397,7 +3399,7 @@ namespace ts {
|
||||
// export class x { }
|
||||
const name = (<ClassDeclaration>node).name;
|
||||
if (!uniqueExports.get(name.text)) {
|
||||
multiMapAdd(exportedBindings, getOriginalNodeId(node), name);
|
||||
multiMapSparseArrayAdd(exportedBindings, getOriginalNodeId(node), name);
|
||||
uniqueExports.set(name.text, true);
|
||||
exportedNames = append(exportedNames, name);
|
||||
}
|
||||
|
||||
@@ -362,7 +362,7 @@ namespace ts {
|
||||
|
||||
const emitNode = node && node.emitNode;
|
||||
const emitFlags = emitNode && emitNode.flags;
|
||||
const range = emitNode && emitNode.tokenSourceMapRanges && emitNode.tokenSourceMapRanges.get(token);
|
||||
const range = emitNode && emitNode.tokenSourceMapRanges && emitNode.tokenSourceMapRanges[token];
|
||||
|
||||
tokenPos = skipTrivia(currentSourceText, range ? range.pos : tokenPos);
|
||||
if ((emitFlags & EmitFlags.NoTokenLeadingSourceMaps) === 0 && tokenPos >= 0) {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/// <reference path="visitor.ts" />
|
||||
/// <reference path="visitor.ts" />
|
||||
/// <reference path="transformers/ts.ts" />
|
||||
/// <reference path="transformers/jsx.ts" />
|
||||
/// <reference path="transformers/esnext.ts" />
|
||||
@@ -13,14 +13,16 @@
|
||||
|
||||
/* @internal */
|
||||
namespace ts {
|
||||
const moduleTransformerMap = createMapFromPairs<Transformer>(
|
||||
[ModuleKind.ES2015, transformES2015Module],
|
||||
[ModuleKind.System, transformSystemModule],
|
||||
[ModuleKind.AMD, transformModule],
|
||||
[ModuleKind.CommonJS, transformModule],
|
||||
[ModuleKind.UMD, transformModule],
|
||||
[ModuleKind.None, transformModule],
|
||||
);
|
||||
function getModuleTransformer(moduleKind: ModuleKind): Transformer {
|
||||
switch (moduleKind) {
|
||||
case ModuleKind.ES2015:
|
||||
return transformES2015Module;
|
||||
case ModuleKind.System:
|
||||
return transformSystemModule;
|
||||
default:
|
||||
return transformModule;
|
||||
}
|
||||
}
|
||||
|
||||
const enum SyntaxKindFeatureFlags {
|
||||
Substitution = 1 << 0,
|
||||
@@ -56,7 +58,7 @@ namespace ts {
|
||||
transformers.push(transformGenerators);
|
||||
}
|
||||
|
||||
transformers.push(moduleTransformerMap.get(moduleKind) || moduleTransformerMap.get(ModuleKind.None));
|
||||
transformers.push(getModuleTransformer(moduleKind));
|
||||
|
||||
// The ES5 transformer is last so that it can substitute expressions like `exports.default`
|
||||
// for ES3.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/// <reference path="../factory.ts" />
|
||||
/// <reference path="../factory.ts" />
|
||||
/// <reference path="../visitor.ts" />
|
||||
|
||||
// Transforms generator functions into a compatible ES5 representation with similar runtime
|
||||
@@ -217,13 +217,15 @@ namespace ts {
|
||||
Endfinally = 7,
|
||||
}
|
||||
|
||||
const instructionNames = createMapFromPairs<string>(
|
||||
[Instruction.Return, "return"],
|
||||
[Instruction.Break, "break"],
|
||||
[Instruction.Yield, "yield"],
|
||||
[Instruction.YieldStar, "yield*"],
|
||||
[Instruction.Endfinally, "endfinally"],
|
||||
);
|
||||
function getInstructionName(instruction: Instruction): string {
|
||||
switch (instruction) {
|
||||
case Instruction.Return: return "return";
|
||||
case Instruction.Break: return "break";
|
||||
case Instruction.Yield: return "yield";
|
||||
case Instruction.YieldStar: return "yield*";
|
||||
case Instruction.Endfinally: return "endfinally";
|
||||
}
|
||||
}
|
||||
|
||||
export function transformGenerators(context: TransformationContext) {
|
||||
const {
|
||||
@@ -241,7 +243,7 @@ namespace ts {
|
||||
|
||||
let currentSourceFile: SourceFile;
|
||||
let renamedCatchVariables: Map<boolean>;
|
||||
let renamedCatchVariableDeclarations: Map<Identifier>;
|
||||
let renamedCatchVariableDeclarations: SparseArray<Identifier>;
|
||||
|
||||
let inGeneratorFunctionBody: boolean;
|
||||
let inStatementContainingYield: boolean;
|
||||
@@ -1926,7 +1928,7 @@ namespace ts {
|
||||
if (isIdentifier(original) && original.parent) {
|
||||
const declaration = resolver.getReferencedValueDeclaration(original);
|
||||
if (declaration) {
|
||||
const name = renamedCatchVariableDeclarations.get(getOriginalNodeId(declaration));
|
||||
const name = renamedCatchVariableDeclarations[getOriginalNodeId(declaration)];
|
||||
if (name) {
|
||||
const clone = getMutableClone(name);
|
||||
setSourceMapRange(clone, node);
|
||||
@@ -2092,12 +2094,12 @@ namespace ts {
|
||||
|
||||
if (!renamedCatchVariables) {
|
||||
renamedCatchVariables = createMap<boolean>();
|
||||
renamedCatchVariableDeclarations = createMap<Identifier>();
|
||||
renamedCatchVariableDeclarations = sparseArray<Identifier>();
|
||||
context.enableSubstitution(SyntaxKind.Identifier);
|
||||
}
|
||||
|
||||
renamedCatchVariables.set(text, true);
|
||||
renamedCatchVariableDeclarations.set(getOriginalNodeId(variable), name);
|
||||
renamedCatchVariableDeclarations[getOriginalNodeId(variable)] = name;
|
||||
|
||||
const exception = <ExceptionBlock>peekBlock();
|
||||
Debug.assert(exception.state < ExceptionBlockState.Catch);
|
||||
@@ -2401,7 +2403,7 @@ namespace ts {
|
||||
*/
|
||||
function createInstruction(instruction: Instruction): NumericLiteral {
|
||||
const literal = createLiteral(instruction);
|
||||
literal.trailingComment = instructionNames.get(instruction);
|
||||
literal.trailingComment = getInstructionName(instruction);
|
||||
return literal;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/// <reference path="../../factory.ts" />
|
||||
/// <reference path="../../factory.ts" />
|
||||
/// <reference path="../../visitor.ts" />
|
||||
|
||||
/*@internal*/
|
||||
@@ -10,12 +10,13 @@ namespace ts {
|
||||
importAliasNames: ParameterDeclaration[];
|
||||
}
|
||||
|
||||
const transformModuleDelegates = createMapFromPairs<(node: SourceFile) => SourceFile>(
|
||||
[ModuleKind.None, transformCommonJSModule],
|
||||
[ModuleKind.CommonJS, transformCommonJSModule],
|
||||
[ModuleKind.AMD, transformAMDModule],
|
||||
[ModuleKind.UMD, transformUMDModule],
|
||||
);
|
||||
function getTransformModuleDelegate(moduleKind: ModuleKind): (node: SourceFile) => SourceFile {
|
||||
switch (moduleKind) {
|
||||
case ModuleKind.AMD: return transformAMDModule;
|
||||
case ModuleKind.UMD: return transformUMDModule;
|
||||
default: return transformCommonJSModule;
|
||||
}
|
||||
}
|
||||
|
||||
const {
|
||||
startLexicalEnvironment,
|
||||
@@ -38,12 +39,12 @@ namespace ts {
|
||||
context.enableSubstitution(SyntaxKind.ShorthandPropertyAssignment); // Substitutes shorthand property assignments for imported/exported symbols.
|
||||
context.enableEmitNotification(SyntaxKind.SourceFile); // Restore state when substituting nodes in a file.
|
||||
|
||||
const moduleInfoMap = createMap<ExternalModuleInfo>(); // The ExternalModuleInfo for each file.
|
||||
const deferredExports = createMap<Statement[]>(); // Exports to defer until an EndOfDeclarationMarker is found.
|
||||
const moduleInfoMap = sparseArray<ExternalModuleInfo>(); // The ExternalModuleInfo for each file.
|
||||
const deferredExports = sparseArray<Statement[]>(); // Exports to defer until an EndOfDeclarationMarker is found.
|
||||
|
||||
let currentSourceFile: SourceFile; // The current file.
|
||||
let currentModuleInfo: ExternalModuleInfo; // The ExternalModuleInfo for the current file.
|
||||
let noSubstitution: Map<boolean>; // Set of nodes for which substitution rules should be ignored.
|
||||
let noSubstitution: SparseArray<boolean>; // Set of nodes for which substitution rules should be ignored.
|
||||
|
||||
return transformSourceFile;
|
||||
|
||||
@@ -61,10 +62,10 @@ namespace ts {
|
||||
|
||||
currentSourceFile = node;
|
||||
currentModuleInfo = collectExternalModuleInfo(node, resolver, compilerOptions);
|
||||
moduleInfoMap.set(getOriginalNodeId(node), currentModuleInfo);
|
||||
moduleInfoMap[getOriginalNodeId(node)] = currentModuleInfo;
|
||||
|
||||
// Perform the transformation.
|
||||
const transformModule = transformModuleDelegates.get(moduleKind) || transformModuleDelegates.get(ModuleKind.None);
|
||||
const transformModule = getTransformModuleDelegate(moduleKind);
|
||||
const updated = transformModule(node);
|
||||
|
||||
currentSourceFile = undefined;
|
||||
@@ -445,7 +446,7 @@ namespace ts {
|
||||
if (hasAssociatedEndOfDeclarationMarker(node)) {
|
||||
// Defer exports until we encounter an EndOfDeclarationMarker node
|
||||
const id = getOriginalNodeId(node);
|
||||
deferredExports.set(id, appendExportsOfImportDeclaration(deferredExports.get(id), node));
|
||||
deferredExports[id] = appendExportsOfImportDeclaration(deferredExports[id], node);
|
||||
}
|
||||
else {
|
||||
statements = appendExportsOfImportDeclaration(statements, node);
|
||||
@@ -524,7 +525,7 @@ namespace ts {
|
||||
if (hasAssociatedEndOfDeclarationMarker(node)) {
|
||||
// Defer exports until we encounter an EndOfDeclarationMarker node
|
||||
const id = getOriginalNodeId(node);
|
||||
deferredExports.set(id, appendExportsOfImportEqualsDeclaration(deferredExports.get(id), node));
|
||||
deferredExports[id] = appendExportsOfImportEqualsDeclaration(deferredExports[id], node);
|
||||
}
|
||||
else {
|
||||
statements = appendExportsOfImportEqualsDeclaration(statements, node);
|
||||
@@ -611,7 +612,7 @@ namespace ts {
|
||||
if (original && hasAssociatedEndOfDeclarationMarker(original)) {
|
||||
// Defer exports until we encounter an EndOfDeclarationMarker node
|
||||
const id = getOriginalNodeId(node);
|
||||
deferredExports.set(id, appendExportStatement(deferredExports.get(id), createIdentifier("default"), node.expression, /*location*/ node, /*allowComments*/ true));
|
||||
deferredExports[id] = appendExportStatement(deferredExports[id], createIdentifier("default"), node.expression, /*location*/ node, /*allowComments*/ true);
|
||||
}
|
||||
else {
|
||||
statements = appendExportStatement(statements, createIdentifier("default"), node.expression, /*location*/ node, /*allowComments*/ true);
|
||||
@@ -652,7 +653,7 @@ namespace ts {
|
||||
if (hasAssociatedEndOfDeclarationMarker(node)) {
|
||||
// Defer exports until we encounter an EndOfDeclarationMarker node
|
||||
const id = getOriginalNodeId(node);
|
||||
deferredExports.set(id, appendExportsOfHoistedDeclaration(deferredExports.get(id), node));
|
||||
deferredExports[id] = appendExportsOfHoistedDeclaration(deferredExports[id], node);
|
||||
}
|
||||
else {
|
||||
statements = appendExportsOfHoistedDeclaration(statements, node);
|
||||
@@ -691,7 +692,7 @@ namespace ts {
|
||||
if (hasAssociatedEndOfDeclarationMarker(node)) {
|
||||
// Defer exports until we encounter an EndOfDeclarationMarker node
|
||||
const id = getOriginalNodeId(node);
|
||||
deferredExports.set(id, appendExportsOfHoistedDeclaration(deferredExports.get(id), node));
|
||||
deferredExports[id] = appendExportsOfHoistedDeclaration(deferredExports[id], node);
|
||||
}
|
||||
else {
|
||||
statements = appendExportsOfHoistedDeclaration(statements, node);
|
||||
@@ -742,7 +743,7 @@ namespace ts {
|
||||
if (hasAssociatedEndOfDeclarationMarker(node)) {
|
||||
// Defer exports until we encounter an EndOfDeclarationMarker node
|
||||
const id = getOriginalNodeId(node);
|
||||
deferredExports.set(id, appendExportsOfVariableStatement(deferredExports.get(id), node));
|
||||
deferredExports[id] = appendExportsOfVariableStatement(deferredExports[id], node);
|
||||
}
|
||||
else {
|
||||
statements = appendExportsOfVariableStatement(statements, node);
|
||||
@@ -795,7 +796,7 @@ namespace ts {
|
||||
// statement.
|
||||
if (hasAssociatedEndOfDeclarationMarker(node) && node.original.kind === SyntaxKind.VariableStatement) {
|
||||
const id = getOriginalNodeId(node);
|
||||
deferredExports.set(id, appendExportsOfVariableStatement(deferredExports.get(id), <VariableStatement>node.original));
|
||||
deferredExports[id] = appendExportsOfVariableStatement(deferredExports[id], <VariableStatement>node.original);
|
||||
}
|
||||
|
||||
return node;
|
||||
@@ -821,9 +822,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.get(id);
|
||||
const statements = deferredExports[id];
|
||||
if (statements) {
|
||||
deferredExports.delete(id);
|
||||
delete deferredExports[id];
|
||||
return append(statements, node);
|
||||
}
|
||||
|
||||
@@ -1103,8 +1104,8 @@ 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.get(getOriginalNodeId(currentSourceFile));
|
||||
noSubstitution = createMap<boolean>();
|
||||
currentModuleInfo = moduleInfoMap[getOriginalNodeId(currentSourceFile)];
|
||||
noSubstitution = sparseArray<boolean>();
|
||||
|
||||
previousOnEmitNode(emitContext, node, emitCallback);
|
||||
|
||||
@@ -1129,7 +1130,7 @@ namespace ts {
|
||||
*/
|
||||
function onSubstituteNode(emitContext: EmitContext, node: Node) {
|
||||
node = previousOnSubstituteNode(emitContext, node);
|
||||
if (node.id && noSubstitution.get(node.id)) {
|
||||
if (node.id && noSubstitution[node.id]) {
|
||||
return node;
|
||||
}
|
||||
|
||||
@@ -1255,7 +1256,7 @@ namespace ts {
|
||||
let expression: Expression = node;
|
||||
for (const exportName of exportedNames) {
|
||||
// Mark the node to prevent triggering this rule again.
|
||||
noSubstitution.set(getNodeId(expression), true);
|
||||
noSubstitution[getNodeId(expression)] = true;
|
||||
expression = createExportExpression(exportName, expression, /*location*/ node);
|
||||
}
|
||||
|
||||
@@ -1297,7 +1298,7 @@ namespace ts {
|
||||
: node;
|
||||
for (const exportName of exportedNames) {
|
||||
// Mark the node to prevent triggering this rule again.
|
||||
noSubstitution.set(getNodeId(expression), true);
|
||||
noSubstitution[getNodeId(expression)] = true;
|
||||
expression = createExportExpression(exportName, expression);
|
||||
}
|
||||
|
||||
@@ -1319,7 +1320,7 @@ namespace ts {
|
||||
|| resolver.getReferencedValueDeclaration(name);
|
||||
if (valueDeclaration) {
|
||||
return currentModuleInfo
|
||||
&& currentModuleInfo.exportedBindings.get(getOriginalNodeId(valueDeclaration));
|
||||
&& currentModuleInfo.exportedBindings[getOriginalNodeId(valueDeclaration)];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/// <reference path="../../factory.ts" />
|
||||
/// <reference path="../../factory.ts" />
|
||||
/// <reference path="../../visitor.ts" />
|
||||
|
||||
/*@internal*/
|
||||
@@ -28,10 +28,10 @@ namespace ts {
|
||||
context.enableSubstitution(SyntaxKind.PostfixUnaryExpression); // Substitutes updates to exported symbols.
|
||||
context.enableEmitNotification(SyntaxKind.SourceFile); // Restore state when substituting nodes in a file.
|
||||
|
||||
const moduleInfoMap = createMap<ExternalModuleInfo>(); // The ExternalModuleInfo for each file.
|
||||
const deferredExports = createMap<Statement[]>(); // Exports to defer until an EndOfDeclarationMarker is found.
|
||||
const exportFunctionsMap = createMap<Identifier>(); // The export function associated with a source file.
|
||||
const noSubstitutionMap = createMap<Map<boolean>>(); // Set of nodes for which substitution rules should be ignored for each file.
|
||||
const moduleInfoMap = sparseArray<ExternalModuleInfo>(); // The ExternalModuleInfo for each file.
|
||||
const deferredExports = sparseArray<Statement[]>(); // Exports to defer until an EndOfDeclarationMarker is found.
|
||||
const exportFunctionsMap = sparseArray<Identifier>(); // The export function associated with a source file.
|
||||
const noSubstitutionMap = sparseArray<SparseArray<boolean>>(); // Set of nodes for which substitution rules should be ignored for each file.
|
||||
|
||||
let currentSourceFile: SourceFile; // The current file.
|
||||
let moduleInfo: ExternalModuleInfo; // ExternalModuleInfo for the current file.
|
||||
@@ -39,7 +39,7 @@ namespace ts {
|
||||
let contextObject: Identifier; // The context object for the current file.
|
||||
let hoistedStatements: Statement[];
|
||||
let enclosingBlockScopedContainer: Node;
|
||||
let noSubstitution: Map<boolean>; // Set of nodes for which substitution rules should be ignored.
|
||||
let noSubstitution: SparseArray<boolean>; // Set of nodes for which substitution rules should be ignored.
|
||||
|
||||
return transformSourceFile;
|
||||
|
||||
@@ -73,13 +73,12 @@ namespace ts {
|
||||
// see comment to 'substitutePostfixUnaryExpression' for more details
|
||||
|
||||
// Collect information about the external module and dependency groups.
|
||||
moduleInfo = collectExternalModuleInfo(node, resolver, compilerOptions);
|
||||
moduleInfoMap.set(id, moduleInfo);
|
||||
moduleInfo = moduleInfoMap[id] = collectExternalModuleInfo(node, resolver, compilerOptions);
|
||||
|
||||
// Make sure that the name of the 'exports' function does not conflict with
|
||||
// existing identifiers.
|
||||
exportFunction = createUniqueName("exports");
|
||||
exportFunctionsMap.set(id, exportFunction);
|
||||
exportFunctionsMap[id] = exportFunction;
|
||||
contextObject = createUniqueName("context");
|
||||
|
||||
// Add the body of the module.
|
||||
@@ -123,7 +122,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
if (noSubstitution) {
|
||||
noSubstitutionMap.set(id, noSubstitution);
|
||||
noSubstitutionMap[id] = noSubstitution;
|
||||
noSubstitution = undefined;
|
||||
}
|
||||
|
||||
@@ -610,7 +609,7 @@ namespace ts {
|
||||
if (hasAssociatedEndOfDeclarationMarker(node)) {
|
||||
// Defer exports until we encounter an EndOfDeclarationMarker node
|
||||
const id = getOriginalNodeId(node);
|
||||
deferredExports.set(id, appendExportsOfImportDeclaration(deferredExports.get(id), node));
|
||||
deferredExports[id] = appendExportsOfImportDeclaration(deferredExports[id], node);
|
||||
}
|
||||
else {
|
||||
statements = appendExportsOfImportDeclaration(statements, node);
|
||||
@@ -633,7 +632,7 @@ namespace ts {
|
||||
if (hasAssociatedEndOfDeclarationMarker(node)) {
|
||||
// Defer exports until we encounter an EndOfDeclarationMarker node
|
||||
const id = getOriginalNodeId(node);
|
||||
deferredExports.set(id, appendExportsOfImportEqualsDeclaration(deferredExports.get(id), node));
|
||||
deferredExports[id] = appendExportsOfImportEqualsDeclaration(deferredExports[id], node);
|
||||
}
|
||||
else {
|
||||
statements = appendExportsOfImportEqualsDeclaration(statements, node);
|
||||
@@ -658,7 +657,7 @@ namespace ts {
|
||||
if (original && hasAssociatedEndOfDeclarationMarker(original)) {
|
||||
// Defer exports until we encounter an EndOfDeclarationMarker node
|
||||
const id = getOriginalNodeId(node);
|
||||
deferredExports.set(id, appendExportStatement(deferredExports.get(id), createIdentifier("default"), expression, /*allowComments*/ true));
|
||||
deferredExports[id] = appendExportStatement(deferredExports[id], createIdentifier("default"), expression, /*allowComments*/ true);
|
||||
}
|
||||
else {
|
||||
return createExportStatement(createIdentifier("default"), expression, /*allowComments*/ true);
|
||||
@@ -690,7 +689,7 @@ namespace ts {
|
||||
if (hasAssociatedEndOfDeclarationMarker(node)) {
|
||||
// Defer exports until we encounter an EndOfDeclarationMarker node
|
||||
const id = getOriginalNodeId(node);
|
||||
deferredExports.set(id, appendExportsOfHoistedDeclaration(deferredExports.get(id), node));
|
||||
deferredExports[id] = appendExportsOfHoistedDeclaration(deferredExports[id], node);
|
||||
}
|
||||
else {
|
||||
hoistedStatements = appendExportsOfHoistedDeclaration(hoistedStatements, node);
|
||||
@@ -732,7 +731,7 @@ namespace ts {
|
||||
if (hasAssociatedEndOfDeclarationMarker(node)) {
|
||||
// Defer exports until we encounter an EndOfDeclarationMarker node
|
||||
const id = getOriginalNodeId(node);
|
||||
deferredExports.set(id, appendExportsOfHoistedDeclaration(deferredExports.get(id), node));
|
||||
deferredExports[id] = appendExportsOfHoistedDeclaration(deferredExports[id], node);
|
||||
}
|
||||
else {
|
||||
statements = appendExportsOfHoistedDeclaration(statements, node);
|
||||
@@ -772,7 +771,7 @@ namespace ts {
|
||||
if (isMarkedDeclaration) {
|
||||
// Defer exports until we encounter an EndOfDeclarationMarker node
|
||||
const id = getOriginalNodeId(node);
|
||||
deferredExports.set(id, appendExportsOfVariableStatement(deferredExports.get(id), node, isExportedDeclaration));
|
||||
deferredExports[id] = appendExportsOfVariableStatement(deferredExports[id], node, isExportedDeclaration);
|
||||
}
|
||||
else {
|
||||
statements = appendExportsOfVariableStatement(statements, node, /*exportSelf*/ false);
|
||||
@@ -885,7 +884,7 @@ namespace ts {
|
||||
if (hasAssociatedEndOfDeclarationMarker(node) && node.original.kind === SyntaxKind.VariableStatement) {
|
||||
const id = getOriginalNodeId(node);
|
||||
const isExportedDeclaration = hasModifier(node.original, ModifierFlags.Export);
|
||||
deferredExports.set(id, appendExportsOfVariableStatement(deferredExports.get(id), <VariableStatement>node.original, isExportedDeclaration));
|
||||
deferredExports[id] = appendExportsOfVariableStatement(deferredExports[id], <VariableStatement>node.original, isExportedDeclaration);
|
||||
}
|
||||
|
||||
return node;
|
||||
@@ -911,9 +910,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.get(id);
|
||||
const statements = deferredExports[id];
|
||||
if (statements) {
|
||||
deferredExports.delete(id);
|
||||
delete deferredExports[id];
|
||||
return append(statements, node);
|
||||
}
|
||||
|
||||
@@ -1556,12 +1555,12 @@ namespace ts {
|
||||
if (node.kind === SyntaxKind.SourceFile) {
|
||||
const id = getOriginalNodeId(node);
|
||||
currentSourceFile = <SourceFile>node;
|
||||
moduleInfo = moduleInfoMap.get(id);
|
||||
exportFunction = exportFunctionsMap.get(id);
|
||||
noSubstitution = noSubstitutionMap.get(id);
|
||||
moduleInfo = moduleInfoMap[id];
|
||||
exportFunction = exportFunctionsMap[id];
|
||||
noSubstitution = noSubstitutionMap[id];
|
||||
|
||||
if (noSubstitution) {
|
||||
noSubstitutionMap.delete(id);
|
||||
delete noSubstitutionMap[id];
|
||||
}
|
||||
|
||||
previousOnEmitNode(emitContext, node, emitCallback);
|
||||
@@ -1758,7 +1757,7 @@ namespace ts {
|
||||
exportedNames = append(exportedNames, getDeclarationName(valueDeclaration));
|
||||
}
|
||||
|
||||
exportedNames = addRange(exportedNames, moduleInfo && moduleInfo.exportedBindings.get(getOriginalNodeId(valueDeclaration)));
|
||||
exportedNames = addRange(exportedNames, moduleInfo && moduleInfo.exportedBindings[getOriginalNodeId(valueDeclaration)]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1771,8 +1770,8 @@ namespace ts {
|
||||
* @param node The node which should not be substituted.
|
||||
*/
|
||||
function preventSubstitution<T extends Node>(node: T): T {
|
||||
if (noSubstitution === undefined) noSubstitution = createMap<boolean>();
|
||||
noSubstitution.set(getNodeId(node), true);
|
||||
if (noSubstitution === undefined) noSubstitution = sparseArray<boolean>();
|
||||
noSubstitution[getNodeId(node)] = true;
|
||||
return node;
|
||||
}
|
||||
|
||||
@@ -1782,7 +1781,7 @@ namespace ts {
|
||||
* @param node The node to test.
|
||||
*/
|
||||
function isSubstitutionPrevented(node: Node) {
|
||||
return noSubstitution && node.id && noSubstitution.get(node.id);
|
||||
return noSubstitution && node.id && noSubstitution[node.id];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/// <reference path="../factory.ts" />
|
||||
/// <reference path="../factory.ts" />
|
||||
/// <reference path="../visitor.ts" />
|
||||
/// <reference path="./destructuring.ts" />
|
||||
|
||||
@@ -60,7 +60,7 @@ namespace ts {
|
||||
* A map that keeps track of aliases created for classes with decorators to avoid issues
|
||||
* with the double-binding behavior of classes.
|
||||
*/
|
||||
let classAliases: Map<Identifier>;
|
||||
let classAliases: SparseArray<Identifier>;
|
||||
|
||||
/**
|
||||
* Keeps track of whether we are within any containing namespaces when performing
|
||||
@@ -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.set(getOriginalNodeId(node), getSynthesizedClone(temp));
|
||||
classAliases[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.get(getOriginalNodeId(node));
|
||||
const classAlias = classAliases && classAliases[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);
|
||||
@@ -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.set(getOriginalNodeId(node), classAlias);
|
||||
classAliases[getOriginalNodeId(node)] = classAlias;
|
||||
hoistVariableDeclaration(classAlias);
|
||||
return classAlias;
|
||||
}
|
||||
@@ -3117,7 +3117,7 @@ namespace ts {
|
||||
context.enableSubstitution(SyntaxKind.Identifier);
|
||||
|
||||
// Keep track of class aliases.
|
||||
classAliases = createMap<Identifier>();
|
||||
classAliases = sparseArray<Identifier>();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3230,7 +3230,7 @@ namespace ts {
|
||||
// constructor references in static property initializers.
|
||||
const declaration = resolver.getReferencedValueDeclaration(node);
|
||||
if (declaration) {
|
||||
const classAlias = classAliases.get(declaration.id);
|
||||
const classAlias = classAliases[declaration.id];
|
||||
if (classAlias) {
|
||||
const clone = getSynthesizedClone(classAlias);
|
||||
setSourceMapRange(clone, node);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/// <reference path="program.ts"/>
|
||||
/// <reference path="program.ts"/>
|
||||
/// <reference path="commandLineParser.ts"/>
|
||||
|
||||
namespace ts {
|
||||
@@ -67,11 +67,13 @@ namespace ts {
|
||||
const gutterSeparator = " ";
|
||||
const resetEscapeSequence = "\u001b[0m";
|
||||
const ellipsis = "...";
|
||||
const categoryFormatMap = createMapFromPairs<string>(
|
||||
[DiagnosticCategory.Warning, yellowForegroundEscapeSequence],
|
||||
[DiagnosticCategory.Error, redForegroundEscapeSequence],
|
||||
[DiagnosticCategory.Message, blueForegroundEscapeSequence],
|
||||
);
|
||||
function getCategoryFormat(category: DiagnosticCategory): string {
|
||||
switch (category) {
|
||||
case DiagnosticCategory.Warning: return yellowForegroundEscapeSequence;
|
||||
case DiagnosticCategory.Error: return redForegroundEscapeSequence;
|
||||
case DiagnosticCategory.Message: return blueForegroundEscapeSequence;
|
||||
}
|
||||
}
|
||||
|
||||
function formatAndReset(text: string, formatStyle: string) {
|
||||
return formatStyle + text + resetEscapeSequence;
|
||||
@@ -139,7 +141,7 @@ namespace ts {
|
||||
output += `${ relativeFileName }(${ firstLine + 1 },${ firstLineChar + 1 }): `;
|
||||
}
|
||||
|
||||
const categoryColor = categoryFormatMap.get(diagnostic.category);
|
||||
const categoryColor = getCategoryFormat(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;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
namespace ts {
|
||||
namespace ts {
|
||||
/**
|
||||
* Type of objects whose values are all of the same type.
|
||||
* The `in` and `for-in` operators can *not* be safely used,
|
||||
@@ -8,15 +8,19 @@ namespace ts {
|
||||
[index: string]: T;
|
||||
}
|
||||
|
||||
/** 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;
|
||||
/**
|
||||
* Like MapLike, but keys must be numbers.
|
||||
*/
|
||||
export interface SparseArray<T> {
|
||||
[key: number]: T;
|
||||
}
|
||||
|
||||
/** Minimal ES6 Map interface. Does not include iterators as those are hard to shim performantly. */
|
||||
export interface Map<T> {
|
||||
get(key: MapKey): T;
|
||||
has(key: MapKey): boolean;
|
||||
set(key: MapKey, value: T): this;
|
||||
delete(key: MapKey): boolean;
|
||||
get(key: string): T;
|
||||
has(key: string): boolean;
|
||||
set(key: string, value: T): this;
|
||||
delete(key: string): 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;
|
||||
@@ -2853,7 +2857,7 @@ namespace ts {
|
||||
|
||||
// Enum types (TypeFlags.Enum)
|
||||
export interface EnumType extends Type {
|
||||
memberTypes: Map<EnumLiteralType>;
|
||||
memberTypes: SparseArray<EnumLiteralType>;
|
||||
}
|
||||
|
||||
// Enum types (TypeFlags.EnumLiteral)
|
||||
@@ -3682,7 +3686,7 @@ namespace ts {
|
||||
flags?: EmitFlags; // Flags that customize emit
|
||||
commentRange?: TextRange; // The text range to use when emitting leading or trailing comments
|
||||
sourceMapRange?: TextRange; // The text range to use when emitting leading or trailing source mappings
|
||||
tokenSourceMapRanges?: Map<TextRange>; // The text range to use when emitting source mappings for tokens
|
||||
tokenSourceMapRanges?: SparseArray<TextRange>; // The text range to use when emitting source mappings for tokens
|
||||
constantValue?: number; // The constant value of an expression
|
||||
externalHelpersModuleName?: Identifier; // The local name for an imported helpers module
|
||||
helpers?: EmitHelper[]; // Emit helpers for the node
|
||||
|
||||
@@ -3311,12 +3311,12 @@ namespace ts {
|
||||
return false;
|
||||
}
|
||||
|
||||
const syntaxKindCache = createMap<string>();
|
||||
const syntaxKindCache = sparseArray<string>();
|
||||
|
||||
export function formatSyntaxKind(kind: SyntaxKind): string {
|
||||
const syntaxKindEnum = (<any>ts).SyntaxKind;
|
||||
if (syntaxKindEnum) {
|
||||
const cached = syntaxKindCache.get(kind);
|
||||
const cached = syntaxKindCache[kind];
|
||||
if (cached !== undefined) {
|
||||
return cached;
|
||||
}
|
||||
@@ -3324,7 +3324,7 @@ namespace ts {
|
||||
for (const name in syntaxKindEnum) {
|
||||
if (syntaxKindEnum[name] === kind) {
|
||||
const result = `${kind} (${name})`;
|
||||
syntaxKindCache.set(kind, result);
|
||||
syntaxKindCache[kind] = result;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/// <reference path="checker.ts" />
|
||||
/// <reference path="checker.ts" />
|
||||
/// <reference path="factory.ts" />
|
||||
/// <reference path="utilities.ts" />
|
||||
|
||||
@@ -46,54 +46,56 @@ namespace ts {
|
||||
* supplant the existing `forEachChild` implementation if performance is not
|
||||
* significantly impacted.
|
||||
*/
|
||||
const nodeEdgeTraversalMap = createMapFromPairs<NodeTraversalPath>(
|
||||
[SyntaxKind.QualifiedName, [
|
||||
{ name: "left", test: isEntityName },
|
||||
{ name: "right", test: isIdentifier }
|
||||
]],
|
||||
[SyntaxKind.Decorator, [
|
||||
{ name: "expression", test: isLeftHandSideExpression }
|
||||
]],
|
||||
[SyntaxKind.TypeAssertionExpression, [
|
||||
{ name: "type", test: isTypeNode },
|
||||
{ name: "expression", test: isUnaryExpression }
|
||||
]],
|
||||
[SyntaxKind.AsExpression, [
|
||||
{ name: "expression", test: isExpression },
|
||||
{ name: "type", test: isTypeNode }
|
||||
]],
|
||||
[SyntaxKind.NonNullExpression, [
|
||||
{ name: "expression", test: isLeftHandSideExpression }
|
||||
]],
|
||||
[SyntaxKind.EnumDeclaration, [
|
||||
{ name: "decorators", test: isDecorator },
|
||||
{ name: "modifiers", test: isModifier },
|
||||
{ name: "name", test: isIdentifier },
|
||||
{ name: "members", test: isEnumMember }
|
||||
]],
|
||||
[SyntaxKind.ModuleDeclaration, [
|
||||
{ name: "decorators", test: isDecorator },
|
||||
{ name: "modifiers", test: isModifier },
|
||||
{ name: "name", test: isModuleName },
|
||||
{ name: "body", test: isModuleBody }
|
||||
]],
|
||||
[SyntaxKind.ModuleBlock, [
|
||||
{ name: "statements", test: isStatement }
|
||||
]],
|
||||
[SyntaxKind.ImportEqualsDeclaration, [
|
||||
{ name: "decorators", test: isDecorator },
|
||||
{ name: "modifiers", test: isModifier },
|
||||
{ name: "name", test: isIdentifier },
|
||||
{ name: "moduleReference", test: isModuleReference }
|
||||
]],
|
||||
[SyntaxKind.ExternalModuleReference, [
|
||||
{ name: "expression", test: isExpression, optional: true }
|
||||
]],
|
||||
[SyntaxKind.EnumMember, [
|
||||
{ name: "name", test: isPropertyName },
|
||||
{ name: "initializer", test: isExpression, optional: true, parenthesize: parenthesizeExpressionForList }
|
||||
]]
|
||||
);
|
||||
function getNodeEdgeTraversal(kind: SyntaxKind): NodeTraversalPath {
|
||||
switch (kind) {
|
||||
case SyntaxKind.QualifiedName: return [
|
||||
{ name: "left", test: isEntityName },
|
||||
{ name: "right", test: isIdentifier }
|
||||
];
|
||||
case SyntaxKind.Decorator: return [
|
||||
{ name: "expression", test: isLeftHandSideExpression }
|
||||
];
|
||||
case SyntaxKind.TypeAssertionExpression: return [
|
||||
{ name: "type", test: isTypeNode },
|
||||
{ name: "expression", test: isUnaryExpression }
|
||||
];
|
||||
case SyntaxKind.AsExpression: return [
|
||||
{ name: "expression", test: isExpression },
|
||||
{ name: "type", test: isTypeNode }
|
||||
];
|
||||
case SyntaxKind.NonNullExpression: return [
|
||||
{ name: "expression", test: isLeftHandSideExpression }
|
||||
];
|
||||
case SyntaxKind.EnumDeclaration: return [
|
||||
{ name: "decorators", test: isDecorator },
|
||||
{ name: "modifiers", test: isModifier },
|
||||
{ name: "name", test: isIdentifier },
|
||||
{ name: "members", test: isEnumMember }
|
||||
];
|
||||
case SyntaxKind.ModuleDeclaration: return [
|
||||
{ name: "decorators", test: isDecorator },
|
||||
{ name: "modifiers", test: isModifier },
|
||||
{ name: "name", test: isModuleName },
|
||||
{ name: "body", test: isModuleBody }
|
||||
];
|
||||
case SyntaxKind.ModuleBlock: return [
|
||||
{ name: "statements", test: isStatement }
|
||||
];
|
||||
case SyntaxKind.ImportEqualsDeclaration: return [
|
||||
{ name: "decorators", test: isDecorator },
|
||||
{ name: "modifiers", test: isModifier },
|
||||
{ name: "name", test: isIdentifier },
|
||||
{ name: "moduleReference", test: isModuleReference }
|
||||
];
|
||||
case SyntaxKind.ExternalModuleReference: return [
|
||||
{ name: "expression", test: isExpression, optional: true }
|
||||
];
|
||||
case SyntaxKind.EnumMember: return [
|
||||
{ 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 +532,7 @@ namespace ts {
|
||||
break;
|
||||
|
||||
default:
|
||||
const edgeTraversalPath = nodeEdgeTraversalMap.get(kind);
|
||||
const edgeTraversalPath = getNodeEdgeTraversal(kind);
|
||||
if (edgeTraversalPath) {
|
||||
for (const edge of edgeTraversalPath) {
|
||||
const value = (<MapLike<any>>node)[edge.name];
|
||||
@@ -1188,7 +1190,7 @@ namespace ts {
|
||||
|
||||
default:
|
||||
let updated: Node & MapLike<any>;
|
||||
const edgeTraversalPath = nodeEdgeTraversalMap.get(kind);
|
||||
const edgeTraversalPath = getNodeEdgeTraversal(kind);
|
||||
if (edgeTraversalPath) {
|
||||
for (const edge of edgeTraversalPath) {
|
||||
const value = <Node | NodeArray<Node>>(<Node & MapLike<any>>node)[edge.name];
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/// <reference path="..\harness.ts" />
|
||||
/// <reference path="..\harness.ts" />
|
||||
|
||||
const expect: typeof _chai.expect = _chai.expect;
|
||||
|
||||
@@ -416,16 +416,16 @@ namespace ts.server {
|
||||
class InProcClient {
|
||||
private server: InProcSession;
|
||||
private seq = 0;
|
||||
private callbacks = createMap<(resp: protocol.Response) => void>();
|
||||
private callbacks = sparseArray<(resp: protocol.Response) => void>();
|
||||
private eventHandlers = createMap<(args: any) => void>();
|
||||
|
||||
handle(msg: protocol.Message): void {
|
||||
if (msg.type === "response") {
|
||||
const response = <protocol.Response>msg;
|
||||
const handler = this.callbacks.get(response.request_seq);
|
||||
const handler = this.callbacks[response.request_seq];
|
||||
if (handler) {
|
||||
handler(response);
|
||||
this.callbacks.delete(response.request_seq);
|
||||
delete this.callbacks[response.request_seq];
|
||||
}
|
||||
}
|
||||
else if (msg.type === "event") {
|
||||
@@ -460,7 +460,7 @@ namespace ts.server {
|
||||
command,
|
||||
arguments: args
|
||||
});
|
||||
this.callbacks.set(this.seq, callback);
|
||||
this.callbacks[this.seq] = callback;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/// <reference path="..\harness.ts" />
|
||||
/// <reference path="..\harness.ts" />
|
||||
/// <reference path="../../server/typingsInstaller/typingsInstaller.ts" />
|
||||
|
||||
namespace ts.projectSystem {
|
||||
@@ -290,30 +290,34 @@ namespace ts.projectSystem {
|
||||
}
|
||||
|
||||
export class Callbacks {
|
||||
private map = createMap<TimeOutCallback>();
|
||||
private map = sparseArray<TimeOutCallback>();
|
||||
private nextId = 1;
|
||||
|
||||
register(cb: (...args: any[]) => void, args: any[]) {
|
||||
const timeoutId = this.nextId;
|
||||
this.nextId++;
|
||||
this.map.set(timeoutId, cb.bind(undefined, ...args));
|
||||
this.map[timeoutId] = cb.bind(undefined, ...args);
|
||||
return timeoutId;
|
||||
}
|
||||
unregister(id: any) {
|
||||
if (typeof id === "number") {
|
||||
this.map.delete(id);
|
||||
delete this.map[id];
|
||||
}
|
||||
}
|
||||
|
||||
count() {
|
||||
return this.map.size;
|
||||
let n = 0;
|
||||
for (const _ in this.map) {
|
||||
n++;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
invoke() {
|
||||
this.map.forEach(cb => {
|
||||
cb();
|
||||
});
|
||||
this.map.clear();
|
||||
for (const key in this.map) {
|
||||
this.map[key]();
|
||||
}
|
||||
this.map = sparseArray<TimeOutCallback>();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -16,25 +16,25 @@ namespace ts {
|
||||
}
|
||||
|
||||
export namespace codefix {
|
||||
const codeFixes = createMap<CodeFix[]>();
|
||||
const codeFixes = sparseArray<CodeFix[]>();
|
||||
|
||||
export function registerCodeFix(action: CodeFix) {
|
||||
forEach(action.errorCodes, error => {
|
||||
let fixes = codeFixes.get(error);
|
||||
let fixes = codeFixes[error];
|
||||
if (!fixes) {
|
||||
fixes = [];
|
||||
codeFixes.set(error, fixes);
|
||||
codeFixes[error] = fixes;
|
||||
}
|
||||
fixes.push(action);
|
||||
});
|
||||
}
|
||||
|
||||
export function getSupportedErrorCodes() {
|
||||
return keysOfMap(codeFixes);
|
||||
return keysOfSparseArray(codeFixes);
|
||||
}
|
||||
|
||||
export function getFixes(context: CodeFixContext): CodeAction[] {
|
||||
const fixes = codeFixes.get(context.errorCode);
|
||||
const fixes = codeFixes[context.errorCode];
|
||||
let allActions: CodeAction[] = [];
|
||||
|
||||
forEach(fixes, f => {
|
||||
|
||||
@@ -14,16 +14,16 @@ namespace ts.codefix {
|
||||
}
|
||||
|
||||
class ImportCodeActionMap {
|
||||
private symbolIdToActionMap = createMap<ImportCodeAction[]>();
|
||||
private symbolIdToActionMap = sparseArray<ImportCodeAction[]>();
|
||||
|
||||
addAction(symbolId: number, newAction: ImportCodeAction) {
|
||||
if (!newAction) {
|
||||
return;
|
||||
}
|
||||
|
||||
const actions = this.symbolIdToActionMap.get(symbolId);
|
||||
const actions = this.symbolIdToActionMap[symbolId];
|
||||
if (!actions) {
|
||||
this.symbolIdToActionMap.set(symbolId, [newAction]);
|
||||
this.symbolIdToActionMap[symbolId] = [newAction];
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ namespace ts.codefix {
|
||||
}
|
||||
|
||||
const updatedNewImports: ImportCodeAction[] = [];
|
||||
for (const existingAction of this.symbolIdToActionMap.get(symbolId)) {
|
||||
for (const existingAction of this.symbolIdToActionMap[symbolId]) {
|
||||
if (existingAction.kind === "CodeChange") {
|
||||
// only import actions should compare
|
||||
updatedNewImports.push(existingAction);
|
||||
@@ -63,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.set(symbolId, updatedNewImports);
|
||||
this.symbolIdToActionMap[symbolId] = updatedNewImports;
|
||||
}
|
||||
|
||||
addActions(symbolId: number, newActions: ImportCodeAction[]) {
|
||||
@@ -74,9 +74,9 @@ namespace ts.codefix {
|
||||
|
||||
getAllActions() {
|
||||
let result: ImportCodeAction[] = [];
|
||||
this.symbolIdToActionMap.forEach(actions => {
|
||||
result = concatenate(result, actions);
|
||||
});
|
||||
for (const key in this.symbolIdToActionMap) {
|
||||
result = concatenate(result, this.symbolIdToActionMap[key])
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -125,7 +125,7 @@ namespace ts.codefix {
|
||||
const symbolIdActionMap = new ImportCodeActionMap();
|
||||
|
||||
// this is a module id -> module import declaration map
|
||||
const cachedImportDeclarations = createMap<(ImportDeclaration | ImportEqualsDeclaration)[]>();
|
||||
const cachedImportDeclarations = sparseArray<(ImportDeclaration | ImportEqualsDeclaration)[]>();
|
||||
let cachedNewImportInsertPosition: number;
|
||||
|
||||
const allPotentialModules = checker.getAmbientModules();
|
||||
@@ -163,7 +163,7 @@ namespace ts.codefix {
|
||||
function getImportDeclarations(moduleSymbol: Symbol) {
|
||||
const moduleSymbolId = getUniqueSymbolId(moduleSymbol);
|
||||
|
||||
const cached = cachedImportDeclarations.get(moduleSymbolId);
|
||||
const cached = cachedImportDeclarations[moduleSymbolId];
|
||||
if (cached) {
|
||||
return cached;
|
||||
}
|
||||
@@ -175,7 +175,7 @@ namespace ts.codefix {
|
||||
existingDeclarations.push(getImportDeclaration(importModuleSpecifier));
|
||||
}
|
||||
}
|
||||
cachedImportDeclarations.set(moduleSymbolId, existingDeclarations);
|
||||
cachedImportDeclarations[moduleSymbolId] = existingDeclarations;
|
||||
return existingDeclarations;
|
||||
|
||||
function getImportDeclaration(moduleSpecifier: LiteralExpression) {
|
||||
|
||||
Reference in New Issue
Block a user