Merge branch 'master' into object-spread

This commit is contained in:
Nathan Shively-Sanders 2016-10-27 15:29:21 -07:00
commit 58ffb4e668
528 changed files with 5998 additions and 3182 deletions

View File

@ -15,7 +15,7 @@ matrix:
branches:
only:
- master
- release-2.0
- release-2.1
install:
- npm uninstall typescript

View File

@ -70,9 +70,6 @@ var compilerSources = [
"visitor.ts",
"transformers/destructuring.ts",
"transformers/ts.ts",
"transformers/module/es2015.ts",
"transformers/module/system.ts",
"transformers/module/module.ts",
"transformers/jsx.ts",
"transformers/experimental.ts",
"transformers/es2017.ts",
@ -80,6 +77,9 @@ var compilerSources = [
"transformers/es2015.ts",
"transformers/generators.ts",
"transformers/es5.ts",
"transformers/module/es2015.ts",
"transformers/module/system.ts",
"transformers/module/module.ts",
"transformer.ts",
"sourcemap.ts",
"comments.ts",
@ -107,9 +107,6 @@ var servicesSources = [
"visitor.ts",
"transformers/destructuring.ts",
"transformers/ts.ts",
"transformers/module/es2015.ts",
"transformers/module/system.ts",
"transformers/module/module.ts",
"transformers/jsx.ts",
"transformers/experimental.ts",
"transformers/es2017.ts",
@ -117,6 +114,9 @@ var servicesSources = [
"transformers/es2015.ts",
"transformers/generators.ts",
"transformers/es5.ts",
"transformers/module/es2015.ts",
"transformers/module/system.ts",
"transformers/module/module.ts",
"transformer.ts",
"sourcemap.ts",
"comments.ts",

View File

@ -54,6 +54,11 @@ namespace ts {
const body = (<ModuleDeclaration>node).body;
return body ? getModuleInstanceState(body) : ModuleInstanceState.Instantiated;
}
// Only jsdoc typedef definition can exist in jsdoc namespace, and it should
// be considered the same as type alias
else if (node.kind === SyntaxKind.Identifier && (<Identifier>node).isInJSDocNamespace) {
return ModuleInstanceState.NonInstantiated;
}
else {
return ModuleInstanceState.Instantiated;
}
@ -429,7 +434,11 @@ namespace ts {
// during global merging in the checker. Why? The only case when ambient module is permitted inside another module is module augmentation
// and this case is specially handled. Module augmentations should only be merged with original module definition
// and should never be merged directly with other augmentation, and the latter case would be possible if automatic merge is allowed.
if (!isAmbientModule(node) && (hasExportModifier || container.flags & NodeFlags.ExportContext)) {
const isJSDocTypedefInJSDocNamespace = node.kind === SyntaxKind.JSDocTypedefTag &&
node.name &&
node.name.kind === SyntaxKind.Identifier &&
(<Identifier>node.name).isInJSDocNamespace;
if ((!isAmbientModule(node) && (hasExportModifier || container.flags & NodeFlags.ExportContext)) || isJSDocTypedefInJSDocNamespace) {
const exportKind =
(symbolFlags & SymbolFlags.Value ? SymbolFlags.ExportValue : 0) |
(symbolFlags & SymbolFlags.Type ? SymbolFlags.ExportType : 0) |
@ -1831,6 +1840,17 @@ namespace ts {
switch (node.kind) {
/* Strict mode checks */
case SyntaxKind.Identifier:
// for typedef type names with namespaces, bind the new jsdoc type symbol here
// because it requires all containing namespaces to be in effect, namely the
// current "blockScopeContainer" needs to be set to its immediate namespace parent.
if ((<Identifier>node).isInJSDocNamespace) {
let parentNode = node.parent;
while (parentNode && parentNode.kind !== SyntaxKind.JSDocTypedefTag) {
parentNode = parentNode.parent;
}
bindBlockScopedDeclaration(<Declaration>parentNode, SymbolFlags.TypeAlias, SymbolFlags.TypeAliasExcludes);
break;
}
case SyntaxKind.ThisKeyword:
if (currentFlow && (isExpression(node) || parent.kind === SyntaxKind.ShorthandPropertyAssignment)) {
node.flowNode = currentFlow;
@ -1955,6 +1975,10 @@ namespace ts {
case SyntaxKind.InterfaceDeclaration:
return bindBlockScopedDeclaration(<Declaration>node, SymbolFlags.Interface, SymbolFlags.InterfaceExcludes);
case SyntaxKind.JSDocTypedefTag:
if (!(<JSDocTypedefTag>node).fullName || (<JSDocTypedefTag>node).fullName.kind === SyntaxKind.Identifier) {
return bindBlockScopedDeclaration(<Declaration>node, SymbolFlags.TypeAlias, SymbolFlags.TypeAliasExcludes);
}
break;
case SyntaxKind.TypeAliasDeclaration:
return bindBlockScopedDeclaration(<Declaration>node, SymbolFlags.TypeAlias, SymbolFlags.TypeAliasExcludes);
case SyntaxKind.EnumDeclaration:
@ -2514,7 +2538,7 @@ namespace ts {
&& (leftKind === SyntaxKind.ObjectLiteralExpression
|| leftKind === SyntaxKind.ArrayLiteralExpression)) {
// Destructuring assignments are ES6 syntax.
transformFlags |= TransformFlags.AssertES2015 | TransformFlags.DestructuringAssignment;
transformFlags |= TransformFlags.AssertES2015 | TransformFlags.AssertDestructuringAssignment;
}
else if (operatorTokenKind === SyntaxKind.AsteriskAsteriskToken
|| operatorTokenKind === SyntaxKind.AsteriskAsteriskEqualsToken) {
@ -2595,9 +2619,9 @@ namespace ts {
// A class with a parameter property assignment, property initializer, or decorator is
// TypeScript syntax.
// An exported declaration may be TypeScript syntax.
// An exported declaration may be TypeScript syntax, but is handled by the visitor
// for a namespace declaration.
if ((subtreeFlags & TransformFlags.TypeScriptClassSyntaxMask)
|| (modifierFlags & ModifierFlags.Export)
|| node.typeParameters) {
transformFlags |= TransformFlags.AssertTypeScript;
}
@ -2767,11 +2791,6 @@ namespace ts {
else {
transformFlags = subtreeFlags | TransformFlags.ContainsHoistedDeclarationOrCompletion;
// If a FunctionDeclaration is exported, then it is either ES6 or TypeScript syntax.
if (modifierFlags & ModifierFlags.Export) {
transformFlags |= TransformFlags.AssertTypeScript | TransformFlags.AssertES2015;
}
// TypeScript-specific modifiers, type parameters, and type annotations are TypeScript
// syntax.
if (modifierFlags & ModifierFlags.TypeScriptModifier
@ -2913,11 +2932,6 @@ namespace ts {
else {
transformFlags = subtreeFlags;
// If a VariableStatement is exported, then it is either ES6 or TypeScript syntax.
if (modifierFlags & ModifierFlags.Export) {
transformFlags |= TransformFlags.AssertES2015 | TransformFlags.AssertTypeScript;
}
if (declarationListTransformFlags & TransformFlags.ContainsBindingPattern) {
transformFlags |= TransformFlags.AssertES2015;
}
@ -3034,12 +3048,6 @@ namespace ts {
transformFlags |= TransformFlags.AssertJsx;
break;
case SyntaxKind.ExportKeyword:
// This node is both ES6 and TypeScript syntax.
transformFlags |= TransformFlags.AssertES2015 | TransformFlags.AssertTypeScript;
break;
case SyntaxKind.DefaultKeyword:
case SyntaxKind.NoSubstitutionTemplateLiteral:
case SyntaxKind.TemplateHead:
case SyntaxKind.TemplateMiddle:
@ -3048,6 +3056,7 @@ namespace ts {
case SyntaxKind.TaggedTemplateExpression:
case SyntaxKind.ShorthandPropertyAssignment:
case SyntaxKind.ForOfStatement:
case SyntaxKind.StaticKeyword:
// These nodes are ES6 syntax.
transformFlags |= TransformFlags.AssertES2015;
break;

View File

@ -1375,7 +1375,8 @@ namespace ts {
}
const resolvedModule = getResolvedModule(getSourceFileOfNode(location), moduleReference);
const sourceFile = resolvedModule && host.getSourceFile(resolvedModule.resolvedFileName);
const resolutionDiagnostic = resolvedModule && getResolutionDiagnostic(compilerOptions, resolvedModule);
const sourceFile = resolvedModule && !resolutionDiagnostic && host.getSourceFile(resolvedModule.resolvedFileName);
if (sourceFile) {
if (sourceFile.symbol) {
// merged symbol is module declaration symbol combined with all augmentations
@ -1397,13 +1398,18 @@ namespace ts {
if (moduleNotFoundError) {
// report errors only if it was requested
const tsExtension = tryExtractTypeScriptExtension(moduleName);
if (tsExtension) {
const diag = Diagnostics.An_import_path_cannot_end_with_a_0_extension_Consider_importing_1_instead;
error(errorNode, diag, tsExtension, removeExtension(moduleName, tsExtension));
if (resolutionDiagnostic) {
error(errorNode, resolutionDiagnostic, moduleName, resolvedModule.resolvedFileName);
}
else {
error(errorNode, moduleNotFoundError, moduleName);
const tsExtension = tryExtractTypeScriptExtension(moduleName);
if (tsExtension) {
const diag = Diagnostics.An_import_path_cannot_end_with_a_0_extension_Consider_importing_1_instead;
error(errorNode, diag, tsExtension, removeExtension(moduleName, tsExtension));
}
else {
error(errorNode, moduleNotFoundError, moduleName);
}
}
}
return undefined;
@ -13180,16 +13186,41 @@ namespace ts {
}
// In JavaScript files, calls to any identifier 'require' are treated as external module imports
if (isInJavaScriptFile(node) &&
isRequireCall(node, /*checkArgumentIsStringLiteral*/true) &&
// Make sure require is not a local function
!resolveName(node.expression, (<Identifier>node.expression).text, SymbolFlags.Value, /*nameNotFoundMessage*/ undefined, /*nameArg*/ undefined)) {
if (isInJavaScriptFile(node) && isCommonJsRequire(node)) {
return resolveExternalModuleTypeByLiteral(<StringLiteral>node.arguments[0]);
}
return getReturnTypeOfSignature(signature);
}
function isCommonJsRequire(node: Node) {
if (!isRequireCall(node, /*checkArgumentIsStringLiteral*/true)) {
return false;
}
// Make sure require is not a local function
const resolvedRequire = resolveName(node.expression, (<Identifier>node.expression).text, SymbolFlags.Value, /*nameNotFoundMessage*/ undefined, /*nameArg*/ undefined);
if (!resolvedRequire) {
// project does not contain symbol named 'require' - assume commonjs require
return true;
}
// project includes symbol named 'require' - make sure that it it ambient and local non-alias
if (resolvedRequire.flags & SymbolFlags.Alias) {
return false;
}
const targetDeclarationKind = resolvedRequire.flags & SymbolFlags.Function
? SyntaxKind.FunctionDeclaration
: resolvedRequire.flags & SymbolFlags.Variable
? SyntaxKind.VariableDeclaration
: SyntaxKind.Unknown;
if (targetDeclarationKind !== SyntaxKind.Unknown) {
const decl = getDeclarationOfKind(resolvedRequire, targetDeclarationKind);
// function/variable declaration should be ambient
return isInAmbientContext(decl);
}
return false;
}
function checkTaggedTemplateExpression(node: TaggedTemplateExpression): Type {
return getReturnTypeOfSignature(getResolvedSignature(node));
}
@ -17575,7 +17606,7 @@ namespace ts {
if (declaration && getModifierFlags(declaration) & ModifierFlags.Private) {
const typeClassDeclaration = <ClassLikeDeclaration>getClassLikeDeclarationOfSymbol(type.symbol);
if (!isNodeWithinClass(node, typeClassDeclaration)) {
error(node, Diagnostics.Cannot_extend_a_class_0_Class_constructor_is_marked_as_private, (<Identifier>node.expression).text);
error(node, Diagnostics.Cannot_extend_a_class_0_Class_constructor_is_marked_as_private, getFullyQualifiedName(type.symbol));
}
}
}
@ -19852,6 +19883,10 @@ namespace ts {
if (typeReferenceDirective) {
(typeReferenceDirectives || (typeReferenceDirectives = [])).push(typeReferenceDirective);
}
else {
// found at least one entry that does not originate from type reference directive
return undefined;
}
}
}
return typeReferenceDirectives;

View File

@ -424,11 +424,16 @@ namespace ts {
export function some<T>(array: T[], predicate?: (value: T) => boolean): boolean {
if (array) {
for (const v of array) {
if (!predicate || predicate(v)) {
return true;
if (predicate) {
for (const v of array) {
if (predicate(v)) {
return true;
}
}
}
else {
return array.length > 0;
}
}
return false;
}
@ -456,6 +461,44 @@ namespace ts {
return result;
}
export function arrayIsEqualTo<T>(array1: ReadonlyArray<T>, array2: ReadonlyArray<T>, equaler?: (a: T, b: T) => boolean): boolean {
if (!array1 || !array2) {
return array1 === array2;
}
if (array1.length !== array2.length) {
return false;
}
for (let i = 0; i < array1.length; i++) {
const equals = equaler ? equaler(array1[i], array2[i]) : array1[i] === array2[i];
if (!equals) {
return false;
}
}
return true;
}
export function changesAffectModuleResolution(oldOptions: CompilerOptions, newOptions: CompilerOptions): boolean {
return !oldOptions ||
(oldOptions.module !== newOptions.module) ||
(oldOptions.moduleResolution !== newOptions.moduleResolution) ||
(oldOptions.noResolve !== newOptions.noResolve) ||
(oldOptions.target !== newOptions.target) ||
(oldOptions.noLib !== newOptions.noLib) ||
(oldOptions.jsx !== newOptions.jsx) ||
(oldOptions.allowJs !== newOptions.allowJs) ||
(oldOptions.rootDir !== newOptions.rootDir) ||
(oldOptions.configFilePath !== newOptions.configFilePath) ||
(oldOptions.baseUrl !== newOptions.baseUrl) ||
(oldOptions.maxNodeModuleJsDepth !== newOptions.maxNodeModuleJsDepth) ||
!arrayIsEqualTo(oldOptions.lib, newOptions.lib) ||
!arrayIsEqualTo(oldOptions.typeRoots, newOptions.typeRoots) ||
!arrayIsEqualTo(oldOptions.rootDirs, newOptions.rootDirs) ||
!equalOwnProperties(oldOptions.paths, newOptions.paths);
}
/**
* Compacts an array, removing any falsey elements.
*/
@ -485,14 +528,35 @@ namespace ts {
return result;
}
export function addRange<T>(to: T[], from: T[]): void {
if (to && from) {
for (const v of from) {
if (v !== undefined) {
to.push(v);
}
}
/**
* Appends a value to an array, returning the array.
*
* @param to The array to which `value` is to be appended. If `to` is `undefined`, a new array
* is created if `value` was appended.
* @param value The value to append to the array. If `value` is `undefined`, nothing is
* appended.
*/
export function append<T>(to: T[] | undefined, value: T | undefined): T[] | undefined {
if (value === undefined) return to;
if (to === undefined) to = [];
to.push(value);
return to;
}
/**
* Appends a range of value to an array, returning the array.
*
* @param to The array to which `value` is to be appended. If `to` is `undefined`, a new array
* is created if `value` was appended.
* @param from The values to append to the array. If `from` is `undefined`, nothing is
* appended. If an element of `from` is `undefined`, that element is not appended.
*/
export function addRange<T>(to: T[] | undefined, from: T[] | undefined): T[] | undefined {
if (from === undefined) return to;
for (const v of from) {
to = append(to, v);
}
return to;
}
export function rangeEquals<T>(array1: T[], array2: T[], pos: number, end: number) {
@ -505,33 +569,43 @@ namespace ts {
return true;
}
/**
* Returns the first element of an array if non-empty, `undefined` otherwise.
*/
export function firstOrUndefined<T>(array: T[]): T {
return array && array.length > 0
? array[0]
: undefined;
}
/**
* Returns the last element of an array if non-empty, `undefined` otherwise.
*/
export function lastOrUndefined<T>(array: T[]): T {
return array && array.length > 0
? array[array.length - 1]
: undefined;
}
/**
* Returns the only element of an array if it contains only one element, `undefined` otherwise.
*/
export function singleOrUndefined<T>(array: T[]): T {
return array && array.length === 1
? array[0]
: undefined;
}
/**
* Returns the only element of an array if it contains only one element; otheriwse, returns the
* array.
*/
export function singleOrMany<T>(array: T[]): T | T[] {
return array && array.length === 1
? array[0]
: array;
}
/**
* Returns the last element of an array if non-empty, undefined otherwise.
*/
export function lastOrUndefined<T>(array: T[]): T {
return array && array.length > 0
? array[array.length - 1]
: undefined;
}
export function replaceElement<T>(array: T[], index: number, value: T): T[] {
const result = array.slice(0);
result[index] = value;
@ -821,7 +895,7 @@ namespace ts {
return result;
}
export function extend<T1, T2>(first: T1 , second: T2): T1 & T2 {
export function extend<T1, T2>(first: T1, second: T2): T1 & T2 {
const result: T1 & T2 = <any>{};
for (const id in second) if (hasOwnProperty.call(second, id)) {
(result as any)[id] = (second as any)[id];
@ -836,7 +910,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, value: V): V[] {
export function multiMapAdd<V>(map: Map<V[]>, key: string | number, value: V): V[] {
const values = map[key];
if (values) {
values.push(value);
@ -974,8 +1048,8 @@ namespace ts {
Debug.assert(length >= 0, "length must be non-negative, is " + length);
if (file) {
Debug.assert(start <= file.text.length, `start must be within the bounds of the file. ${ start } > ${ file.text.length }`);
Debug.assert(end <= file.text.length, `end must be the bounds of the file. ${ end } > ${ file.text.length }`);
Debug.assert(start <= file.text.length, `start must be within the bounds of the file. ${start} > ${file.text.length}`);
Debug.assert(end <= file.text.length, `end must be the bounds of the file. ${end} > ${file.text.length}`);
}
let text = getLocaleSpecificMessage(message);
@ -1525,7 +1599,7 @@ namespace ts {
return undefined;
}
const replaceWildcardCharacter = usage === "files" ? replaceWildCardCharacterFiles : replaceWildCardCharacterOther;
const replaceWildcardCharacter = usage === "files" ? replaceWildCardCharacterFiles : replaceWildCardCharacterOther;
const singleAsteriskRegexFragment = usage === "files" ? singleAsteriskRegexFragmentFiles : singleAsteriskRegexFragmentOther;
/**
@ -1767,7 +1841,7 @@ namespace ts {
/** Must have ".d.ts" first because if ".ts" goes first, that will be detected as the extension instead of ".d.ts". */
export const supportedTypescriptExtensionsForExtractExtension = [".d.ts", ".ts", ".tsx"];
export const supportedJavascriptExtensions = [".js", ".jsx"];
const allSupportedExtensions = supportedTypeScriptExtensions.concat(supportedJavascriptExtensions);
const allSupportedExtensions = supportedTypeScriptExtensions.concat(supportedJavascriptExtensions);
export function getSupportedExtensions(options?: CompilerOptions): string[] {
return options && options.allowJs ? allSupportedExtensions : supportedTypeScriptExtensions;
@ -1864,10 +1938,6 @@ namespace ts {
return path.substring(0, path.length - extension.length);
}
export function isJsxOrTsxExtension(ext: string): boolean {
return ext === ".jsx" || ext === ".tsx";
}
export function changeExtension<T extends string | Path>(path: T, newExtension: string): T {
return <T>(removeFileExtension(path) + newExtension);
}
@ -2060,4 +2130,33 @@ namespace ts {
// pos === undefined || pos === null || isNaN(pos) || pos < 0;
return !(pos >= 0);
}
/** True if an extension is one of the supported TypeScript extensions. */
export function extensionIsTypeScript(ext: Extension): boolean {
return ext <= Extension.LastTypeScriptExtension;
}
/**
* Gets the extension from a path.
* Path must have a valid extension.
*/
export function extensionFromPath(path: string): Extension {
if (fileExtensionIs(path, ".d.ts")) {
return Extension.Dts;
}
if (fileExtensionIs(path, ".ts")) {
return Extension.Ts;
}
if (fileExtensionIs(path, ".tsx")) {
return Extension.Tsx;
}
if (fileExtensionIs(path, ".js")) {
return Extension.Js;
}
if (fileExtensionIs(path, ".jsx")) {
return Extension.Jsx;
}
Debug.fail(`File ${path} has unknown extension.`);
return Extension.Js;
}
}

View File

@ -2701,7 +2701,7 @@
"category": "Message",
"code": 6099
},
"'package.json' does not have 'types' field.": {
"'package.json' does not have a 'types' or 'main' field.": {
"category": "Message",
"code": 6100
},
@ -2849,7 +2849,7 @@
"category": "Message",
"code": 6136
},
"No types specified in 'package.json' but 'allowJs' is set, so returning 'main' value of '{0}'": {
"No types specified in 'package.json', so returning 'main' value of '{0}'": {
"category": "Message",
"code": 6137
},
@ -2869,6 +2869,14 @@
"category": "Message",
"code": 6141
},
"Module '{0}' was resolved to '{1}', but '--jsx' is not set.": {
"category": "Error",
"code": 6142
},
"Module '{0}' was resolved to '{1}', but '--allowJs' is not set.": {
"category": "Error",
"code": 6143
},
"Variable '{0}' implicitly has an '{1}' type.": {
"category": "Error",
"code": 7005

View File

@ -109,12 +109,12 @@ namespace ts {
export function createLiteral(value: string | number | boolean, location?: TextRange): PrimaryExpression;
export function createLiteral(value: string | number | boolean | StringLiteral | Identifier, location?: TextRange): PrimaryExpression {
if (typeof value === "number") {
const node = <LiteralExpression>createNode(SyntaxKind.NumericLiteral, location, /*flags*/ undefined);
const node = <NumericLiteral>createNode(SyntaxKind.NumericLiteral, location, /*flags*/ undefined);
node.text = value.toString();
return node;
}
else if (typeof value === "boolean") {
return <PrimaryExpression>createNode(value ? SyntaxKind.TrueKeyword : SyntaxKind.FalseKeyword, location, /*flags*/ undefined);
return <BooleanLiteral>createNode(value ? SyntaxKind.TrueKeyword : SyntaxKind.FalseKeyword, location, /*flags*/ undefined);
}
else if (typeof value === "string") {
const node = <StringLiteral>createNode(SyntaxKind.StringLiteral, location, /*flags*/ undefined);
@ -226,20 +226,7 @@ namespace ts {
// Signature elements
export function createParameter(name: string | Identifier | BindingPattern, initializer?: Expression, location?: TextRange) {
return createParameterDeclaration(
/*decorators*/ undefined,
/*modifiers*/ undefined,
/*dotDotDotToken*/ undefined,
name,
/*questionToken*/ undefined,
/*type*/ undefined,
initializer,
location
);
}
export function createParameterDeclaration(decorators: Decorator[], modifiers: Modifier[], dotDotDotToken: DotDotDotToken, name: string | Identifier | BindingPattern, questionToken: QuestionToken, type: TypeNode, initializer: Expression, location?: TextRange, flags?: NodeFlags) {
export function createParameter(decorators: Decorator[], modifiers: Modifier[], dotDotDotToken: DotDotDotToken, name: string | Identifier | BindingPattern, questionToken?: QuestionToken, type?: TypeNode, initializer?: Expression, location?: TextRange, flags?: NodeFlags) {
const node = <ParameterDeclaration>createNode(SyntaxKind.Parameter, location, flags);
node.decorators = decorators ? createNodeArray(decorators) : undefined;
node.modifiers = modifiers ? createNodeArray(modifiers) : undefined;
@ -251,9 +238,9 @@ namespace ts {
return node;
}
export function updateParameterDeclaration(node: ParameterDeclaration, decorators: Decorator[], modifiers: Modifier[], name: BindingName, type: TypeNode, initializer: Expression) {
export function updateParameter(node: ParameterDeclaration, decorators: Decorator[], modifiers: Modifier[], name: BindingName, type: TypeNode, initializer: Expression) {
if (node.decorators !== decorators || node.modifiers !== modifiers || node.name !== name || node.type !== type || node.initializer !== initializer) {
return updateNode(createParameterDeclaration(decorators, modifiers, node.dotDotDotToken, name, node.questionToken, type, initializer, /*location*/ node, /*flags*/ node.flags), node);
return updateNode(createParameter(decorators, modifiers, node.dotDotDotToken, name, node.questionToken, type, initializer, /*location*/ node, /*flags*/ node.flags), node);
}
return node;
@ -1474,6 +1461,28 @@ namespace ts {
return node;
}
/**
* Creates a synthetic element to act as a placeholder for the end of an emitted declaration in
* order to properly emit exports.
*/
export function createEndOfDeclarationMarker(original: Node) {
const node = <EndOfDeclarationMarker>createNode(SyntaxKind.EndOfDeclarationMarker);
node.emitNode = {};
node.original = original;
return node;
}
/**
* Creates a synthetic element to act as a placeholder for the beginning of a merged declaration in
* order to properly emit exports.
*/
export function createMergeDeclarationMarker(original: Node) {
const node = <MergeDeclarationMarker>createNode(SyntaxKind.MergeDeclarationMarker);
node.emitNode = {};
node.original = original;
return node;
}
/**
* Creates a synthetic expression to act as a placeholder for a not-emitted expression in
* order to preserve comments or sourcemap positions.
@ -1557,18 +1566,6 @@ namespace ts {
}
}
export function createRestParameter(name: string | Identifier) {
return createParameterDeclaration(
/*decorators*/ undefined,
/*modifiers*/ undefined,
createToken(SyntaxKind.DotDotDotToken),
name,
/*questionToken*/ undefined,
/*type*/ undefined,
/*initializer*/ undefined
);
}
export function createFunctionCall(func: Expression, thisArg: Expression, argumentsList: Expression[], location?: TextRange) {
return createCall(
createPropertyAccess(func, "call"),
@ -1664,6 +1661,18 @@ namespace ts {
);
}
export function createExportDefault(expression: Expression) {
return createExportAssignment(/*decorators*/ undefined, /*modifiers*/ undefined, /*isExportEquals*/ false, expression);
}
export function createExternalModuleExport(exportName: Identifier) {
return createExportDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, createNamedExports([createExportSpecifier(exportName)]));
}
export function createLetStatement(name: Identifier, initializer: Expression, location?: TextRange) {
return createVariableStatement(/*modifiers*/ undefined, createLetDeclarationList([createVariableDeclaration(name, /*type*/ undefined, initializer)]), location);
}
export function createLetDeclarationList(declarations: VariableDeclaration[], location?: TextRange) {
return createVariableDeclarationList(declarations, location, NodeFlags.Let);
}
@ -1783,13 +1792,10 @@ namespace ts {
return createArrowFunction(
/*modifiers*/ undefined,
/*typeParameters*/ undefined,
[createParameter("name")],
[createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, "name")],
/*type*/ undefined,
/*equalsGreaterThanToken*/ undefined,
createElementAccess(
target,
createIdentifier("name")
)
createToken(SyntaxKind.EqualsGreaterThanToken),
createElementAccess(target, createIdentifier("name"))
);
}
@ -1799,11 +1805,11 @@ namespace ts {
/*modifiers*/ undefined,
/*typeParameters*/ undefined,
[
createParameter("name"),
createParameter("value")
createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, "name"),
createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, "value")
],
/*type*/ undefined,
/*equalsGreaterThanToken*/ undefined,
createToken(SyntaxKind.EqualsGreaterThanToken),
createAssignment(
createElementAccess(
target,
@ -1855,7 +1861,7 @@ namespace ts {
/*decorators*/ undefined,
/*modifiers*/ undefined,
"value",
[createParameter("v")],
[createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, "v")],
createBlock([
createStatement(
createCall(
@ -1875,9 +1881,9 @@ namespace ts {
createArrowFunction(
/*modifiers*/ undefined,
/*typeParameters*/ undefined,
[createParameter("name")],
[createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, "name")],
/*type*/ undefined,
/*equalsGreaterThanToken*/ undefined,
createToken(SyntaxKind.EqualsGreaterThanToken),
createLogicalOr(
createElementAccess(
createIdentifier("cache"),
@ -1917,8 +1923,8 @@ namespace ts {
/*name*/ undefined,
/*typeParameters*/ undefined,
[
createParameter("geti"),
createParameter("seti")
createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, "geti"),
createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, "seti")
],
/*type*/ undefined,
createBlock([
@ -2195,6 +2201,107 @@ namespace ts {
);
}
/**
* Gets the local name of a declaration. This is primarily used for declarations that can be
* referred to by name in the declaration's immediate scope (classes, enums, namespaces). A
* local name will *never* be prefixed with an module or namespace export modifier like
* "exports." when emitted as an expression.
*
* @param node The declaration.
* @param allowComments A value indicating whether comments may be emitted for the name.
* @param allowSourceMaps A value indicating whether source maps may be emitted for the name.
*/
export function getLocalName(node: Declaration, allowComments?: boolean, allowSourceMaps?: boolean) {
return getName(node, allowComments, allowSourceMaps, EmitFlags.LocalName);
}
/**
* Gets whether an identifier should only be referred to by its local name.
*/
export function isLocalName(node: Identifier) {
return (getEmitFlags(node) & EmitFlags.LocalName) !== 0;
}
/**
* Gets the export name of a declaration. This is primarily used for declarations that can be
* referred to by name in the declaration's immediate scope (classes, enums, namespaces). An
* export name will *always* be prefixed with an module or namespace export modifier like
* `"exports."` when emitted as an expression if the name points to an exported symbol.
*
* @param node The declaration.
* @param allowComments A value indicating whether comments may be emitted for the name.
* @param allowSourceMaps A value indicating whether source maps may be emitted for the name.
*/
export function getExportName(node: Declaration, allowComments?: boolean, allowSourceMaps?: boolean): Identifier {
return getName(node, allowComments, allowSourceMaps, EmitFlags.ExportName);
}
/**
* Gets whether an identifier should only be referred to by its export representation if the
* name points to an exported symbol.
*/
export function isExportName(node: Identifier) {
return (getEmitFlags(node) & EmitFlags.ExportName) !== 0;
}
/**
* Gets the name of a declaration for use in declarations.
*
* @param node The declaration.
* @param allowComments A value indicating whether comments may be emitted for the name.
* @param allowSourceMaps A value indicating whether source maps may be emitted for the name.
*/
export function getDeclarationName(node: Declaration, allowComments?: boolean, allowSourceMaps?: boolean) {
return getName(node, allowComments, allowSourceMaps);
}
function getName(node: Declaration, allowComments?: boolean, allowSourceMaps?: boolean, emitFlags?: EmitFlags) {
if (node.name && isIdentifier(node.name) && !isGeneratedIdentifier(node.name)) {
const name = getMutableClone(node.name);
emitFlags |= getEmitFlags(node.name);
if (!allowSourceMaps) emitFlags |= EmitFlags.NoSourceMap;
if (!allowComments) emitFlags |= EmitFlags.NoComments;
if (emitFlags) setEmitFlags(name, emitFlags);
return name;
}
return getGeneratedNameForNode(node);
}
/**
* Gets the exported name of a declaration for use in expressions.
*
* An exported name will *always* be prefixed with an module or namespace export modifier like
* "exports." if the name points to an exported symbol.
*
* @param ns The namespace identifier.
* @param node The declaration.
* @param allowComments A value indicating whether comments may be emitted for the name.
* @param allowSourceMaps A value indicating whether source maps may be emitted for the name.
*/
export function getExternalModuleOrNamespaceExportName(ns: Identifier | undefined, node: Declaration, allowComments?: boolean, allowSourceMaps?: boolean): Identifier | PropertyAccessExpression {
if (ns && hasModifier(node, ModifierFlags.Export)) {
return getNamespaceMemberName(ns, getName(node), allowComments, allowSourceMaps);
}
return getExportName(node, allowComments, allowSourceMaps);
}
/**
* Gets a namespace-qualified name for use in expressions.
*
* @param ns The namespace identifier.
* @param name The name.
* @param allowComments A value indicating whether comments may be emitted for the name.
* @param allowSourceMaps A value indicating whether source maps may be emitted for the name.
*/
export function getNamespaceMemberName(ns: Identifier, name: Identifier, allowComments?: boolean, allowSourceMaps?: boolean): PropertyAccessExpression {
const qualifiedName = createPropertyAccess(ns, nodeIsSynthesized(name) ? name : getSynthesizedClone(name), /*location*/ name);
let emitFlags: EmitFlags;
if (!allowSourceMaps) emitFlags |= EmitFlags.NoSourceMap;
if (!allowComments) emitFlags |= EmitFlags.NoComments;
if (emitFlags) setEmitFlags(qualifiedName, emitFlags);
return qualifiedName;
}
// Utilities
function isUseStrictPrologue(node: ExpressionStatement): boolean {
@ -2248,7 +2355,7 @@ namespace ts {
/**
* Ensures "use strict" directive is added
*
*
* @param node source file
*/
export function ensureUseStrict(node: SourceFile): SourceFile {

View File

@ -2,39 +2,86 @@
/// <reference path="diagnosticInformationMap.generated.ts" />
namespace ts {
/* @internal */
export function trace(host: ModuleResolutionHost, message: DiagnosticMessage, ...args: any[]): void;
export function trace(host: ModuleResolutionHost): void {
function trace(host: ModuleResolutionHost, message: DiagnosticMessage, ...args: any[]): void;
function trace(host: ModuleResolutionHost): void {
host.trace(formatMessage.apply(undefined, arguments));
}
/* @internal */
export function isTraceEnabled(compilerOptions: CompilerOptions, host: ModuleResolutionHost): boolean {
function isTraceEnabled(compilerOptions: CompilerOptions, host: ModuleResolutionHost): boolean {
return compilerOptions.traceResolution && host.trace !== undefined;
}
/* @internal */
export function createResolvedModule(resolvedFileName: string, isExternalLibraryImport: boolean, failedLookupLocations: string[]): ResolvedModuleWithFailedLookupLocations {
return { resolvedModule: resolvedFileName ? { resolvedFileName, isExternalLibraryImport } : undefined, failedLookupLocations };
/**
* Result of trying to resolve a module.
* At least one of `ts` and `js` should be defined, or the whole thing should be `undefined`.
*/
interface Resolved {
path: string;
extension: Extension;
}
/**
* Kinds of file that we are currently looking for.
* Typically there is one pass with Extensions.TypeScript, then a second pass with Extensions.JavaScript.
*/
const enum Extensions {
TypeScript, /** '.ts', '.tsx', or '.d.ts' */
JavaScript, /** '.js' or '.jsx' */
DtsOnly /** Only '.d.ts' */
}
/** Used with `Extensions.DtsOnly` to extract the path from TypeScript results. */
function resolvedTypeScriptOnly(resolved: Resolved | undefined): string | undefined {
if (!resolved) {
return undefined;
}
Debug.assert(extensionIsTypeScript(resolved.extension));
return resolved.path;
}
/** Create Resolved from a file with unknown extension. */
function resolvedFromAnyFile(path: string): Resolved | undefined {
return { path, extension: extensionFromPath(path) };
}
/** Adds `isExernalLibraryImport` to a Resolved to get a ResolvedModule. */
function resolvedModuleFromResolved({ path, extension }: Resolved, isExternalLibraryImport: boolean): ResolvedModule {
return { resolvedFileName: path, extension, isExternalLibraryImport };
}
function createResolvedModuleWithFailedLookupLocations(resolved: Resolved | undefined, isExternalLibraryImport: boolean, failedLookupLocations: string[]): ResolvedModuleWithFailedLookupLocations {
return { resolvedModule: resolved && resolvedModuleFromResolved(resolved, isExternalLibraryImport), failedLookupLocations };
}
function moduleHasNonRelativeName(moduleName: string): boolean {
return !(isRootedDiskPath(moduleName) || isExternalModuleNameRelative(moduleName));
}
/* @internal */
export interface ModuleResolutionState {
interface ModuleResolutionState {
host: ModuleResolutionHost;
compilerOptions: CompilerOptions;
// We only use this subset of the compiler options.
compilerOptions: { rootDirs?: string[], baseUrl?: string, paths?: MapLike<string[]> };
traceEnabled: boolean;
// skip .tsx files if jsx is not enabled
skipTsx: boolean;
}
function tryReadTypesSection(packageJsonPath: string, baseDirectory: string, state: ModuleResolutionState): string {
function tryReadTypesSection(extensions: Extensions, packageJsonPath: string, baseDirectory: string, state: ModuleResolutionState): string {
const jsonContent = readJson(packageJsonPath, state.host);
switch (extensions) {
case Extensions.DtsOnly:
case Extensions.TypeScript:
return tryReadFromField("typings") || tryReadFromField("types");
case Extensions.JavaScript:
if (typeof jsonContent.main === "string") {
if (state.traceEnabled) {
trace(state.host, Diagnostics.No_types_specified_in_package_json_so_returning_main_value_of_0, jsonContent.main);
}
return normalizePath(combinePaths(baseDirectory, jsonContent.main));
}
return undefined;
}
function tryReadFromField(fieldName: string) {
if (hasProperty(jsonContent, fieldName)) {
const typesFile = (<any>jsonContent)[fieldName];
@ -52,21 +99,6 @@ namespace ts {
}
}
}
const typesFilePath = tryReadFromField("typings") || tryReadFromField("types");
if (typesFilePath) {
return typesFilePath;
}
// Use the main module for inferring types if no types package specified and the allowJs is set
if (state.compilerOptions.allowJs && jsonContent.main && typeof jsonContent.main === "string") {
if (state.traceEnabled) {
trace(state.host, Diagnostics.No_types_specified_in_package_json_but_allowJs_is_set_so_returning_main_value_of_0, jsonContent.main);
}
const mainFilePath = normalizePath(combinePaths(baseDirectory, jsonContent.main));
return mainFilePath;
}
return undefined;
}
function readJson(path: string, host: ModuleResolutionHost): { typings?: string, types?: string, main?: string } {
@ -80,8 +112,6 @@ namespace ts {
}
}
const typeReferenceExtensions = [".d.ts"];
export function getEffectiveTypeRoots(options: CompilerOptions, host: { directoryExists?: (directoryName: string) => boolean, getCurrentDirectory?: () => string }): string[] | undefined {
if (options.typeRoots) {
return options.typeRoots;
@ -132,12 +162,11 @@ namespace ts {
* This is possible in case if resolution is performed for directives specified via 'types' parameter. In this case initial path for secondary lookups
* is assumed to be the same as root directory of the project.
*/
export function resolveTypeReferenceDirective(typeReferenceDirectiveName: string, containingFile: string, options: CompilerOptions, host: ModuleResolutionHost): ResolvedTypeReferenceDirectiveWithFailedLookupLocations {
export function resolveTypeReferenceDirective(typeReferenceDirectiveName: string, containingFile: string | undefined, options: CompilerOptions, host: ModuleResolutionHost): ResolvedTypeReferenceDirectiveWithFailedLookupLocations {
const traceEnabled = isTraceEnabled(options, host);
const moduleResolutionState: ModuleResolutionState = {
compilerOptions: options,
host: host,
skipTsx: true,
traceEnabled
};
@ -168,19 +197,20 @@ namespace ts {
if (traceEnabled) {
trace(host, Diagnostics.Resolving_with_primary_search_path_0, typeRoots.join(", "));
}
const primarySearchPaths = typeRoots;
for (const typeRoot of primarySearchPaths) {
for (const typeRoot of typeRoots) {
const candidate = combinePaths(typeRoot, typeReferenceDirectiveName);
const candidateDirectory = getDirectoryPath(candidate);
const resolvedFile = loadNodeModuleFromDirectory(typeReferenceExtensions, candidate, failedLookupLocations,
!directoryProbablyExists(candidateDirectory, host), moduleResolutionState);
if (resolvedFile) {
const resolved = resolvedTypeScriptOnly(
loadNodeModuleFromDirectory(Extensions.DtsOnly, candidate, failedLookupLocations,
!directoryProbablyExists(candidateDirectory, host), moduleResolutionState));
if (resolved) {
if (traceEnabled) {
trace(host, Diagnostics.Type_reference_directive_0_was_successfully_resolved_to_1_primary_Colon_2, typeReferenceDirectiveName, resolvedFile, true);
trace(host, Diagnostics.Type_reference_directive_0_was_successfully_resolved_to_1_primary_Colon_2, typeReferenceDirectiveName, resolved, true);
}
return {
resolvedTypeReferenceDirective: { primary: true, resolvedFileName: resolvedFile },
resolvedTypeReferenceDirective: { primary: true, resolvedFileName: resolved },
failedLookupLocations
};
}
@ -193,17 +223,14 @@ namespace ts {
}
let resolvedFile: string;
let initialLocationForSecondaryLookup: string;
if (containingFile) {
initialLocationForSecondaryLookup = getDirectoryPath(containingFile);
}
const initialLocationForSecondaryLookup = containingFile && getDirectoryPath(containingFile);
if (initialLocationForSecondaryLookup !== undefined) {
// check secondary locations
if (traceEnabled) {
trace(host, Diagnostics.Looking_up_in_node_modules_folder_initial_location_0, initialLocationForSecondaryLookup);
}
resolvedFile = loadModuleFromNodeModules(typeReferenceDirectiveName, initialLocationForSecondaryLookup, failedLookupLocations, moduleResolutionState, /*checkOneLevel*/ false);
resolvedFile = resolvedTypeScriptOnly(loadModuleFromNodeModules(Extensions.DtsOnly, typeReferenceDirectiveName, initialLocationForSecondaryLookup, failedLookupLocations, moduleResolutionState, /*checkOneLevel*/ false));
if (traceEnabled) {
if (resolvedFile) {
trace(host, Diagnostics.Type_reference_directive_0_was_successfully_resolved_to_1_primary_Colon_2, typeReferenceDirectiveName, resolvedFile, false);
@ -219,9 +246,7 @@ namespace ts {
}
}
return {
resolvedTypeReferenceDirective: resolvedFile
? { primary: false, resolvedFileName: resolvedFile }
: undefined,
resolvedTypeReferenceDirective: resolvedFile ? { primary: false, resolvedFileName: resolvedFile } : undefined,
failedLookupLocations
};
}
@ -313,7 +338,7 @@ namespace ts {
* 'typings' entry or file 'index' with some supported extension
* - Classic loader will only try to interpret '/a/b/c' as file.
*/
type ResolutionKindSpecificLoader = (candidate: string, extensions: string[], failedLookupLocations: string[], onlyRecordFailures: boolean, state: ModuleResolutionState) => string;
type ResolutionKindSpecificLoader = (extensions: Extensions, candidate: string, failedLookupLocations: string[], onlyRecordFailures: boolean, state: ModuleResolutionState) => Resolved | undefined;
/**
* Any module resolution kind can be augmented with optional settings: 'baseUrl', 'paths' and 'rootDirs' - they are used to
@ -375,19 +400,19 @@ namespace ts {
* be converted to a path relative to found rootDir entry './content/protocols/file2' (*). As a last step compiler will check all remaining
* entries in 'rootDirs', use them to build absolute path out of (*) and try to resolve module from this location.
*/
function tryLoadModuleUsingOptionalResolutionSettings(moduleName: string, containingDirectory: string, loader: ResolutionKindSpecificLoader,
failedLookupLocations: string[], supportedExtensions: string[], state: ModuleResolutionState): string {
function tryLoadModuleUsingOptionalResolutionSettings(extensions: Extensions, moduleName: string, containingDirectory: string, loader: ResolutionKindSpecificLoader,
failedLookupLocations: string[], state: ModuleResolutionState): Resolved | undefined {
if (moduleHasNonRelativeName(moduleName)) {
return tryLoadModuleUsingBaseUrl(moduleName, loader, failedLookupLocations, supportedExtensions, state);
return tryLoadModuleUsingBaseUrl(extensions, moduleName, loader, failedLookupLocations, state);
}
else {
return tryLoadModuleUsingRootDirs(moduleName, containingDirectory, loader, failedLookupLocations, supportedExtensions, state);
return tryLoadModuleUsingRootDirs(extensions, moduleName, containingDirectory, loader, failedLookupLocations, state);
}
}
function tryLoadModuleUsingRootDirs(moduleName: string, containingDirectory: string, loader: ResolutionKindSpecificLoader,
failedLookupLocations: string[], supportedExtensions: string[], state: ModuleResolutionState): string {
function tryLoadModuleUsingRootDirs(extensions: Extensions, moduleName: string, containingDirectory: string, loader: ResolutionKindSpecificLoader,
failedLookupLocations: string[], state: ModuleResolutionState): Resolved | undefined {
if (!state.compilerOptions.rootDirs) {
return undefined;
@ -432,7 +457,7 @@ namespace ts {
if (state.traceEnabled) {
trace(state.host, Diagnostics.Loading_0_from_the_root_dir_1_candidate_location_2, suffix, matchedNormalizedPrefix, candidate);
}
const resolvedFileName = loader(candidate, supportedExtensions, failedLookupLocations, !directoryProbablyExists(containingDirectory, state.host), state);
const resolvedFileName = loader(extensions, candidate, failedLookupLocations, !directoryProbablyExists(containingDirectory, state.host), state);
if (resolvedFileName) {
return resolvedFileName;
}
@ -451,7 +476,7 @@ namespace ts {
trace(state.host, Diagnostics.Loading_0_from_the_root_dir_1_candidate_location_2, suffix, rootDir, candidate);
}
const baseDirectory = getDirectoryPath(candidate);
const resolvedFileName = loader(candidate, supportedExtensions, failedLookupLocations, !directoryProbablyExists(baseDirectory, state.host), state);
const resolvedFileName = loader(extensions, candidate, failedLookupLocations, !directoryProbablyExists(baseDirectory, state.host), state);
if (resolvedFileName) {
return resolvedFileName;
}
@ -463,9 +488,7 @@ namespace ts {
return undefined;
}
function tryLoadModuleUsingBaseUrl(moduleName: string, loader: ResolutionKindSpecificLoader, failedLookupLocations: string[],
supportedExtensions: string[], state: ModuleResolutionState): string {
function tryLoadModuleUsingBaseUrl(extensions: Extensions, moduleName: string, loader: ResolutionKindSpecificLoader, failedLookupLocations: string[], state: ModuleResolutionState): Resolved | undefined {
if (!state.compilerOptions.baseUrl) {
return undefined;
}
@ -494,9 +517,9 @@ namespace ts {
if (state.traceEnabled) {
trace(state.host, Diagnostics.Trying_substitution_0_candidate_module_location_Colon_1, subst, path);
}
const resolvedFileName = loader(candidate, supportedExtensions, failedLookupLocations, !directoryProbablyExists(getDirectoryPath(candidate), state.host), state);
if (resolvedFileName) {
return resolvedFileName;
const resolved = loader(extensions, candidate, failedLookupLocations, !directoryProbablyExists(getDirectoryPath(candidate), state.host), state);
if (resolved) {
return resolved;
}
}
return undefined;
@ -508,56 +531,64 @@ namespace ts {
trace(state.host, Diagnostics.Resolving_module_name_0_relative_to_base_url_1_2, moduleName, state.compilerOptions.baseUrl, candidate);
}
return loader(candidate, supportedExtensions, failedLookupLocations, !directoryProbablyExists(getDirectoryPath(candidate), state.host), state);
return loader(extensions, candidate, failedLookupLocations, !directoryProbablyExists(getDirectoryPath(candidate), state.host), state);
}
}
export function nodeModuleNameResolver(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost): ResolvedModuleWithFailedLookupLocations {
const containingDirectory = getDirectoryPath(containingFile);
const supportedExtensions = getSupportedExtensions(compilerOptions);
const traceEnabled = isTraceEnabled(compilerOptions, host);
const failedLookupLocations: string[] = [];
const state = { compilerOptions, host, traceEnabled, skipTsx: false };
let resolvedFileName = tryLoadModuleUsingOptionalResolutionSettings(moduleName, containingDirectory, nodeLoadModuleByRelativeName,
failedLookupLocations, supportedExtensions, state);
const state: ModuleResolutionState = { compilerOptions, host, traceEnabled };
const result = tryResolve(Extensions.TypeScript) || tryResolve(Extensions.JavaScript);
if (result) {
const { resolved, isExternalLibraryImport } = result;
return createResolvedModuleWithFailedLookupLocations(resolved && resolvedWithRealpath(resolved, host, traceEnabled), isExternalLibraryImport, failedLookupLocations);
}
return { resolvedModule: undefined, failedLookupLocations };
function tryResolve(extensions: Extensions): { resolved: Resolved, isExternalLibraryImport: boolean } | undefined {
const resolved = tryLoadModuleUsingOptionalResolutionSettings(extensions, moduleName, containingDirectory, nodeLoadModuleByRelativeName, failedLookupLocations, state);
if (resolved) {
return { resolved, isExternalLibraryImport: false };
}
let isExternalLibraryImport = false;
if (!resolvedFileName) {
if (moduleHasNonRelativeName(moduleName)) {
if (traceEnabled) {
trace(host, Diagnostics.Loading_module_0_from_node_modules_folder, moduleName);
}
resolvedFileName = loadModuleFromNodeModules(moduleName, containingDirectory, failedLookupLocations, state, /*checkOneLevel*/ false);
isExternalLibraryImport = resolvedFileName !== undefined;
const resolved = loadModuleFromNodeModules(extensions, moduleName, containingDirectory, failedLookupLocations, state, /*checkOneLevel*/ false);
return resolved && { resolved, isExternalLibraryImport: true };
}
else {
const candidate = normalizePath(combinePaths(containingDirectory, moduleName));
resolvedFileName = nodeLoadModuleByRelativeName(candidate, supportedExtensions, failedLookupLocations, /*onlyRecordFailures*/ false, state);
const resolved = nodeLoadModuleByRelativeName(extensions, candidate, failedLookupLocations, /*onlyRecordFailures*/ false, state);
return resolved && { resolved, isExternalLibraryImport: false };
}
}
if (resolvedFileName && host.realpath) {
const originalFileName = resolvedFileName;
resolvedFileName = normalizePath(host.realpath(resolvedFileName));
if (traceEnabled) {
trace(host, Diagnostics.Resolving_real_path_for_0_result_1, originalFileName, resolvedFileName);
}
}
return createResolvedModule(resolvedFileName, isExternalLibraryImport, failedLookupLocations);
}
function nodeLoadModuleByRelativeName(candidate: string, supportedExtensions: string[], failedLookupLocations: string[],
onlyRecordFailures: boolean, state: ModuleResolutionState): string {
function resolvedWithRealpath(resolved: Resolved, host: ModuleResolutionHost, traceEnabled: boolean): Resolved {
if (!host.realpath) {
return resolved;
}
const real = normalizePath(host.realpath(resolved.path));
if (traceEnabled) {
trace(host, Diagnostics.Resolving_real_path_for_0_result_1, resolved.path, real);
}
return { path: real, extension: resolved.extension };
}
function nodeLoadModuleByRelativeName(extensions: Extensions, candidate: string, failedLookupLocations: string[], onlyRecordFailures: boolean, state: ModuleResolutionState): Resolved | undefined {
if (state.traceEnabled) {
trace(state.host, Diagnostics.Loading_module_as_file_Slash_folder_candidate_module_location_0, candidate);
}
const resolvedFileName = !pathEndsWithDirectorySeparator(candidate) && loadModuleFromFile(candidate, supportedExtensions, failedLookupLocations, onlyRecordFailures, state);
return resolvedFileName || loadNodeModuleFromDirectory(supportedExtensions, candidate, failedLookupLocations, onlyRecordFailures, state);
const resolvedFromFile = !pathEndsWithDirectorySeparator(candidate) && loadModuleFromFile(extensions, candidate, failedLookupLocations, onlyRecordFailures, state);
return resolvedFromFile || loadNodeModuleFromDirectory(extensions, candidate, failedLookupLocations, onlyRecordFailures, state);
}
/* @internal */
@ -570,9 +601,9 @@ namespace ts {
* @param {boolean} onlyRecordFailures - if true then function won't try to actually load files but instead record all attempts as failures. This flag is necessary
* in cases when we know upfront that all load attempts will fail (because containing folder does not exists) however we still need to record all failed lookup locations.
*/
function loadModuleFromFile(candidate: string, extensions: string[], failedLookupLocation: string[], onlyRecordFailures: boolean, state: ModuleResolutionState): string | undefined {
function loadModuleFromFile(extensions: Extensions, candidate: string, failedLookupLocations: string[], onlyRecordFailures: boolean, state: ModuleResolutionState): Resolved | undefined {
// First, try adding an extension. An import of "foo" could be matched by a file "foo.ts", or "foo.js" by "foo.js.ts"
const resolvedByAddingExtension = tryAddingExtensions(candidate, extensions, failedLookupLocation, onlyRecordFailures, state);
const resolvedByAddingExtension = tryAddingExtensions(candidate, extensions, failedLookupLocations, onlyRecordFailures, state);
if (resolvedByAddingExtension) {
return resolvedByAddingExtension;
}
@ -585,12 +616,12 @@ namespace ts {
const extension = candidate.substring(extensionless.length);
trace(state.host, Diagnostics.File_name_0_has_a_1_extension_stripping_it, candidate, extension);
}
return tryAddingExtensions(extensionless, extensions, failedLookupLocation, onlyRecordFailures, state);
return tryAddingExtensions(extensionless, extensions, failedLookupLocations, onlyRecordFailures, state);
}
}
/** Try to return an existing file that adds one of the `extensions` to `candidate`. */
function tryAddingExtensions(candidate: string, extensions: string[], failedLookupLocation: string[], onlyRecordFailures: boolean, state: ModuleResolutionState): string | undefined {
function tryAddingExtensions(candidate: string, extensions: Extensions, failedLookupLocations: string[], onlyRecordFailures: boolean, state: ModuleResolutionState): Resolved | undefined {
if (!onlyRecordFailures) {
// check if containing folder exists - if it doesn't then just record failures for all supported extensions without disk probing
const directory = getDirectoryPath(candidate);
@ -598,8 +629,20 @@ namespace ts {
onlyRecordFailures = !directoryProbablyExists(directory, state.host);
}
}
return forEach(extensions, ext =>
!(state.skipTsx && isJsxOrTsxExtension(ext)) && tryFile(candidate + ext, failedLookupLocation, onlyRecordFailures, state));
switch (extensions) {
case Extensions.DtsOnly:
return tryExtension(".d.ts", Extension.Dts);
case Extensions.TypeScript:
return tryExtension(".ts", Extension.Ts) || tryExtension(".tsx", Extension.Tsx) || tryExtension(".d.ts", Extension.Dts);
case Extensions.JavaScript:
return tryExtension(".js", Extension.Js) || tryExtension(".jsx", Extension.Jsx);
}
function tryExtension(ext: string, extension: Extension): Resolved | undefined {
const path = tryFile(candidate + ext, failedLookupLocations, onlyRecordFailures, state);
return path && { path, extension };
}
}
/** Return the file if it exists. */
@ -619,26 +662,31 @@ namespace ts {
}
}
function loadNodeModuleFromDirectory(extensions: string[], candidate: string, failedLookupLocation: string[], onlyRecordFailures: boolean, state: ModuleResolutionState): string {
function loadNodeModuleFromDirectory(extensions: Extensions, candidate: string, failedLookupLocation: string[], onlyRecordFailures: boolean, state: ModuleResolutionState): Resolved | undefined {
const packageJsonPath = pathToPackageJson(candidate);
const directoryExists = !onlyRecordFailures && directoryProbablyExists(candidate, state.host);
if (directoryExists && state.host.fileExists(packageJsonPath)) {
if (state.traceEnabled) {
trace(state.host, Diagnostics.Found_package_json_at_0, packageJsonPath);
}
const typesFile = tryReadTypesSection(packageJsonPath, candidate, state);
const typesFile = tryReadTypesSection(extensions, packageJsonPath, candidate, state);
if (typesFile) {
const onlyRecordFailures = !directoryProbablyExists(getDirectoryPath(typesFile), state.host);
// A package.json "typings" may specify an exact filename, or may choose to omit an extension.
const result = tryFile(typesFile, failedLookupLocation, onlyRecordFailures, state) ||
tryAddingExtensions(typesFile, extensions, failedLookupLocation, onlyRecordFailures, state);
if (result) {
return result;
const fromFile = tryFile(typesFile, failedLookupLocation, onlyRecordFailures, state);
if (fromFile) {
// Note: this would allow a package.json to specify a ".js" file as typings. Maybe that should be forbidden.
return resolvedFromAnyFile(fromFile);
}
const x = tryAddingExtensions(typesFile, Extensions.TypeScript, failedLookupLocation, onlyRecordFailures, state);
if (x) {
return x;
}
}
else {
if (state.traceEnabled) {
trace(state.host, Diagnostics.package_json_does_not_have_types_field);
trace(state.host, Diagnostics.package_json_does_not_have_a_types_or_main_field);
}
}
}
@ -650,104 +698,90 @@ namespace ts {
failedLookupLocation.push(packageJsonPath);
}
return loadModuleFromFile(combinePaths(candidate, "index"), extensions, failedLookupLocation, !directoryExists, state);
return loadModuleFromFile(extensions, combinePaths(candidate, "index"), failedLookupLocation, !directoryExists, state);
}
function pathToPackageJson(directory: string): string {
return combinePaths(directory, "package.json");
}
function loadModuleFromNodeModulesFolder(moduleName: string, directory: string, failedLookupLocations: string[], state: ModuleResolutionState): string {
function loadModuleFromNodeModulesFolder(extensions: Extensions, moduleName: string, directory: string, failedLookupLocations: string[], state: ModuleResolutionState): Resolved | undefined {
const nodeModulesFolder = combinePaths(directory, "node_modules");
const nodeModulesFolderExists = directoryProbablyExists(nodeModulesFolder, state.host);
const candidate = normalizePath(combinePaths(nodeModulesFolder, moduleName));
const supportedExtensions = getSupportedExtensions(state.compilerOptions);
let result = loadModuleFromFile(candidate, supportedExtensions, failedLookupLocations, !nodeModulesFolderExists, state);
if (result) {
return result;
}
result = loadNodeModuleFromDirectory(supportedExtensions, candidate, failedLookupLocations, !nodeModulesFolderExists, state);
if (result) {
return result;
}
return loadModuleFromFile(extensions, candidate, failedLookupLocations, !nodeModulesFolderExists, state) ||
loadNodeModuleFromDirectory(extensions, candidate, failedLookupLocations, !nodeModulesFolderExists, state);
}
/* @internal */
export function loadModuleFromNodeModules(moduleName: string, directory: string, failedLookupLocations: string[], state: ModuleResolutionState, checkOneLevel: boolean): string {
return loadModuleFromNodeModulesWorker(moduleName, directory, failedLookupLocations, state, checkOneLevel, /*typesOnly*/ false);
function loadModuleFromNodeModules(extensions: Extensions, moduleName: string, directory: string, failedLookupLocations: string[], state: ModuleResolutionState, checkOneLevel: boolean): Resolved | undefined {
return loadModuleFromNodeModulesWorker(extensions, moduleName, directory, failedLookupLocations, state, checkOneLevel, /*typesOnly*/ false);
}
function loadModuleFromNodeModulesAtTypes(moduleName: string, directory: string, failedLookupLocations: string[], state: ModuleResolutionState): Resolved | undefined {
return loadModuleFromNodeModulesWorker(Extensions.TypeScript, moduleName, directory, failedLookupLocations, state, /*checkOneLevel*/ false, /*typesOnly*/ true);
}
function loadModuleFromNodeModulesAtTypes(moduleName: string, directory: string, failedLookupLocations: string[], state: ModuleResolutionState): string {
return loadModuleFromNodeModulesWorker(moduleName, directory, failedLookupLocations, state, /*checkOneLevel*/ false, /*typesOnly*/ true);
}
function loadModuleFromNodeModulesWorker(moduleName: string, directory: string, failedLookupLocations: string[], state: ModuleResolutionState, checkOneLevel: boolean, typesOnly: boolean): string {
function loadModuleFromNodeModulesWorker(extensions: Extensions, moduleName: string, directory: string, failedLookupLocations: string[], state: ModuleResolutionState, checkOneLevel: boolean, typesOnly: boolean): Resolved | undefined {
directory = normalizeSlashes(directory);
while (true) {
const baseName = getBaseFileName(directory);
if (baseName !== "node_modules") {
let packageResult: string | undefined;
if (!typesOnly) {
// Try to load source from the package
packageResult = loadModuleFromNodeModulesFolder(moduleName, directory, failedLookupLocations, state);
if (packageResult && hasTypeScriptFileExtension(packageResult)) {
// Always prefer a TypeScript (.ts, .tsx, .d.ts) file shipped with the package
return packageResult;
}
}
// Else prefer a types package over non-TypeScript results (e.g. JavaScript files)
const typesResult = loadModuleFromNodeModulesFolder(combinePaths("@types", moduleName), directory, failedLookupLocations, state);
if (typesResult || packageResult) {
return typesResult || packageResult;
if (getBaseFileName(directory) !== "node_modules") {
const resolved = tryInDirectory();
if (resolved) {
return resolved;
}
}
const parentPath = getDirectoryPath(directory);
if (parentPath === directory || checkOneLevel) {
break;
return undefined;
}
directory = parentPath;
}
return undefined;
function tryInDirectory(): Resolved | undefined {
const packageResult = typesOnly ? undefined : loadModuleFromNodeModulesFolder(extensions, moduleName, directory, failedLookupLocations, state);
return packageResult || loadModuleFromNodeModulesFolder(extensions, combinePaths("@types", moduleName), directory, failedLookupLocations, state);
}
}
export function classicNameResolver(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost): ResolvedModuleWithFailedLookupLocations {
const traceEnabled = isTraceEnabled(compilerOptions, host);
const state = { compilerOptions, host, traceEnabled, skipTsx: !compilerOptions.jsx };
const state: ModuleResolutionState = { compilerOptions, host, traceEnabled };
const failedLookupLocations: string[] = [];
const supportedExtensions = getSupportedExtensions(compilerOptions);
const containingDirectory = getDirectoryPath(containingFile);
const resolvedFileName = tryLoadModuleUsingOptionalResolutionSettings(moduleName, containingDirectory, loadModuleFromFile, failedLookupLocations, supportedExtensions, state);
if (resolvedFileName) {
return createResolvedModule(resolvedFileName, /*isExternalLibraryImport*/false, failedLookupLocations);
}
const resolved = tryResolve(Extensions.TypeScript) || tryResolve(Extensions.JavaScript);
return createResolvedModuleWithFailedLookupLocations(resolved, /*isExternalLibraryImport*/ false, failedLookupLocations);
let referencedSourceFile: string;
if (moduleHasNonRelativeName(moduleName)) {
referencedSourceFile = referencedSourceFile = loadModuleFromAncestorDirectories(moduleName, containingDirectory, supportedExtensions, failedLookupLocations, state) ||
// If we didn't find the file normally, look it up in @types.
loadModuleFromNodeModulesAtTypes(moduleName, containingDirectory, failedLookupLocations, state);
}
else {
const candidate = normalizePath(combinePaths(containingDirectory, moduleName));
referencedSourceFile = loadModuleFromFile(candidate, supportedExtensions, failedLookupLocations, /*onlyRecordFailures*/ false, state);
}
function tryResolve(extensions: Extensions): Resolved | undefined {
const resolvedUsingSettings = tryLoadModuleUsingOptionalResolutionSettings(extensions, moduleName, containingDirectory, loadModuleFromFile, failedLookupLocations, state);
if (resolvedUsingSettings) {
return resolvedUsingSettings;
}
return referencedSourceFile
? { resolvedModule: { resolvedFileName: referencedSourceFile }, failedLookupLocations }
: { resolvedModule: undefined, failedLookupLocations };
if (moduleHasNonRelativeName(moduleName)) {
const resolved = loadModuleFromAncestorDirectories(extensions, moduleName, containingDirectory, failedLookupLocations, state);
if (resolved) {
return resolved;
}
if (extensions === Extensions.TypeScript) {
// If we didn't find the file normally, look it up in @types.
return loadModuleFromNodeModulesAtTypes(moduleName, containingDirectory, failedLookupLocations, state);
}
}
else {
const candidate = normalizePath(combinePaths(containingDirectory, moduleName));
return loadModuleFromFile(extensions, candidate, failedLookupLocations, /*onlyRecordFailures*/ false, state);
}
}
}
/** Climb up parent directories looking for a module. */
function loadModuleFromAncestorDirectories(moduleName: string, containingDirectory: string, supportedExtensions: string[], failedLookupLocations: string[], state: ModuleResolutionState): string | undefined {
function loadModuleFromAncestorDirectories(extensions: Extensions, moduleName: string, containingDirectory: string, failedLookupLocations: string[], state: ModuleResolutionState): Resolved | undefined {
while (true) {
const searchName = normalizePath(combinePaths(containingDirectory, moduleName));
const referencedSourceFile = loadModuleFromFile(searchName, supportedExtensions, failedLookupLocations, /*onlyRecordFailures*/ false, state);
const referencedSourceFile = loadModuleFromFile(extensions, searchName, failedLookupLocations, /*onlyRecordFailures*/ false, state);
if (referencedSourceFile) {
return referencedSourceFile;
}
@ -758,4 +792,21 @@ namespace ts {
containingDirectory = parentPath;
}
}
/**
* LSHost may load a module from a global cache of typings.
* This is the minumum code needed to expose that functionality; the rest is in LSHost.
*/
/* @internal */
export function loadModuleFromGlobalCache(moduleName: string, projectName: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost, globalCache: string): ResolvedModuleWithFailedLookupLocations {
const traceEnabled = isTraceEnabled(compilerOptions, host);
if (traceEnabled) {
trace(host, Diagnostics.Auto_discovery_for_typings_is_enabled_in_project_0_Running_extra_resolution_pass_for_module_1_using_cache_location_2, projectName, moduleName, globalCache);
}
const state: ModuleResolutionState = { compilerOptions, host, traceEnabled };
const failedLookupLocations: string[] = [];
const resolved = loadModuleFromNodeModules(Extensions.TypeScript, moduleName, globalCache, failedLookupLocations, state, /*checkOneLevel*/ true) ||
loadModuleFromNodeModules(Extensions.JavaScript, moduleName, globalCache, failedLookupLocations, state, /*checkOneLevel*/ true);
return createResolvedModuleWithFailedLookupLocations(resolved, /*isExternalLibraryImport*/ true, failedLookupLocations);
}
}

View File

@ -415,6 +415,7 @@ namespace ts {
return visitNodes(cbNodes, (<JSDocTemplateTag>node).typeParameters);
case SyntaxKind.JSDocTypedefTag:
return visitNode(cbNode, (<JSDocTypedefTag>node).typeExpression) ||
visitNode(cbNode, (<JSDocTypedefTag>node).fullName) ||
visitNode(cbNode, (<JSDocTypedefTag>node).name) ||
visitNode(cbNode, (<JSDocTypedefTag>node).jsDocTypeLiteral);
case SyntaxKind.JSDocTypeLiteral:
@ -6577,7 +6578,14 @@ namespace ts {
const typedefTag = <JSDocTypedefTag>createNode(SyntaxKind.JSDocTypedefTag, atToken.pos);
typedefTag.atToken = atToken;
typedefTag.tagName = tagName;
typedefTag.name = parseJSDocIdentifierName();
typedefTag.fullName = parseJSDocTypeNameWithNamespace(/*flags*/ 0);
if (typedefTag.fullName) {
let rightNode = typedefTag.fullName;
while (rightNode.kind !== SyntaxKind.Identifier) {
rightNode = rightNode.body;
}
typedefTag.name = rightNode;
}
typedefTag.typeExpression = typeExpression;
skipWhitespace();
@ -6640,8 +6648,27 @@ namespace ts {
scanner.setTextPos(resumePos);
return finishNode(jsDocTypeLiteral);
}
function parseJSDocTypeNameWithNamespace(flags: NodeFlags) {
const pos = scanner.getTokenPos();
const typeNameOrNamespaceName = parseJSDocIdentifierName();
if (typeNameOrNamespaceName && parseOptional(SyntaxKind.DotToken)) {
const jsDocNamespaceNode = <JSDocNamespaceDeclaration>createNode(SyntaxKind.ModuleDeclaration, pos);
jsDocNamespaceNode.flags |= flags;
jsDocNamespaceNode.name = typeNameOrNamespaceName;
jsDocNamespaceNode.body = parseJSDocTypeNameWithNamespace(NodeFlags.NestedNamespace);
return jsDocNamespaceNode;
}
if (typeNameOrNamespaceName && flags & NodeFlags.NestedNamespace) {
typeNameOrNamespaceName.isInJSDocNamespace = true;
}
return typeNameOrNamespaceName;
}
}
function tryParseChildTag(parentTag: JSDocTypeLiteral): boolean {
Debug.assert(token() === SyntaxKind.AtToken);
const atToken = <AtToken>createNode(SyntaxKind.AtToken, scanner.getStartPos());
@ -6664,12 +6691,16 @@ namespace ts {
return true;
case "prop":
case "property":
if (!parentTag.jsDocPropertyTags) {
parentTag.jsDocPropertyTags = <NodeArray<JSDocPropertyTag>>[];
}
const propertyTag = parsePropertyTag(atToken, tagName);
parentTag.jsDocPropertyTags.push(propertyTag);
return true;
if (propertyTag) {
if (!parentTag.jsDocPropertyTags) {
parentTag.jsDocPropertyTags = <NodeArray<JSDocPropertyTag>>[];
}
parentTag.jsDocPropertyTags.push(propertyTag);
return true;
}
// Error parsing property tag
return false;
}
return false;
}

View File

@ -307,7 +307,7 @@ namespace ts {
// - This calls resolveModuleNames, and then calls findSourceFile for each resolved module.
// As all these operations happen - and are nested - within the createProgram call, they close over the below variables.
// The current resolution depth is tracked by incrementing/decrementing as the depth first search progresses.
const maxNodeModulesJsDepth = typeof options.maxNodeModuleJsDepth === "number" ? options.maxNodeModuleJsDepth : 0;
const maxNodeModuleJsDepth = typeof options.maxNodeModuleJsDepth === "number" ? options.maxNodeModuleJsDepth : 0;
let currentNodeModulesDepth = 0;
// If a module has some of its imports skipped due to being at the depth limit under node_modules, then track
@ -331,7 +331,15 @@ namespace ts {
let resolveModuleNamesWorker: (moduleNames: string[], containingFile: string) => ResolvedModule[];
if (host.resolveModuleNames) {
resolveModuleNamesWorker = (moduleNames, containingFile) => host.resolveModuleNames(moduleNames, containingFile);
resolveModuleNamesWorker = (moduleNames, containingFile) => host.resolveModuleNames(moduleNames, containingFile).map(resolved => {
// An older host may have omitted extension, in which case we should infer it from the file extension of resolvedFileName.
if (!resolved || resolved.extension !== undefined) {
return resolved;
}
resolved = clone(resolved);
resolved.extension = extensionFromPath(resolved.resolvedFileName);
return resolved;
});
}
else {
const loader = (moduleName: string, containingFile: string) => resolveModuleName(moduleName, containingFile, options, host).resolvedModule;
@ -462,21 +470,7 @@ namespace ts {
// check properties that can affect structure of the program or module resolution strategy
// if any of these properties has changed - structure cannot be reused
const oldOptions = oldProgram.getCompilerOptions();
if ((oldOptions.module !== options.module) ||
(oldOptions.moduleResolution !== options.moduleResolution) ||
(oldOptions.noResolve !== options.noResolve) ||
(oldOptions.target !== options.target) ||
(oldOptions.noLib !== options.noLib) ||
(oldOptions.jsx !== options.jsx) ||
(oldOptions.allowJs !== options.allowJs) ||
(oldOptions.rootDir !== options.rootDir) ||
(oldOptions.configFilePath !== options.configFilePath) ||
(oldOptions.baseUrl !== options.baseUrl) ||
(oldOptions.maxNodeModuleJsDepth !== options.maxNodeModuleJsDepth) ||
!arrayIsEqualTo(oldOptions.lib, options.lib) ||
!arrayIsEqualTo(oldOptions.typeRoots, options.typeRoots) ||
!arrayIsEqualTo(oldOptions.rootDirs, options.rootDirs) ||
!equalOwnProperties(oldOptions.paths, options.paths)) {
if (changesAffectModuleResolution(oldOptions, options)) {
return false;
}
@ -1084,9 +1078,6 @@ namespace ts {
}
}
/**
* 'isReference' indicates whether the file was brought in via a reference directive (rather than an import declaration)
*/
function processSourceFile(fileName: string, isDefaultLib: boolean, refFile?: SourceFile, refPos?: number, refEnd?: number) {
let diagnosticArgument: string[];
let diagnostic: DiagnosticMessage;
@ -1163,7 +1154,7 @@ namespace ts {
}
// See if we need to reprocess the imports due to prior skipped imports
else if (file && modulesWithElidedImports[file.path]) {
if (currentNodeModulesDepth < maxNodeModulesJsDepth) {
if (currentNodeModulesDepth < maxNodeModuleJsDepth) {
modulesWithElidedImports[file.path] = false;
processImportedModules(file);
}
@ -1306,35 +1297,39 @@ namespace ts {
file.resolvedModules = createMap<ResolvedModule>();
const moduleNames = map(concatenate(file.imports, file.moduleAugmentations), getTextOfLiteral);
const resolutions = resolveModuleNamesWorker(moduleNames, getNormalizedAbsolutePath(file.fileName, currentDirectory));
Debug.assert(resolutions.length === moduleNames.length);
for (let i = 0; i < moduleNames.length; i++) {
const resolution = resolutions[i];
setResolvedModule(file, moduleNames[i], resolution);
if (!resolution) {
continue;
}
const isFromNodeModulesSearch = resolution.isExternalLibraryImport;
const isJsFileFromNodeModules = isFromNodeModulesSearch && !extensionIsTypeScript(resolution.extension);
const resolvedFileName = resolution.resolvedFileName;
if (isFromNodeModulesSearch) {
currentNodeModulesDepth++;
}
// add file to program only if:
// - resolution was successful
// - noResolve is falsy
// - module name comes from the list of imports
// - it's not a top level JavaScript module that exceeded the search max
const isFromNodeModulesSearch = resolution && resolution.isExternalLibraryImport;
const isJsFileFromNodeModules = isFromNodeModulesSearch && hasJavaScriptFileExtension(resolution.resolvedFileName);
if (isFromNodeModulesSearch) {
currentNodeModulesDepth++;
}
const elideImport = isJsFileFromNodeModules && currentNodeModulesDepth > maxNodeModulesJsDepth;
const shouldAddFile = resolution && !options.noResolve && i < file.imports.length && !elideImport;
const elideImport = isJsFileFromNodeModules && currentNodeModulesDepth > maxNodeModuleJsDepth;
// Don't add the file if it has a bad extension (e.g. 'tsx' if we don't have '--allowJs')
const shouldAddFile = resolvedFileName && !getResolutionDiagnostic(options, resolution) && !options.noResolve && i < file.imports.length && !elideImport;
if (elideImport) {
modulesWithElidedImports[file.path] = true;
}
else if (shouldAddFile) {
findSourceFile(resolution.resolvedFileName,
toPath(resolution.resolvedFileName, currentDirectory, getCanonicalFileName),
/*isDefaultLib*/ false,
file,
skipTrivia(file.text, file.imports[i].pos),
file.imports[i].end);
const path = toPath(resolvedFileName, currentDirectory, getCanonicalFileName);
const pos = skipTrivia(file.text, file.imports[i].pos);
findSourceFile(resolvedFileName, path, /*isDefaultLib*/ false, file, pos, file.imports[i].end);
}
if (isFromNodeModulesSearch) {
@ -1346,7 +1341,6 @@ namespace ts {
// no imports - drop cached module resolutions
file.resolvedModules = undefined;
}
return;
}
function computeCommonSourceDirectory(sourceFiles: SourceFile[]): string {
@ -1571,4 +1565,25 @@ namespace ts {
programDiagnostics.add(createCompilerDiagnostic(message, emitFileName));
}
}
/* @internal */
/**
* Returns a DiagnosticMessage if we can't use a resolved module due to its extension.
* The DiagnosticMessage's parameters are the imported module name, and the filename it resolved to.
*/
export function getResolutionDiagnostic(options: CompilerOptions, { extension }: ResolvedModule): DiagnosticMessage | undefined {
switch (extension) {
case Extension.Ts:
case Extension.Dts:
// These are always allowed.
return undefined;
case Extension.Tsx:
case Extension.Jsx:
return options.jsx ? undefined : Diagnostics.Module_0_was_resolved_to_1_but_jsx_is_not_set;
case Extension.Js:
return options.allowJs ? undefined : Diagnostics.Module_0_was_resolved_to_1_but_allowJs_is_not_set;
}
}
}

View File

@ -1799,6 +1799,9 @@ namespace ts {
case CharacterCodes.comma:
pos++;
return token = SyntaxKind.CommaToken;
case CharacterCodes.dot:
pos++;
return token = SyntaxKind.DotToken;
}
if (isIdentifierStart(ch, ScriptTarget.Latest)) {

View File

@ -112,7 +112,6 @@ namespace ts {
const transformers: Transformer[] = [];
transformers.push(transformTypeScript);
transformers.push(moduleTransformerMap[moduleKind] || moduleTransformerMap[ModuleKind.None]);
if (jsx === JsxEmit.React) {
transformers.push(transformJsx);
@ -132,6 +131,10 @@ namespace ts {
transformers.push(transformGenerators);
}
transformers.push(moduleTransformerMap[moduleKind] || moduleTransformerMap[ModuleKind.None]);
// The ES5 transformer is last so that it can substitute expressions like `exports.default`
// for ES3.
if (languageVersion < ScriptTarget.ES5) {
transformers.push(transformES5);
}

View File

@ -174,13 +174,14 @@ namespace ts {
*
* @param node The VariableDeclaration to flatten.
* @param recordTempVariable A callback used to record new temporary variables.
* @param nameSubstitution An optional callback used to substitute binding names.
* @param createAssignmentCallback An optional callback used to create assignment expressions
* for non-temporary variables.
* @param visitor An optional visitor to use to visit expressions.
*/
export function flattenVariableDestructuringToExpression(
node: VariableDeclaration,
recordTempVariable: (name: Identifier) => void,
nameSubstitution?: (name: Identifier) => Expression,
createAssignmentCallback?: (name: Identifier, value: Expression, location?: TextRange) => Expression,
visitor?: (node: Node) => VisitResult<Node>) {
const pendingAssignments: Expression[] = [];
@ -192,18 +193,20 @@ namespace ts {
return expression;
function emitAssignment(name: Identifier, value: Expression, location: TextRange, original: Node) {
const left = nameSubstitution && nameSubstitution(name) || name;
emitPendingAssignment(left, value, location, original);
const expression = createAssignmentCallback
? createAssignmentCallback(name, value, location)
: createAssignment(name, value, location);
emitPendingAssignment(expression, original);
}
function emitTempVariableAssignment(value: Expression, location: TextRange) {
const name = createTempVariable(recordTempVariable);
emitPendingAssignment(name, value, location, /*original*/ undefined);
emitPendingAssignment(createAssignment(name, value, location), /*original*/ undefined);
return name;
}
function emitPendingAssignment(name: Expression, value: Expression, location: TextRange, original: Node) {
const expression = createAssignment(name, value, location);
function emitPendingAssignment(expression: Expression, original: Node) {
expression.original = original;
// NOTE: this completely disables source maps, but aligns with the behavior of
@ -211,7 +214,6 @@ namespace ts {
setEmitFlags(expression, EmitFlags.NoNestedSourceMaps);
pendingAssignments.push(expression);
return expression;
}
}

View File

@ -186,6 +186,7 @@ namespace ts {
let enclosingFunction: FunctionLikeDeclaration;
let enclosingNonArrowFunction: FunctionLikeDeclaration;
let enclosingNonAsyncFunctionBody: FunctionLikeDeclaration | ClassElement;
let isInConstructorWithCapturedSuper: boolean;
/**
* Used to track if we are emitting body of the converted loop
@ -231,14 +232,17 @@ namespace ts {
const savedCurrentParent = currentParent;
const savedCurrentNode = currentNode;
const savedConvertedLoopState = convertedLoopState;
const savedIsInConstructorWithCapturedSuper = isInConstructorWithCapturedSuper;
if (nodeStartsNewLexicalEnvironment(node)) {
// don't treat content of nodes that start new lexical environment as part of converted loop copy
// don't treat content of nodes that start new lexical environment as part of converted loop copy or constructor body
isInConstructorWithCapturedSuper = false;
convertedLoopState = undefined;
}
onBeforeVisitNode(node);
const visited = f(node);
isInConstructorWithCapturedSuper = savedIsInConstructorWithCapturedSuper;
convertedLoopState = savedConvertedLoopState;
enclosingFunction = savedEnclosingFunction;
enclosingNonArrowFunction = savedEnclosingNonArrowFunction;
@ -251,6 +255,14 @@ namespace ts {
return visited;
}
function returnCapturedThis(node: Node): Node {
return setOriginalNode(createReturn(createIdentifier("_this")), node);
}
function isReturnVoidStatementInConstructorWithCapturedSuper(node: Node): boolean {
return isInConstructorWithCapturedSuper && node.kind === SyntaxKind.ReturnStatement && !(<ReturnStatement>node).expression;
}
function shouldCheckNode(node: Node): boolean {
return (node.transformFlags & TransformFlags.ES2015) !== 0 ||
node.kind === SyntaxKind.LabeledStatement ||
@ -258,10 +270,16 @@ namespace ts {
}
function visitorWorker(node: Node): VisitResult<Node> {
if (shouldCheckNode(node)) {
if (isReturnVoidStatementInConstructorWithCapturedSuper(node)) {
return returnCapturedThis(<ReturnStatement>node);
}
else if (shouldCheckNode(node)) {
return visitJavaScript(node);
}
else if (node.transformFlags & TransformFlags.ContainsES2015) {
else if (node.transformFlags & TransformFlags.ContainsES2015 || (isInConstructorWithCapturedSuper && !isExpression(node))) {
// we want to dive in this branch either if node has children with ES2015 specific syntax
// or we are inside constructor that captures result of the super call so all returns without expression should be
// rewritten. Note: we skip expressions since returns should never appear there
return visitEachChild(node, visitor, context);
}
else {
@ -283,6 +301,7 @@ namespace ts {
function visitNodesInConvertedLoop(node: Node): VisitResult<Node> {
switch (node.kind) {
case SyntaxKind.ReturnStatement:
node = isReturnVoidStatementInConstructorWithCapturedSuper(node) ? returnCapturedThis(node) : node;
return visitReturnStatement(<ReturnStatement>node);
case SyntaxKind.VariableStatement:
@ -308,8 +327,8 @@ namespace ts {
function visitJavaScript(node: Node): VisitResult<Node> {
switch (node.kind) {
case SyntaxKind.ExportKeyword:
return node;
case SyntaxKind.StaticKeyword:
return undefined; // elide static keyword
case SyntaxKind.ClassDeclaration:
return visitClassDeclaration(<ClassDeclaration>node);
@ -587,47 +606,39 @@ namespace ts {
// return C;
// }());
const modifierFlags = getModifierFlags(node);
const isExported = modifierFlags & ModifierFlags.Export;
const isDefault = modifierFlags & ModifierFlags.Default;
// Add an `export` modifier to the statement if needed (for `--target es5 --module es6`)
const modifiers = isExported && !isDefault
? filter(node.modifiers, isExportModifier)
: undefined;
const statement = createVariableStatement(
modifiers,
createVariableDeclarationList([
createVariableDeclaration(
getDeclarationName(node, /*allowComments*/ true),
/*type*/ undefined,
transformClassLikeDeclarationToExpression(node)
)
]),
/*location*/ node
const variable = createVariableDeclaration(
getLocalName(node, /*allowComments*/ true),
/*type*/ undefined,
transformClassLikeDeclarationToExpression(node)
);
setOriginalNode(variable, node);
const statements: Statement[] = [];
const statement = createVariableStatement(/*modifiers*/ undefined, createVariableDeclarationList([variable]), /*location*/ node);
setOriginalNode(statement, node);
startOnNewLine(statement);
statements.push(statement);
// Add an `export default` statement for default exports (for `--target es5 --module es6`)
if (isExported && isDefault) {
const statements: Statement[] = [statement];
statements.push(createExportAssignment(
/*decorators*/ undefined,
/*modifiers*/ undefined,
/*isExportEquals*/ false,
getDeclarationName(node, /*allowComments*/ false)
));
return statements;
if (hasModifier(node, ModifierFlags.Export)) {
const exportStatement = hasModifier(node, ModifierFlags.Default)
? createExportDefault(getLocalName(node))
: createExternalModuleExport(getLocalName(node));
setOriginalNode(exportStatement, statement);
statements.push(exportStatement);
}
return statement;
}
const emitFlags = getEmitFlags(node);
if ((emitFlags & EmitFlags.HasEndOfDeclarationMarker) === 0) {
// Add a DeclarationMarker as a marker for the end of the declaration
statements.push(createEndOfDeclarationMarker(node));
setEmitFlags(statement, emitFlags | EmitFlags.HasEndOfDeclarationMarker);
}
function isExportModifier(node: Modifier) {
return node.kind === SyntaxKind.ExportKeyword;
return singleOrMany(statements);
}
/**
@ -688,7 +699,7 @@ namespace ts {
/*asteriskToken*/ undefined,
/*name*/ undefined,
/*typeParameters*/ undefined,
extendsClauseElement ? [createParameter("_super")] : [],
extendsClauseElement ? [createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, "_super")] : [],
/*type*/ undefined,
transformClassBody(node, extendsClauseElement)
);
@ -767,7 +778,7 @@ namespace ts {
if (extendsClauseElement) {
statements.push(
createStatement(
createExtendsHelper(currentSourceFile.externalHelpersModuleName, getDeclarationName(node)),
createExtendsHelper(currentSourceFile.externalHelpersModuleName, getLocalName(node)),
/*location*/ extendsClauseElement
)
);
@ -864,7 +875,10 @@ namespace ts {
}
if (constructor) {
const body = saveStateAndInvoke(constructor, constructor => visitNodes(constructor.body.statements, visitor, isStatement, /*start*/ statementOffset));
const body = saveStateAndInvoke(constructor, constructor => {
isInConstructorWithCapturedSuper = superCaptureStatus === SuperCaptureResult.ReplaceSuperCapture;
return visitNodes(constructor.body.statements, visitor, isStatement, /*start*/ statementOffset);
});
addRange(statements, body);
}
@ -1038,7 +1052,12 @@ namespace ts {
// evaluated inside the function body.
return setOriginalNode(
createParameter(
/*decorators*/ undefined,
/*modifiers*/ undefined,
/*dotDotDotToken*/ undefined,
getGeneratedNameForNode(node),
/*questionToken*/ undefined,
/*type*/ undefined,
/*initializer*/ undefined,
/*location*/ node
),
@ -1049,7 +1068,12 @@ namespace ts {
// Initializers are elided
return setOriginalNode(
createParameter(
/*decorators*/ undefined,
/*modifiers*/ undefined,
/*dotDotDotToken*/ undefined,
node.name,
/*questionToken*/ undefined,
/*type*/ undefined,
/*initializer*/ undefined,
/*location*/ node
),
@ -1693,7 +1717,7 @@ namespace ts {
if (decl.initializer) {
let assignment: Expression;
if (isBindingPattern(decl.name)) {
assignment = flattenVariableDestructuringToExpression(decl, hoistVariableDeclaration, /*nameSubstitution*/ undefined, visitor);
assignment = flattenVariableDestructuringToExpression(decl, hoistVariableDeclaration, /*createAssignmentCallback*/ undefined, visitor);
}
else {
assignment = createBinary(<Identifier>decl.name, SyntaxKind.EqualsToken, visitNode(decl.initializer, visitor, isExpression));
@ -1976,13 +2000,16 @@ namespace ts {
statements.push(
createVariableStatement(
/*modifiers*/ undefined,
createVariableDeclarationList([
createVariableDeclaration(
firstOriginalDeclaration ? firstOriginalDeclaration.name : createTempVariable(/*recordTempVariable*/ undefined),
/*type*/ undefined,
createElementAccess(rhsReference, counter)
)
], /*location*/ moveRangePos(initializer, -1)),
setOriginalNode(
createVariableDeclarationList([
createVariableDeclaration(
firstOriginalDeclaration ? firstOriginalDeclaration.name : createTempVariable(/*recordTempVariable*/ undefined),
/*type*/ undefined,
createElementAccess(rhsReference, counter)
)
], /*location*/ moveRangePos(initializer, -1)),
initializer
),
/*location*/ moveRangeEnd(initializer, -1)
)
);
@ -2044,10 +2071,13 @@ namespace ts {
setEmitFlags(body, EmitFlags.NoSourceMap | EmitFlags.NoTokenSourceMaps);
const forStatement = createFor(
createVariableDeclarationList([
createVariableDeclaration(counter, /*type*/ undefined, createLiteral(0), /*location*/ moveRangePos(node.expression, -1)),
createVariableDeclaration(rhsReference, /*type*/ undefined, expression, /*location*/ node.expression)
], /*location*/ node.expression),
setEmitFlags(
createVariableDeclarationList([
createVariableDeclaration(counter, /*type*/ undefined, createLiteral(0), /*location*/ moveRangePos(node.expression, -1)),
createVariableDeclaration(rhsReference, /*type*/ undefined, expression, /*location*/ node.expression)
], /*location*/ node.expression),
EmitFlags.NoHoisting
),
createLessThan(
counter,
createPropertyAccess(rhsReference, "length"),
@ -2239,25 +2269,28 @@ namespace ts {
const convertedLoopVariable =
createVariableStatement(
/*modifiers*/ undefined,
createVariableDeclarationList(
[
createVariableDeclaration(
functionName,
/*type*/ undefined,
setEmitFlags(
createFunctionExpression(
/*modifiers*/ undefined,
isAsyncBlockContainingAwait ? createToken(SyntaxKind.AsteriskToken) : undefined,
/*name*/ undefined,
/*typeParameters*/ undefined,
loopParameters,
/*type*/ undefined,
<Block>loopBody
),
loopBodyFlags
setEmitFlags(
createVariableDeclarationList(
[
createVariableDeclaration(
functionName,
/*type*/ undefined,
setEmitFlags(
createFunctionExpression(
/*modifiers*/ undefined,
isAsyncBlockContainingAwait ? createToken(SyntaxKind.AsteriskToken) : undefined,
/*name*/ undefined,
/*typeParameters*/ undefined,
loopParameters,
/*type*/ undefined,
<Block>loopBody
),
loopBodyFlags
)
)
)
]
]
),
EmitFlags.NoHoisting
)
);
@ -2508,7 +2541,7 @@ namespace ts {
}
}
else {
loopParameters.push(createParameter(name));
loopParameters.push(createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, name));
if (resolver.getNodeCheckFlags(decl) & NodeCheckFlags.NeedsLoopOutParameter) {
const outParamName = createUniqueName("out_" + name.text);
loopOutParameters.push({ originalName: name, outParamName });
@ -3101,9 +3134,8 @@ namespace ts {
/**
* Hooks node substitutions.
*
* @param emitContext The context for the emitter.
* @param node The node to substitute.
* @param isExpression A value indicating whether the node is to be used in an expression
* position.
*/
function onSubstituteNode(emitContext: EmitContext, node: Node) {
node = previousOnSubstituteNode(emitContext, node);
@ -3203,45 +3235,6 @@ namespace ts {
return node;
}
/**
* Gets the local name for a declaration for use in expressions.
*
* A local name will *never* be prefixed with an module or namespace export modifier like
* "exports.".
*
* @param node The declaration.
* @param allowComments A value indicating whether comments may be emitted for the name.
* @param allowSourceMaps A value indicating whether source maps may be emitted for the name.
*/
function getLocalName(node: ClassDeclaration | ClassExpression | FunctionDeclaration, allowComments?: boolean, allowSourceMaps?: boolean) {
return getDeclarationName(node, allowComments, allowSourceMaps, EmitFlags.LocalName);
}
/**
* Gets the name of a declaration, without source map or comments.
*
* @param node The declaration.
* @param allowComments Allow comments for the name.
*/
function getDeclarationName(node: ClassDeclaration | ClassExpression | FunctionDeclaration, allowComments?: boolean, allowSourceMaps?: boolean, emitFlags?: EmitFlags) {
if (node.name && !isGeneratedIdentifier(node.name)) {
const name = getMutableClone(node.name);
emitFlags |= getEmitFlags(node.name);
if (!allowSourceMaps) {
emitFlags |= EmitFlags.NoSourceMap;
}
if (!allowComments) {
emitFlags |= EmitFlags.NoComments;
}
if (emitFlags) {
setEmitFlags(name, emitFlags);
}
return name;
}
return getGeneratedNameForNode(node);
}
function getClassMemberPrefix(node: ClassExpression | ClassDeclaration, member: ClassElement) {
const expression = getLocalName(node);
return hasModifier(member, ModifierFlags.Static) ? expression : createPropertyAccess(expression, "prototype");

View File

@ -2369,7 +2369,7 @@ namespace ts {
labelExpressions = [];
}
const expression = <LiteralExpression>createSynthesizedNode(SyntaxKind.NumericLiteral);
const expression = createLiteral(-1);
if (labelExpressions[label] === undefined) {
labelExpressions[label] = [expression];
}
@ -2380,7 +2380,7 @@ namespace ts {
return expression;
}
return <OmittedExpression>createNode(SyntaxKind.OmittedExpression);
return createOmittedExpression();
}
/**
@ -2596,7 +2596,7 @@ namespace ts {
/*asteriskToken*/ undefined,
/*name*/ undefined,
/*typeParameters*/ undefined,
[createParameter(state)],
[createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, state)],
/*type*/ undefined,
createBlock(
buildResult,

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -48,7 +48,7 @@ namespace ts {
let currentNamespaceContainerName: Identifier;
let currentScope: SourceFile | Block | ModuleBlock | CaseBlock;
let currentScopeFirstDeclarationsOfName: Map<Node>;
let currentSourceFileExternalHelpersModuleName: Identifier;
let currentExternalHelpersModuleName: Identifier;
/**
* Keeps track of whether expression substitution has been enabled for specific edge cases.
@ -241,6 +241,18 @@ namespace ts {
}
}
function modifierVisitor(node: Node): VisitResult<Node> {
if (modifierToFlag(node.kind) & ModifierFlags.TypeScriptModifier) {
return undefined;
}
else if (currentNamespace && node.kind === SyntaxKind.ExportKeyword) {
return undefined;
}
return node;
}
/**
* Branching visitor, visits a TypeScript syntax node.
*
@ -475,16 +487,16 @@ namespace ts {
/*decorators*/ undefined,
/*modifiers*/ undefined,
createImportClause(/*name*/ undefined, createNamespaceImport(externalHelpersModuleName)),
createLiteral(externalHelpersModuleNameText)
);
createLiteral(externalHelpersModuleNameText));
externalHelpersModuleImport.parent = node;
externalHelpersModuleImport.flags &= ~NodeFlags.Synthesized;
statements.push(externalHelpersModuleImport);
currentSourceFileExternalHelpersModuleName = externalHelpersModuleName;
currentExternalHelpersModuleName = externalHelpersModuleName;
addRange(statements, visitNodes(node.statements, sourceElementVisitor, isStatement, statementOffset));
addRange(statements, endLexicalEnvironment());
currentSourceFileExternalHelpersModuleName = undefined;
currentExternalHelpersModuleName = undefined;
node = updateSourceFileNode(node, createNodeArray(statements, node.statements));
node.externalHelpersModuleName = externalHelpersModuleName;
@ -535,7 +547,6 @@ namespace ts {
const staticProperties = getInitializedProperties(node, /*isStatic*/ true);
const hasExtendsClause = getClassExtendsHeritageClauseElement(node) !== undefined;
const isDecoratedClass = shouldEmitDecorateCallForClass(node);
let classAlias: Identifier;
// emit name if
// - node has a name
@ -546,33 +557,11 @@ namespace ts {
name = getGeneratedNameForNode(node);
}
const statements: Statement[] = [];
if (!isDecoratedClass) {
// ${modifiers} class ${name} ${heritageClauses} {
// ${members}
// }
const classDeclaration = createClassDeclaration(
/*decorators*/ undefined,
visitNodes(node.modifiers, visitor, isModifier),
name,
/*typeParameters*/ undefined,
visitNodes(node.heritageClauses, visitor, isHeritageClause),
transformClassMembers(node, hasExtendsClause),
/*location*/ node
);
setOriginalNode(classDeclaration, node);
const classStatement = isDecoratedClass
? createClassDeclarationHeadWithDecorators(node, name, hasExtendsClause)
: createClassDeclarationHeadWithoutDecorators(node, name, hasExtendsClause, staticProperties.length > 0);
// To better align with the old emitter, we should not emit a trailing source map
// entry if the class has static properties.
if (staticProperties.length > 0) {
setEmitFlags(classDeclaration, EmitFlags.NoTrailingSourceMap | getEmitFlags(classDeclaration));
}
statements.push(classDeclaration);
}
else {
classAlias = addClassDeclarationHeadWithDecorators(statements, node, name, hasExtendsClause);
}
const statements: Statement[] = [classStatement];
// Emit static property assignment. Because classDeclaration is lexically evaluated,
// it is safe to emit static property assignment after classDeclaration
@ -580,13 +569,13 @@ namespace ts {
// HasLexicalDeclaration (N) : Determines if the argument identifier has a binding in this environment record that was created using
// a lexical declaration such as a LexicalDeclaration or a ClassDeclaration.
if (staticProperties.length) {
addInitializedPropertyStatements(statements, staticProperties, getLocalName(node, /*noSourceMaps*/ true));
addInitializedPropertyStatements(statements, staticProperties, getLocalName(node));
}
// Write any decorators of the node.
addClassElementDecorationStatements(statements, node, /*isStatic*/ false);
addClassElementDecorationStatements(statements, node, /*isStatic*/ true);
addConstructorDecorationStatement(statements, node, classAlias);
addConstructorDecorationStatement(statements, node);
// If the class is exported as part of a TypeScript namespace, emit the namespace export.
// Otherwise, if the class was exported at the top level and was decorated, emit an export
@ -596,29 +585,66 @@ namespace ts {
}
else if (isDecoratedClass) {
if (isDefaultExternalModuleExport(node)) {
statements.push(createExportAssignment(
/*decorators*/ undefined,
/*modifiers*/ undefined,
/*isExportEquals*/ false,
getLocalName(node)));
statements.push(createExportDefault(getLocalName(node, /*allowComments*/ false, /*allowSourceMaps*/ true)));
}
else if (isNamedExternalModuleExport(node)) {
statements.push(createExternalModuleExport(name));
statements.push(createExternalModuleExport(getLocalName(node, /*allowComments*/ false, /*allowSourceMaps*/ true)));
}
}
return statements;
if (statements.length > 1) {
// Add a DeclarationMarker as a marker for the end of the declaration
statements.push(createEndOfDeclarationMarker(node));
setEmitFlags(classStatement, getEmitFlags(classStatement) | EmitFlags.HasEndOfDeclarationMarker);
}
return singleOrMany(statements);
}
/**
* Transforms a non-decorated class declaration and appends the resulting statements.
*
* @param node A ClassDeclaration node.
* @param name The name of the class.
* @param hasExtendsClause A value indicating whether the class has an extends clause.
* @param hasStaticProperties A value indicating whether the class has static properties.
*/
function createClassDeclarationHeadWithoutDecorators(node: ClassDeclaration, name: Identifier, hasExtendsClause: boolean, hasStaticProperties: boolean) {
// ${modifiers} class ${name} ${heritageClauses} {
// ${members}
// }
const classDeclaration = createClassDeclaration(
/*decorators*/ undefined,
visitNodes(node.modifiers, modifierVisitor, isModifier),
name,
/*typeParameters*/ undefined,
visitNodes(node.heritageClauses, visitor, isHeritageClause),
transformClassMembers(node, hasExtendsClause),
node);
let emitFlags = getEmitFlags(node);
// To better align with the old emitter, we should not emit a trailing source map
// entry if the class has static properties.
if (hasStaticProperties) {
emitFlags |= EmitFlags.NoTrailingSourceMap;
}
setOriginalNode(classDeclaration, node);
setEmitFlags(classDeclaration, emitFlags);
return classDeclaration;
}
/**
* Transforms a decorated class declaration and appends the resulting statements. If
* the class requires an alias to avoid issues with double-binding, the alias is returned.
*
* @param statements A statement list to which to add the declaration.
* @param node A ClassDeclaration node.
* @param name The name of the class.
* @param hasExtendsClause A value indicating whether
* @param hasExtendsClause A value indicating whether the class has an extends clause.
*/
function addClassDeclarationHeadWithDecorators(statements: Statement[], node: ClassDeclaration, name: Identifier, hasExtendsClause: boolean) {
function createClassDeclarationHeadWithDecorators(node: ClassDeclaration, name: Identifier, hasExtendsClause: boolean) {
// When we emit an ES6 class that has a class decorator, we must tailor the
// emit to certain specific cases.
//
@ -653,20 +679,20 @@ namespace ts {
// ---------------------------------------------------------------------
// TypeScript | Javascript
// ---------------------------------------------------------------------
// @dec | let C_1 = class C {
// @dec | let C = C_1 = class C {
// class C { | static x() { return C_1.y; }
// static x() { return C.y; } | }
// static y = 1; | let C = C_1;
// } | C.y = 1;
// | C = C_1 = __decorate([dec], C);
// static y = 1; | C.y = 1;
// } | C = C_1 = __decorate([dec], C);
// | var C_1;
// ---------------------------------------------------------------------
// @dec | let C_1 = class C {
// @dec | let C = class C {
// export class C { | static x() { return C_1.y; }
// static x() { return C.y; } | }
// static y = 1; | let C = C_1;
// } | C.y = 1;
// | C = C_1 = __decorate([dec], C);
// static y = 1; | C.y = 1;
// } | C = C_1 = __decorate([dec], C);
// | export { C };
// | var C_1;
// ---------------------------------------------------------------------
//
// If a class declaration is the default export of a module, we instead emit
@ -695,92 +721,34 @@ namespace ts {
// ---------------------------------------------------------------------
// TypeScript | Javascript
// ---------------------------------------------------------------------
// @dec | let C_1 = class C {
// @dec | let C = class C {
// export default class C { | static x() { return C_1.y; }
// static x() { return C.y; } | }
// static y = 1; | let C = C_1;
// } | C.y = 1;
// | C = C_1 = __decorate([dec], C);
// static y = 1; | C.y = 1;
// } | C = C_1 = __decorate([dec], C);
// | export default C;
// | var C_1;
// ---------------------------------------------------------------------
//
const location = moveRangePastDecorators(node);
const classAlias = getClassAliasIfNeeded(node);
const declName = getLocalName(node, /*allowComments*/ false, /*allowSourceMaps*/ true);
// ... = class ${name} ${heritageClauses} {
// ${members}
// }
const classExpression: Expression = setOriginalNode(
createClassExpression(
/*modifiers*/ undefined,
name,
/*typeParameters*/ undefined,
visitNodes(node.heritageClauses, visitor, isHeritageClause),
transformClassMembers(node, hasExtendsClause),
/*location*/ location
),
node
);
if (!name) {
name = getGeneratedNameForNode(node);
}
// Record an alias to avoid class double-binding.
let classAlias: Identifier;
if (resolver.getNodeCheckFlags(node) & NodeCheckFlags.ClassWithConstructorReference) {
enableSubstitutionForClassAliases();
classAlias = createUniqueName(node.name && !isGeneratedIdentifier(node.name) ? node.name.text : "default");
classAliases[getOriginalNodeId(node)] = classAlias;
}
const declaredName = getDeclarationName(node, /*allowComments*/ true);
const heritageClauses = visitNodes(node.heritageClauses, visitor, isHeritageClause);
const members = transformClassMembers(node, hasExtendsClause);
const classExpression = createClassExpression(/*modifiers*/ undefined, name, /*typeParameters*/ undefined, heritageClauses, members, location);
setOriginalNode(classExpression, node);
// let ${name} = ${classExpression} where name is either declaredName if the class doesn't contain self-reference
// or decoratedClassAlias if the class contain self-reference.
const transformedClassExpression = createVariableStatement(
/*modifiers*/ undefined,
createLetDeclarationList([
createVariableDeclaration(
classAlias || declaredName,
/*type*/ undefined,
classExpression
)
]),
/*location*/ location
);
setCommentRange(transformedClassExpression, node);
statements.push(
setOriginalNode(
/*node*/ transformedClassExpression,
/*original*/ node
)
);
if (classAlias) {
// We emit the class alias as a `let` declaration here so that it has the same
// TDZ as the class.
// let ${declaredName} = ${decoratedClassAlias}
statements.push(
setOriginalNode(
createVariableStatement(
/*modifiers*/ undefined,
createLetDeclarationList([
createVariableDeclaration(
declaredName,
/*type*/ undefined,
classAlias
)
]),
/*location*/ location
),
/*original*/ node
)
);
}
return classAlias;
const statement = createLetStatement(declName, classAlias ? createAssignment(classAlias, classExpression) : classExpression, location);
setOriginalNode(statement, node);
setCommentRange(statement, node);
return statement;
}
/**
@ -990,7 +958,7 @@ namespace ts {
statements,
/*location*/ constructor ? constructor.body.statements : node.members
),
/*location*/ constructor ? constructor.body : undefined
/*location*/ constructor ? constructor.body : /*location*/ undefined
),
true
);
@ -1450,7 +1418,7 @@ namespace ts {
: undefined;
const helper = createDecorateHelper(
currentSourceFileExternalHelpersModuleName,
currentExternalHelpersModuleName,
decoratorExpressions,
prefix,
memberName,
@ -1467,8 +1435,8 @@ namespace ts {
*
* @param node The class node.
*/
function addConstructorDecorationStatement(statements: Statement[], node: ClassDeclaration, decoratedClassAlias: Identifier) {
const expression = generateConstructorDecorationExpression(node, decoratedClassAlias);
function addConstructorDecorationStatement(statements: Statement[], node: ClassDeclaration) {
const expression = generateConstructorDecorationExpression(node);
if (expression) {
statements.push(setOriginalNode(createStatement(expression), node));
}
@ -1479,61 +1447,20 @@ namespace ts {
*
* @param node The class node.
*/
function generateConstructorDecorationExpression(node: ClassExpression | ClassDeclaration, decoratedClassAlias: Identifier) {
function generateConstructorDecorationExpression(node: ClassExpression | ClassDeclaration) {
const allDecorators = getAllDecoratorsOfConstructor(node);
const decoratorExpressions = transformAllDecoratorsOfDeclaration(node, allDecorators);
if (!decoratorExpressions) {
return undefined;
}
// Emit the call to __decorate. Given the class:
//
// @dec
// class C {
// }
//
// The emit for the class is:
//
// C = C_1 = __decorate([dec], C);
//
if (decoratedClassAlias) {
const expression = createAssignment(
decoratedClassAlias,
createDecorateHelper(
currentSourceFileExternalHelpersModuleName,
decoratorExpressions,
getDeclarationName(node)
)
);
const result = createAssignment(getDeclarationName(node), expression, moveRangePastDecorators(node));
setEmitFlags(result, EmitFlags.NoComments);
return result;
}
// Emit the call to __decorate. Given the class:
//
// @dec
// export declare class C {
// }
//
// The emit for the class is:
//
// C = __decorate([dec], C);
//
else {
const result = createAssignment(
getDeclarationName(node),
createDecorateHelper(
currentSourceFileExternalHelpersModuleName,
decoratorExpressions,
getDeclarationName(node)
),
moveRangePastDecorators(node)
);
setEmitFlags(result, EmitFlags.NoComments);
return result;
}
const classAlias = classAliases && classAliases[getOriginalNodeId(node)];
const localName = getLocalName(node, /*allowComments*/ false, /*allowSourceMaps*/ true);
const decorate = createDecorateHelper(currentExternalHelpersModuleName, decoratorExpressions, localName);
const expression = createAssignment(localName, classAlias ? createAssignment(classAlias, decorate) : decorate);
setEmitFlags(expression, EmitFlags.NoComments);
setSourceMapRange(expression, moveRangePastDecorators(node));
return expression;
}
/**
@ -1557,7 +1484,7 @@ namespace ts {
expressions = [];
for (const decorator of decorators) {
const helper = createParamHelper(
currentSourceFileExternalHelpersModuleName,
currentExternalHelpersModuleName,
transformDecorator(decorator),
parameterOffset,
/*location*/ decorator.expression);
@ -1587,13 +1514,13 @@ namespace ts {
function addOldTypeMetadata(node: Declaration, decoratorExpressions: Expression[]) {
if (compilerOptions.emitDecoratorMetadata) {
if (shouldAddTypeMetadata(node)) {
decoratorExpressions.push(createMetadataHelper(currentSourceFileExternalHelpersModuleName, "design:type", serializeTypeOfNode(node)));
decoratorExpressions.push(createMetadataHelper(currentExternalHelpersModuleName, "design:type", serializeTypeOfNode(node)));
}
if (shouldAddParamTypesMetadata(node)) {
decoratorExpressions.push(createMetadataHelper(currentSourceFileExternalHelpersModuleName, "design:paramtypes", serializeParameterTypesOfNode(node)));
decoratorExpressions.push(createMetadataHelper(currentExternalHelpersModuleName, "design:paramtypes", serializeParameterTypesOfNode(node)));
}
if (shouldAddReturnTypeMetadata(node)) {
decoratorExpressions.push(createMetadataHelper(currentSourceFileExternalHelpersModuleName, "design:returntype", serializeReturnTypeOfNode(node)));
decoratorExpressions.push(createMetadataHelper(currentExternalHelpersModuleName, "design:returntype", serializeReturnTypeOfNode(node)));
}
}
}
@ -1602,16 +1529,16 @@ namespace ts {
if (compilerOptions.emitDecoratorMetadata) {
let properties: ObjectLiteralElementLike[];
if (shouldAddTypeMetadata(node)) {
(properties || (properties = [])).push(createPropertyAssignment("type", createArrowFunction(/*modifiers*/ undefined, /*typeParameters*/ undefined, [], /*type*/ undefined, /*equalsGreaterThanToken*/ undefined, serializeTypeOfNode(node))));
(properties || (properties = [])).push(createPropertyAssignment("type", createArrowFunction(/*modifiers*/ undefined, /*typeParameters*/ undefined, [], /*type*/ undefined, createToken(SyntaxKind.EqualsGreaterThanToken), serializeTypeOfNode(node))));
}
if (shouldAddParamTypesMetadata(node)) {
(properties || (properties = [])).push(createPropertyAssignment("paramTypes", createArrowFunction(/*modifiers*/ undefined, /*typeParameters*/ undefined, [], /*type*/ undefined, /*equalsGreaterThanToken*/ undefined, serializeParameterTypesOfNode(node))));
(properties || (properties = [])).push(createPropertyAssignment("paramTypes", createArrowFunction(/*modifiers*/ undefined, /*typeParameters*/ undefined, [], /*type*/ undefined, createToken(SyntaxKind.EqualsGreaterThanToken), serializeParameterTypesOfNode(node))));
}
if (shouldAddReturnTypeMetadata(node)) {
(properties || (properties = [])).push(createPropertyAssignment("returnType", createArrowFunction(/*modifiers*/ undefined, /*typeParameters*/ undefined, [], /*type*/ undefined, /*equalsGreaterThanToken*/ undefined, serializeReturnTypeOfNode(node))));
(properties || (properties = [])).push(createPropertyAssignment("returnType", createArrowFunction(/*modifiers*/ undefined, /*typeParameters*/ undefined, [], /*type*/ undefined, createToken(SyntaxKind.EqualsGreaterThanToken), serializeReturnTypeOfNode(node))));
}
if (properties) {
decoratorExpressions.push(createMetadataHelper(currentSourceFileExternalHelpersModuleName, "design:typeinfo", createObjectLiteral(properties, /*location*/ undefined, /*multiLine*/ true)));
decoratorExpressions.push(createMetadataHelper(currentExternalHelpersModuleName, "design:typeinfo", createObjectLiteral(properties, /*location*/ undefined, /*multiLine*/ true)));
}
}
}
@ -2129,7 +2056,7 @@ namespace ts {
const method = createMethod(
/*decorators*/ undefined,
visitNodes(node.modifiers, visitor, isModifier),
visitNodes(node.modifiers, modifierVisitor, isModifier),
node.asteriskToken,
visitPropertyNameOfClassElement(node),
/*typeParameters*/ undefined,
@ -2174,7 +2101,7 @@ namespace ts {
const accessor = createGetAccessor(
/*decorators*/ undefined,
visitNodes(node.modifiers, visitor, isModifier),
visitNodes(node.modifiers, modifierVisitor, isModifier),
visitPropertyNameOfClassElement(node),
visitNodes(node.parameters, visitor, isParameter),
/*type*/ undefined,
@ -2184,9 +2111,9 @@ namespace ts {
// While we emit the source map for the node after skipping decorators and modifiers,
// we need to emit the comments for the original range.
setOriginalNode(accessor, node);
setCommentRange(accessor, node);
setSourceMapRange(accessor, moveRangePastDecorators(node));
setOriginalNode(accessor, node);
return accessor;
}
@ -2207,7 +2134,7 @@ namespace ts {
const accessor = createSetAccessor(
/*decorators*/ undefined,
visitNodes(node.modifiers, visitor, isModifier),
visitNodes(node.modifiers, modifierVisitor, isModifier),
visitPropertyNameOfClassElement(node),
visitNodes(node.parameters, visitor, isParameter),
node.body ? visitEachChild(node.body, visitor, context) : createBlock([]),
@ -2216,9 +2143,9 @@ namespace ts {
// While we emit the source map for the node after skipping decorators and modifiers,
// we need to emit the comments for the original range.
setOriginalNode(accessor, node);
setCommentRange(accessor, node);
setSourceMapRange(accessor, moveRangePastDecorators(node));
setOriginalNode(accessor, node);
return accessor;
}
@ -2240,7 +2167,7 @@ namespace ts {
const func = createFunctionDeclaration(
/*decorators*/ undefined,
visitNodes(node.modifiers, visitor, isModifier),
visitNodes(node.modifiers, modifierVisitor, isModifier),
node.asteriskToken,
node.name,
/*typeParameters*/ undefined,
@ -2274,7 +2201,7 @@ namespace ts {
}
const func = createFunctionExpression(
visitNodes(node.modifiers, visitor, isModifier),
visitNodes(node.modifiers, modifierVisitor, isModifier),
node.asteriskToken,
node.name,
/*typeParameters*/ undefined,
@ -2296,7 +2223,7 @@ namespace ts {
*/
function visitArrowFunction(node: ArrowFunction) {
const func = createArrowFunction(
visitNodes(node.modifiers, visitor, isModifier),
visitNodes(node.modifiers, modifierVisitor, isModifier),
/*typeParameters*/ undefined,
visitNodes(node.parameters, visitor, isParameter),
/*type*/ undefined,
@ -2368,7 +2295,7 @@ namespace ts {
return undefined;
}
const parameter = createParameterDeclaration(
const parameter = createParameter(
/*decorators*/ undefined,
/*modifiers*/ undefined,
node.dotDotDotToken,
@ -2421,7 +2348,7 @@ namespace ts {
return flattenVariableDestructuringToExpression(
node,
hoistVariableDeclaration,
getNamespaceMemberNameWithSourceMapsAndWithoutComments,
createNamespaceExportExpression,
visitor
);
}
@ -2511,29 +2438,6 @@ namespace ts {
|| compilerOptions.isolatedModules;
}
function shouldEmitVarForEnumDeclaration(node: EnumDeclaration | ModuleDeclaration) {
return isFirstEmittedDeclarationInScope(node)
&& (!hasModifier(node, ModifierFlags.Export)
|| isES6ExportedDeclaration(node));
}
/*
* Adds a trailing VariableStatement for an enum or module declaration.
*/
function addVarForEnumExportedFromNamespace(statements: Statement[], node: EnumDeclaration | ModuleDeclaration) {
const statement = createVariableStatement(
/*modifiers*/ undefined,
[createVariableDeclaration(
getDeclarationName(node),
/*type*/ undefined,
getExportName(node)
)]
);
setSourceMapRange(statement, node);
statements.push(statement);
}
/**
* Visits an enum declaration.
*
@ -2555,10 +2459,7 @@ namespace ts {
// If needed, we should emit a variable declaration for the enum. If we emit
// a leading variable declaration, we should not emit leading comments for the
// enum body.
recordEmittedDeclarationInScope(node);
if (shouldEmitVarForEnumDeclaration(node)) {
addVarForEnumOrModuleDeclaration(statements, node);
if (addVarForEnumOrModuleDeclaration(statements, node)) {
// We should still emit the comments if we are emitting a system module.
if (moduleKind !== ModuleKind.System || currentScope !== currentSourceFile) {
emitFlags |= EmitFlags.NoLeadingComments;
@ -2572,7 +2473,28 @@ namespace ts {
const containerName = getNamespaceContainerName(node);
// `exportName` is the expression used within this node's container for any exported references.
const exportName = getExportName(node);
const exportName = hasModifier(node, ModifierFlags.Export)
? getExternalModuleOrNamespaceExportName(currentNamespaceContainerName, node, /*allowComments*/ false, /*allowSourceMaps*/ true)
: getLocalName(node, /*allowComments*/ false, /*allowSourceMaps*/ true);
// x || (x = {})
// exports.x || (exports.x = {})
let moduleArg =
createLogicalOr(
exportName,
createAssignment(
exportName,
createObjectLiteral()
)
);
if (hasNamespaceQualifiedExportName(node)) {
// `localName` is the expression used within this node's containing scope for any local references.
const localName = getLocalName(node, /*allowComments*/ false, /*allowSourceMaps*/ true);
// x = (exports.x || (exports.x = {}))
moduleArg = createAssignment(localName, moduleArg);
}
// (function (x) {
// x[x["y"] = 0] = "y";
@ -2585,18 +2507,12 @@ namespace ts {
/*asteriskToken*/ undefined,
/*name*/ undefined,
/*typeParameters*/ undefined,
[createParameter(parameterName)],
[createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, parameterName)],
/*type*/ undefined,
transformEnumBody(node, containerName)
),
/*typeArguments*/ undefined,
[createLogicalOr(
exportName,
createAssignment(
exportName,
createObjectLiteral()
)
)]
[moduleArg]
),
/*location*/ node
);
@ -2605,10 +2521,9 @@ namespace ts {
setEmitFlags(enumStatement, emitFlags);
statements.push(enumStatement);
if (isNamespaceExport(node)) {
addVarForEnumExportedFromNamespace(statements, node);
}
// Add a DeclarationMarker for the enum to preserve trailing comments and mark
// the end of the declaration.
statements.push(createEndOfDeclarationMarker(node));
return statements;
}
@ -2693,9 +2608,15 @@ namespace ts {
return isInstantiatedModule(node, compilerOptions.preserveConstEnums || compilerOptions.isolatedModules);
}
function isES6ExportedDeclaration(node: Node) {
return isExternalModuleExport(node)
&& moduleKind === ModuleKind.ES2015;
/**
* Determines whether an exported declaration will have a qualified export name (e.g. `f.x`
* or `exports.x`).
*/
function hasNamespaceQualifiedExportName(node: Node) {
return isNamespaceExport(node)
|| (isExternalModuleExport(node)
&& moduleKind !== ModuleKind.ES2015
&& moduleKind !== ModuleKind.System);
}
/**
@ -2733,57 +2654,65 @@ namespace ts {
return false;
}
function shouldEmitVarForModuleDeclaration(node: ModuleDeclaration) {
return isFirstEmittedDeclarationInScope(node);
}
/**
* Adds a leading VariableStatement for a enum or module declaration.
*/
function addVarForEnumOrModuleDeclaration(statements: Statement[], node: ModuleDeclaration | EnumDeclaration) {
// Emit a variable statement for the module.
const statement = createVariableStatement(
isES6ExportedDeclaration(node)
? visitNodes(node.modifiers, visitor, isModifier)
: undefined,
visitNodes(node.modifiers, modifierVisitor, isModifier),
[
createVariableDeclaration(
getDeclarationName(node, /*allowComments*/ false, /*allowSourceMaps*/ true)
getLocalName(node, /*allowComments*/ false, /*allowSourceMaps*/ true)
)
]
);
setOriginalNode(statement, /*original*/ node);
setOriginalNode(statement, node);
// Adjust the source map emit to match the old emitter.
if (node.kind === SyntaxKind.EnumDeclaration) {
setSourceMapRange(statement.declarationList, node);
recordEmittedDeclarationInScope(node);
if (isFirstEmittedDeclarationInScope(node)) {
// Adjust the source map emit to match the old emitter.
if (node.kind === SyntaxKind.EnumDeclaration) {
setSourceMapRange(statement.declarationList, node);
}
else {
setSourceMapRange(statement, node);
}
// Trailing comments for module declaration should be emitted after the function closure
// instead of the variable statement:
//
// /** Module comment*/
// module m1 {
// function foo4Export() {
// }
// } // trailing comment module
//
// Should emit:
//
// /** Module comment*/
// var m1;
// (function (m1) {
// function foo4Export() {
// }
// })(m1 || (m1 = {})); // trailing comment module
//
setCommentRange(statement, node);
setEmitFlags(statement, EmitFlags.NoTrailingComments | EmitFlags.HasEndOfDeclarationMarker);
statements.push(statement);
return true;
}
else {
setSourceMapRange(statement, node);
// For an EnumDeclaration or ModuleDeclaration that merges with a preceeding
// declaration we do not emit a leading variable declaration. To preserve the
// begin/end semantics of the declararation and to properly handle exports
// we wrap the leading variable declaration in a `MergeDeclarationMarker`.
const mergeMarker = createMergeDeclarationMarker(statement);
setEmitFlags(mergeMarker, EmitFlags.NoComments | EmitFlags.HasEndOfDeclarationMarker);
statements.push(mergeMarker);
return false;
}
// Trailing comments for module declaration should be emitted after the function closure
// instead of the variable statement:
//
// /** Module comment*/
// module m1 {
// function foo4Export() {
// }
// } // trailing comment module
//
// Should emit:
//
// /** Module comment*/
// var m1;
// (function (m1) {
// function foo4Export() {
// }
// })(m1 || (m1 = {})); // trailing comment module
//
setCommentRange(statement, node);
setEmitFlags(statement, EmitFlags.NoTrailingComments);
statements.push(statement);
}
/**
@ -2810,9 +2739,7 @@ namespace ts {
// If needed, we should emit a variable declaration for the module. If we emit
// a leading variable declaration, we should not emit leading comments for the
// module body.
recordEmittedDeclarationInScope(node);
if (shouldEmitVarForModuleDeclaration(node)) {
addVarForEnumOrModuleDeclaration(statements, node);
if (addVarForEnumOrModuleDeclaration(statements, node)) {
// We should still emit the comments if we are emitting a system module.
if (moduleKind !== ModuleKind.System || currentScope !== currentSourceFile) {
emitFlags |= EmitFlags.NoLeadingComments;
@ -2826,7 +2753,9 @@ namespace ts {
const containerName = getNamespaceContainerName(node);
// `exportName` is the expression used within this node's container for any exported references.
const exportName = getExportName(node);
const exportName = hasModifier(node, ModifierFlags.Export)
? getExternalModuleOrNamespaceExportName(currentNamespaceContainerName, node, /*allowComments*/ false, /*allowSourceMaps*/ true)
: getLocalName(node, /*allowComments*/ false, /*allowSourceMaps*/ true);
// x || (x = {})
// exports.x || (exports.x = {})
@ -2839,9 +2768,9 @@ namespace ts {
)
);
if (hasModifier(node, ModifierFlags.Export) && !isES6ExportedDeclaration(node)) {
if (hasNamespaceQualifiedExportName(node)) {
// `localName` is the expression used within this node's containing scope for any local references.
const localName = getLocalName(node);
const localName = getLocalName(node, /*allowComments*/ false, /*allowSourceMaps*/ true);
// x = (exports.x || (exports.x = {}))
moduleArg = createAssignment(localName, moduleArg);
@ -2857,7 +2786,7 @@ namespace ts {
/*asteriskToken*/ undefined,
/*name*/ undefined,
/*typeParameters*/ undefined,
[createParameter(parameterName)],
[createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, parameterName)],
/*type*/ undefined,
transformModuleBody(node, containerName)
),
@ -2870,6 +2799,10 @@ namespace ts {
setOriginalNode(moduleStatement, node);
setEmitFlags(moduleStatement, emitFlags);
statements.push(moduleStatement);
// Add a DeclarationMarker for the namespace to preserve trailing comments and mark
// the end of the declaration.
statements.push(createEndOfDeclarationMarker(node));
return statements;
}
@ -3125,12 +3058,15 @@ namespace ts {
// var ${name} = ${moduleReference};
return setOriginalNode(
createVariableStatement(
visitNodes(node.modifiers, visitor, isModifier),
visitNodes(node.modifiers, modifierVisitor, isModifier),
createVariableDeclarationList([
createVariableDeclaration(
node.name,
/*type*/ undefined,
moduleReference
setOriginalNode(
createVariableDeclaration(
node.name,
/*type*/ undefined,
moduleReference
),
node
)
]),
node
@ -3198,8 +3134,8 @@ namespace ts {
function addExportMemberAssignment(statements: Statement[], node: ClassDeclaration | FunctionDeclaration) {
const expression = createAssignment(
getExportName(node),
getLocalName(node, /*noSourceMaps*/ true)
getExternalModuleOrNamespaceExportName(currentNamespaceContainerName, node, /*allowComments*/ false, /*allowSourceMaps*/ true),
getLocalName(node)
);
setSourceMapRange(expression, createRange(node.name.pos, node.end));
@ -3211,40 +3147,19 @@ namespace ts {
function createNamespaceExport(exportName: Identifier, exportValue: Expression, location?: TextRange) {
return createStatement(
createAssignment(
getNamespaceMemberName(exportName, /*allowComments*/ false, /*allowSourceMaps*/ true),
getNamespaceMemberName(currentNamespaceContainerName, exportName, /*allowComments*/ false, /*allowSourceMaps*/ true),
exportValue
),
location
);
}
function createExternalModuleExport(exportName: Identifier) {
return createExportDeclaration(
/*decorators*/ undefined,
/*modifiers*/ undefined,
createNamedExports([
createExportSpecifier(exportName)
])
);
}
function getNamespaceMemberName(name: Identifier, allowComments?: boolean, allowSourceMaps?: boolean): Expression {
const qualifiedName = createPropertyAccess(currentNamespaceContainerName, getSynthesizedClone(name), /*location*/ name);
let emitFlags: EmitFlags;
if (!allowComments) {
emitFlags |= EmitFlags.NoComments;
}
if (!allowSourceMaps) {
emitFlags |= EmitFlags.NoSourceMap;
}
if (emitFlags) {
setEmitFlags(qualifiedName, emitFlags);
}
return qualifiedName;
function createNamespaceExportExpression(exportName: Identifier, exportValue: Expression, location?: TextRange) {
return createAssignment(getNamespaceMemberNameWithSourceMapsAndWithoutComments(exportName), exportValue, location);
}
function getNamespaceMemberNameWithSourceMapsAndWithoutComments(name: Identifier) {
return getNamespaceMemberName(name, /*allowComments*/ false, /*allowSourceMaps*/ true);
return getNamespaceMemberName(currentNamespaceContainerName, name, /*allowComments*/ false, /*allowSourceMaps*/ true);
}
/**
@ -3265,65 +3180,17 @@ namespace ts {
}
/**
* Gets the local name for a declaration for use in expressions.
*
* A local name will *never* be prefixed with an module or namespace export modifier like
* "exports.".
*
* @param node The declaration.
* @param noSourceMaps A value indicating whether source maps may not be emitted for the name.
* @param allowComments A value indicating whether comments may be emitted for the name.
* Gets a local alias for a class declaration if it is a decorated class with an internal
* reference to the static side of the class. This is necessary to avoid issues with
* double-binding semantics for the class name.
*/
function getLocalName(node: FunctionDeclaration | ClassDeclaration | ClassExpression | ModuleDeclaration | EnumDeclaration, noSourceMaps?: boolean, allowComments?: boolean) {
return getDeclarationName(node, allowComments, !noSourceMaps, EmitFlags.LocalName);
}
/**
* Gets the export name for a declaration for use in expressions.
*
* An export name will *always* be prefixed with an module or namespace export modifier
* like "exports." if one is required.
*
* @param node The declaration.
* @param noSourceMaps A value indicating whether source maps may not be emitted for the name.
* @param allowComments A value indicating whether comments may be emitted for the name.
*/
function getExportName(node: FunctionDeclaration | ClassDeclaration | ClassExpression | ModuleDeclaration | EnumDeclaration, noSourceMaps?: boolean, allowComments?: boolean) {
if (isNamespaceExport(node)) {
return getNamespaceMemberName(getDeclarationName(node), allowComments, !noSourceMaps);
}
return getDeclarationName(node, allowComments, !noSourceMaps, EmitFlags.ExportName);
}
/**
* Gets the name for a declaration for use in declarations.
*
* @param node The declaration.
* @param allowComments A value indicating whether comments may be emitted for the name.
* @param allowSourceMaps A value indicating whether source maps may be emitted for the name.
* @param emitFlags Additional NodeEmitFlags to specify for the name.
*/
function getDeclarationName(node: FunctionDeclaration | ClassDeclaration | ClassExpression | ModuleDeclaration | EnumDeclaration, allowComments?: boolean, allowSourceMaps?: boolean, emitFlags?: EmitFlags) {
if (node.name) {
const name = getMutableClone(<Identifier>node.name);
emitFlags |= getEmitFlags(node.name);
if (!allowSourceMaps) {
emitFlags |= EmitFlags.NoSourceMap;
}
if (!allowComments) {
emitFlags |= EmitFlags.NoComments;
}
if (emitFlags) {
setEmitFlags(name, emitFlags);
}
return name;
}
else {
return getGeneratedNameForNode(node);
function getClassAliasIfNeeded(node: ClassDeclaration) {
if (resolver.getNodeCheckFlags(node) & NodeCheckFlags.ClassWithConstructorReference) {
enableSubstitutionForClassAliases();
const classAlias = createUniqueName(node.name && !isGeneratedIdentifier(node.name) ? node.name.text : "default");
classAliases[getOriginalNodeId(node)] = classAlias;
hoistVariableDeclaration(classAlias);
return classAlias;
}
}
@ -3382,6 +3249,7 @@ namespace ts {
/**
* Hook for node emit.
*
* @param emitContext A context hint for the emitter.
* @param node The node to emit.
* @param emit A callback used to emit the node in the printer.
*/
@ -3404,9 +3272,8 @@ namespace ts {
/**
* Hooks node substitutions.
*
* @param emitContext A context hint for the emitter.
* @param node The node to substitute.
* @param isExpression A value indicating whether the node is to be used in an expression
* position.
*/
function onSubstituteNode(emitContext: EmitContext, node: Node) {
node = previousOnSubstituteNode(emitContext, node);
@ -3482,11 +3349,11 @@ namespace ts {
function trySubstituteNamespaceExportedName(node: Identifier): Expression {
// If this is explicitly a local name, do not substitute.
if (enabledSubstitutions & applicableSubstitutions && (getEmitFlags(node) & EmitFlags.LocalName) === 0) {
if (enabledSubstitutions & applicableSubstitutions && !isLocalName(node)) {
// If we are nested within a namespace declaration, we may need to qualifiy
// an identifier that is exported from a merged namespace.
const container = resolver.getReferencedExportContainer(node, /*prefixLocals*/ false);
if (container) {
if (container && container.kind !== SyntaxKind.SourceFile) {
const substitute =
(applicableSubstitutions & TypeScriptSubstitutionFlags.NamespaceExports && container.kind === SyntaxKind.ModuleDeclaration) ||
(applicableSubstitutions & TypeScriptSubstitutionFlags.NonQualifiedEnumMembers && container.kind === SyntaxKind.EnumDeclaration);

View File

@ -31,6 +31,7 @@
"transformers/es2017.ts",
"transformers/es2016.ts",
"transformers/es2015.ts",
"transformers/es5.ts",
"transformers/generators.ts",
"transformers/es5.ts",
"transformers/destructuring.ts",

View File

@ -365,6 +365,8 @@ namespace ts {
// Transformation nodes
NotEmittedStatement,
PartiallyEmittedExpression,
MergeDeclarationMarker,
EndOfDeclarationMarker,
// Enum value count
Count,
@ -424,7 +426,7 @@ namespace ts {
ThisNodeHasError = 1 << 19, // If the parser encountered an error when parsing the code that created this node
JavaScriptFile = 1 << 20, // If node was parsed in a JavaScript
ThisNodeOrAnySubNodesHasError = 1 << 21, // If this node or any of its children had an error
HasAggregatedChildData = 1 << 22, // If we've computed data from children and cached it in this node
HasAggregatedChildData = 1 << 22, // If we've computed data from children and cached it in this node
BlockScoped = Let | Const,
@ -459,7 +461,8 @@ namespace ts {
ParameterPropertyModifier = AccessibilityModifier | Readonly,
NonPublicAccessibilityModifier = Private | Protected,
TypeScriptModifier = Ambient | Public | Private | Protected | Readonly | Abstract | Const
TypeScriptModifier = Ambient | Public | Private | Protected | Readonly | Abstract | Const,
ExportDefault = Export | Default,
}
export const enum JsxFlags {
@ -547,6 +550,7 @@ namespace ts {
originalKeywordKind?: SyntaxKind; // Original syntaxKind which get set so that we can report an error later
/*@internal*/ autoGenerateKind?: GeneratedIdentifierKind; // Specifies whether to auto-generate the text for an identifier.
/*@internal*/ autoGenerateId?: number; // Ensures unique generated identifiers get unique names, but clones get the same name.
isInJSDocNamespace?: boolean; // if the node is a member in a JSDoc namespace
}
// Transient identifier node (marked by id === -1)
@ -554,6 +558,14 @@ namespace ts {
resolvedSymbol: Symbol;
}
/*@internal*/
export interface GeneratedIdentifier extends Identifier {
autoGenerateKind: GeneratedIdentifierKind.Auto
| GeneratedIdentifierKind.Loop
| GeneratedIdentifierKind.Unique
| GeneratedIdentifierKind.Node;
}
export interface QualifiedName extends Node {
kind: SyntaxKind.QualifiedName;
left: EntityName;
@ -1159,6 +1171,21 @@ namespace ts {
right: Expression;
}
export interface AssignmentExpression extends BinaryExpression {
left: LeftHandSideExpression;
operatorToken: Token<SyntaxKind.EqualsToken>;
}
export interface ObjectDestructuringAssignment extends AssignmentExpression {
left: ObjectLiteralExpression;
}
export interface ArrayDestructuringAssignment extends AssignmentExpression {
left: ArrayLiteralExpression;
}
export type DestructuringAssignment = ObjectDestructuringAssignment | ArrayDestructuringAssignment;
export interface ConditionalExpression extends Expression {
kind: SyntaxKind.ConditionalExpression;
condition: Expression;
@ -1432,6 +1459,22 @@ namespace ts {
kind: SyntaxKind.NotEmittedStatement;
}
/**
* Marks the end of transformed declaration to properly emit exports.
*/
/* @internal */
export interface EndOfDeclarationMarker extends Statement {
kind: SyntaxKind.EndOfDeclarationMarker;
}
/**
* Marks the beginning of a merged transformed declaration.
*/
/* @internal */
export interface MergeDeclarationMarker extends Statement {
kind: SyntaxKind.MergeDeclarationMarker;
}
export interface EmptyStatement extends Statement {
kind: SyntaxKind.EmptyStatement;
}
@ -1648,7 +1691,7 @@ namespace ts {
export interface ModuleDeclaration extends DeclarationStatement {
kind: SyntaxKind.ModuleDeclaration;
name: Identifier | LiteralExpression;
body?: ModuleBlock | NamespaceDeclaration;
body?: ModuleBlock | NamespaceDeclaration | JSDocNamespaceDeclaration | Identifier;
}
export interface NamespaceDeclaration extends ModuleDeclaration {
@ -1656,6 +1699,11 @@ namespace ts {
body: ModuleBlock | NamespaceDeclaration;
}
export interface JSDocNamespaceDeclaration extends ModuleDeclaration {
name: Identifier;
body: JSDocNamespaceDeclaration | Identifier;
}
export interface ModuleBlock extends Node, Statement {
kind: SyntaxKind.ModuleBlock;
statements: NodeArray<Statement>;
@ -1885,6 +1933,7 @@ namespace ts {
export interface JSDocTypedefTag extends JSDocTag, Declaration {
kind: SyntaxKind.JSDocTypedefTag;
fullName?: JSDocNamespaceDeclaration | Identifier;
name?: Identifier;
typeExpression?: JSDocTypeExpression;
jsDocTypeLiteral?: JSDocTypeLiteral;
@ -3064,6 +3113,7 @@ namespace ts {
packageNameToTypingLocation: Map<string>; // The map of package names to their cached typing locations
typingOptions: TypingOptions; // Used to customize the typing inference process
compilerOptions: CompilerOptions; // Used as a source for typing inference
unresolvedImports: ReadonlyArray<string>; // List of unresolved module ids from imports
}
export enum ModuleKind {
@ -3327,10 +3377,21 @@ namespace ts {
getDirectories?(path: string): string[];
}
/**
* Represents the result of module resolution.
* Module resolution will pick up tsx/jsx/js files even if '--jsx' and '--allowJs' are turned off.
* The Program will then filter results based on these flags.
*
* At least one of `resolvedTsFileName` or `resolvedJsFileName` must be defined,
* else resolution should just return `undefined` instead of a ResolvedModule.
*/
export interface ResolvedModule {
/** Path of the file the module was resolved to. */
resolvedFileName: string;
/*
* Denotes if 'resolvedFileName' is isExternalLibraryImport and thus should be proper external module:
/** Extension of resolvedFileName. This must match what's at the end of resolvedFileName. */
extension: Extension;
/**
* Denotes if 'resolvedFileName' is isExternalLibraryImport and thus should be a proper external module:
* - be a .d.ts file
* - use top level imports\exports
* - don't use tripleslash references
@ -3338,8 +3399,17 @@ namespace ts {
isExternalLibraryImport?: boolean;
}
export enum Extension {
Ts,
Tsx,
Dts,
Js,
Jsx,
LastTypeScriptExtension = Dts
}
export interface ResolvedModuleWithFailedLookupLocations {
resolvedModule: ResolvedModule;
resolvedModule: ResolvedModule | undefined;
failedLookupLocations: string[];
}
@ -3401,25 +3471,26 @@ namespace ts {
ContainsES2016 = 1 << 9,
ES2015 = 1 << 10,
ContainsES2015 = 1 << 11,
DestructuringAssignment = 1 << 12,
Generator = 1 << 13,
ContainsGenerator = 1 << 14,
Generator = 1 << 12,
ContainsGenerator = 1 << 13,
DestructuringAssignment = 1 << 14,
ContainsDestructuringAssignment = 1 << 15,
// Markers
// - Flags used to indicate that a subtree contains a specific transformation.
ContainsDecorators = 1 << 15,
ContainsPropertyInitializer = 1 << 16,
ContainsLexicalThis = 1 << 17,
ContainsCapturedLexicalThis = 1 << 18,
ContainsLexicalThisInComputedPropertyName = 1 << 19,
ContainsDefaultValueAssignments = 1 << 20,
ContainsParameterPropertyAssignments = 1 << 21,
ContainsSpreadExpression = 1 << 22,
ContainsComputedPropertyName = 1 << 23,
ContainsBlockScopedBinding = 1 << 24,
ContainsBindingPattern = 1 << 25,
ContainsYield = 1 << 26,
ContainsHoistedDeclarationOrCompletion = 1 << 27,
ContainsDecorators = 1 << 16,
ContainsPropertyInitializer = 1 << 17,
ContainsLexicalThis = 1 << 18,
ContainsCapturedLexicalThis = 1 << 19,
ContainsLexicalThisInComputedPropertyName = 1 << 20,
ContainsDefaultValueAssignments = 1 << 21,
ContainsParameterPropertyAssignments = 1 << 22,
ContainsSpreadExpression = 1 << 23,
ContainsComputedPropertyName = 1 << 24,
ContainsBlockScopedBinding = 1 << 25,
ContainsBindingPattern = 1 << 26,
ContainsYield = 1 << 27,
ContainsHoistedDeclarationOrCompletion = 1 << 28,
HasComputedFlags = 1 << 29, // Transform flags have been computed.
@ -3432,6 +3503,7 @@ namespace ts {
AssertES2016 = ES2016 | ContainsES2016,
AssertES2015 = ES2015 | ContainsES2015,
AssertGenerator = Generator | ContainsGenerator,
AssertDestructuringAssignment = DestructuringAssignment | ContainsDestructuringAssignment,
// Scope Exclusions
// - Bitmasks that exclude flags from propagating out of a specific context
@ -3494,6 +3566,8 @@ namespace ts {
AsyncFunctionBody = 1 << 21,
ReuseTempVariableScope = 1 << 22, // Reuse the existing temp variable scope during emit.
CustomPrologue = 1 << 23, // Treat the statement as if it were a prologue directive (NOTE: Prologue directives are *not* transformed).
NoHoisting = 1 << 24, // Do not hoist this declaration in --module system
HasEndOfDeclarationMarker = 1 << 25, // Declaration has an associated NotEmittedStatement to mark the end of the declaration
}
/* @internal */

View File

@ -83,25 +83,6 @@ namespace ts {
return node.end - node.pos;
}
export function arrayIsEqualTo<T>(array1: ReadonlyArray<T>, array2: ReadonlyArray<T>, equaler?: (a: T, b: T) => boolean): boolean {
if (!array1 || !array2) {
return array1 === array2;
}
if (array1.length !== array2.length) {
return false;
}
for (let i = 0; i < array1.length; i++) {
const equals = equaler ? equaler(array1[i], array2[i]) : array1[i] === array2[i];
if (!equals) {
return false;
}
}
return true;
}
export function hasResolvedModule(sourceFile: SourceFile, moduleNameText: string): boolean {
return !!(sourceFile && sourceFile.resolvedModules && sourceFile.resolvedModules[moduleNameText]);
}
@ -127,8 +108,14 @@ namespace ts {
}
/* @internal */
/**
* Considers two ResolvedModules equal if they have the same `resolvedFileName`.
* Thus `{ ts: foo, js: bar }` is equal to `{ ts: foo, js: baz }` because `ts` is preferred.
*/
export function moduleResolutionIsEqualTo(oldResolution: ResolvedModule, newResolution: ResolvedModule): boolean {
return oldResolution.resolvedFileName === newResolution.resolvedFileName && oldResolution.isExternalLibraryImport === newResolution.isExternalLibraryImport;
return oldResolution.isExternalLibraryImport === newResolution.isExternalLibraryImport &&
oldResolution.extension === newResolution.extension &&
oldResolution.resolvedFileName === newResolution.resolvedFileName;
}
/* @internal */
@ -1951,14 +1938,16 @@ namespace ts {
|| positionIsSynthesized(node.end);
}
export function getOriginalNode(node: Node): Node {
export function getOriginalNode(node: Node): Node;
export function getOriginalNode<T extends Node>(node: Node, nodeTest: (node: Node) => node is T): T;
export function getOriginalNode(node: Node, nodeTest?: (node: Node) => boolean): Node {
if (node) {
while (node.original !== undefined) {
node = node.original;
}
}
return node;
return !nodeTest || nodeTest(node) ? node : undefined;
}
/**
@ -3036,7 +3025,7 @@ namespace ts {
}
}
if (node.flags & NodeFlags.NestedNamespace) {
if (node.flags & NodeFlags.NestedNamespace || (node.kind === SyntaxKind.Identifier && (<Identifier>node).isInJSDocNamespace)) {
flags |= ModifierFlags.Export;
}
@ -3080,7 +3069,13 @@ namespace ts {
}
}
export function isDestructuringAssignment(node: Node): node is BinaryExpression {
export function isAssignmentExpression(node: Node): node is AssignmentExpression {
return isBinaryExpression(node)
&& isAssignmentOperator(node.operatorToken.kind)
&& isLeftHandSideExpression(node.left);
}
export function isDestructuringAssignment(node: Node): node is DestructuringAssignment {
if (isBinaryExpression(node)) {
if (node.operatorToken.kind === SyntaxKind.EqualsToken) {
const kind = node.left.kind;
@ -3504,9 +3499,21 @@ namespace ts {
return positionIsSynthesized(range.pos) ? -1 : skipTrivia(sourceFile.text, range.pos);
}
export function collectExternalModuleInfo(sourceFile: SourceFile) {
export interface ExternalModuleInfo {
externalImports: (ImportDeclaration | ImportEqualsDeclaration | ExportDeclaration)[]; // imports of other external modules
exportSpecifiers: Map<ExportSpecifier[]>; // export specifiers by name
exportedBindings: Map<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*
}
export function collectExternalModuleInfo(sourceFile: SourceFile, resolver: EmitResolver): ExternalModuleInfo {
const externalImports: (ImportDeclaration | ImportEqualsDeclaration | ExportDeclaration)[] = [];
const exportSpecifiers = createMap<ExportSpecifier[]>();
const exportedBindings = createMap<Identifier[]>();
const uniqueExports = createMap<Identifier>();
let hasExportDefault = false;
let exportEquals: ExportAssignment = undefined;
let hasExportStarsToExportValues = false;
for (const node of sourceFile.statements) {
@ -3524,6 +3531,7 @@ namespace ts {
// import x = require("mod")
externalImports.push(<ImportEqualsDeclaration>node);
}
break;
case SyntaxKind.ExportDeclaration:
@ -3541,8 +3549,19 @@ namespace ts {
else {
// export { x, y }
for (const specifier of (<ExportDeclaration>node).exportClause.elements) {
const name = (specifier.propertyName || specifier.name).text;
(exportSpecifiers[name] || (exportSpecifiers[name] = [])).push(specifier);
if (!uniqueExports[specifier.name.text]) {
const name = specifier.propertyName || specifier.name;
multiMapAdd(exportSpecifiers, name.text, specifier);
const decl = resolver.getReferencedImportDeclaration(name)
|| resolver.getReferencedValueDeclaration(name);
if (decl) {
multiMapAdd(exportedBindings, getOriginalNodeId(decl), specifier.name);
}
uniqueExports[specifier.name.text] = specifier.name;
}
}
}
break;
@ -3553,10 +3572,94 @@ namespace ts {
exportEquals = <ExportAssignment>node;
}
break;
case SyntaxKind.VariableStatement:
if (hasModifier(node, ModifierFlags.Export)) {
for (const decl of (<VariableStatement>node).declarationList.declarations) {
collectExportedVariableInfo(decl, uniqueExports);
}
}
break;
case SyntaxKind.FunctionDeclaration:
if (hasModifier(node, ModifierFlags.Export)) {
if (hasModifier(node, ModifierFlags.Default)) {
// export default function() { }
if (!hasExportDefault) {
multiMapAdd(exportedBindings, getOriginalNodeId(node), getDeclarationName(<FunctionDeclaration>node));
hasExportDefault = true;
}
}
else {
// export function x() { }
const name = (<FunctionDeclaration>node).name;
if (!uniqueExports[name.text]) {
multiMapAdd(exportedBindings, getOriginalNodeId(node), name);
uniqueExports[name.text] = name;
}
}
}
break;
case SyntaxKind.ClassDeclaration:
if (hasModifier(node, ModifierFlags.Export)) {
if (hasModifier(node, ModifierFlags.Default)) {
// export default class { }
if (!hasExportDefault) {
multiMapAdd(exportedBindings, getOriginalNodeId(node), getDeclarationName(<ClassDeclaration>node));
hasExportDefault = true;
}
}
else {
// export class x { }
const name = (<ClassDeclaration>node).name;
if (!uniqueExports[name.text]) {
multiMapAdd(exportedBindings, getOriginalNodeId(node), name);
uniqueExports[name.text] = name;
}
}
}
break;
}
}
return { externalImports, exportSpecifiers, exportEquals, hasExportStarsToExportValues };
let exportedNames: Identifier[];
for (const key in uniqueExports) {
exportedNames = ts.append(exportedNames, uniqueExports[key]);
}
return { externalImports, exportSpecifiers, exportEquals, hasExportStarsToExportValues, exportedBindings, exportedNames };
}
function collectExportedVariableInfo(decl: VariableDeclaration | BindingElement, uniqueExports: Map<Identifier>) {
if (isBindingPattern(decl.name)) {
for (const element of decl.name.elements) {
if (!isOmittedExpression(element)) {
collectExportedVariableInfo(element, uniqueExports);
}
}
}
else if (!isGeneratedIdentifier(decl.name)) {
if (!uniqueExports[decl.name.text]) {
uniqueExports[decl.name.text] = decl.name;
}
}
}
/**
* Determines whether a name was originally the declaration name of an enum or namespace
* declaration.
*/
export function isDeclarationNameOfEnumOrNamespace(node: Identifier) {
const parseNode = getParseTreeNode(node);
if (parseNode) {
switch (parseNode.parent.kind) {
case SyntaxKind.EnumDeclaration:
case SyntaxKind.ModuleDeclaration:
return parseNode === (<EnumDeclaration | ModuleDeclaration>parseNode.parent).name;
}
}
return false;
}
export function getInitializedVariables(node: VariableDeclarationList) {
@ -3644,7 +3747,7 @@ namespace ts {
return node.kind === SyntaxKind.Identifier;
}
export function isGeneratedIdentifier(node: Node): boolean {
export function isGeneratedIdentifier(node: Node): node is GeneratedIdentifier {
// Using `>` here catches both `GeneratedIdentifierKind.None` and `undefined`.
return isIdentifier(node) && node.autoGenerateKind > GeneratedIdentifierKind.None;
}
@ -3781,6 +3884,14 @@ namespace ts {
// Expression
export function isArrayLiteralExpression(node: Node): node is ArrayLiteralExpression {
return node.kind === SyntaxKind.ArrayLiteralExpression;
}
export function isObjectLiteralExpression(node: Node): node is ObjectLiteralExpression {
return node.kind === SyntaxKind.ObjectLiteralExpression;
}
export function isPropertyAccessExpression(node: Node): node is PropertyAccessExpression {
return node.kind === SyntaxKind.PropertyAccessExpression;
}
@ -4040,7 +4151,9 @@ namespace ts {
|| kind === SyntaxKind.VariableStatement
|| kind === SyntaxKind.WhileStatement
|| kind === SyntaxKind.WithStatement
|| kind === SyntaxKind.NotEmittedStatement;
|| kind === SyntaxKind.NotEmittedStatement
|| kind === SyntaxKind.EndOfDeclarationMarker
|| kind === SyntaxKind.MergeDeclarationMarker;
}
export function isDeclaration(node: Node): node is Declaration {

View File

@ -692,7 +692,7 @@ namespace ts {
// Signature elements
case SyntaxKind.Parameter:
return updateParameterDeclaration(<ParameterDeclaration>node,
return updateParameter(<ParameterDeclaration>node,
visitNodes((<ParameterDeclaration>node).decorators, visitor, isDecorator),
visitNodes((<ParameterDeclaration>node).modifiers, visitor, isModifier),
visitNode((<ParameterDeclaration>node).name, visitor, isBindingName),

View File

@ -1238,7 +1238,7 @@ namespace Harness {
if (options.declaration && result.errors.length === 0 && result.declFilesCode.length > 0) {
ts.forEach(inputFiles, file => addDtsFile(file, declInputFiles));
ts.forEach(otherFiles, file => addDtsFile(file, declOtherFiles));
const output = compileFiles(declInputFiles, declOtherFiles, harnessSettings, options, currentDirectory);
const output = compileFiles(declInputFiles, declOtherFiles, harnessSettings, options, currentDirectory || harnessSettings["currentDirectory"]);
return { declInputFiles, declOtherFiles, declResult: output.result };
}

View File

@ -33,6 +33,7 @@
"../compiler/transformers/es2017.ts",
"../compiler/transformers/es2016.ts",
"../compiler/transformers/es2015.ts",
"../compiler/transformers/es5.ts",
"../compiler/transformers/generators.ts",
"../compiler/transformers/es5.ts",
"../compiler/transformers/destructuring.ts",

View File

@ -1,6 +1,28 @@
/// <reference path="..\harness.ts" />
namespace ts {
export function checkResolvedModule(expected: ResolvedModule, actual: ResolvedModule): boolean {
if (!expected === !actual) {
if (expected) {
assert.isTrue(expected.resolvedFileName === actual.resolvedFileName, `'resolvedFileName': expected '${expected.resolvedFileName}' to be equal to '${actual.resolvedFileName}'`);
assert.isTrue(expected.extension === actual.extension, `'ext': expected '${Extension[expected.extension]}' to be equal to '${Extension[actual.extension]}'`);
assert.isTrue(expected.isExternalLibraryImport === actual.isExternalLibraryImport, `'isExternalLibraryImport': expected '${expected.isExternalLibraryImport}' to be equal to '${actual.isExternalLibraryImport}'`);
}
return true;
}
return false;
}
export function checkResolvedModuleWithFailedLookupLocations(actual: ResolvedModuleWithFailedLookupLocations, expectedResolvedModule: ResolvedModule, expectedFailedLookupLocations: string[]): void {
assert.isTrue(actual.resolvedModule !== undefined, "module should be resolved");
checkResolvedModule(actual.resolvedModule, expectedResolvedModule);
assert.deepEqual(actual.failedLookupLocations, expectedFailedLookupLocations);
}
export function createResolvedModule(resolvedFileName: string, isExternalLibraryImport = false): ResolvedModule {
return { resolvedFileName, extension: extensionFromPath(resolvedFileName), isExternalLibraryImport };
}
interface File {
name: string;
content?: string;
@ -53,8 +75,7 @@ namespace ts {
const containingFile = { name: containingFileName };
const moduleFile = { name: moduleFileNameNoExt + ext };
const resolution = nodeModuleNameResolver(moduleName, containingFile.name, {}, createModuleResolutionHost(hasDirectoryExists, containingFile, moduleFile));
assert.equal(resolution.resolvedModule.resolvedFileName, moduleFile.name);
assert.equal(!!resolution.resolvedModule.isExternalLibraryImport, false);
checkResolvedModule(resolution.resolvedModule, createResolvedModule(moduleFile.name));
const failedLookupLocations: string[] = [];
const dir = getDirectoryPath(containingFileName);
@ -97,8 +118,7 @@ namespace ts {
const packageJson = { name: packageJsonFileName, content: JSON.stringify({ "typings": fieldRef }) };
const moduleFile = { name: moduleFileName };
const resolution = nodeModuleNameResolver(moduleName, containingFile.name, {}, createModuleResolutionHost(hasDirectoryExists, containingFile, packageJson, moduleFile));
assert.equal(resolution.resolvedModule.resolvedFileName, moduleFile.name);
assert.equal(!!resolution.resolvedModule.isExternalLibraryImport, false);
checkResolvedModule(resolution.resolvedModule, createResolvedModule(moduleFile.name));
// expect three failed lookup location - attempt to load module as file with all supported extensions
assert.equal(resolution.failedLookupLocations.length, supportedTypeScriptExtensions.length);
}
@ -125,7 +145,7 @@ namespace ts {
const resolution = nodeModuleNameResolver("b", containingFile.name, {}, createModuleResolutionHost(hasDirectoryExists, containingFile, packageJson, moduleFile, indexFile));
assert.equal(resolution.resolvedModule.resolvedFileName, indexPath);
checkResolvedModule(resolution.resolvedModule, createResolvedModule(indexPath, /*isExternalLibraryImport*/true));
}
}
@ -138,7 +158,6 @@ namespace ts {
/* tslint:enable no-null-keyword */
testTypingsIgnored(undefined);
});
it("module name as directory - load index.d.ts", () => {
test(/*hasDirectoryExists*/ false);
test(/*hasDirectoryExists*/ true);
@ -148,9 +167,7 @@ namespace ts {
const packageJson = { name: "/a/b/foo/package.json", content: JSON.stringify({ main: "/c/d" }) };
const indexFile = { name: "/a/b/foo/index.d.ts" };
const resolution = nodeModuleNameResolver("./foo", containingFile.name, {}, createModuleResolutionHost(hasDirectoryExists, containingFile, packageJson, indexFile));
assert.equal(resolution.resolvedModule.resolvedFileName, indexFile.name);
assert.equal(!!resolution.resolvedModule.isExternalLibraryImport, false);
assert.deepEqual(resolution.failedLookupLocations, [
checkResolvedModuleWithFailedLookupLocations(resolution, createResolvedModule(indexFile.name), [
"/a/b/foo.ts",
"/a/b/foo.tsx",
"/a/b/foo.d.ts",
@ -170,33 +187,39 @@ namespace ts {
const containingFile = { name: "/a/b/c/d/e.ts" };
const moduleFile = { name: "/a/b/node_modules/foo.ts" };
const resolution = nodeModuleNameResolver("foo", containingFile.name, {}, createModuleResolutionHost(hasDirectoryExists, containingFile, moduleFile));
assert.equal(resolution.resolvedModule.resolvedFileName, moduleFile.name);
assert.deepEqual(resolution.failedLookupLocations, [
checkResolvedModuleWithFailedLookupLocations(resolution, createResolvedModule(moduleFile.name, /*isExternalLibraryImport*/ true), [
"/a/b/c/d/node_modules/foo.ts",
"/a/b/c/d/node_modules/foo.tsx",
"/a/b/c/d/node_modules/foo.d.ts",
"/a/b/c/d/node_modules/foo/package.json",
"/a/b/c/d/node_modules/foo/index.ts",
"/a/b/c/d/node_modules/foo/index.tsx",
"/a/b/c/d/node_modules/foo/index.d.ts",
"/a/b/c/d/node_modules/@types/foo.ts",
"/a/b/c/d/node_modules/@types/foo.tsx",
"/a/b/c/d/node_modules/@types/foo.d.ts",
"/a/b/c/d/node_modules/@types/foo/package.json",
"/a/b/c/d/node_modules/@types/foo/index.ts",
"/a/b/c/d/node_modules/@types/foo/index.tsx",
"/a/b/c/d/node_modules/@types/foo/index.d.ts",
"/a/b/c/node_modules/foo.ts",
"/a/b/c/node_modules/foo.tsx",
"/a/b/c/node_modules/foo.d.ts",
"/a/b/c/node_modules/foo/package.json",
"/a/b/c/node_modules/foo/index.ts",
"/a/b/c/node_modules/foo/index.tsx",
"/a/b/c/node_modules/foo/index.d.ts",
"/a/b/c/node_modules/@types/foo.ts",
"/a/b/c/node_modules/@types/foo.tsx",
"/a/b/c/node_modules/@types/foo.d.ts",
"/a/b/c/node_modules/@types/foo/package.json",
"/a/b/c/node_modules/@types/foo/index.ts",
"/a/b/c/node_modules/@types/foo/index.tsx",
"/a/b/c/node_modules/@types/foo/index.d.ts",
@ -212,8 +235,7 @@ namespace ts {
const containingFile = { name: "/a/b/c/d/e.ts" };
const moduleFile = { name: "/a/b/node_modules/foo.d.ts" };
const resolution = nodeModuleNameResolver("foo", containingFile.name, {}, createModuleResolutionHost(hasDirectoryExists, containingFile, moduleFile));
assert.equal(resolution.resolvedModule.resolvedFileName, moduleFile.name);
assert.equal(resolution.resolvedModule.isExternalLibraryImport, true);
checkResolvedModule(resolution.resolvedModule, createResolvedModule(moduleFile.name, /*isExternalLibraryImport*/ true));
}
});
@ -225,55 +247,66 @@ namespace ts {
const containingFile = { name: "/a/node_modules/b/c/node_modules/d/e.ts" };
const moduleFile = { name: "/a/node_modules/foo/index.d.ts" };
const resolution = nodeModuleNameResolver("foo", containingFile.name, {}, createModuleResolutionHost(hasDirectoryExists, containingFile, moduleFile));
assert.equal(resolution.resolvedModule.resolvedFileName, moduleFile.name);
assert.equal(resolution.resolvedModule.isExternalLibraryImport, true);
assert.deepEqual(resolution.failedLookupLocations, [
checkResolvedModuleWithFailedLookupLocations(resolution, createResolvedModule(moduleFile.name, /*isExternalLibraryImport*/ true), [
"/a/node_modules/b/c/node_modules/d/node_modules/foo.ts",
"/a/node_modules/b/c/node_modules/d/node_modules/foo.tsx",
"/a/node_modules/b/c/node_modules/d/node_modules/foo.d.ts",
"/a/node_modules/b/c/node_modules/d/node_modules/foo/package.json",
"/a/node_modules/b/c/node_modules/d/node_modules/foo/index.ts",
"/a/node_modules/b/c/node_modules/d/node_modules/foo/index.tsx",
"/a/node_modules/b/c/node_modules/d/node_modules/foo/index.d.ts",
"/a/node_modules/b/c/node_modules/d/node_modules/@types/foo.ts",
"/a/node_modules/b/c/node_modules/d/node_modules/@types/foo.tsx",
"/a/node_modules/b/c/node_modules/d/node_modules/@types/foo.d.ts",
"/a/node_modules/b/c/node_modules/d/node_modules/@types/foo/package.json",
"/a/node_modules/b/c/node_modules/d/node_modules/@types/foo/index.ts",
"/a/node_modules/b/c/node_modules/d/node_modules/@types/foo/index.tsx",
"/a/node_modules/b/c/node_modules/d/node_modules/@types/foo/index.d.ts",
"/a/node_modules/b/c/node_modules/foo.ts",
"/a/node_modules/b/c/node_modules/foo.tsx",
"/a/node_modules/b/c/node_modules/foo.d.ts",
"/a/node_modules/b/c/node_modules/foo/package.json",
"/a/node_modules/b/c/node_modules/foo/index.ts",
"/a/node_modules/b/c/node_modules/foo/index.tsx",
"/a/node_modules/b/c/node_modules/foo/index.d.ts",
"/a/node_modules/b/c/node_modules/@types/foo.ts",
"/a/node_modules/b/c/node_modules/@types/foo.tsx",
"/a/node_modules/b/c/node_modules/@types/foo.d.ts",
"/a/node_modules/b/c/node_modules/@types/foo/package.json",
"/a/node_modules/b/c/node_modules/@types/foo/index.ts",
"/a/node_modules/b/c/node_modules/@types/foo/index.tsx",
"/a/node_modules/b/c/node_modules/@types/foo/index.d.ts",
"/a/node_modules/b/node_modules/foo.ts",
"/a/node_modules/b/node_modules/foo.tsx",
"/a/node_modules/b/node_modules/foo.d.ts",
"/a/node_modules/b/node_modules/foo/package.json",
"/a/node_modules/b/node_modules/foo/index.ts",
"/a/node_modules/b/node_modules/foo/index.tsx",
"/a/node_modules/b/node_modules/foo/index.d.ts",
"/a/node_modules/b/node_modules/@types/foo.ts",
"/a/node_modules/b/node_modules/@types/foo.tsx",
"/a/node_modules/b/node_modules/@types/foo.d.ts",
"/a/node_modules/b/node_modules/@types/foo/package.json",
"/a/node_modules/b/node_modules/@types/foo/index.ts",
"/a/node_modules/b/node_modules/@types/foo/index.tsx",
"/a/node_modules/b/node_modules/@types/foo/index.d.ts",
"/a/node_modules/foo.ts",
"/a/node_modules/foo.tsx",
"/a/node_modules/foo.d.ts",
"/a/node_modules/foo/package.json",
"/a/node_modules/foo/index.ts",
"/a/node_modules/foo/index.tsx"
]);
@ -481,21 +514,15 @@ import b = require("./moduleB");
const options: CompilerOptions = { moduleResolution, baseUrl: "/root" };
{
const result = resolveModuleName("folder2/file2", file1.name, options, host);
assert.isTrue(result.resolvedModule !== undefined, "module should be resolved");
assert.equal(result.resolvedModule.resolvedFileName, file2.name);
assert.deepEqual(result.failedLookupLocations, []);
checkResolvedModuleWithFailedLookupLocations(result, createResolvedModule(file2.name), []);
}
{
const result = resolveModuleName("./file3", file2.name, options, host);
assert.isTrue(result.resolvedModule !== undefined, "module should be resolved");
assert.equal(result.resolvedModule.resolvedFileName, file3.name);
assert.deepEqual(result.failedLookupLocations, []);
checkResolvedModuleWithFailedLookupLocations(result, createResolvedModule(file3.name), []);
}
{
const result = resolveModuleName("/root/folder1/file1", file2.name, options, host);
assert.isTrue(result.resolvedModule !== undefined, "module should be resolved");
assert.equal(result.resolvedModule.resolvedFileName, file1.name);
assert.deepEqual(result.failedLookupLocations, []);
checkResolvedModuleWithFailedLookupLocations(result, createResolvedModule(file1.name), []);
}
}
}
@ -520,12 +547,11 @@ import b = require("./moduleB");
check("m1", main, m1);
check("m2", main, m2);
check("m3", main, m3Typings);
check("m4", main, m4);
check("m4", main, m4, /*isExternalLibraryImport*/true);
function check(name: string, caller: File, expected: File) {
function check(name: string, caller: File, expected: File, isExternalLibraryImport = false) {
const result = resolveModuleName(name, caller.name, options, host);
assert.isTrue(result.resolvedModule !== undefined);
assert.equal(result.resolvedModule.resolvedFileName, expected.name);
checkResolvedModule(result.resolvedModule, createResolvedModule(expected.name, isExternalLibraryImport));
}
}
});
@ -547,8 +573,7 @@ import b = require("./moduleB");
function check(name: string, caller: File, expected: File) {
const result = resolveModuleName(name, caller.name, options, host);
assert.isTrue(result.resolvedModule !== undefined);
assert.equal(result.resolvedModule.resolvedFileName, expected.name);
checkResolvedModule(result.resolvedModule, createResolvedModule(expected.name));
}
}
});
@ -590,9 +615,10 @@ import b = require("./moduleB");
"/root/folder1/file2.tsx",
"/root/folder1/file2.d.ts",
"/root/folder1/file2/package.json",
"/root/folder1/file2/index.ts",
"/root/folder1/file2/index.tsx",
"/root/folder1/file2/index.d.ts"
"/root/folder1/file2/index.d.ts",
// then first attempt on 'generated/*' was successful
]);
check("folder2/file3", file3, [
@ -601,14 +627,17 @@ import b = require("./moduleB");
"/root/folder2/file3.tsx",
"/root/folder2/file3.d.ts",
"/root/folder2/file3/package.json",
"/root/folder2/file3/index.ts",
"/root/folder2/file3/index.tsx",
"/root/folder2/file3/index.d.ts",
// then use remapped location
"/root/generated/folder2/file3.ts",
"/root/generated/folder2/file3.tsx",
"/root/generated/folder2/file3.d.ts",
"/root/generated/folder2/file3/package.json",
"/root/generated/folder2/file3/index.ts",
"/root/generated/folder2/file3/index.tsx",
// success on index.d.ts
@ -619,13 +648,15 @@ import b = require("./moduleB");
"/root/folder2/file4.tsx",
"/root/folder2/file4.d.ts",
"/root/folder2/file4/package.json",
"/root/folder2/file4/index.ts",
"/root/folder2/file4/index.tsx",
"/root/folder2/file4/index.d.ts",
// try to load from file from remapped location
"/root/generated/folder2/file4.ts",
"/root/generated/folder2/file4.tsx",
"/root/generated/folder2/file4.d.ts"
"/root/generated/folder2/file4.d.ts",
// success on loading as from folder
]);
check("somefolder/file5", file5, [
@ -634,6 +665,7 @@ import b = require("./moduleB");
"/root/someanotherfolder/file5.ts",
"/root/someanotherfolder/file5.tsx",
"/root/someanotherfolder/file5.d.ts",
// load from folder
"/root/someanotherfolder/file5/package.json",
"/root/someanotherfolder/file5/index.ts",
@ -646,46 +678,51 @@ import b = require("./moduleB");
"/root/file6.ts",
"/root/file6.tsx",
"/root/file6.d.ts",
// load from folder
"/root/file6/package.json",
"/root/file6/index.ts",
"/root/file6/index.tsx",
"/root/file6/index.d.ts",
// then try 'generated/*'
// load from file
"/root/generated/file6.ts",
"/root/generated/file6.tsx",
"/root/generated/file6.d.ts",
// load from folder
"/root/generated/file6/package.json",
"/root/generated/file6/index.ts",
"/root/generated/file6/index.tsx",
"/root/generated/file6/index.d.ts",
// fallback to standard node behavior
// load from file
"/root/folder1/node_modules/file6.ts",
"/root/folder1/node_modules/file6.tsx",
"/root/folder1/node_modules/file6.d.ts",
// load from folder
"/root/folder1/node_modules/file6/package.json",
"/root/folder1/node_modules/file6/index.ts",
"/root/folder1/node_modules/file6/index.tsx",
"/root/folder1/node_modules/file6/index.d.ts",
"/root/folder1/node_modules/@types/file6.ts",
"/root/folder1/node_modules/@types/file6.tsx",
"/root/folder1/node_modules/@types/file6.d.ts",
"/root/folder1/node_modules/@types/file6/package.json",
"/root/folder1/node_modules/@types/file6/index.ts",
"/root/folder1/node_modules/@types/file6/index.tsx",
"/root/folder1/node_modules/@types/file6/index.d.ts"
"/root/folder1/node_modules/@types/file6/index.d.ts",
// success on /root/node_modules/file6.ts
]);
], /*isExternalLibraryImport*/ true);
function check(name: string, expected: File, expectedFailedLookups: string[]) {
function check(name: string, expected: File, expectedFailedLookups: string[], isExternalLibraryImport = false) {
const result = resolveModuleName(name, main.name, options, host);
assert.isTrue(result.resolvedModule !== undefined, "module should be resolved");
assert.equal(result.resolvedModule.resolvedFileName, expected.name);
assert.deepEqual(result.failedLookupLocations, expectedFailedLookups);
checkResolvedModuleWithFailedLookupLocations(result, createResolvedModule(expected.name, isExternalLibraryImport), expectedFailedLookups);
}
}
});
@ -744,9 +781,7 @@ import b = require("./moduleB");
function check(name: string, expected: File, expectedFailedLookups: string[]) {
const result = resolveModuleName(name, main.name, options, host);
assert.isTrue(result.resolvedModule !== undefined, "module should be resolved");
assert.equal(result.resolvedModule.resolvedFileName, expected.name);
assert.deepEqual(result.failedLookupLocations, expectedFailedLookups);
checkResolvedModuleWithFailedLookupLocations(result, createResolvedModule(expected.name), expectedFailedLookups);
}
}
});
@ -819,9 +854,7 @@ import b = require("./moduleB");
function check(name: string, container: File, expected: File, expectedFailedLookups: string[]) {
const result = resolveModuleName(name, container.name, options, host);
assert.isTrue(result.resolvedModule !== undefined, "module should be resolved");
assert.equal(result.resolvedModule.resolvedFileName, expected.name);
assert.deepEqual(result.failedLookupLocations, expectedFailedLookups);
checkResolvedModuleWithFailedLookupLocations(result, createResolvedModule(expected.name), expectedFailedLookups);
}
}
});
@ -875,9 +908,7 @@ import b = require("./moduleB");
function check(name: string, container: File, expected: File, expectedFailedLookups: string[]) {
const result = resolveModuleName(name, container.name, options, host);
assert.isTrue(result.resolvedModule !== undefined, "module should be resolved");
assert.equal(result.resolvedModule.resolvedFileName, expected.name);
assert.deepEqual(result.failedLookupLocations, expectedFailedLookups);
checkResolvedModuleWithFailedLookupLocations(result, createResolvedModule(expected.name), expectedFailedLookups);
}
}
});
@ -899,9 +930,7 @@ import b = require("./moduleB");
}
};
const result = resolveModuleName("libs/guid", app.name, options, host);
assert.isTrue(result.resolvedModule !== undefined, "module should be resolved");
assert.equal(result.resolvedModule.resolvedFileName, libsTypings.name);
assert.deepEqual(result.failedLookupLocations, [
checkResolvedModuleWithFailedLookupLocations(result, createResolvedModule(libsTypings.name), [
// first try to load module as file
"/root/src/libs/guid.ts",
"/root/src/libs/guid.tsx",

View File

@ -150,17 +150,6 @@ namespace ts {
return program;
}
function checkResolvedModule(expected: ResolvedModule, actual: ResolvedModule): boolean {
if (!expected === !actual) {
if (expected) {
assert.isTrue(expected.resolvedFileName === actual.resolvedFileName, `'resolvedFileName': expected '${expected.resolvedFileName}' to be equal to '${actual.resolvedFileName}'`);
assert.isTrue(expected.isExternalLibraryImport === actual.isExternalLibraryImport, `'isExternalLibraryImport': expected '${expected.isExternalLibraryImport}' to be equal to '${actual.isExternalLibraryImport}'`);
}
return true;
}
return false;
}
function checkResolvedTypeDirective(expected: ResolvedTypeReferenceDirective, actual: ResolvedTypeReferenceDirective): boolean {
if (!expected === !actual) {
if (expected) {
@ -300,7 +289,7 @@ namespace ts {
const options: CompilerOptions = { target };
const program_1 = newProgram(files, ["a.ts"], options);
checkResolvedModulesCache(program_1, "a.ts", createMap({ "b": { resolvedFileName: "b.ts" } }));
checkResolvedModulesCache(program_1, "a.ts", createMap({ "b": createResolvedModule("b.ts") }));
checkResolvedModulesCache(program_1, "b.ts", undefined);
const program_2 = updateProgram(program_1, ["a.ts"], options, files => {
@ -309,7 +298,7 @@ namespace ts {
assert.isTrue(program_1.structureIsReused);
// content of resolution cache should not change
checkResolvedModulesCache(program_1, "a.ts", createMap({ "b": { resolvedFileName: "b.ts" } }));
checkResolvedModulesCache(program_1, "a.ts", createMap({ "b": createResolvedModule("b.ts") }));
checkResolvedModulesCache(program_1, "b.ts", undefined);
// imports has changed - program is not reused
@ -326,7 +315,7 @@ namespace ts {
files[0].text = files[0].text.updateImportsAndExports(newImports);
});
assert.isTrue(!program_3.structureIsReused);
checkResolvedModulesCache(program_4, "a.ts", createMap({ "b": { resolvedFileName: "b.ts" }, "c": undefined }));
checkResolvedModulesCache(program_4, "a.ts", createMap({ "b": createResolvedModule("b.ts"), "c": undefined }));
});
it("resolved type directives cache follows type directives", () => {

View File

@ -94,8 +94,8 @@ namespace ts.projectSystem {
this.projectService.updateTypingsForProject(response);
}
enqueueInstallTypingsRequest(project: server.Project, typingOptions: TypingOptions) {
const request = server.createInstallTypingsRequest(project, typingOptions, this.globalTypingsCacheLocation);
enqueueInstallTypingsRequest(project: server.Project, typingOptions: TypingOptions, unresolvedImports: server.SortedReadonlyArray<string>) {
const request = server.createInstallTypingsRequest(project, typingOptions, unresolvedImports, this.globalTypingsCacheLocation);
this.install(request);
}
@ -1659,67 +1659,74 @@ namespace ts.projectSystem {
"File '/a/b/node_modules/lib.ts' does not exist.",
"File '/a/b/node_modules/lib.tsx' does not exist.",
"File '/a/b/node_modules/lib.d.ts' does not exist.",
"File '/a/b/node_modules/lib.js' does not exist.",
"File '/a/b/node_modules/lib.jsx' does not exist.",
"File '/a/b/node_modules/lib/package.json' does not exist.",
"File '/a/b/node_modules/lib/index.ts' does not exist.",
"File '/a/b/node_modules/lib/index.tsx' does not exist.",
"File '/a/b/node_modules/lib/index.d.ts' does not exist.",
"File '/a/b/node_modules/lib/index.js' does not exist.",
"File '/a/b/node_modules/lib/index.jsx' does not exist.",
"File '/a/b/node_modules/@types/lib.ts' does not exist.",
"File '/a/b/node_modules/@types/lib.tsx' does not exist.",
"File '/a/b/node_modules/@types/lib.d.ts' does not exist.",
"File '/a/b/node_modules/@types/lib.js' does not exist.",
"File '/a/b/node_modules/@types/lib.jsx' does not exist.",
"File '/a/b/node_modules/@types/lib/package.json' does not exist.",
"File '/a/b/node_modules/@types/lib/index.ts' does not exist.",
"File '/a/b/node_modules/@types/lib/index.tsx' does not exist.",
"File '/a/b/node_modules/@types/lib/index.d.ts' does not exist.",
"File '/a/b/node_modules/@types/lib/index.js' does not exist.",
"File '/a/b/node_modules/@types/lib/index.jsx' does not exist.",
"File '/a/node_modules/lib.ts' does not exist.",
"File '/a/node_modules/lib.tsx' does not exist.",
"File '/a/node_modules/lib.d.ts' does not exist.",
"File '/a/node_modules/lib.js' does not exist.",
"File '/a/node_modules/lib.jsx' does not exist.",
"File '/a/node_modules/lib/package.json' does not exist.",
"File '/a/node_modules/lib/index.ts' does not exist.",
"File '/a/node_modules/lib/index.tsx' does not exist.",
"File '/a/node_modules/lib/index.d.ts' does not exist.",
"File '/a/node_modules/lib/index.js' does not exist.",
"File '/a/node_modules/lib/index.jsx' does not exist.",
"File '/a/node_modules/@types/lib.ts' does not exist.",
"File '/a/node_modules/@types/lib.tsx' does not exist.",
"File '/a/node_modules/@types/lib.d.ts' does not exist.",
"File '/a/node_modules/@types/lib.js' does not exist.",
"File '/a/node_modules/@types/lib.jsx' does not exist.",
"File '/a/node_modules/@types/lib/package.json' does not exist.",
"File '/a/node_modules/@types/lib/index.ts' does not exist.",
"File '/a/node_modules/@types/lib/index.tsx' does not exist.",
"File '/a/node_modules/@types/lib/index.d.ts' does not exist.",
"File '/a/node_modules/@types/lib/index.js' does not exist.",
"File '/a/node_modules/@types/lib/index.jsx' does not exist.",
"File '/node_modules/lib.ts' does not exist.",
"File '/node_modules/lib.tsx' does not exist.",
"File '/node_modules/lib.d.ts' does not exist.",
"File '/node_modules/lib.js' does not exist.",
"File '/node_modules/lib.jsx' does not exist.",
"File '/node_modules/lib/package.json' does not exist.",
"File '/node_modules/lib/index.ts' does not exist.",
"File '/node_modules/lib/index.tsx' does not exist.",
"File '/node_modules/lib/index.d.ts' does not exist.",
"File '/node_modules/lib/index.js' does not exist.",
"File '/node_modules/lib/index.jsx' does not exist.",
"File '/node_modules/@types/lib.ts' does not exist.",
"File '/node_modules/@types/lib.tsx' does not exist.",
"File '/node_modules/@types/lib.d.ts' does not exist.",
"File '/node_modules/@types/lib.js' does not exist.",
"File '/node_modules/@types/lib.jsx' does not exist.",
"File '/node_modules/@types/lib/package.json' does not exist.",
"File '/node_modules/@types/lib/index.ts' does not exist.",
"File '/node_modules/@types/lib/index.tsx' does not exist.",
"File '/node_modules/@types/lib/index.d.ts' does not exist.",
"Loading module 'lib' from 'node_modules' folder.",
"File '/a/b/node_modules/lib.js' does not exist.",
"File '/a/b/node_modules/lib.jsx' does not exist.",
"File '/a/b/node_modules/lib/package.json' does not exist.",
"File '/a/b/node_modules/lib/index.js' does not exist.",
"File '/a/b/node_modules/lib/index.jsx' does not exist.",
"File '/a/b/node_modules/@types/lib.js' does not exist.",
"File '/a/b/node_modules/@types/lib.jsx' does not exist.",
"File '/a/b/node_modules/@types/lib/package.json' does not exist.",
"File '/a/b/node_modules/@types/lib/index.js' does not exist.",
"File '/a/b/node_modules/@types/lib/index.jsx' does not exist.",
"File '/a/node_modules/lib.js' does not exist.",
"File '/a/node_modules/lib.jsx' does not exist.",
"File '/a/node_modules/lib/package.json' does not exist.",
"File '/a/node_modules/lib/index.js' does not exist.",
"File '/a/node_modules/lib/index.jsx' does not exist.",
"File '/a/node_modules/@types/lib.js' does not exist.",
"File '/a/node_modules/@types/lib.jsx' does not exist.",
"File '/a/node_modules/@types/lib/package.json' does not exist.",
"File '/a/node_modules/@types/lib/index.js' does not exist.",
"File '/a/node_modules/@types/lib/index.jsx' does not exist.",
"File '/node_modules/lib.js' does not exist.",
"File '/node_modules/lib.jsx' does not exist.",
"File '/node_modules/lib/package.json' does not exist.",
"File '/node_modules/lib/index.js' does not exist.",
"File '/node_modules/lib/index.jsx' does not exist.",
"File '/node_modules/@types/lib.js' does not exist.",
"File '/node_modules/@types/lib.jsx' does not exist.",
"File '/node_modules/@types/lib/package.json' does not exist.",
"File '/node_modules/@types/lib/index.js' does not exist.",
"File '/node_modules/@types/lib/index.jsx' does not exist.",
"======== Module name 'lib' was not resolved. ========",
@ -1727,19 +1734,13 @@ namespace ts.projectSystem {
"File '/a/cache/node_modules/lib.ts' does not exist.",
"File '/a/cache/node_modules/lib.tsx' does not exist.",
"File '/a/cache/node_modules/lib.d.ts' does not exist.",
"File '/a/cache/node_modules/lib.js' does not exist.",
"File '/a/cache/node_modules/lib.jsx' does not exist.",
"File '/a/cache/node_modules/lib/package.json' does not exist.",
"File '/a/cache/node_modules/lib/index.ts' does not exist.",
"File '/a/cache/node_modules/lib/index.tsx' does not exist.",
"File '/a/cache/node_modules/lib/index.d.ts' does not exist.",
"File '/a/cache/node_modules/lib/index.js' does not exist.",
"File '/a/cache/node_modules/lib/index.jsx' does not exist.",
"File '/a/cache/node_modules/@types/lib.ts' does not exist.",
"File '/a/cache/node_modules/@types/lib.tsx' does not exist.",
"File '/a/cache/node_modules/@types/lib.d.ts' does not exist.",
"File '/a/cache/node_modules/@types/lib.js' does not exist.",
"File '/a/cache/node_modules/@types/lib.jsx' does not exist.",
"File '/a/cache/node_modules/@types/lib/package.json' does not exist.",
"File '/a/cache/node_modules/@types/lib/index.ts' does not exist.",
"File '/a/cache/node_modules/@types/lib/index.tsx' does not exist.",

View File

@ -217,9 +217,9 @@ namespace ts.projectSystem {
constructor() {
super(host);
}
enqueueInstallTypingsRequest(project: server.Project, typingOptions: TypingOptions) {
enqueueInstallTypingsRequest(project: server.Project, typingOptions: TypingOptions, unresolvedImports: server.SortedReadonlyArray<string>) {
enqueueIsCalled = true;
super.enqueueInstallTypingsRequest(project, typingOptions);
super.enqueueInstallTypingsRequest(project, typingOptions, unresolvedImports);
}
executeRequest(requestKind: TI.RequestKind, _requestId: number, _args: string[], _cwd: string, cb: TI.RequestCompletedAction): void {
const installedTypings = ["@types/jquery"];
@ -319,9 +319,9 @@ namespace ts.projectSystem {
constructor() {
super(host);
}
enqueueInstallTypingsRequest(project: server.Project, typingOptions: TypingOptions) {
enqueueInstallTypingsRequest(project: server.Project, typingOptions: TypingOptions, unresolvedImports: server.SortedReadonlyArray<string>) {
enqueueIsCalled = true;
super.enqueueInstallTypingsRequest(project, typingOptions);
super.enqueueInstallTypingsRequest(project, typingOptions, unresolvedImports);
}
executeRequest(requestKind: TI.RequestKind, _requestId: number, _args: string[], _cwd: string, cb: TI.RequestCompletedAction): void {
const installedTypings: string[] = [];
@ -724,7 +724,7 @@ namespace ts.projectSystem {
it("Malformed package.json should be watched", () => {
const f = {
path: "/a/b/app.js",
content: "var x = require('commander')"
content: "var x = 1"
};
const brokenPackageJson = {
path: "/a/b/package.json",
@ -763,6 +763,133 @@ namespace ts.projectSystem {
service.checkNumberOfProjects({ inferredProjects: 1 });
checkProjectActualFiles(service.inferredProjects[0], [f.path, commander.path]);
});
it("should install typings for unresolved imports", () => {
const file = {
path: "/a/b/app.js",
content: `
import * as fs from "fs";
import * as commander from "commander";`
};
const cachePath = "/a/cache";
const node = {
path: cachePath + "/node_modules/@types/node/index.d.ts",
content: "export let x: number"
};
const commander = {
path: cachePath + "/node_modules/@types/commander/index.d.ts",
content: "export let y: string"
};
const host = createServerHost([file]);
const installer = new (class extends Installer {
constructor() {
super(host, { globalTypingsCacheLocation: cachePath });
}
executeRequest(requestKind: TI.RequestKind, _requestId: number, _args: string[], _cwd: string, cb: server.typingsInstaller.RequestCompletedAction) {
const installedTypings = ["@types/node", "@types/commander"];
const typingFiles = [node, commander];
executeCommand(this, host, installedTypings, typingFiles, requestKind, cb);
}
})();
const service = createProjectService(host, { typingsInstaller: installer });
service.openClientFile(file.path);
service.checkNumberOfProjects({ inferredProjects: 1 });
checkProjectActualFiles(service.inferredProjects[0], [file.path]);
installer.installAll([TI.NpmViewRequest, TI.NpmViewRequest], [TI.NpmInstallRequest]);
assert.isTrue(host.fileExists(node.path), "typings for 'node' should be created");
assert.isTrue(host.fileExists(commander.path), "typings for 'commander' should be created");
checkProjectActualFiles(service.inferredProjects[0], [file.path, node.path, commander.path]);
});
it("should pick typing names from non-relative unresolved imports", () => {
const f1 = {
path: "/a/b/app.js",
content: `
import * as a from "foo/a/a";
import * as b from "foo/a/b";
import * as c from "foo/a/c";
import * as d from "@bar/router/";
import * as e from "@bar/common/shared";
import * as e from "@bar/common/apps";
import * as f from "./lib"
`
};
const host = createServerHost([f1]);
const installer = new (class extends Installer {
constructor() {
super(host, { globalTypingsCacheLocation: "/tmp" });
}
executeRequest(requestKind: TI.RequestKind, _requestId: number, args: string[], _cwd: string, cb: server.typingsInstaller.RequestCompletedAction) {
if (requestKind === TI.NpmViewRequest) {
// args should have only non-scoped packages - scoped packages are not yet supported
assert.deepEqual(args, ["foo"]);
}
executeCommand(this, host, ["foo"], [], requestKind, cb);
}
})();
const projectService = createProjectService(host, { typingsInstaller: installer });
projectService.openClientFile(f1.path);
projectService.checkNumberOfProjects({ inferredProjects: 1 });
const proj = projectService.inferredProjects[0];
proj.updateGraph();
assert.deepEqual(
proj.getCachedUnresolvedImportsPerFile_TestOnly().get(<Path>f1.path),
["foo", "foo", "foo", "@bar/router", "@bar/common", "@bar/common"]
);
installer.installAll([TI.NpmViewRequest], [TI.NpmInstallRequest]);
});
it("cached unresolved typings are not recomputed if program structure did not change", () => {
const host = createServerHost([]);
const session = createSession(host);
const f = {
path: "/a/app.js",
content: `
import * as fs from "fs";
import * as cmd from "commander
`
};
session.executeCommand(<server.protocol.OpenRequest>{
seq: 1,
type: "request",
command: "open",
arguments: {
file: f.path,
fileContent: f.content
}
});
const projectService = session.getProjectService();
checkNumberOfProjects(projectService, { inferredProjects: 1 });
const proj = projectService.inferredProjects[0];
const version1 = proj.getCachedUnresolvedImportsPerFile_TestOnly().getVersion();
// make a change that should not affect the structure of the program
session.executeCommand(<server.protocol.ChangeRequest>{
seq: 2,
type: "request",
command: "change",
arguments: {
file: f.path,
insertString: "\nlet x = 1;",
line: 2,
offset: 0,
endLine: 2,
endOffset: 0
}
});
host.checkTimeoutQueueLength(1);
host.runQueuedTimeoutCallbacks();
const version2 = proj.getCachedUnresolvedImportsPerFile_TestOnly().getVersion();
assert.equal(version1, version2, "set of unresolved imports should not change");
});
});
describe("Validate package name:", () => {
@ -820,4 +947,35 @@ namespace ts.projectSystem {
assert.isTrue(messages.indexOf("Package name '; say Hello from TypeScript! #' contains non URI safe characters") > 0, "should find package with invalid name");
});
});
describe("discover typings", () => {
it("should return node for core modules", () => {
const f = {
path: "/a/b/app.js",
content: ""
};
const host = createServerHost([f]);
const cache = createMap<string>();
for (const name of JsTyping.nodeCoreModuleList) {
const result = JsTyping.discoverTypings(host, [f.path], getDirectoryPath(<Path>f.path), /*safeListPath*/ undefined, cache, { enableAutoDiscovery: true }, [name, "somename"]);
assert.deepEqual(result.newTypingNames.sort(), ["node", "somename"]);
}
});
it("should use cached locaitons", () => {
const f = {
path: "/a/b/app.js",
content: ""
};
const node = {
path: "/a/b/node.d.ts",
content: ""
};
const host = createServerHost([f, node]);
const cache = createMap<string>({ "node": node.path });
const result = JsTyping.discoverTypings(host, [f.path], getDirectoryPath(<Path>f.path), /*safeListPath*/ undefined, cache, { enableAutoDiscovery: true }, ["fs", "bar"]);
assert.deepEqual(result.cachedTypingPaths, [node.path]);
assert.deepEqual(result.newTypingNames, ["bar"]);
});
});
}

View File

@ -287,13 +287,13 @@ namespace ts.server {
}
switch (response.kind) {
case "set":
this.typingsCache.updateTypingsForProject(response.projectName, response.compilerOptions, response.typingOptions, response.typings);
project.updateGraph();
this.typingsCache.updateTypingsForProject(response.projectName, response.compilerOptions, response.typingOptions, response.unresolvedImports, response.typings);
break;
case "invalidate":
this.typingsCache.invalidateCachedTypingsForProject(project);
this.typingsCache.deleteTypingsForProject(response.projectName);
break;
}
project.updateGraph();
}
setCompilerOptionsForInferredProjects(projectCompilerOptions: protocol.ExternalProjectCompilerOptions): void {

View File

@ -5,59 +5,60 @@
namespace ts.server {
export class LSHost implements ts.LanguageServiceHost, ModuleResolutionHost, ServerLanguageServiceHost {
private compilationSettings: ts.CompilerOptions;
private readonly resolvedModuleNames: ts.FileMap<Map<ResolvedModuleWithFailedLookupLocations>>;
private readonly resolvedTypeReferenceDirectives: ts.FileMap<Map<ResolvedTypeReferenceDirectiveWithFailedLookupLocations>>;
private readonly resolvedModuleNames= createFileMap<Map<ResolvedModuleWithFailedLookupLocations>>();
private readonly resolvedTypeReferenceDirectives = createFileMap<Map<ResolvedTypeReferenceDirectiveWithFailedLookupLocations>>();
private readonly getCanonicalFileName: (fileName: string) => string;
private filesWithChangedSetOfUnresolvedImports: Path[];
private readonly resolveModuleName: typeof resolveModuleName;
readonly trace: (s: string) => void;
constructor(private readonly host: ServerHost, private readonly project: Project, private readonly cancellationToken: HostCancellationToken) {
this.getCanonicalFileName = ts.createGetCanonicalFileName(this.host.useCaseSensitiveFileNames);
this.resolvedModuleNames = createFileMap<Map<ResolvedModuleWithFailedLookupLocations>>();
this.resolvedTypeReferenceDirectives = createFileMap<Map<ResolvedTypeReferenceDirectiveWithFailedLookupLocations>>();
if (host.trace) {
this.trace = s => host.trace(s);
}
this.resolveModuleName = (moduleName, containingFile, compilerOptions, host) => {
const globalCache = this.project.getTypingOptions().enableAutoDiscovery
? this.project.projectService.typingsInstaller.globalTypingsCacheLocation
: undefined;
const primaryResult = resolveModuleName(moduleName, containingFile, compilerOptions, host);
if (primaryResult.resolvedModule) {
// return result immediately only if it is .ts, .tsx or .d.ts
// return result immediately only if it is .ts, .tsx or .d.ts
if (!(primaryResult.resolvedModule && extensionIsTypeScript(primaryResult.resolvedModule.extension)) && globalCache !== undefined) {
// otherwise try to load typings from @types
if (fileExtensionIsAny(primaryResult.resolvedModule.resolvedFileName, supportedTypeScriptExtensions)) {
return primaryResult;
// create different collection of failed lookup locations for second pass
// if it will fail and we've already found something during the first pass - we don't want to pollute its results
const { resolvedModule, failedLookupLocations } = loadModuleFromGlobalCache(moduleName, this.project.getProjectName(), compilerOptions, host, globalCache);
if (resolvedModule) {
return { resolvedModule, failedLookupLocations: primaryResult.failedLookupLocations.concat(failedLookupLocations) };
}
}
// create different collection of failed lookup locations for second pass
// if it will fail and we've already found something during the first pass - we don't want to pollute its results
const secondaryLookupFailedLookupLocations: string[] = [];
const globalCache = this.project.projectService.typingsInstaller.globalTypingsCacheLocation;
if (this.project.getTypingOptions().enableAutoDiscovery && globalCache) {
const traceEnabled = isTraceEnabled(compilerOptions, host);
if (traceEnabled) {
trace(host, Diagnostics.Auto_discovery_for_typings_is_enabled_in_project_0_Running_extra_resolution_pass_for_module_1_using_cache_location_2, this.project.getProjectName(), moduleName, globalCache);
}
const state: ModuleResolutionState = { compilerOptions, host, skipTsx: false, traceEnabled };
const resolvedName = loadModuleFromNodeModules(moduleName, globalCache, secondaryLookupFailedLookupLocations, state, /*checkOneLevel*/ true);
if (resolvedName) {
return createResolvedModule(resolvedName, /*isExternalLibraryImport*/ true, primaryResult.failedLookupLocations.concat(secondaryLookupFailedLookupLocations));
}
}
if (!primaryResult.resolvedModule && secondaryLookupFailedLookupLocations.length) {
primaryResult.failedLookupLocations = primaryResult.failedLookupLocations.concat(secondaryLookupFailedLookupLocations);
}
return primaryResult;
};
}
private resolveNamesWithLocalCache<T extends { failedLookupLocations: string[] }, R extends { resolvedFileName?: string }>(
public startRecordingFilesWithChangedResolutions() {
this.filesWithChangedSetOfUnresolvedImports = [];
}
public finishRecordingFilesWithChangedResolutions() {
const collected = this.filesWithChangedSetOfUnresolvedImports;
this.filesWithChangedSetOfUnresolvedImports = undefined;
return collected;
}
private resolveNamesWithLocalCache<T extends { failedLookupLocations: string[] }, R>(
names: string[],
containingFile: string,
cache: ts.FileMap<Map<T>>,
loader: (name: string, containingFile: string, options: CompilerOptions, host: ModuleResolutionHost) => T,
getResult: (s: T) => R): R[] {
getResult: (s: T) => R,
getResultFileName: (result: R) => string | undefined,
logChanges: boolean): R[] {
const path = toPath(containingFile, this.host.getCurrentDirectory(), this.getCanonicalFileName);
const currentResolutionsInFile = cache.get(path);
@ -79,6 +80,11 @@ namespace ts.server {
else {
newResolutions[name] = resolution = loader(name, containingFile, compilerOptions, this);
}
if (logChanges && this.filesWithChangedSetOfUnresolvedImports && !resolutionIsEqualTo(existingResolution, resolution)) {
this.filesWithChangedSetOfUnresolvedImports.push(path);
// reset log changes to avoid recording the same file multiple times
logChanges = false;
}
}
ts.Debug.assert(resolution !== undefined);
@ -90,6 +96,24 @@ namespace ts.server {
cache.set(path, newResolutions);
return resolvedModules;
function resolutionIsEqualTo(oldResolution: T, newResolution: T): boolean {
if (oldResolution === newResolution) {
return true;
}
if (!oldResolution || !newResolution) {
return false;
}
const oldResult = getResult(oldResolution);
const newResult = getResult(newResolution);
if (oldResult === newResult) {
return true;
}
if (!oldResult || !newResult) {
return false;
}
return getResultFileName(oldResult) === getResultFileName(newResult);
}
function moduleResolutionIsValid(resolution: T): boolean {
if (!resolution) {
return false;
@ -97,10 +121,7 @@ namespace ts.server {
const result = getResult(resolution);
if (result) {
if (result.resolvedFileName && result.resolvedFileName === lastDeletedFileName) {
return false;
}
return true;
return getResultFileName(result) !== lastDeletedFileName;
}
// consider situation if we have no candidate locations as valid resolution.
@ -126,11 +147,13 @@ namespace ts.server {
}
resolveTypeReferenceDirectives(typeDirectiveNames: string[], containingFile: string): ResolvedTypeReferenceDirective[] {
return this.resolveNamesWithLocalCache(typeDirectiveNames, containingFile, this.resolvedTypeReferenceDirectives, resolveTypeReferenceDirective, m => m.resolvedTypeReferenceDirective);
return this.resolveNamesWithLocalCache(typeDirectiveNames, containingFile, this.resolvedTypeReferenceDirectives, resolveTypeReferenceDirective,
m => m.resolvedTypeReferenceDirective, r => r.resolvedFileName, /*logChanges*/ false);
}
resolveModuleNames(moduleNames: string[], containingFile: string): ResolvedModule[] {
return this.resolveNamesWithLocalCache(moduleNames, containingFile, this.resolvedModuleNames, this.resolveModuleName, m => m.resolvedModule);
return this.resolveNamesWithLocalCache(moduleNames, containingFile, this.resolvedModuleNames, this.resolveModuleName,
m => m.resolvedModule, r => r.resolvedFileName, /*logChanges*/ true);
}
getDefaultLibFileName() {
@ -197,10 +220,11 @@ namespace ts.server {
}
setCompilationSettings(opt: ts.CompilerOptions) {
if (changesAffectModuleResolution(this.compilationSettings, opt)) {
this.resolvedModuleNames.clear();
this.resolvedTypeReferenceDirectives.clear();
}
this.compilationSettings = opt;
// conservatively assume that changing compiler options might affect module resolution strategy
this.resolvedModuleNames.clear();
this.resolvedTypeReferenceDirectives.clear();
}
}
}

View File

@ -62,12 +62,43 @@ namespace ts.server {
projectErrors: Diagnostic[];
}
export class UnresolvedImportsMap {
readonly perFileMap = createFileMap<ReadonlyArray<string>>();
private version = 0;
public clear() {
this.perFileMap.clear();
this.version = 0;
}
public getVersion() {
return this.version;
}
public remove(path: Path) {
this.perFileMap.remove(path);
this.version++;
}
public get(path: Path) {
return this.perFileMap.get(path);
}
public set(path: Path, value: ReadonlyArray<string>) {
this.perFileMap.set(path, value);
this.version++;
}
}
export abstract class Project {
private rootFiles: ScriptInfo[] = [];
private rootFilesMap: FileMap<ScriptInfo> = createFileMap<ScriptInfo>();
private lsHost: ServerLanguageServiceHost;
private program: ts.Program;
private cachedUnresolvedImportsPerFile = new UnresolvedImportsMap();
private lastCachedUnresolvedImportsList: SortedReadonlyArray<string>;
private languageService: LanguageService;
builder: Builder;
/**
@ -91,7 +122,7 @@ namespace ts.server {
*/
private projectStateVersion = 0;
private typingFiles: TypingsArray;
private typingFiles: SortedReadonlyArray<string>;
protected projectErrors: Diagnostic[];
@ -107,6 +138,10 @@ namespace ts.server {
return hasOneOrMoreJsAndNoTsFiles(this);
}
public getCachedUnresolvedImportsPerFile_TestOnly() {
return this.cachedUnresolvedImportsPerFile;
}
constructor(
readonly projectKind: ProjectKind,
readonly projectService: ProjectService,
@ -326,6 +361,7 @@ namespace ts.server {
removeFile(info: ScriptInfo, detachFromProject = true) {
this.removeRootFileIfNecessary(info);
this.lsHost.notifyFileRemoved(info);
this.cachedUnresolvedImportsPerFile.remove(info.path);
if (detachFromProject) {
info.detachFromProject(this);
@ -338,6 +374,38 @@ namespace ts.server {
this.projectStateVersion++;
}
private extractUnresolvedImportsFromSourceFile(file: SourceFile, result: string[]) {
const cached = this.cachedUnresolvedImportsPerFile.get(file.path);
if (cached) {
// found cached result - use it and return
for (const f of cached) {
result.push(f);
}
return;
}
let unresolvedImports: string[];
if (file.resolvedModules) {
for (const name in file.resolvedModules) {
// pick unresolved non-relative names
if (!file.resolvedModules[name] && !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();
let i = trimmed.indexOf("/");
if (i !== -1 && trimmed.charCodeAt(0) === CharacterCodes.at) {
i = trimmed.indexOf("/", i + 1);
}
if (i !== -1) {
trimmed = trimmed.substr(0, i);
}
(unresolvedImports || (unresolvedImports = [])).push(trimmed);
result.push(trimmed);
}
}
}
this.cachedUnresolvedImportsPerFile.set(file.path, unresolvedImports || emptyArray);
}
/**
* Updates set of files that contribute to this project
* @returns: true if set of files in the project stays the same and false - otherwise.
@ -346,8 +414,35 @@ namespace ts.server {
if (!this.languageServiceEnabled) {
return true;
}
this.lsHost.startRecordingFilesWithChangedResolutions();
let hasChanges = this.updateGraphWorker();
const cachedTypings = this.projectService.typingsCache.getTypingsForProject(this, hasChanges);
const changedFiles: ReadonlyArray<Path> = this.lsHost.finishRecordingFilesWithChangedResolutions() || emptyArray;
for (const file of changedFiles) {
// delete cached information for changed files
this.cachedUnresolvedImportsPerFile.remove(file);
}
// 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
// (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)
// 4. compilation settings were changed in the way that might affect module resolution - drop all caches and collect all data from the scratch
let unresolvedImports: SortedReadonlyArray<string>;
if (hasChanges || changedFiles.length) {
const result: string[] = [];
for (const sourceFile of this.program.getSourceFiles()) {
this.extractUnresolvedImportsFromSourceFile(sourceFile, result);
}
this.lastCachedUnresolvedImportsList = toSortedReadonlyArray(result);
}
unresolvedImports = this.lastCachedUnresolvedImportsList;
const cachedTypings = this.projectService.typingsCache.getTypingsForProject(this, unresolvedImports, hasChanges);
if (this.setTypings(cachedTypings)) {
hasChanges = this.updateGraphWorker() || hasChanges;
}
@ -357,7 +452,7 @@ namespace ts.server {
return !hasChanges;
}
private setTypings(typings: TypingsArray): boolean {
private setTypings(typings: SortedReadonlyArray<string>): boolean {
if (arrayIsEqualTo(this.typingFiles, typings)) {
return false;
}
@ -430,6 +525,11 @@ namespace ts.server {
compilerOptions.allowJs = true;
}
compilerOptions.allowNonTsExtensions = true;
if (changesAffectModuleResolution(this.compilerOptions, compilerOptions)) {
// reset cached unresolved imports if changes in compiler options affected module resolution
this.cachedUnresolvedImportsPerFile.clear();
this.lastCachedUnresolvedImportsList = undefined;
}
this.compilerOptions = compilerOptions;
this.lsHost.setCompilationSettings(compilerOptions);

View File

@ -14,21 +14,33 @@ namespace ts.server {
} = require("child_process");
const os: {
homedir(): string
homedir?(): string;
tmpdir(): string;
} = require("os");
function getGlobalTypingsCacheLocation() {
let basePath: string;
switch (process.platform) {
case "win32":
basePath = process.env.LOCALAPPDATA || process.env.APPDATA || os.homedir();
basePath = process.env.LOCALAPPDATA ||
process.env.APPDATA ||
(os.homedir && os.homedir()) ||
process.env.USERPROFILE ||
(process.env.HOMEDRIVE && process.env.HOMEPATH && normalizeSlashes(process.env.HOMEDRIVE + process.env.HOMEPATH)) ||
os.tmpdir();
break;
case "linux":
basePath = os.homedir();
basePath = (os.homedir && os.homedir()) ||
process.env.HOME ||
((process.env.LOGNAME || process.env.USER) && `/home/${process.env.LOGNAME || process.env.USER}`) ||
os.tmpdir();
break;
case "darwin":
basePath = combinePaths(os.homedir(), "Library/Application Support/");
const homeDir = (os.homedir && os.homedir()) ||
process.env.HOME ||
((process.env.LOGNAME || process.env.USER) && `/Users/${process.env.LOGNAME || process.env.USER}`) ||
os.tmpdir();
basePath = combinePaths(homeDir, "Library/Application Support/");
break;
}
@ -40,6 +52,7 @@ namespace ts.server {
send(message: any, sendHandle?: any): void;
on(message: "message", f: (m: any) => void): void;
kill(): void;
pid: number;
}
interface NodeSocket {
@ -179,21 +192,40 @@ namespace ts.server {
class NodeTypingsInstaller implements ITypingsInstaller {
private installer: NodeChildProcess;
private installerPidReported = false;
private socket: NodeSocket;
private projectService: ProjectService;
private throttledOperations: ThrottledOperations;
constructor(
private readonly logger: server.Logger,
host: ServerHost,
eventPort: number,
readonly globalTypingsCacheLocation: string,
private newLine: string) {
this.throttledOperations = new ThrottledOperations(host);
if (eventPort) {
const s = net.connect({ port: eventPort }, () => {
this.socket = s;
this.reportInstallerProcessId();
});
}
}
private reportInstallerProcessId() {
if (this.installerPidReported) {
return;
}
if (this.socket && this.installer) {
this.sendEvent(0, "typingsInstallerPid", { pid: this.installer.pid });
this.installerPidReported = true;
}
}
private sendEvent(seq: number, event: string, body: any): void {
this.socket.write(formatMessage({ seq, type: "event", event, body }, this.logger, Buffer.byteLength, this.newLine), "utf8");
}
attach(projectService: ProjectService) {
this.projectService = projectService;
if (this.logger.hasLevel(LogLevel.requestTime)) {
@ -222,6 +254,8 @@ namespace ts.server {
this.installer = childProcess.fork(combinePaths(__dirname, "typingsInstaller.js"), args, { execArgv });
this.installer.on("message", m => this.handleMessage(m));
this.reportInstallerProcessId();
process.on("exit", () => {
this.installer.kill();
});
@ -231,12 +265,19 @@ namespace ts.server {
this.installer.send({ projectName: p.getProjectName(), kind: "closeProject" });
}
enqueueInstallTypingsRequest(project: Project, typingOptions: TypingOptions): void {
const request = createInstallTypingsRequest(project, typingOptions);
enqueueInstallTypingsRequest(project: Project, typingOptions: TypingOptions, unresolvedImports: SortedReadonlyArray<string>): void {
const request = createInstallTypingsRequest(project, typingOptions, unresolvedImports);
if (this.logger.hasLevel(LogLevel.verbose)) {
this.logger.info(`Sending request: ${JSON.stringify(request)}`);
if (this.logger.hasLevel(LogLevel.verbose)) {
this.logger.info(`Scheduling throttled operation: ${JSON.stringify(request)}`);
}
}
this.installer.send(request);
this.throttledOperations.schedule(project.getProjectName(), /*ms*/ 250, () => {
if (this.logger.hasLevel(LogLevel.verbose)) {
this.logger.info(`Sending request: ${JSON.stringify(request)}`);
}
this.installer.send(request);
});
}
private handleMessage(response: SetTypings | InvalidateCachedTypings) {
@ -245,7 +286,7 @@ namespace ts.server {
}
this.projectService.updateTypingsForProject(response);
if (response.kind == "set" && this.socket) {
this.socket.write(formatMessage({ seq: 0, type: "event", message: response }, this.logger, Buffer.byteLength, this.newLine), "utf8");
this.sendEvent(0, "setTypings", response);
}
}
}
@ -266,7 +307,7 @@ namespace ts.server {
useSingleInferredProject,
disableAutomaticTypingAcquisition
? nullTypingsInstaller
: new NodeTypingsInstaller(logger, installerEventPort, globalTypingsCacheLocation, host.newLine),
: new NodeTypingsInstaller(logger, host, installerEventPort, globalTypingsCacheLocation, host.newLine),
Buffer.byteLength,
process.hrtime,
logger,

16
src/server/types.d.ts vendored
View File

@ -18,6 +18,10 @@ declare namespace ts.server {
trace?(s: string): void;
}
export interface SortedReadonlyArray<T> extends ReadonlyArray<T> {
" __sortedReadonlyArrayBrand": any;
}
export interface TypingInstallerRequest {
readonly projectName: string;
readonly kind: "discover" | "closeProject";
@ -26,8 +30,9 @@ declare namespace ts.server {
export interface DiscoverTypings extends TypingInstallerRequest {
readonly fileNames: string[];
readonly projectRootPath: ts.Path;
readonly typingOptions: ts.TypingOptions;
readonly compilerOptions: ts.CompilerOptions;
readonly typingOptions: ts.TypingOptions;
readonly unresolvedImports: SortedReadonlyArray<string>;
readonly cachePath?: string;
readonly kind: "discover";
}
@ -36,20 +41,23 @@ declare namespace ts.server {
readonly kind: "closeProject";
}
export type SetRequest = "set";
export type InvalidateRequest = "invalidate";
export interface TypingInstallerResponse {
readonly projectName: string;
readonly kind: "set" | "invalidate";
readonly kind: SetRequest | InvalidateRequest;
}
export interface SetTypings extends TypingInstallerResponse {
readonly typingOptions: ts.TypingOptions;
readonly compilerOptions: ts.CompilerOptions;
readonly typings: string[];
readonly kind: "set";
readonly unresolvedImports: SortedReadonlyArray<string>;
readonly kind: SetRequest;
}
export interface InvalidateCachedTypings extends TypingInstallerResponse {
readonly kind: "invalidate";
readonly kind: InvalidateRequest;
}
export interface InstallTypingHost extends JsTyping.TypingResolutionHost {

View File

@ -2,7 +2,7 @@
namespace ts.server {
export interface ITypingsInstaller {
enqueueInstallTypingsRequest(p: Project, typingOptions: TypingOptions): void;
enqueueInstallTypingsRequest(p: Project, typingOptions: TypingOptions, unresolvedImports: SortedReadonlyArray<string>): void;
attach(projectService: ProjectService): void;
onProjectClosed(p: Project): void;
readonly globalTypingsCacheLocation: string;
@ -18,7 +18,9 @@ namespace ts.server {
class TypingsCacheEntry {
readonly typingOptions: TypingOptions;
readonly compilerOptions: CompilerOptions;
readonly typings: TypingsArray;
readonly typings: SortedReadonlyArray<string>;
readonly unresolvedImports: SortedReadonlyArray<string>;
/* mainly useful for debugging */
poisoned: boolean;
}
@ -61,13 +63,11 @@ namespace ts.server {
return opt1.allowJs != opt2.allowJs;
}
export interface TypingsArray extends ReadonlyArray<string> {
" __typingsArrayBrand": any;
}
function toTypingsArray(arr: string[]): TypingsArray {
arr.sort();
return <any>arr;
function unresolvedImportsChanged(imports1: SortedReadonlyArray<string>, imports2: SortedReadonlyArray<string>): boolean {
if (imports1 === imports2) {
return false;
}
return !arrayIsEqualTo(imports1, imports2);
}
export class TypingsCache {
@ -76,7 +76,7 @@ namespace ts.server {
constructor(private readonly installer: ITypingsInstaller) {
}
getTypingsForProject(project: Project, forceRefresh: boolean): TypingsArray {
getTypingsForProject(project: Project, unresolvedImports: SortedReadonlyArray<string>, forceRefresh: boolean): SortedReadonlyArray<string> {
const typingOptions = project.getTypingOptions();
if (!typingOptions || !typingOptions.enableAutoDiscovery) {
@ -84,39 +84,41 @@ namespace ts.server {
}
const entry = this.perProjectCache[project.getProjectName()];
const result: TypingsArray = entry ? entry.typings : <any>emptyArray;
if (forceRefresh || !entry || typingOptionsChanged(typingOptions, entry.typingOptions) || compilerOptionsChanged(project.getCompilerOptions(), entry.compilerOptions)) {
const result: SortedReadonlyArray<string> = entry ? entry.typings : <any>emptyArray;
if (forceRefresh ||
!entry ||
typingOptionsChanged(typingOptions, entry.typingOptions) ||
compilerOptionsChanged(project.getCompilerOptions(), entry.compilerOptions) ||
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()] = {
compilerOptions: project.getCompilerOptions(),
typingOptions,
typings: result,
unresolvedImports,
poisoned: true
};
// something has been changed, issue a request to update typings
this.installer.enqueueInstallTypingsRequest(project, typingOptions);
this.installer.enqueueInstallTypingsRequest(project, typingOptions, unresolvedImports);
}
return result;
}
invalidateCachedTypingsForProject(project: Project) {
const typingOptions = project.getTypingOptions();
if (!typingOptions.enableAutoDiscovery) {
return;
}
this.installer.enqueueInstallTypingsRequest(project, typingOptions);
}
updateTypingsForProject(projectName: string, compilerOptions: CompilerOptions, typingOptions: TypingOptions, newTypings: string[]) {
updateTypingsForProject(projectName: string, compilerOptions: CompilerOptions, typingOptions: TypingOptions, unresolvedImports: SortedReadonlyArray<string>, newTypings: string[]) {
this.perProjectCache[projectName] = {
compilerOptions,
typingOptions,
typings: toTypingsArray(newTypings),
typings: toSortedReadonlyArray(newTypings),
unresolvedImports,
poisoned: false
};
}
deleteTypingsForProject(projectName: string) {
delete this.perProjectCache[projectName];
}
onProjectClosed(project: Project) {
delete this.perProjectCache[project.getProjectName()];
this.installer.onProjectClosed(project);

View File

@ -26,6 +26,7 @@ namespace ts.server.typingsInstaller {
export enum PackageNameValidationResult {
Ok,
ScopedPackagesNotSupported,
EmptyName,
NameTooLong,
NameStartsWithDot,
NameStartsWithUnderscore,
@ -38,7 +39,9 @@ namespace ts.server.typingsInstaller {
* Validates package name using rules defined at https://docs.npmjs.com/files/package.json
*/
export function validatePackageName(packageName: string): PackageNameValidationResult {
Debug.assert(!!packageName, "Package name is not specified");
if (!packageName) {
return PackageNameValidationResult.EmptyName;
}
if (packageName.length > MaxPackageNameLength) {
return PackageNameValidationResult.NameTooLong;
}
@ -145,7 +148,8 @@ namespace ts.server.typingsInstaller {
req.projectRootPath,
this.safeListPath,
this.packageNameToTypingLocation,
req.typingOptions);
req.typingOptions,
req.unresolvedImports);
if (this.log.isEnabled()) {
this.log.writeLine(`Finished typings discovery: ${JSON.stringify(discoverTypingsResult)}`);
@ -238,6 +242,9 @@ namespace ts.server.typingsInstaller {
this.missingTypingsSet[typing] = true;
if (this.log.isEnabled()) {
switch (validationResult) {
case PackageNameValidationResult.EmptyName:
this.log.writeLine(`Package name '${typing}' cannot be empty`);
break;
case PackageNameValidationResult.NameTooLong:
this.log.writeLine(`Package name '${typing}' should be less than ${MaxPackageNameLength} characters`);
break;
@ -397,6 +404,7 @@ namespace ts.server.typingsInstaller {
typingOptions: request.typingOptions,
compilerOptions: request.compilerOptions,
typings,
unresolvedImports: request.unresolvedImports,
kind: "set"
};
}

View File

@ -45,12 +45,13 @@ namespace ts.server {
}
}
export function createInstallTypingsRequest(project: Project, typingOptions: TypingOptions, cachePath?: string): DiscoverTypings {
export function createInstallTypingsRequest(project: Project, typingOptions: TypingOptions, unresolvedImports: SortedReadonlyArray<string>, cachePath?: string): DiscoverTypings {
return {
projectName: project.getProjectName(),
fileNames: project.getFileNames(),
compilerOptions: project.getCompilerOptions(),
typingOptions,
unresolvedImports,
projectRootPath: getProjectRootPath(project),
cachePath,
kind: "discover"
@ -209,11 +210,15 @@ namespace ts.server {
export interface ServerLanguageServiceHost {
setCompilationSettings(options: CompilerOptions): void;
notifyFileRemoved(info: ScriptInfo): void;
startRecordingFilesWithChangedResolutions(): void;
finishRecordingFilesWithChangedResolutions(): Path[];
}
export const nullLanguageServiceHost: ServerLanguageServiceHost = {
setCompilationSettings: () => undefined,
notifyFileRemoved: () => undefined
notifyFileRemoved: () => undefined,
startRecordingFilesWithChangedResolutions: () => undefined,
finishRecordingFilesWithChangedResolutions: () => undefined
};
export interface ProjectOptions {
@ -240,6 +245,11 @@ namespace ts.server {
return `/dev/null/inferredProject${counter}*`;
}
export function toSortedReadonlyArray(arr: string[]): SortedReadonlyArray<string> {
arr.sort();
return <any>arr;
}
export class ThrottledOperations {
private pendingTimeouts: Map<any> = createMap<any>();
constructor(private readonly host: ServerHost) {

View File

@ -1590,7 +1590,9 @@ namespace ts.Completions {
if (m.kind !== SyntaxKind.PropertyAssignment &&
m.kind !== SyntaxKind.ShorthandPropertyAssignment &&
m.kind !== SyntaxKind.BindingElement &&
m.kind !== SyntaxKind.MethodDeclaration) {
m.kind !== SyntaxKind.MethodDeclaration &&
m.kind !== SyntaxKind.GetAccessor &&
m.kind !== SyntaxKind.SetAccessor) {
continue;
}

View File

@ -31,6 +31,17 @@ namespace ts.JsTyping {
const EmptySafeList: Map<string> = createMap<string>();
/* @internal */
export const nodeCoreModuleList: ReadonlyArray<string> = [
"buffer", "querystring", "events", "http", "cluster",
"zlib", "os", "https", "punycode", "repl", "readline",
"vm", "child_process", "url", "dns", "net",
"dgram", "fs", "path", "string_decoder", "tls",
"crypto", "stream", "util", "assert", "tty", "domain",
"constants", "process", "v8", "timers", "console"];
const nodeCoreModules = arrayToMap(<string[]>nodeCoreModuleList, x => x);
/**
* @param host is the object providing I/O related operations.
* @param fileNames are the file names that belong to the same project
@ -46,7 +57,8 @@ namespace ts.JsTyping {
projectRootPath: Path,
safeListPath: Path,
packageNameToTypingLocation: Map<string>,
typingOptions: TypingOptions):
typingOptions: TypingOptions,
unresolvedImports: ReadonlyArray<string>):
{ cachedTypingPaths: string[], newTypingNames: string[], filesToWatch: string[] } {
// A typing name to typing file path mapping
@ -92,6 +104,15 @@ namespace ts.JsTyping {
}
getTypingNamesFromSourceFileNames(fileNames);
// 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;
}
}
}
// Add the cached typing locations for inferred typings that are already installed
for (const name in packageNameToTypingLocation) {
if (name in inferredTypings && !inferredTypings[name]) {

View File

@ -403,6 +403,9 @@ namespace ts.NavigationBar {
if (getModifierFlags(node) & ModifierFlags.Default) {
return "default";
}
// We may get a string with newlines or other whitespace in the case of an object dereference
// (eg: "app\n.onactivated"), so we should remove the whitespace for readabiltiy in the
// navigation bar.
return getFunctionOrClassName(<ArrowFunction | FunctionExpression | ClassExpression>node);
case SyntaxKind.Constructor:
return "constructor";
@ -602,7 +605,7 @@ namespace ts.NavigationBar {
// See if it is of the form "<expr> = function(){...}". If so, use the text from the left-hand side.
else if (node.parent.kind === SyntaxKind.BinaryExpression &&
(node.parent as BinaryExpression).operatorToken.kind === SyntaxKind.EqualsToken) {
return nodeText((node.parent as BinaryExpression).left);
return nodeText((node.parent as BinaryExpression).left).replace(whiteSpaceRegex, "");
}
// See if it is a property assignment, and if so use the property name
else if (node.parent.kind === SyntaxKind.PropertyAssignment && (node.parent as PropertyAssignment).name) {
@ -620,4 +623,19 @@ namespace ts.NavigationBar {
function isFunctionOrClassExpression(node: Node): boolean {
return node.kind === SyntaxKind.FunctionExpression || node.kind === SyntaxKind.ArrowFunction || node.kind === SyntaxKind.ClassExpression;
}
/**
* 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;
}

View File

@ -328,7 +328,7 @@ namespace ts {
const resolutionsInFile = <MapLike<string>>JSON.parse(this.shimHost.getModuleResolutionsForFile(containingFile));
return map(moduleNames, name => {
const result = getProperty(resolutionsInFile, name);
return result ? { resolvedFileName: result } : undefined;
return result ? { resolvedFileName: result, extension: extensionFromPath(result), isExternalLibraryImport: false } : undefined;
});
};
}
@ -1168,7 +1168,8 @@ namespace ts {
toPath(info.projectRootPath, info.projectRootPath, getCanonicalFileName),
toPath(info.safeListPath, info.safeListPath, getCanonicalFileName),
info.packageNameToTypingLocation,
info.typingOptions);
info.typingOptions,
info.unresolvedImports);
});
}
}

View File

@ -32,6 +32,7 @@
"../compiler/transformers/es2017.ts",
"../compiler/transformers/es2016.ts",
"../compiler/transformers/es2015.ts",
"../compiler/transformers/es5.ts",
"../compiler/transformers/generators.ts",
"../compiler/transformers/generators.ts",
"../compiler/transformers/destructuring.ts",

View File

@ -11,5 +11,4 @@ var C = (function () {
}
return C;
}());
exports.C = C;
module.exports = B;

View File

@ -11,5 +11,4 @@ var C = (function () {
}
return C;
}());
exports.C = C;
module.exports = B;

View File

@ -18,6 +18,12 @@
"end": 16,
"text": "typedef"
},
"fullName": {
"kind": "Identifier",
"pos": 17,
"end": 23,
"text": "People"
},
"name": {
"kind": "Identifier",
"pos": 17,

View File

@ -14,11 +14,11 @@ var b = A.Day.Monday;
//// [ModuleWithExportedAndNonExportedEnums.js]
var A;
(function (A) {
var Color;
(function (Color) {
Color[Color["Red"] = 0] = "Red";
Color[Color["Blue"] = 1] = "Blue";
})(A.Color || (A.Color = {}));
var Color = A.Color;
})(Color = A.Color || (A.Color = {}));
var Day;
(function (Day) {
Day[Day["Monday"] = 0] = "Monday";

View File

@ -0,0 +1,21 @@
//// [tests/cases/compiler/ambientRequireFunction.ts] ////
//// [node.d.ts]
declare function require(moduleName: string): any;
declare module "fs" {
export function readFileSync(s: string): string;
}
//// [app.js]
/// <reference path="node.d.ts"/>
const fs = require("fs");
const text = fs.readFileSync("/a/b/c");
//// [app.js]
/// <reference path="node.d.ts"/>
var fs = require("fs");
var text = fs.readFileSync("/a/b/c");

View File

@ -0,0 +1,27 @@
=== tests/cases/compiler/app.js ===
/// <reference path="node.d.ts"/>
const fs = require("fs");
>fs : Symbol(fs, Decl(app.js, 2, 5))
>require : Symbol(require, Decl(node.d.ts, 0, 0))
>"fs" : Symbol("fs", Decl(node.d.ts, 2, 50))
const text = fs.readFileSync("/a/b/c");
>text : Symbol(text, Decl(app.js, 3, 5))
>fs.readFileSync : Symbol(readFileSync, Decl(node.d.ts, 4, 21))
>fs : Symbol(fs, Decl(app.js, 2, 5))
>readFileSync : Symbol(readFileSync, Decl(node.d.ts, 4, 21))
=== tests/cases/compiler/node.d.ts ===
declare function require(moduleName: string): any;
>require : Symbol(require, Decl(node.d.ts, 0, 0))
>moduleName : Symbol(moduleName, Decl(node.d.ts, 2, 25))
declare module "fs" {
export function readFileSync(s: string): string;
>readFileSync : Symbol(readFileSync, Decl(node.d.ts, 4, 21))
>s : Symbol(s, Decl(node.d.ts, 5, 33))
}

View File

@ -0,0 +1,30 @@
=== tests/cases/compiler/app.js ===
/// <reference path="node.d.ts"/>
const fs = require("fs");
>fs : typeof "fs"
>require("fs") : typeof "fs"
>require : (moduleName: string) => any
>"fs" : "fs"
const text = fs.readFileSync("/a/b/c");
>text : string
>fs.readFileSync("/a/b/c") : string
>fs.readFileSync : (s: string) => string
>fs : typeof "fs"
>readFileSync : (s: string) => string
>"/a/b/c" : "/a/b/c"
=== tests/cases/compiler/node.d.ts ===
declare function require(moduleName: string): any;
>require : (moduleName: string) => any
>moduleName : string
declare module "fs" {
export function readFileSync(s: string): string;
>readFileSync : (s: string) => string
>s : string
}

View File

@ -15,12 +15,12 @@ if(foo.E1.A === 0){
//// [foo_0.js]
define(["require", "exports"], function (require, exports) {
"use strict";
var E1;
(function (E1) {
E1[E1["A"] = 0] = "A";
E1[E1["B"] = 1] = "B";
E1[E1["C"] = 2] = "C";
})(exports.E1 || (exports.E1 = {}));
var E1 = exports.E1;
})(E1 = exports.E1 || (exports.E1 = {}));
});
//// [foo_1.js]
define(["require", "exports", "./foo_0"], function (require, exports, foo) {

View File

@ -40,14 +40,14 @@ define(["require", "exports"], function (require, exports) {
}
return C1;
}());
exports.C1 = C1;
C1.s1 = true;
exports.C1 = C1;
var E1;
(function (E1) {
E1[E1["A"] = 0] = "A";
E1[E1["B"] = 1] = "B";
E1[E1["C"] = 2] = "C";
})(exports.E1 || (exports.E1 = {}));
var E1 = exports.E1;
})(E1 = exports.E1 || (exports.E1 = {}));
});
//// [foo_1.js]
define(["require", "exports"], function (require, exports) {

View File

@ -151,13 +151,13 @@ System.register([], function (exports_1, context_1) {
function exportedFoo() {
return v0 + v00 + v1 + v2 + v3 + v4 + v5 + v6 + v7 + v8;
}
exports_1("exportedFoo", exportedFoo);
//======const
function exportedFoo2() {
return v0_c + v00_c + v1_c + v2_c + v3_c + v4_c + v5_c + v6_c + v7_c + v8_c;
}
var v0, v00, v1, v2, v3, v4, v5, v6, v7, v8, v0_c, v00_c, v1_c, v2_c, v3_c, v4_c, v5_c, v6_c, v7_c, v8_c;
exports_1("exportedFoo", exportedFoo);
exports_1("exportedFoo2", exportedFoo2);
var v0, v00, v1, v2, v3, v4, v5, v6, v7, v8, v0_c, v00_c, v1_c, v2_c, v3_c, v4_c, v5_c, v6_c, v7_c, v8_c;
return {
setters: [],
execute: function () {

View File

@ -63,16 +63,16 @@ module m4 {
//// [collisionExportsRequireAndEnum_externalmodule.js]
define(["require", "exports"], function (require, exports) {
"use strict";
var require;
(function (require) {
require[require["_thisVal1"] = 0] = "_thisVal1";
require[require["_thisVal2"] = 1] = "_thisVal2";
})(exports.require || (exports.require = {}));
var require = exports.require;
})(require = exports.require || (exports.require = {}));
var exports;
(function (exports) {
exports[exports["_thisVal1"] = 0] = "_thisVal1";
exports[exports["_thisVal2"] = 1] = "_thisVal2";
})(exports.exports || (exports.exports = {}));
var exports = exports.exports;
})(exports = exports.exports || (exports.exports = {}));
var m1;
(function (m1) {
var require;
@ -88,16 +88,16 @@ define(["require", "exports"], function (require, exports) {
})(m1 || (m1 = {}));
var m2;
(function (m2) {
var require;
(function (require) {
require[require["_thisVal1"] = 0] = "_thisVal1";
require[require["_thisVal2"] = 1] = "_thisVal2";
})(m2.require || (m2.require = {}));
var require = m2.require;
})(require = m2.require || (m2.require = {}));
var exports;
(function (exports) {
exports[exports["_thisVal1"] = 0] = "_thisVal1";
exports[exports["_thisVal2"] = 1] = "_thisVal2";
})(m2.exports || (m2.exports = {}));
var exports = m2.exports;
})(exports = m2.exports || (m2.exports = {}));
})(m2 || (m2 = {}));
});
//// [collisionExportsRequireAndEnum_globalFile.js]
@ -126,14 +126,14 @@ var m3;
})(m3 || (m3 = {}));
var m4;
(function (m4) {
var require;
(function (require) {
require[require["_thisVal1"] = 0] = "_thisVal1";
require[require["_thisVal2"] = 1] = "_thisVal2";
})(m4.require || (m4.require = {}));
var require = m4.require;
})(require = m4.require || (m4.require = {}));
var exports;
(function (exports) {
exports[exports["_thisVal1"] = 0] = "_thisVal1";
exports[exports["_thisVal2"] = 1] = "_thisVal2";
})(m4.exports || (m4.exports = {}));
var exports = m4.exports;
})(exports = m4.exports || (m4.exports = {}));
})(m4 || (m4 = {}));

View File

@ -11,9 +11,9 @@ export enum Color {
/**
* comment
*/
var Color;
(function (Color) {
Color[Color["r"] = 0] = "r";
Color[Color["g"] = 1] = "g";
Color[Color["b"] = 2] = "b";
})(exports.Color || (exports.Color = {}));
var Color = exports.Color;
})(Color = exports.Color || (exports.Color = {}));

View File

@ -21,8 +21,8 @@ var C1 = (function () {
}
return C1;
}());
exports.C1 = C1;
C1.s1 = true;
exports.C1 = C1;
//// [foo_1.js]
"use strict";
var foo = require("./foo_0");

View File

@ -39,14 +39,14 @@ var C1 = (function () {
}
return C1;
}());
exports.C1 = C1;
C1.s1 = true;
exports.C1 = C1;
var E1;
(function (E1) {
E1[E1["A"] = 0] = "A";
E1[E1["B"] = 1] = "B";
E1[E1["C"] = 2] = "C";
})(exports.E1 || (exports.E1 = {}));
var E1 = exports.E1;
})(E1 = exports.E1 || (exports.E1 = {}));
//// [foo_1.js]
"use strict";
var i;

View File

@ -0,0 +1,123 @@
//// [constructorWithCapturedSuper.ts]
let oneA: A;
class A {
constructor() {
return oneA;
}
}
class B extends A {
constructor(x: number) {
super();
if (x === 1) {
return;
}
while (x < 2) {
return;
}
try {
return
}
catch (e) {
return;
}
finally {
return;
}
}
}
class C extends A {
constructor(x: number) {
super();
for (let i = 0; i < 10; ++i) {
() => i + x;
if (x === 1) {
return;
}
}
}
}
class D extends A {
constructor(x: number) {
super();
() => {
return;
}
function foo() {
return;
}
}
}
//// [constructorWithCapturedSuper.js]
var __extends = (this && this.__extends) || function (d, b) {
for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
var oneA;
var A = (function () {
function A() {
return oneA;
}
return A;
}());
var B = (function (_super) {
__extends(B, _super);
function B(x) {
var _this = _super.call(this) || this;
if (x === 1) {
return _this;
}
while (x < 2) {
return _this;
}
try {
return _this;
}
catch (e) {
return _this;
}
finally {
return _this;
}
return _this;
}
return B;
}(A));
var C = (function (_super) {
__extends(C, _super);
function C(x) {
var _this = _super.call(this) || this;
var _loop_1 = function (i) {
(function () { return i + x; });
if (x === 1) {
return { value: _this };
}
};
for (var i = 0; i < 10; ++i) {
var state_1 = _loop_1(i);
if (typeof state_1 === "object")
return state_1.value;
}
return _this;
}
return C;
}(A));
var D = (function (_super) {
__extends(D, _super);
function D(x) {
var _this = _super.call(this) || this;
(function () {
return;
});
function foo() {
return;
}
return _this;
}
return D;
}(A));

View File

@ -0,0 +1,96 @@
=== tests/cases/compiler/constructorWithCapturedSuper.ts ===
let oneA: A;
>oneA : Symbol(oneA, Decl(constructorWithCapturedSuper.ts, 0, 3))
>A : Symbol(A, Decl(constructorWithCapturedSuper.ts, 0, 12))
class A {
>A : Symbol(A, Decl(constructorWithCapturedSuper.ts, 0, 12))
constructor() {
return oneA;
>oneA : Symbol(oneA, Decl(constructorWithCapturedSuper.ts, 0, 3))
}
}
class B extends A {
>B : Symbol(B, Decl(constructorWithCapturedSuper.ts, 6, 1))
>A : Symbol(A, Decl(constructorWithCapturedSuper.ts, 0, 12))
constructor(x: number) {
>x : Symbol(x, Decl(constructorWithCapturedSuper.ts, 9, 16))
super();
>super : Symbol(A, Decl(constructorWithCapturedSuper.ts, 0, 12))
if (x === 1) {
>x : Symbol(x, Decl(constructorWithCapturedSuper.ts, 9, 16))
return;
}
while (x < 2) {
>x : Symbol(x, Decl(constructorWithCapturedSuper.ts, 9, 16))
return;
}
try {
return
}
catch (e) {
>e : Symbol(e, Decl(constructorWithCapturedSuper.ts, 20, 15))
return;
}
finally {
return;
}
}
}
class C extends A {
>C : Symbol(C, Decl(constructorWithCapturedSuper.ts, 27, 1))
>A : Symbol(A, Decl(constructorWithCapturedSuper.ts, 0, 12))
constructor(x: number) {
>x : Symbol(x, Decl(constructorWithCapturedSuper.ts, 30, 16))
super();
>super : Symbol(A, Decl(constructorWithCapturedSuper.ts, 0, 12))
for (let i = 0; i < 10; ++i) {
>i : Symbol(i, Decl(constructorWithCapturedSuper.ts, 32, 16))
>i : Symbol(i, Decl(constructorWithCapturedSuper.ts, 32, 16))
>i : Symbol(i, Decl(constructorWithCapturedSuper.ts, 32, 16))
() => i + x;
>i : Symbol(i, Decl(constructorWithCapturedSuper.ts, 32, 16))
>x : Symbol(x, Decl(constructorWithCapturedSuper.ts, 30, 16))
if (x === 1) {
>x : Symbol(x, Decl(constructorWithCapturedSuper.ts, 30, 16))
return;
}
}
}
}
class D extends A {
>D : Symbol(D, Decl(constructorWithCapturedSuper.ts, 39, 1))
>A : Symbol(A, Decl(constructorWithCapturedSuper.ts, 0, 12))
constructor(x: number) {
>x : Symbol(x, Decl(constructorWithCapturedSuper.ts, 42, 16))
super();
>super : Symbol(A, Decl(constructorWithCapturedSuper.ts, 0, 12))
() => {
return;
}
function foo() {
>foo : Symbol(foo, Decl(constructorWithCapturedSuper.ts, 46, 9))
return;
}
}
}

View File

@ -0,0 +1,113 @@
=== tests/cases/compiler/constructorWithCapturedSuper.ts ===
let oneA: A;
>oneA : A
>A : A
class A {
>A : A
constructor() {
return oneA;
>oneA : A
}
}
class B extends A {
>B : B
>A : A
constructor(x: number) {
>x : number
super();
>super() : void
>super : typeof A
if (x === 1) {
>x === 1 : boolean
>x : number
>1 : 1
return;
}
while (x < 2) {
>x < 2 : boolean
>x : number
>2 : 2
return;
}
try {
return
}
catch (e) {
>e : any
return;
}
finally {
return;
}
}
}
class C extends A {
>C : C
>A : A
constructor(x: number) {
>x : number
super();
>super() : void
>super : typeof A
for (let i = 0; i < 10; ++i) {
>i : number
>0 : 0
>i < 10 : boolean
>i : number
>10 : 10
>++i : number
>i : number
() => i + x;
>() => i + x : () => number
>i + x : number
>i : number
>x : number
if (x === 1) {
>x === 1 : boolean
>x : number
>1 : 1
return;
}
}
}
}
class D extends A {
>D : D
>A : A
constructor(x: number) {
>x : number
super();
>super() : void
>super : typeof A
() => {
>() => { return; } : () => void
return;
}
function foo() {
>foo : () => void
return;
}
}
}

View File

@ -31,12 +31,12 @@ var m1;
return c;
}());
m1.c = c;
var e;
(function (e) {
e[e["weekday"] = 0] = "weekday";
e[e["weekend"] = 1] = "weekend";
e[e["holiday"] = 2] = "holiday";
})(m1.e || (m1.e = {}));
var e = m1.e;
})(e = m1.e || (m1.e = {}));
})(m1 || (m1 = {}));
var a;
var b = {

View File

@ -33,9 +33,9 @@ var X;
var M;
(function (M) {
})(M = base.M || (base.M = {}));
var E;
(function (E) {
})(base.E || (base.E = {}));
var E = base.E;
})(E = base.E || (base.E = {}));
})(base = Y.base || (Y.base = {}));
})(Y = X.Y || (X.Y = {}));
})(X || (X = {}));

View File

@ -68,10 +68,10 @@ var M;
return E;
}(C));
P.E = E;
var D;
(function (D) {
D[D["f"] = 0] = "f";
})(P.D || (P.D = {}));
var D = P.D;
})(D = P.D || (P.D = {}));
P.w = M.D.f; // error, should be typeof M.D.f
P.x = M.C.f; // error, should be typeof M.C.f
P.x = M.E.f; // error, should be typeof M.E.f

View File

@ -0,0 +1,22 @@
//// [tests/cases/compiler/declarationFilesWithTypeReferences1.ts] ////
//// [index.d.ts]
interface Error {
stack2: string;
}
//// [app.ts]
function foo(): Error {
return undefined;
}
//// [app.js]
function foo() {
return undefined;
}
//// [app.d.ts]
declare function foo(): Error;

View File

@ -0,0 +1,18 @@
=== /node_modules/@types/node/index.d.ts ===
interface Error {
>Error : Symbol(Error, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(index.d.ts, 0, 0))
stack2: string;
>stack2 : Symbol(Error.stack2, Decl(index.d.ts, 1, 17))
}
=== /app.ts ===
function foo(): Error {
>foo : Symbol(foo, Decl(app.ts, 0, 0))
>Error : Symbol(Error, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(index.d.ts, 0, 0))
return undefined;
>undefined : Symbol(undefined)
}

View File

@ -0,0 +1,18 @@
=== /node_modules/@types/node/index.d.ts ===
interface Error {
>Error : Error
stack2: string;
>stack2 : string
}
=== /app.ts ===
function foo(): Error {
>foo : () => Error
>Error : Error
return undefined;
>undefined : undefined
}

View File

@ -0,0 +1,23 @@
//// [tests/cases/compiler/declarationFilesWithTypeReferences2.ts] ////
//// [index.d.ts]
interface Error2 {
stack2: string;
}
//// [app.ts]
function foo(): Error2 {
return undefined;
}
//// [app.js]
function foo() {
return undefined;
}
//// [app.d.ts]
/// <reference types="node" />
declare function foo(): Error2;

View File

@ -0,0 +1,18 @@
=== /node_modules/@types/node/index.d.ts ===
interface Error2 {
>Error2 : Symbol(Error2, Decl(index.d.ts, 0, 0))
stack2: string;
>stack2 : Symbol(Error2.stack2, Decl(index.d.ts, 1, 18))
}
=== /app.ts ===
function foo(): Error2 {
>foo : Symbol(foo, Decl(app.ts, 0, 0))
>Error2 : Symbol(Error2, Decl(index.d.ts, 0, 0))
return undefined;
>undefined : Symbol(undefined)
}

View File

@ -0,0 +1,18 @@
=== /node_modules/@types/node/index.d.ts ===
interface Error2 {
>Error2 : Error2
stack2: string;
>stack2 : string
}
=== /app.ts ===
function foo(): Error2 {
>foo : () => Error2
>Error2 : Error2
return undefined;
>undefined : undefined
}

View File

@ -0,0 +1,24 @@
//// [tests/cases/compiler/declarationFilesWithTypeReferences3.ts] ////
//// [index.d.ts]
interface Error2 {
stack2: string;
}
//// [app.ts]
/// <reference types="node"/>
function foo(): Error2 {
return undefined;
}
//// [app.js]
/// <reference types="node"/>
function foo() {
return undefined;
}
//// [app.d.ts]
/// <reference types="node" />
declare function foo(): Error2;

View File

@ -0,0 +1,18 @@
=== /a/node_modules/@types/node/index.d.ts ===
interface Error2 {
>Error2 : Symbol(Error2, Decl(index.d.ts, 0, 0))
stack2: string;
>stack2 : Symbol(Error2.stack2, Decl(index.d.ts, 1, 18))
}
=== /a/app.ts ===
/// <reference types="node"/>
function foo(): Error2 {
>foo : Symbol(foo, Decl(app.ts, 0, 0))
>Error2 : Symbol(Error2, Decl(index.d.ts, 0, 0))
return undefined;
>undefined : Symbol(undefined)
}

View File

@ -0,0 +1,18 @@
=== /a/node_modules/@types/node/index.d.ts ===
interface Error2 {
>Error2 : Error2
stack2: string;
>stack2 : string
}
=== /a/app.ts ===
/// <reference types="node"/>
function foo(): Error2 {
>foo : () => Error2
>Error2 : Error2
return undefined;
>undefined : undefined
}

View File

@ -0,0 +1,23 @@
//// [tests/cases/compiler/declarationFilesWithTypeReferences4.ts] ////
//// [index.d.ts]
interface Error {
stack2: string;
}
//// [app.ts]
/// <reference types="node"/>
function foo(): Error {
return undefined;
}
//// [app.js]
/// <reference types="node"/>
function foo() {
return undefined;
}
//// [app.d.ts]
declare function foo(): Error;

View File

@ -0,0 +1,18 @@
=== /a/node_modules/@types/node/index.d.ts ===
interface Error {
>Error : Symbol(Error, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(index.d.ts, 0, 0))
stack2: string;
>stack2 : Symbol(Error.stack2, Decl(index.d.ts, 1, 17))
}
=== /a/app.ts ===
/// <reference types="node"/>
function foo(): Error {
>foo : Symbol(foo, Decl(app.ts, 0, 0))
>Error : Symbol(Error, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(index.d.ts, 0, 0))
return undefined;
>undefined : Symbol(undefined)
}

View File

@ -0,0 +1,18 @@
=== /a/node_modules/@types/node/index.d.ts ===
interface Error {
>Error : Error
stack2: string;
>stack2 : string
}
=== /a/app.ts ===
/// <reference types="node"/>
function foo(): Error {
>foo : () => Error
>Error : Error
return undefined;
>undefined : undefined
}

View File

@ -17,12 +17,12 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
var __metadata = (this && this.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
let Testing123_1 = class Testing123 {
let Testing123 = Testing123_1 = class Testing123 {
};
let Testing123 = Testing123_1;
Testing123.prop1 = Testing123_1.prop0;
Testing123 = Testing123_1 = __decorate([
Something({ v: () => Testing123_1 }),
__metadata("design:paramtypes", [])
], Testing123);
exports.Testing123 = Testing123;
var Testing123_1;

View File

@ -16,11 +16,11 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
var __metadata = (this && this.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
let Testing123_1 = class Testing123 {
let Testing123 = Testing123_1 = class Testing123 {
};
let Testing123 = Testing123_1;
Testing123 = Testing123_1 = __decorate([
Something({ v: () => Testing123_1 }),
__metadata("design:paramtypes", [])
], Testing123);
exports.Testing123 = Testing123;
var Testing123_1;

View File

@ -21,13 +21,12 @@ System.register([], function (exports_1, context_1) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
var __moduleName = context_1 && context_1.id;
var Testing123_1, Testing123;
var Testing123, Testing123_1;
return {
setters: [],
execute: function () {
Testing123_1 = class Testing123 {
Testing123 = Testing123_1 = class Testing123 {
};
Testing123 = Testing123_1;
Testing123.prop1 = Testing123_1.prop0;
Testing123 = Testing123_1 = __decorate([
Something({ v: () => Testing123_1 }),

View File

@ -18,13 +18,12 @@ System.register([], function (exports_1, context_1) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
var __moduleName = context_1 && context_1.id;
var Testing123_1, Testing123;
var Testing123, Testing123_1;
return {
setters: [],
execute: function () {
Testing123_1 = class Testing123 {
Testing123 = Testing123_1 = class Testing123 {
};
Testing123 = Testing123_1;
Testing123 = Testing123_1 = __decorate([
Something({ v: () => Testing123_1 }),
__metadata("design:paramtypes", [])

View File

@ -33,8 +33,8 @@ var B = (function () {
}
return B;
}());
exports.B = B;
__decorate([
decorator,
__metadata("design:type", Object)
], B.prototype, "x", void 0);
exports.B = B;

View File

@ -33,8 +33,8 @@ var B = (function () {
}
return B;
}());
exports.B = B;
__decorate([
decorator,
__metadata("design:type", A)
], B.prototype, "x", void 0);
exports.B = B;

View File

@ -16,12 +16,12 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
let C_1 = class C {
let C = C_1 = class C {
static x() { return C_1.y; }
};
let C = C_1;
C.y = 1;
C = C_1 = __decorate([
dec
], C);
let c = new C();
var C_1;

View File

@ -16,13 +16,13 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
let C_1 = class C {
let C = C_1 = class C {
static x() { return C_1.y; }
};
let C = C_1;
C.y = 1;
C = C_1 = __decorate([
dec
], C);
export { C };
let c = new C();
var C_1;

View File

@ -16,13 +16,13 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
let C_1 = class C {
let C = C_1 = class C {
static x() { return C_1.y; }
};
let C = C_1;
C.y = 1;
C = C_1 = __decorate([
dec
], C);
export default C;
let c = new C();
var C_1;

View File

@ -33,7 +33,7 @@ var Decl = (function () {
return Decl;
}());
Object.defineProperty(exports, "__esModule", { value: true });
exports.default = exports.Decl;
exports.default = Decl;
//// [m2.js]
"use strict";
var m1_1 = require("m1");

View File

@ -18,7 +18,7 @@ export interface Foo {
function Foo() {
}
Object.defineProperty(exports, "__esModule", { value: true });
exports.default = exports.Foo;
exports.default = Foo;
var Foo;
(function (Foo) {
})(exports.Foo || (exports.Foo = {}));
})(Foo || (Foo = {}));

View File

@ -138,9 +138,9 @@ var m;
}
return City;
}());
var Enum;
(function (Enum) {
Enum[Enum["claw"] = (function () { return 10; })()] = "claw";
})(m.Enum || (m.Enum = {}));
var Enum = m.Enum;
})(Enum = m.Enum || (m.Enum = {}));
m.v = function (x) { return new City(Enum.claw); };
})(m || (m = {}));

View File

@ -14,8 +14,8 @@ System.register([], function (exports_1, context_1) {
function bar() {
return A.B.C.foo();
}
var A;
exports_1("bar", bar);
var A;
return {
setters: [],
execute: function () {
@ -28,7 +28,7 @@ System.register([], function (exports_1, context_1) {
C.foo = foo;
})(C = B.C || (B.C = {}));
})(B = A.B || (A.B = {}));
})(A = A || (A = {}));
})(A || (A = {}));
exports_1("A", A);
}
};

View File

@ -92,78 +92,77 @@ merged2 = abc; // ok
//// [enumAssignmentCompat3.js]
var First;
(function (First) {
var E;
(function (E) {
E[E["a"] = 0] = "a";
E[E["b"] = 1] = "b";
E[E["c"] = 2] = "c";
})(First.E || (First.E = {}));
var E = First.E;
})(E = First.E || (First.E = {}));
})(First || (First = {}));
var Abc;
(function (Abc) {
var E;
(function (E) {
E[E["a"] = 0] = "a";
E[E["b"] = 1] = "b";
E[E["c"] = 2] = "c";
})(Abc.E || (Abc.E = {}));
var E = Abc.E;
})(E = Abc.E || (Abc.E = {}));
var Nope;
(function (Nope) {
Nope[Nope["a"] = 0] = "a";
Nope[Nope["b"] = 1] = "b";
Nope[Nope["c"] = 2] = "c";
})(Abc.Nope || (Abc.Nope = {}));
var Nope = Abc.Nope;
})(Nope = Abc.Nope || (Abc.Nope = {}));
})(Abc || (Abc = {}));
var Abcd;
(function (Abcd) {
var E;
(function (E) {
E[E["a"] = 0] = "a";
E[E["b"] = 1] = "b";
E[E["c"] = 2] = "c";
E[E["d"] = 3] = "d";
})(Abcd.E || (Abcd.E = {}));
var E = Abcd.E;
})(E = Abcd.E || (Abcd.E = {}));
})(Abcd || (Abcd = {}));
var Ab;
(function (Ab) {
var E;
(function (E) {
E[E["a"] = 0] = "a";
E[E["b"] = 1] = "b";
})(Ab.E || (Ab.E = {}));
var E = Ab.E;
})(E = Ab.E || (Ab.E = {}));
})(Ab || (Ab = {}));
var Cd;
(function (Cd) {
var E;
(function (E) {
E[E["c"] = 0] = "c";
E[E["d"] = 1] = "d";
})(Cd.E || (Cd.E = {}));
var E = Cd.E;
})(E = Cd.E || (Cd.E = {}));
})(Cd || (Cd = {}));
var Decl;
(function (Decl) {
})(Decl || (Decl = {}));
var Merged;
(function (Merged) {
var E;
(function (E) {
E[E["a"] = 0] = "a";
E[E["b"] = 1] = "b";
})(Merged.E || (Merged.E = {}));
var E = Merged.E;
})(E = Merged.E || (Merged.E = {}));
(function (E) {
E[E["c"] = 3] = "c";
E[E["d"] = 4] = "d";
})(Merged.E || (Merged.E = {}));
var E = Merged.E;
})(E = Merged.E || (Merged.E = {}));
})(Merged || (Merged = {}));
var Merged2;
(function (Merged2) {
var E;
(function (E) {
E[E["a"] = 0] = "a";
E[E["b"] = 1] = "b";
E[E["c"] = 2] = "c";
})(Merged2.E || (Merged2.E = {}));
var E = Merged2.E;
})(E = Merged2.E || (Merged2.E = {}));
(function (E) {
E.d = 5;
})(E = Merged2.E || (Merged2.E = {}));

View File

@ -26,20 +26,20 @@ let broken = [
//// [enumAssignmentCompat4.js]
var M;
(function (M) {
var MyEnum;
(function (MyEnum) {
MyEnum[MyEnum["BAR"] = 0] = "BAR";
})(M.MyEnum || (M.MyEnum = {}));
var MyEnum = M.MyEnum;
})(MyEnum = M.MyEnum || (M.MyEnum = {}));
M.object2 = {
foo: MyEnum.BAR
};
})(M || (M = {}));
var N;
(function (N) {
var MyEnum;
(function (MyEnum) {
MyEnum[MyEnum["FOO"] = 0] = "FOO";
})(N.MyEnum || (N.MyEnum = {}));
var MyEnum = N.MyEnum;
})(MyEnum = N.MyEnum || (N.MyEnum = {}));
;
N.object1 = {
foo: MyEnum.FOO

View File

@ -12,10 +12,10 @@ var x = f.Mode.Open;
//// [enumFromExternalModule_0.js]
"use strict";
var Mode;
(function (Mode) {
Mode[Mode["Open"] = 0] = "Open";
})(exports.Mode || (exports.Mode = {}));
var Mode = exports.Mode;
})(Mode = exports.Mode || (exports.Mode = {}));
//// [enumFromExternalModule_1.js]
"use strict";
///<reference path='enumFromExternalModule_0.ts'/>

View File

@ -32,35 +32,35 @@ const e5: Ka.Foo | boolean = Z.Foo.A; // ok
//// [enumLiteralAssignableToEnumInsideUnion.js]
var X;
(function (X) {
var Foo;
(function (Foo) {
Foo[Foo["A"] = 0] = "A";
Foo[Foo["B"] = 1] = "B";
})(X.Foo || (X.Foo = {}));
var Foo = X.Foo;
})(Foo = X.Foo || (X.Foo = {}));
})(X || (X = {}));
var Y;
(function (Y) {
var Foo;
(function (Foo) {
Foo[Foo["A"] = 0] = "A";
Foo[Foo["B"] = 1] = "B";
})(Y.Foo || (Y.Foo = {}));
var Foo = Y.Foo;
})(Foo = Y.Foo || (Y.Foo = {}));
})(Y || (Y = {}));
var Z;
(function (Z) {
var Foo;
(function (Foo) {
Foo[Foo["A"] = 2] = "A";
Foo[Foo["B"] = 4] = "B";
})(Z.Foo || (Z.Foo = {}));
var Foo = Z.Foo;
})(Foo = Z.Foo || (Z.Foo = {}));
})(Z || (Z = {}));
var Ka;
(function (Ka) {
var Foo;
(function (Foo) {
Foo[Foo["A"] = 1024] = "A";
Foo[Foo["B"] = 2048] = "B";
})(Ka.Foo || (Ka.Foo = {}));
var Foo = Ka.Foo;
})(Foo = Ka.Foo || (Ka.Foo = {}));
})(Ka || (Ka = {}));
var e0 = Y.Foo.A; // ok
var e1 = Z.Foo.A; // not legal, Z is computed

View File

@ -82,35 +82,33 @@ var M1;
EImpl1[EImpl1["E"] = 2] = "E";
EImpl1[EImpl1["F"] = 3] = "F";
})(EImpl1 || (EImpl1 = {}));
var EConst1;
(function (EConst1) {
EConst1[EConst1["A"] = 3] = "A";
EConst1[EConst1["B"] = 2] = "B";
EConst1[EConst1["C"] = 1] = "C";
})(M1.EConst1 || (M1.EConst1 = {}));
var EConst1 = M1.EConst1;
})(EConst1 = M1.EConst1 || (M1.EConst1 = {}));
(function (EConst1) {
EConst1[EConst1["D"] = 7] = "D";
EConst1[EConst1["E"] = 9] = "E";
EConst1[EConst1["F"] = 8] = "F";
})(M1.EConst1 || (M1.EConst1 = {}));
var EConst1 = M1.EConst1;
})(EConst1 = M1.EConst1 || (M1.EConst1 = {}));
var x = [EConst1.A, EConst1.B, EConst1.C, EConst1.D, EConst1.E, EConst1.F];
})(M1 || (M1 = {}));
// Enum with only computed members across 2 declarations with the same root module
var M2;
(function (M2) {
var EComp2;
(function (EComp2) {
EComp2[EComp2["A"] = 'foo'.length] = "A";
EComp2[EComp2["B"] = 'foo'.length] = "B";
EComp2[EComp2["C"] = 'foo'.length] = "C";
})(M2.EComp2 || (M2.EComp2 = {}));
var EComp2 = M2.EComp2;
})(EComp2 = M2.EComp2 || (M2.EComp2 = {}));
(function (EComp2) {
EComp2[EComp2["D"] = 'foo'.length] = "D";
EComp2[EComp2["E"] = 'foo'.length] = "E";
EComp2[EComp2["F"] = 'foo'.length] = "F";
})(M2.EComp2 || (M2.EComp2 = {}));
var EComp2 = M2.EComp2;
})(EComp2 = M2.EComp2 || (M2.EComp2 = {}));
var x = [EComp2.A, EComp2.B, EComp2.C, EComp2.D, EComp2.E, EComp2.F];
})(M2 || (M2 = {}));
// Enum with initializer in only one of two declarations with constant members with the same root module
@ -130,41 +128,41 @@ var M3;
// Enums with same name but different root module
var M4;
(function (M4) {
var Color;
(function (Color) {
Color[Color["Red"] = 0] = "Red";
Color[Color["Green"] = 1] = "Green";
Color[Color["Blue"] = 2] = "Blue";
})(M4.Color || (M4.Color = {}));
var Color = M4.Color;
})(Color = M4.Color || (M4.Color = {}));
})(M4 || (M4 = {}));
var M5;
(function (M5) {
var Color;
(function (Color) {
Color[Color["Red"] = 0] = "Red";
Color[Color["Green"] = 1] = "Green";
Color[Color["Blue"] = 2] = "Blue";
})(M5.Color || (M5.Color = {}));
var Color = M5.Color;
})(Color = M5.Color || (M5.Color = {}));
})(M5 || (M5 = {}));
var M6;
(function (M6) {
var A;
(function (A) {
var Color;
(function (Color) {
Color[Color["Red"] = 0] = "Red";
Color[Color["Green"] = 1] = "Green";
Color[Color["Blue"] = 2] = "Blue";
})(A.Color || (A.Color = {}));
var Color = A.Color;
})(Color = A.Color || (A.Color = {}));
})(A = M6.A || (M6.A = {}));
})(M6 || (M6 = {}));
(function (M6) {
var A;
(function (A) {
var Color;
(function (Color) {
Color[Color["Yellow"] = 1] = "Yellow";
})(A.Color || (A.Color = {}));
var Color = A.Color;
})(Color = A.Color || (A.Color = {}));
})(A = M6.A || (M6.A = {}));
var t = A.Color.Yellow;
t = A.Color.Red;

View File

@ -46,84 +46,84 @@ module M2 {
// Enum with constant, computed, constant members split across 3 declarations with the same root module
var M;
(function (M) {
var E1;
(function (E1) {
E1[E1["A"] = 0] = "A";
})(M.E1 || (M.E1 = {}));
var E1 = M.E1;
})(E1 = M.E1 || (M.E1 = {}));
var E2;
(function (E2) {
E2[E2["C"] = 0] = "C";
})(M.E2 || (M.E2 = {}));
var E2 = M.E2;
})(E2 = M.E2 || (M.E2 = {}));
var E3;
(function (E3) {
E3[E3["A"] = 0] = "A";
})(M.E3 || (M.E3 = {}));
var E3 = M.E3;
})(E3 = M.E3 || (M.E3 = {}));
})(M || (M = {}));
(function (M) {
var E1;
(function (E1) {
E1[E1["B"] = 'foo'.length] = "B";
})(M.E1 || (M.E1 = {}));
var E1 = M.E1;
})(E1 = M.E1 || (M.E1 = {}));
var E2;
(function (E2) {
E2[E2["B"] = 'foo'.length] = "B";
})(M.E2 || (M.E2 = {}));
var E2 = M.E2;
})(E2 = M.E2 || (M.E2 = {}));
var E3;
(function (E3) {
E3[E3["C"] = 0] = "C";
})(M.E3 || (M.E3 = {}));
var E3 = M.E3;
})(E3 = M.E3 || (M.E3 = {}));
})(M || (M = {}));
(function (M) {
var E1;
(function (E1) {
E1[E1["C"] = 0] = "C";
})(M.E1 || (M.E1 = {}));
var E1 = M.E1;
})(E1 = M.E1 || (M.E1 = {}));
var E2;
(function (E2) {
E2[E2["A"] = 0] = "A";
})(M.E2 || (M.E2 = {}));
var E2 = M.E2;
})(E2 = M.E2 || (M.E2 = {}));
var E3;
(function (E3) {
E3[E3["B"] = 'foo'.length] = "B";
})(M.E3 || (M.E3 = {}));
var E3 = M.E3;
})(E3 = M.E3 || (M.E3 = {}));
})(M || (M = {}));
// Enum with no initializer in either declaration with constant members with the same root module
var M1;
(function (M1) {
var E1;
(function (E1) {
E1[E1["A"] = 0] = "A";
})(M1.E1 || (M1.E1 = {}));
var E1 = M1.E1;
})(E1 = M1.E1 || (M1.E1 = {}));
})(M1 || (M1 = {}));
(function (M1) {
var E1;
(function (E1) {
E1[E1["B"] = 0] = "B";
})(M1.E1 || (M1.E1 = {}));
var E1 = M1.E1;
})(E1 = M1.E1 || (M1.E1 = {}));
})(M1 || (M1 = {}));
(function (M1) {
var E1;
(function (E1) {
E1[E1["C"] = 0] = "C";
})(M1.E1 || (M1.E1 = {}));
var E1 = M1.E1;
})(E1 = M1.E1 || (M1.E1 = {}));
})(M1 || (M1 = {}));
// Enum with initializer in only one of three declarations with constant members with the same root module
var M2;
(function (M2) {
var E1;
(function (E1) {
E1[E1["A"] = 0] = "A";
})(M2.E1 || (M2.E1 = {}));
var E1 = M2.E1;
})(E1 = M2.E1 || (M2.E1 = {}));
})(M2 || (M2 = {}));
(function (M2) {
var E1;
(function (E1) {
E1[E1["B"] = 0] = "B";
})(M2.E1 || (M2.E1 = {}));
var E1 = M2.E1;
})(E1 = M2.E1 || (M2.E1 = {}));
})(M2 || (M2 = {}));
(function (M2) {
var E1;
(function (E1) {
E1[E1["C"] = 0] = "C";
})(M2.E1 || (M2.E1 = {}));
var E1 = M2.E1;
})(E1 = M2.E1 || (M2.E1 = {}));
})(M2 || (M2 = {}));

View File

@ -21,8 +21,8 @@ var Foo = (function () {
}
return Foo;
}());
exports.Foo = Foo;
Foo.CONSTANT = "Foo";
exports.Foo = Foo;
function assert(value) {
if (!value)
throw new Error("Assertion failed!");

View File

@ -8,7 +8,6 @@ export = f;
//// [es5ExportEquals.js]
"use strict";
function f() { }
exports.f = f;
module.exports = f;

View File

@ -59,9 +59,9 @@ define(["require", "exports"], function (require, exports) {
function M_F() { }
M.M_F = M_F;
// enum
var M_E;
(function (M_E) {
})(M.M_E || (M.M_E = {}));
var M_E = M.M_E;
})(M_E = M.M_E || (M.M_E = {}));
// alias
M.M_A = M_M;
})(M = exports.M || (exports.M = {}));

View File

@ -63,12 +63,12 @@ var x = 0 /* a */;
var y = 0 /* x */;
export var m1;
(function (m1) {
var e3;
(function (e3) {
e3[e3["a"] = 0] = "a";
e3[e3["b"] = 1] = "b";
e3[e3["c"] = 2] = "c";
})(m1.e3 || (m1.e3 = {}));
var e3 = m1.e3;
})(e3 = m1.e3 || (m1.e3 = {}));
var e4;
(function (e4) {
e4[e4["x"] = 0] = "x";
@ -82,12 +82,12 @@ export var m1;
})(m1 || (m1 = {}));
var m2;
(function (m2) {
var e5;
(function (e5) {
e5[e5["a"] = 0] = "a";
e5[e5["b"] = 1] = "b";
e5[e5["c"] = 2] = "c";
})(m2.e5 || (m2.e5 = {}));
var e5 = m2.e5;
})(e5 = m2.e5 || (m2.e5 = {}));
var e6;
(function (e6) {
e6[e6["x"] = 0] = "x";

View File

@ -62,12 +62,12 @@ var x = e1.a;
var y = e2.x;
export var m1;
(function (m1) {
var e3;
(function (e3) {
e3[e3["a"] = 0] = "a";
e3[e3["b"] = 1] = "b";
e3[e3["c"] = 2] = "c";
})(m1.e3 || (m1.e3 = {}));
var e3 = m1.e3;
})(e3 = m1.e3 || (m1.e3 = {}));
var e4;
(function (e4) {
e4[e4["x"] = 0] = "x";
@ -81,12 +81,12 @@ export var m1;
})(m1 || (m1 = {}));
var m2;
(function (m2) {
var e5;
(function (e5) {
e5[e5["a"] = 0] = "a";
e5[e5["b"] = 1] = "b";
e5[e5["c"] = 2] = "c";
})(m2.e5 || (m2.e5 = {}));
var e5 = m2.e5;
})(e5 = m2.e5 || (m2.e5 = {}));
var e6;
(function (e6) {
e6[e6["x"] = 0] = "x";

View File

@ -50,9 +50,9 @@ export var M;
function M_F() { }
M.M_F = M_F;
// enum
var M_E;
(function (M_E) {
})(M.M_E || (M.M_E = {}));
var M_E = M.M_E;
})(M_E = M.M_E || (M.M_E = {}));
// alias
M.M_A = M_M;
})(M || (M = {}));

View File

@ -52,9 +52,9 @@ export var M;
function M_F() { }
M.M_F = M_F;
// enum
var M_E;
(function (M_E) {
})(M.M_E || (M.M_E = {}));
var M_E = M.M_E;
})(M_E = M.M_E || (M.M_E = {}));
// alias
M.M_A = M_M;
})(M || (M = {}));

View File

@ -27,13 +27,14 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
export var C = (function () {
var C = (function () {
function C() {
this.p = 1;
}
C.prototype.method = function () { };
return C;
}());
export { C };
C.s = 0;
export { C as C2 };
var D = (function () {

Some files were not shown because too many files have changed in this diff Show More