Skip to content

Commit 093cc72

Browse files
committed
Merge branch 'master' into add-unmeasurable-variance-kind
2 parents dc40484 + 47d9081 commit 093cc72

File tree

98 files changed

+1779
-182
lines changed

Some content is hidden

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

98 files changed

+1779
-182
lines changed

.github/pull_request_template.md

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
<!--
22
Thank you for submitting a pull request!
33
4-
Here's a checklist you might find useful.
5-
* [ ] There is an associated issue that is labeled 'Bug' or 'help wanted'
4+
Please verify that:
5+
* [ ] There is an associated issue in the `Backlog` milestone (**required**)
66
* [ ] Code is up-to-date with the `master` branch
77
* [ ] You've successfully run `gulp runtests` locally
88
* [ ] There are new or updated unit tests validating the change
@@ -12,4 +12,3 @@ Refer to CONTRIBUTING.MD for more details.
1212
-->
1313

1414
Fixes #
15-

src/compiler/binder.ts

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1625,15 +1625,8 @@ namespace ts {
16251625
}
16261626

16271627
function hasExportDeclarations(node: ModuleDeclaration | SourceFile): boolean {
1628-
const body = node.kind === SyntaxKind.SourceFile ? node : node.body;
1629-
if (body && (body.kind === SyntaxKind.SourceFile || body.kind === SyntaxKind.ModuleBlock)) {
1630-
for (const stat of (<BlockLike>body).statements) {
1631-
if (stat.kind === SyntaxKind.ExportDeclaration || stat.kind === SyntaxKind.ExportAssignment) {
1632-
return true;
1633-
}
1634-
}
1635-
}
1636-
return false;
1628+
const body = isSourceFile(node) ? node : tryCast(node.body, isModuleBlock);
1629+
return !!body && body.statements.some(s => isExportDeclaration(s) || isExportAssignment(s));
16371630
}
16381631

