Skip to content

Commit bb26ab5

Browse files
committed
Merge branch 'master' into vfs
2 parents e422365 + 054a6ff commit bb26ab5

File tree

243 files changed

+3141
-1362
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

243 files changed

+3141
-1362
lines changed

src/compiler/binder.ts

+9-5
Original file line numberDiff line numberDiff line change
@@ -516,8 +516,9 @@ namespace ts {
516516
const saveReturnTarget = currentReturnTarget;
517517
const saveActiveLabels = activeLabels;
518518
const saveHasExplicitReturn = hasExplicitReturn;
519-
const isIIFE = containerFlags & ContainerFlags.IsFunctionExpression && !hasModifier(node, ModifierFlags.Async) && !!getImmediatelyInvokedFunctionExpression(node);
520-
// A non-async IIFE is considered part of the containing control flow. Return statements behave
519+
const isIIFE = containerFlags & ContainerFlags.IsFunctionExpression && !hasModifier(node, ModifierFlags.Async) &&
520+
!(<FunctionLikeDeclaration>node).asteriskToken && !!getImmediatelyInvokedFunctionExpression(node);
521+
// A non-async, non-generator IIFE is considered part of the containing control flow. Return statements behave
521522
// similarly to break statements that exit to a label just past the statement body.
522523
if (!isIIFE) {
523524
currentFlow = { flags: FlowFlags.Start };
@@ -2219,14 +2220,14 @@ namespace ts {
22192220
bindAnonymousDeclaration(file, SymbolFlags.ValueModule, `"${removeFileExtension(file.fileName)}"` as __String);
22202221
}
22212222

2222-
function bindExportAssignment(node: ExportAssignment | BinaryExpression) {
2223+
function bindExportAssignment(node: ExportAssignment) {
22232224
if (!container.symbol || !container.symbol.exports) {
22242225
// Export assignment in some sort of block construct
22252226
bindAnonymousDeclaration(node, SymbolFlags.Alias, getDeclarationName(node));
22262227
}
22272228
else {
22282229
const flags = node.kind === SyntaxKind.ExportAssignment && exportAssignmentIsAlias(node)
2229-
// An export default clause with an EntityNameExpression exports all meanings of that identifier
2230+
// An export default clause with an EntityNameExpression or a class expression exports all meanings of that identifier or expression;
22302231
? SymbolFlags.Alias
22312232
// An export default clause with any other expression exports a value
22322233
: SymbolFlags.Property;
@@ -2321,7 +2322,10 @@ namespace ts {
23212322

23222323
// 'module.exports = expr' assignment
23232324
setCommonJsModuleIndicator(node);
2324-
declareSymbol(file.symbol.exports, file.symbol, node, SymbolFlags.Property | SymbolFlags.ExportValue | SymbolFlags.ValueModule, SymbolFlags.None);
2325+
const flags = exportAssignmentIsAlias(node)
2326+
? SymbolFlags.Alias // An export= with an EntityNameExpression or a ClassExpression exports all meanings of that identifier or class
2327+
: SymbolFlags.Property | SymbolFlags.ExportValue | SymbolFlags.ValueModule;
2328+
declareSymbol(file.symbol.exports, file.symbol, node, flags, SymbolFlags.None);
23252329
}
23262330

23272331
function bindThisPropertyAssignment(node: BinaryExpression | PropertyAccessExpression) {

src/compiler/checker.ts

+268-208
Large diffs are not rendered by default.

src/compiler/commandLineParser.ts

+6
Original file line numberDiff line numberDiff line change
@@ -672,6 +672,12 @@ namespace ts {
672672
category: Diagnostics.Advanced_Options,
673673
description: Diagnostics.Disable_strict_checking_of_generic_signatures_in_function_types,
674674
},
675+
{
676+
name: "keyofStringsOnly",
677+
type: "boolean",
678+
category: Diagnostics.Advanced_Options,
679+
description: Diagnostics.Resolve_keyof_to_string_valued_property_names_only_no_numbers_or_symbols,
680+
},
675681
{
676682
// A list of plugins to load in the language service
677683
name: "plugins",

src/compiler/core.ts

+9
Original file line numberDiff line numberDiff line change
@@ -2212,6 +2212,15 @@ namespace ts {
22122212
return absolutePath;
22132213
}
22142214

2215+
export function getRelativePath(path: string, directoryPath: string, getCanonicalFileName: GetCanonicalFileName) {
2216+
const relativePath = getRelativePathToDirectoryOrUrl(directoryPath, path, directoryPath, getCanonicalFileName, /*isAbsolutePathAnUrl*/ false);
2217+
return ensurePathIsRelative(relativePath);
2218+
}
2219+
2220+
export function ensurePathIsRelative(path: string): string {
2221+
return !pathIsRelative(path) ? "./" + path : path;
2222+
}
2223+
22152224
export function getBaseFileName(path: string) {
22162225
if (path === undefined) {
22172226
return undefined;

src/compiler/diagnosticMessages.json

+4
Original file line numberDiff line numberDiff line change
@@ -3526,6 +3526,10 @@
35263526
"category": "Message",
35273527
"code": 6194
35283528
},
3529+
"Resolve 'keyof' to string valued property names only (no numbers or symbols).": {
3530+
"category": "Message",
3531+
"code": 6195
3532+
},
35293533
"Variable '{0}' implicitly has an '{1}' type.": {
35303534
"category": "Error",
35313535
"code": 7005

src/compiler/moduleNameResolver.ts

+6
Original file line numberDiff line numberDiff line change
@@ -444,6 +444,12 @@ namespace ts {
444444
}
445445
}
446446

447+
export function resolveModuleNameFromCache(moduleName: string, containingFile: string, cache: ModuleResolutionCache): ResolvedModuleWithFailedLookupLocations | undefined {
448+
const containingDirectory = getDirectoryPath(containingFile);
449+
const perFolderCache = cache && cache.getOrCreateCacheForDirectory(containingDirectory);
450+
return perFolderCache && perFolderCache.get(moduleName);
451+
}
452+
447453
export function resolveModuleName(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache?: ModuleResolutionCache): ResolvedModuleWithFailedLookupLocations {
448454
const traceEnabled = isTraceEnabled(compilerOptions, host);
449455
if (traceEnabled) {

src/compiler/program.ts

+6-4
Original file line numberDiff line numberDiff line change
@@ -622,9 +622,6 @@ namespace ts {
622622

623623
Debug.assert(!!missingFilePaths);
624624

625-
// unconditionally set moduleResolutionCache to undefined to avoid unnecessary leaks
626-
moduleResolutionCache = undefined;
627-
628625
// Release any files we have acquired in the old program but are
629626
// not part of the new program.
630627
if (oldProgram && host.onReleaseOldSourceFile) {
@@ -670,7 +667,8 @@ namespace ts {
670667
sourceFileToPackageName,
671668
redirectTargetsSet,
672669
isEmittedFile,
673-
getConfigFileParsingDiagnostics
670+
getConfigFileParsingDiagnostics,
671+
getResolvedModuleWithFailedLookupLocationsFromCache,
674672
};
675673

676674
verifyCompilerOptions();
@@ -679,6 +677,10 @@ namespace ts {
679677

680678
return program;
681679

680+
function getResolvedModuleWithFailedLookupLocationsFromCache(moduleName: string, containingFile: string): ResolvedModuleWithFailedLookupLocations {
681+
return moduleResolutionCache && resolveModuleNameFromCache(moduleName, containingFile, moduleResolutionCache);
682+
}
683+
682684
function toPath(fileName: string): Path {
683685
return ts.toPath(fileName, currentDirectory, getCanonicalFileName);
684686
}

src/compiler/types.ts

+14-11
Original file line numberDiff line numberDiff line change
@@ -2332,7 +2332,7 @@ namespace ts {
23322332
}
23332333

23342334
export interface JSDocTag extends Node {
2335-
parent: JSDoc;
2335+
parent: JSDoc | JSDocTypeLiteral;
23362336
atToken: AtToken;
23372337
tagName: Identifier;
23382338
comment: string | undefined;
@@ -2725,6 +2725,8 @@ namespace ts {
27252725
/* @internal */ redirectTargetsSet: Map<true>;
27262726
/** Is the file emitted file */
27272727
/* @internal */ isEmittedFile(file: string): boolean;
2728+
2729+
/* @internal */ getResolvedModuleWithFailedLookupLocationsFromCache(moduleName: string, containingFile: string): ResolvedModuleWithFailedLookupLocations | undefined;
27282730
}
27292731

27302732
/* @internal */
@@ -3375,6 +3377,7 @@ namespace ts {
33753377
/* @internal */ mergeId?: number; // Merge id (used to look up merged symbol)
33763378
/* @internal */ parent?: Symbol; // Parent symbol
33773379
/* @internal */ exportSymbol?: Symbol; // Exported symbol associated with this symbol
3380+
/* @internal */ nameType?: Type; // Type associated with a late-bound symbol
33783381
/* @internal */ constEnumOnlyModule?: boolean; // True if module contains only const enums or other modules with only const enums
33793382
/* @internal */ isReferenced?: SymbolFlags; // True if the symbol is referenced elsewhere. Keeps track of the meaning of a reference in case a symbol is both a type parameter and parameter.
33803383
/* @internal */ isReplaceableByMethod?: boolean; // Can this Javascript class property be replaced by a method symbol?
@@ -3409,7 +3412,6 @@ namespace ts {
34093412
enumKind?: EnumKind; // Enum declaration classification
34103413
originatingImport?: ImportDeclaration | ImportCall; // Import declaration which produced the symbol, present if the symbol is marked as uncallable but had call signatures in `resolveESModuleSymbol`
34113414
lateSymbol?: Symbol; // Late-bound symbol for a computed property
3412-
nameType?: Type; // Type associate with a late-bound or mapped type property symbol's name
34133415
}
34143416

34153417
/* @internal */
@@ -3606,7 +3608,7 @@ namespace ts {
36063608
Intrinsic = Any | String | Number | Boolean | BooleanLiteral | ESSymbol | Void | Undefined | Null | Never | NonPrimitive,
36073609
/* @internal */
36083610
Primitive = String | Number | Boolean | Enum | EnumLiteral | ESSymbol | Void | Undefined | Null | Literal | UniqueESSymbol,
3609-
StringLike = String | StringLiteral | Index,
3611+
StringLike = String | StringLiteral,
36103612
NumberLike = Number | NumberLiteral | Enum,
36113613
BooleanLike = Boolean | BooleanLiteral,
36123614
EnumLike = Enum | EnumLiteral,
@@ -3763,7 +3765,7 @@ namespace ts {
37633765
/* @internal */
37643766
resolvedIndexType: IndexType;
37653767
/* @internal */
3766-
resolvedDeclaredIndexType: IndexType;
3768+
resolvedStringIndexType: IndexType;
37673769
/* @internal */
37683770
resolvedBaseConstraint: Type;
37693771
/* @internal */
@@ -3852,7 +3854,7 @@ namespace ts {
38523854
/* @internal */
38533855
resolvedIndexType?: IndexType;
38543856
/* @internal */
3855-
resolvedDeclaredIndexType?: IndexType;
3857+
resolvedStringIndexType?: IndexType;
38563858
}
38573859

38583860
// Type parameters (TypeFlags.TypeParameter)
@@ -3884,9 +3886,9 @@ namespace ts {
38843886

38853887
// keyof T types (TypeFlags.Index)
38863888
export interface IndexType extends InstantiableType {
3887-
/* @internal */
3888-
isDeclaredType?: boolean;
38893889
type: InstantiableType | UnionOrIntersectionType;
3890+
/* @internal */
3891+
stringsOnly: boolean;
38903892
}
38913893

38923894
export interface ConditionalRoot {
@@ -4045,10 +4047,10 @@ namespace ts {
40454047

40464048
/* @internal */
40474049
export interface WideningContext {
4048-
parent?: WideningContext; // Parent context
4049-
propertyName?: __String; // Name of property in parent
4050-
siblings?: Type[]; // Types of siblings
4051-
resolvedPropertyNames?: __String[]; // Property names occurring in sibling object literals
4050+
parent?: WideningContext; // Parent context
4051+
propertyName?: __String; // Name of property in parent
4052+
siblings?: Type[]; // Types of siblings
4053+
resolvedProperties?: Symbol[]; // Properties occurring in sibling object literals
40524054
}
40534055

40544056
/* @internal */
@@ -4163,6 +4165,7 @@ namespace ts {
41634165
inlineSources?: boolean;
41644166
isolatedModules?: boolean;
41654167
jsx?: JsxEmit;
4168+
keyofStringsOnly?: boolean;
41664169
lib?: string[];
41674170
/*@internal*/listEmittedFiles?: boolean;
41684171
/*@internal*/listFiles?: boolean;

src/compiler/utilities.ts

+17-16
Original file line numberDiff line numberDiff line change
@@ -1818,10 +1818,8 @@ namespace ts {
18181818

18191819
function getJSDocCommentsAndTagsWorker(node: Node): void {
18201820
const parent = node.parent;
1821-
if (parent &&
1822-
(parent.kind === SyntaxKind.PropertyAssignment ||
1823-
parent.kind === SyntaxKind.PropertyDeclaration ||
1824-
getNestedModuleDeclaration(parent))) {
1821+
if (!parent) return;
1822+
if (parent.kind === SyntaxKind.PropertyAssignment || parent.kind === SyntaxKind.PropertyDeclaration || getNestedModuleDeclaration(parent)) {
18251823
getJSDocCommentsAndTagsWorker(parent);
18261824
}
18271825
// Try to recognize this pattern when node is initializer of variable declaration and JSDoc comments are on containing variable statement.
@@ -1830,16 +1828,18 @@ namespace ts {
18301828
// * @returns {number}
18311829
// */
18321830
// var x = function(name) { return name.length; }
1833-
if (parent && parent.parent &&
1831+
if (parent.parent &&
18341832
(getSingleVariableOfVariableStatement(parent.parent) === node || getSourceOfAssignment(parent.parent))) {
18351833
getJSDocCommentsAndTagsWorker(parent.parent);
18361834
}
1837-
if (parent && parent.parent && parent.parent.parent &&
1838-
(getSingleInitializerOfVariableStatementOrPropertyDeclaration(parent.parent.parent) === node || getSourceOfDefaultedAssignment(parent.parent.parent))) {
1835+
if (parent.parent && parent.parent.parent &&
1836+
(getSingleVariableOfVariableStatement(parent.parent.parent) ||
1837+
getSingleInitializerOfVariableStatementOrPropertyDeclaration(parent.parent.parent) === node ||
1838+
getSourceOfDefaultedAssignment(parent.parent.parent))) {
18391839
getJSDocCommentsAndTagsWorker(parent.parent.parent);
18401840
}
18411841
if (isBinaryExpression(node) && getSpecialPropertyAssignmentKind(node) !== SpecialPropertyAssignmentKind.None ||
1842-
parent && isBinaryExpression(parent) && getSpecialPropertyAssignmentKind(parent) !== SpecialPropertyAssignmentKind.None ||
1842+
isBinaryExpression(parent) && getSpecialPropertyAssignmentKind(parent) !== SpecialPropertyAssignmentKind.None ||
18431843
node.kind === SyntaxKind.PropertyAccessExpression && node.parent && node.parent.kind === SyntaxKind.ExpressionStatement) {
18441844
getJSDocCommentsAndTagsWorker(parent);
18451845
}
@@ -1888,6 +1888,9 @@ namespace ts {
18881888
}
18891889

18901890
export function getJSDocHost(node: JSDocTag): HasJSDoc {
1891+
while (node.parent.kind === SyntaxKind.JSDocTypeLiteral) {
1892+
node = node.parent.parent.parent as JSDocParameterTag;
1893+
}
18911894
Debug.assert(node.parent!.kind === SyntaxKind.JSDocComment);
18921895
return node.parent!.parent!;
18931896
}
@@ -2137,11 +2140,13 @@ namespace ts {
21372140
node.kind === SyntaxKind.NamespaceImport ||
21382141
node.kind === SyntaxKind.ImportSpecifier ||
21392142
node.kind === SyntaxKind.ExportSpecifier ||
2140-
node.kind === SyntaxKind.ExportAssignment && exportAssignmentIsAlias(<ExportAssignment>node);
2143+
node.kind === SyntaxKind.ExportAssignment && exportAssignmentIsAlias(<ExportAssignment>node) ||
2144+
isBinaryExpression(node) && getSpecialPropertyAssignmentKind(node) === SpecialPropertyAssignmentKind.ModuleExports;
21412145
}
21422146

2143-
export function exportAssignmentIsAlias(node: ExportAssignment): boolean {
2144-
return isEntityNameExpression(node.expression);
2147+
export function exportAssignmentIsAlias(node: ExportAssignment | BinaryExpression): boolean {
2148+
const e = isExportAssignment(node) ? node.expression : node.right;
2149+
return isEntityNameExpression(e) || isClassExpression(e);
21452150
}
21462151

21472152
export function getClassExtendsHeritageClauseElement(node: ClassLikeDeclaration | InterfaceDeclaration) {
@@ -2933,11 +2938,7 @@ namespace ts {
29332938
}
29342939

29352940
export function getFirstConstructorWithBody(node: ClassLikeDeclaration): ConstructorDeclaration {
2936-
return forEach(node.members, member => {
2937-
if (member.kind === SyntaxKind.Constructor && nodeIsPresent((<ConstructorDeclaration>member).body)) {
2938-
return <ConstructorDeclaration>member;
2939-
}
2940-
});
2941+
return find(node.members, (member): member is ConstructorDeclaration => isConstructorDeclaration(member) && nodeIsPresent(member.body));
29412942
}
29422943

29432944
function getSetAccessorValueParameter(accessor: SetAccessorDeclaration): ParameterDeclaration | undefined {

src/compiler/watch.ts

+29-5
Original file line numberDiff line numberDiff line change
@@ -33,14 +33,32 @@ namespace ts {
3333
Diagnostics.Found_0_errors_Watching_for_file_changes.code
3434
];
3535

36-
function clearScreenIfNotWatchingForFileChanges(system: System, diagnostic: Diagnostic, options: CompilerOptions) {
36+
/**
37+
* @returns Whether the screen was cleared.
38+
*/
39+
function clearScreenIfNotWatchingForFileChanges(system: System, diagnostic: Diagnostic, options: CompilerOptions): boolean {
3740
if (system.clearScreen &&
3841
!options.preserveWatchOutput &&
3942
!options.extendedDiagnostics &&
4043
!options.diagnostics &&
4144
!contains(nonClearingMessageCodes, diagnostic.code)) {
4245
system.clearScreen();
46+
return true;
4347
}
48+
49+
return false;
50+
}
51+
52+
/** @internal */
53+
export const screenStartingMessageCodes: number[] = [
54+
Diagnostics.Starting_compilation_in_watch_mode.code,
55+
Diagnostics.File_change_detected_Starting_incremental_compilation.code,
56+
];
57+
58+
function getPlainDiagnosticFollowingNewLines(diagnostic: Diagnostic, newLine: string): string {
59+
return contains(screenStartingMessageCodes, diagnostic.code)
60+
? newLine + newLine
61+
: newLine;
4462
}
4563

4664
/**
@@ -51,13 +69,19 @@ namespace ts {
5169
(diagnostic, newLine, options) => {
5270
clearScreenIfNotWatchingForFileChanges(system, diagnostic, options);
5371
let output = `[${formatColorAndReset(new Date().toLocaleTimeString(), ForegroundColorEscapeSequences.Grey)}] `;
54-
output += `${flattenDiagnosticMessageText(diagnostic.messageText, system.newLine)}${newLine + newLine + newLine}`;
72+
output += `${flattenDiagnosticMessageText(diagnostic.messageText, system.newLine)}${newLine + newLine}`;
5573
system.write(output);
5674
} :
5775
(diagnostic, newLine, options) => {
58-
clearScreenIfNotWatchingForFileChanges(system, diagnostic, options);
59-
let output = new Date().toLocaleTimeString() + " - ";
60-
output += `${flattenDiagnosticMessageText(diagnostic.messageText, system.newLine)}${newLine + newLine + newLine}`;
76+
let output = "";
77+
78+
if (!clearScreenIfNotWatchingForFileChanges(system, diagnostic, options)) {
79+
output += newLine;
80+
}
81+
82+
output += `${new Date().toLocaleTimeString()} - `;
83+
output += `${flattenDiagnosticMessageText(diagnostic.messageText, system.newLine)}${getPlainDiagnosticFollowingNewLines(diagnostic, newLine)}`;
84+
6185
system.write(output);
6286
};
6387
}

0 commit comments

Comments
 (0)