16391632
function setExportContextFlag(node: ModuleDeclaration | SourceFile) {

src/compiler/checker.ts

Lines changed: 67 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1410,15 +1410,14 @@ namespace ts {
14101410
}
14111411
break;
14121412
case SyntaxKind.PropertyDeclaration:
1413-
case SyntaxKind.PropertySignature:
14141413
// TypeScript 1.0 spec (April 2014): 8.4.1
14151414
// Initializer expressions for instance member variables are evaluated in the scope
14161415
// of the class constructor body but are not permitted to reference parameters or
14171416
// local variables of the constructor. This effectively means that entities from outer scopes
14181417
// by the same name as a constructor parameter or local variable are inaccessible
14191418
// in initializer expressions for instance member variables.
1420-
if (isClassLike(location.parent) && !hasModifier(location, ModifierFlags.Static)) {
1421-
const ctor = findConstructorDeclaration(location.parent);
1419+
if (!hasModifier(location, ModifierFlags.Static)) {
1420+
const ctor = findConstructorDeclaration(location.parent as ClassLikeDeclaration);
14221421
if (ctor && ctor.locals) {
14231422
if (lookup(ctor.locals, name, meaning & SymbolFlags.Value)) {
14241423
// Remember the property node, it will be used later to report appropriate error
@@ -9944,13 +9943,13 @@ namespace ts {
99449943
return type.flags & TypeFlags.Union ? getIntersectionType(map((<IntersectionType>type).types, t => getIndexType(t, stringsOnly, noIndexSignatures))) :
99459944
type.flags & TypeFlags.Intersection ? getUnionType(map((<IntersectionType>type).types, t => getIndexType(t, stringsOnly, noIndexSignatures))) :
99469945
maybeTypeOfKind(type, TypeFlags.InstantiableNonPrimitive) ? getIndexTypeForGenericType(<InstantiableType | UnionOrIntersectionType>type, stringsOnly) :
9947-
getObjectFlags(type) & ObjectFlags.Mapped ? filterType(getConstraintTypeFromMappedType(<MappedType>type), t => !(noIndexSignatures && t.flags & (TypeFlags.Any | TypeFlags.String | TypeFlags.Number))) :
9946+
getObjectFlags(type) & ObjectFlags.Mapped ? filterType(getConstraintTypeFromMappedType(<MappedType>type), t => !(noIndexSignatures && t.flags & (TypeFlags.Any | TypeFlags.String))) :
99489947
type === wildcardType ? wildcardType :
99499948
type.flags & TypeFlags.Unknown ? neverType :
99509949
type.flags & (TypeFlags.Any | TypeFlags.Never) ? keyofConstraintType :
99519950
stringsOnly ? !noIndexSignatures && getIndexInfoOfType(type, IndexKind.String) ? stringType : getLiteralTypeFromProperties(type, TypeFlags.StringLiteral) :
99529951
!noIndexSignatures && getIndexInfoOfType(type, IndexKind.String) ? getUnionType([stringType, numberType, getLiteralTypeFromProperties(type, TypeFlags.UniqueESSymbol)]) :
9953-
!noIndexSignatures && getNonEnumNumberIndexInfo(type) ? getUnionType([numberType, getLiteralTypeFromProperties(type, TypeFlags.StringLiteral | TypeFlags.UniqueESSymbol)]) :
9952+
getNonEnumNumberIndexInfo(type) ? getUnionType([numberType, getLiteralTypeFromProperties(type, TypeFlags.StringLiteral | TypeFlags.UniqueESSymbol)]) :
99549953
getLiteralTypeFromProperties(type, TypeFlags.StringOrNumberLiteralOrUnique);
99559954
}
99569955

@@ -10068,10 +10067,10 @@ namespace ts {
1006810067
if (objectType.flags & (TypeFlags.Any | TypeFlags.Never)) {
1006910068
return objectType;
1007010069
}
10071-
const indexInfo = isTypeAssignableToKind(indexType, TypeFlags.NumberLike) && getIndexInfoOfType(objectType, IndexKind.Number) ||
10072-
getIndexInfoOfType(objectType, IndexKind.String);
10070+
const stringIndexInfo = getIndexInfoOfType(objectType, IndexKind.String);
10071+
const indexInfo = isTypeAssignableToKind(indexType, TypeFlags.NumberLike) && getIndexInfoOfType(objectType, IndexKind.Number) || stringIndexInfo;
1007310072
if (indexInfo) {
10074-
if (accessFlags & AccessFlags.NoIndexSignatures) {
10073+
if (accessFlags & AccessFlags.NoIndexSignatures && indexInfo === stringIndexInfo) {
1007510074
if (accessExpression) {
1007610075
error(accessExpression, Diagnostics.Type_0_cannot_be_used_to_index_type_1, typeToString(indexType), typeToString(originalObjectType));
1007710076
}
@@ -14270,6 +14269,32 @@ namespace ts {
1427014269
return strictNullChecks ? getGlobalNonNullableTypeInstantiation(type) : type;
1427114270
}
1427214271

14272+
14273+
/**
14274+
* Is source potentially coercible to target type under `==`.
14275+
* Assumes that `source` is a constituent of a union, hence
14276+
* the boolean literal flag on the LHS, but not on the RHS.
14277+
*
14278+
* This does not fully replicate the semantics of `==`. The
14279+
* intention is to catch cases that are clearly not right.
14280+
*
14281+
* Comparing (string | number) to number should not remove the
14282+
* string element.
14283+
*
14284+
* Comparing (string | number) to 1 will remove the string
14285+
* element, though this is not sound. This is a pragmatic
14286+
* choice.
14287+
*
14288+
* @see narrowTypeByEquality
14289+
*
14290+
* @param source
14291+
* @param target
14292+
*/
14293+
function isCoercibleUnderDoubleEquals(source: Type, target: Type): boolean {
14294+
return ((source.flags & (TypeFlags.Number | TypeFlags.String | TypeFlags.BooleanLiteral)) !== 0)
14295+
&& ((target.flags & (TypeFlags.Number | TypeFlags.String | TypeFlags.Boolean)) !== 0);
14296+
}
14297+
1427314298
/**
1427414299
* Return true if type was inferred from an object literal, written as an object type literal, or is the shape of a module
1427514300
* with no call or construct signatures.
@@ -16613,7 +16638,10 @@ namespace ts {
1661316638
return type;
1661416639
}
1661516640
if (assumeTrue) {
16616-
const narrowedType = filterType(type, t => areTypesComparable(t, valueType));
16641+
const filterFn: (t: Type) => boolean = operator === SyntaxKind.EqualsEqualsToken ?
16642+
(t => areTypesComparable(t, valueType) || isCoercibleUnderDoubleEquals(t, valueType)) :
16643+
t => areTypesComparable(t, valueType);
16644+
const narrowedType = filterType(type, filterFn);
1661716645
return narrowedType.flags & TypeFlags.Never ? type : replacePrimitivesWithLiterals(narrowedType, valueType);
1661816646
}
1661916647
if (isUnitType(valueType)) {
@@ -25678,7 +25706,7 @@ namespace ts {
2567825706
}
2567925707

2568025708
if (!compilerOptions.experimentalDecorators) {
25681-
error(node, Diagnostics.Experimental_support_for_decorators_is_a_feature_that_is_subject_to_change_in_a_future_release_Set_the_experimentalDecorators_option_to_remove_this_warning);
25709+
error(node, Diagnostics.Experimental_support_for_decorators_is_a_feature_that_is_subject_to_change_in_a_future_release_Set_the_experimentalDecorators_option_in_your_tsconfig_or_jsconfig_to_remove_this_warning);
2568225710
}
2568325711

2568425712
const firstDecorator = node.decorators[0];
@@ -26476,14 +26504,28 @@ namespace ts {
2647626504
}
2647726505
// For a binding pattern, validate the initializer and exit
2647826506
if (isBindingPattern(node.name)) {
26479-
// Don't validate for-in initializer as it is already an error
26480-
if (node.initializer && node.parent.parent.kind !== SyntaxKind.ForInStatement) {
26481-
const initializerType = checkExpressionCached(node.initializer);
26482-
if (strictNullChecks && node.name.elements.length === 0) {
26483-
checkNonNullNonVoidType(initializerType, node);
26507+
const needCheckInitializer = node.initializer && node.parent.parent.kind !== SyntaxKind.ForInStatement;
26508+
const needCheckWidenedType = node.name.elements.length === 0;
26509+
if (needCheckInitializer || needCheckWidenedType) {
26510+
// Don't validate for-in initializer as it is already an error
26511+
const widenedType = getWidenedTypeForVariableLikeDeclaration(node);
26512+
if (needCheckInitializer) {
26513+
const initializerType = checkExpressionCached(node.initializer!);
26514+
if (strictNullChecks && needCheckWidenedType) {
26515+
checkNonNullNonVoidType(initializerType, node);
26516+
}
26517+
else {
26518+
checkTypeAssignableToAndOptionallyElaborate(initializerType, getWidenedTypeForVariableLikeDeclaration(node), node, node.initializer);
26519+
}
2648426520
}
26485-
else {
26486-
checkTypeAssignableToAndOptionallyElaborate(initializerType, getWidenedTypeForVariableLikeDeclaration(node), node, node.initializer);
26521+
// check the binding pattern with empty elements
26522+
if (needCheckWidenedType) {
26523+
if (isArrayBindingPattern(node.name)) {
26524+
checkIteratedTypeOrElementType(widenedType, node, /* allowStringInput */ false, /* allowAsyncIterables */ false);
26525+
}
26526+
else if (strictNullChecks) {
26527+
checkNonNullNonVoidType(widenedType, node);
26528+
}
2648726529
}
2648826530
}
2648926531
return;
@@ -31228,6 +31270,13 @@ namespace ts {
3122831270

3122931271
for (const prop of node.properties) {
3123031272
if (prop.kind === SyntaxKind.SpreadAssignment) {
31273+
if (inDestructuring) {
31274+
// a rest property cannot be destructured any further
31275+
const expression = skipParentheses(prop.expression);
31276+
if (isArrayLiteralExpression(expression) || isObjectLiteralExpression(expression)) {
31277+
return grammarErrorOnNode(prop.expression, Diagnostics.A_rest_element_cannot_contain_a_binding_pattern);
31278+
}
31279+
}
3123131280
continue;
3123231281
}
3123331282
const name = prop.name;
@@ -31890,7 +31939,7 @@ namespace ts {
3189031939
return false;
3189131940
}
3189231941

31893-
return grammarErrorOnFirstToken(node, Diagnostics.A_declare_modifier_is_required_for_a_top_level_declaration_in_a_d_ts_file);
31942+
return grammarErrorOnFirstToken(node, Diagnostics.Top_level_declarations_in_d_ts_files_must_start_with_either_a_declare_or_export_modifier);
3189431943
}
3189531944

3189631945
function checkGrammarTopLevelElementsForRequiredDeclareModifier(file: SourceFile): boolean {

src/compiler/commandLineParser.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ namespace ts {
1616
["es2017", "lib.es2017.d.ts"],
1717
["es2018", "lib.es2018.d.ts"],
1818
["es2019", "lib.es2019.d.ts"],
19+
["es2020", "lib.es2020.d.ts"],
1920
["esnext", "lib.esnext.d.ts"],
2021
// Host only
2122
["dom", "lib.dom.d.ts"],
@@ -46,6 +47,8 @@ namespace ts {
4647
["es2019.array", "lib.es2019.array.d.ts"],
4748
["es2019.string", "lib.es2019.string.d.ts"],
4849
["es2019.symbol", "lib.es2019.symbol.d.ts"],
50+
["es2020.string", "lib.es2020.string.d.ts"],
51+
["es2020.symbol.wellknown", "lib.es2020.symbol.wellknown.d.ts"],
4952
["esnext.array", "lib.es2019.array.d.ts"],
5053
["esnext.symbol", "lib.es2019.symbol.d.ts"],
5154
["esnext.asynciterable", "lib.es2018.asynciterable.d.ts"],
@@ -210,6 +213,7 @@ namespace ts {
210213
es2017: ScriptTarget.ES2017,
211214
es2018: ScriptTarget.ES2018,
212215
es2019: ScriptTarget.ES2019,
216+
es2020: ScriptTarget.ES2020,
213217
esnext: ScriptTarget.ESNext,
214218
}),
215219
affectsSourceFile: true,

src/compiler/diagnosticMessages.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@
139139
"category": "Error",
140140
"code": 1045
141141
},
142-
"A 'declare' modifier is required for a top level declaration in a .d.ts file.": {
142+
"Top-level declarations in .d.ts files must start with either a 'declare' or 'export' modifier.": {
143143
"category": "Error",
144144
"code": 1046
145145
},
@@ -691,7 +691,7 @@
691691
"category": "Error",
692692
"code": 1218
693693
},
694-
"Experimental support for decorators is a feature that is subject to change in a future release. Set the 'experimentalDecorators' option to remove this warning.": {
694+
"Experimental support for decorators is a feature that is subject to change in a future release. Set the 'experimentalDecorators' option in your 'tsconfig' or 'jsconfig' to remove this warning.": {
695695
"category": "Error",
696696
"code": 1219
697697
},

src/compiler/moduleNameResolver.ts

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -421,6 +421,7 @@ namespace ts {
421421
*/
422422
export interface ModuleResolutionCache extends NonRelativeModuleNameResolutionCache {
423423
getOrCreateCacheForDirectory(directoryName: string, redirectedReference?: ResolvedProjectReference): Map<ResolvedModuleWithFailedLookupLocations>;
424+
/*@internal*/ directoryToModuleNameMap: CacheWithRedirects<Map<ResolvedModuleWithFailedLookupLocations>>;
424425
}
425426

426427
/**
@@ -429,49 +430,64 @@ namespace ts {
429430
*/
430431
export interface NonRelativeModuleNameResolutionCache {
431432
getOrCreateCacheForModuleName(nonRelativeModuleName: string, redirectedReference?: ResolvedProjectReference): PerModuleNameCache;
433+
/*@internal*/ moduleNameToDirectoryMap: CacheWithRedirects<PerModuleNameCache>;
432434
}
433435

434436
export interface PerModuleNameCache {
435437
get(directory: string): ResolvedModuleWithFailedLookupLocations | undefined;
436438
set(directory: string, result: ResolvedModuleWithFailedLookupLocations): void;
437439
}
438440

439-
export function createModuleResolutionCache(currentDirectory: string, getCanonicalFileName: (s: string) => string): ModuleResolutionCache {
441+
export function createModuleResolutionCache(currentDirectory: string, getCanonicalFileName: (s: string) => string, options?: CompilerOptions): ModuleResolutionCache {
440442
return createModuleResolutionCacheWithMaps(
441-
createCacheWithRedirects(),
442-
createCacheWithRedirects(),
443+
createCacheWithRedirects(options),
444+
createCacheWithRedirects(options),
443445
currentDirectory,
444446
getCanonicalFileName
445447
);
446448
}
447449

450+
448451
/*@internal*/
449452
export interface CacheWithRedirects<T> {
450453
ownMap: Map<T>;
451454
redirectsMap: Map<Map<T>>;
452455
getOrCreateMapOfCacheRedirects(redirectedReference: ResolvedProjectReference | undefined): Map<T>;
453456
clear(): void;
457+
setOwnOptions(newOptions: CompilerOptions): void;
458+
setOwnMap(newOwnMap: Map<T>): void;
454459
}
455460

456461
/*@internal*/
457-
export function createCacheWithRedirects<T>(): CacheWithRedirects<T> {
458-
const ownMap: Map<T> = createMap();
462+
export function createCacheWithRedirects<T>(options?: CompilerOptions): CacheWithRedirects<T> {
463+
let ownMap: Map<T> = createMap();
459464
const redirectsMap: Map<Map<T>> = createMap();
460465
return {
461466
ownMap,
462467
redirectsMap,
463468
getOrCreateMapOfCacheRedirects,
464-
clear
469+
clear,
470+
setOwnOptions,
471+
setOwnMap
465472
};
466473

474+
function setOwnOptions(newOptions: CompilerOptions) {
475+
options = newOptions;
476+
}
477+
478+
function setOwnMap(newOwnMap: Map<T>) {
479+
ownMap = newOwnMap;
480+
}
481+
467482
function getOrCreateMapOfCacheRedirects(redirectedReference: ResolvedProjectReference | undefined) {
468483
if (!redirectedReference) {
469484
return ownMap;
470485
}
471486
const path = redirectedReference.sourceFile.path;
472487
let redirects = redirectsMap.get(path);
473488
if (!redirects) {
474-
redirects = createMap();
489+
// Reuse map if redirected reference map uses same resolution
490+
redirects = !options || optionsHaveModuleResolutionChanges(options, redirectedReference.commandLine.options) ? createMap() : ownMap;
475491
redirectsMap.set(path, redirects);
476492
}
477493
return redirects;
@@ -490,7 +506,7 @@ namespace ts {
490506
currentDirectory: string,
491507
getCanonicalFileName: GetCanonicalFileName): ModuleResolutionCache {
492508

493-
return { getOrCreateCacheForDirectory, getOrCreateCacheForModuleName };
509+
return { getOrCreateCacheForDirectory, getOrCreateCacheForModuleName, directoryToModuleNameMap, moduleNameToDirectoryMap };
494510

495511
function getOrCreateCacheForDirectory(directoryName: string, redirectedReference?: ResolvedProjectReference) {
496512
const path = toPath(directoryName, currentDirectory, getCanonicalFileName);

0 commit comments

Comments
 (0)