Skip to content

Commit a8ee8fb

Browse files
committed
Merge branch 'master' of https://github.com/Microsoft/TypeScript into feature/eslint
2 parents 64baa80 + a24e4b0 commit a8ee8fb

File tree

94 files changed

+11175
-11189
lines changed

Some content is hidden

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

94 files changed

+11175
-11189
lines changed

src/compiler/checker.ts

Lines changed: 65 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,10 @@ namespace ts {
4242
iterableCacheKey: "iterationTypesOfAsyncIterable" | "iterationTypesOfIterable";
4343
iteratorCacheKey: "iterationTypesOfAsyncIterator" | "iterationTypesOfIterator";
4444
iteratorSymbolName: "asyncIterator" | "iterator";
45-
getGlobalIteratorType: (reportErrors: boolean) => Type;
46-
getGlobalIterableType: (reportErrors: boolean) => Type;
47-
getGlobalIterableIteratorType: (reportErrors: boolean) => Type;
48-
getGlobalGeneratorType: (reportErrors: boolean) => Type;
45+
getGlobalIteratorType: (reportErrors: boolean) => GenericType;
46+
getGlobalIterableType: (reportErrors: boolean) => GenericType;
47+
getGlobalIterableIteratorType: (reportErrors: boolean) => GenericType;
48+
getGlobalGeneratorType: (reportErrors: boolean) => GenericType;
4949
resolveIterationType: (type: Type, errorNode: Node | undefined) => Type | undefined;
5050
mustHaveANextMethodDiagnostic: DiagnosticMessage;
5151
mustBeAMethodDiagnostic: DiagnosticMessage;
@@ -9531,24 +9531,10 @@ namespace ts {
95319531
return createTypeFromGenericGlobalType(getGlobalTypedPropertyDescriptorType(), [propertyType]);
95329532
}
95339533

9534-
function createAsyncGeneratorType(yieldType: Type, returnType: Type, nextType: Type) {
9535-
const globalAsyncGeneratorType = getGlobalAsyncGeneratorType(/*reportErrors*/ true);
9536-
if (globalAsyncGeneratorType !== emptyGenericType) {
9537-
yieldType = getAwaitedType(yieldType) || unknownType;
9538-
returnType = getAwaitedType(returnType) || unknownType;
9539-
nextType = getAwaitedType(nextType) || unknownType;
9540-
}
9541-
return createTypeFromGenericGlobalType(globalAsyncGeneratorType, [yieldType, returnType, nextType]);
9542-
}
9543-
95449534
function createIterableType(iteratedType: Type): Type {
95459535
return createTypeFromGenericGlobalType(getGlobalIterableType(/*reportErrors*/ true), [iteratedType]);
95469536
}
95479537

9548-
function createGeneratorType(yieldType: Type, returnType: Type, nextType: Type) {
9549-
return createTypeFromGenericGlobalType(getGlobalGeneratorType(/*reportErrors*/ true), [yieldType, returnType, nextType]);
9550-
}
9551-
95529538
function createArrayType(elementType: Type, readonly?: boolean): ObjectType {
95539539
return createTypeFromGenericGlobalType(readonly ? globalReadonlyArrayType : globalArrayType, [elementType]);
95549540
}
@@ -9904,28 +9890,28 @@ namespace ts {
99049890
return links.resolvedType;
99059891
}
99069892

9907-
function addTypeToIntersection(typeSet: Type[], includes: TypeFlags, type: Type) {
9893+
function addTypeToIntersection(typeSet: Map<Type>, includes: TypeFlags, type: Type) {
99089894
const flags = type.flags;
99099895
if (flags & TypeFlags.Intersection) {
99109896
return addTypesToIntersection(typeSet, includes, (<IntersectionType>type).types);
99119897
}
99129898
if (isEmptyAnonymousObjectType(type)) {
99139899
if (!(includes & TypeFlags.IncludesEmptyObject)) {
99149900
includes |= TypeFlags.IncludesEmptyObject;
9915-
typeSet.push(type);
9901+
typeSet.set(type.id.toString(), type);
99169902
}
99179903
}
99189904
else {
99199905
if (flags & TypeFlags.AnyOrUnknown) {
99209906
if (type === wildcardType) includes |= TypeFlags.IncludesWildcard;
99219907
}
9922-
else if ((strictNullChecks || !(flags & TypeFlags.Nullable)) && !contains(typeSet, type)) {
9908+
else if ((strictNullChecks || !(flags & TypeFlags.Nullable)) && !typeSet.has(type.id.toString())) {
99239909
if (type.flags & TypeFlags.Unit && includes & TypeFlags.Unit) {
99249910
// We have seen two distinct unit types which means we should reduce to an
99259911
// empty intersection. Adding TypeFlags.NonPrimitive causes that to happen.
99269912
includes |= TypeFlags.NonPrimitive;
99279913
}
9928-
typeSet.push(type);
9914+
typeSet.set(type.id.toString(), type);
99299915
}
99309916
includes |= flags & TypeFlags.IncludesMask;
99319917
}
@@ -9934,7 +9920,7 @@ namespace ts {
99349920

99359921
// Add the given types to the given type set. Order is preserved, freshness is removed from literal
99369922
// types, duplicates are removed, and nested types of the given kind are flattened into the set.
9937-
function addTypesToIntersection(typeSet: Type[], includes: TypeFlags, types: ReadonlyArray<Type>) {
9923+
function addTypesToIntersection(typeSet: Map<Type>, includes: TypeFlags, types: ReadonlyArray<Type>) {
99389924
for (const type of types) {
99399925
includes = addTypeToIntersection(typeSet, includes, getRegularTypeOfLiteralType(type));
99409926
}
@@ -10041,8 +10027,9 @@ namespace ts {
1004110027
// Also, unlike union types, the order of the constituent types is preserved in order that overload resolution
1004210028
// for intersections of types with signatures can be deterministic.
1004310029
function getIntersectionType(types: ReadonlyArray<Type>, aliasSymbol?: Symbol, aliasTypeArguments?: ReadonlyArray<Type>): Type {
10044-
const typeSet: Type[] = [];
10045-
const includes = addTypesToIntersection(typeSet, 0, types);
10030+
const typeMembershipMap: Map<Type> = createMap();
10031+
const includes = addTypesToIntersection(typeMembershipMap, 0, types);
10032+
const typeSet: Type[] = arrayFrom(typeMembershipMap.values());
1004610033
// An intersection type is considered empty if it contains
1004710034
// the type never, or
1004810035
// more than one unit type or,
@@ -20583,10 +20570,15 @@ namespace ts {
2058320570
}
2058420571
propType = getConstraintForLocation(getTypeOfSymbol(prop), node);
2058520572
}
20573+
return getFlowTypeOfAccessExpression(node, prop, propType, right);
20574+
}
20575+
20576+
function getFlowTypeOfAccessExpression(node: ElementAccessExpression | PropertyAccessExpression | QualifiedName, prop: Symbol | undefined, propType: Type, errorNode: Node) {
2058620577
// Only compute control flow type if this is a property access expression that isn't an
2058720578
// assignment target, and the referenced property was declared as a variable, property,
2058820579
// accessor, or optional method.
20589-
if (node.kind !== SyntaxKind.PropertyAccessExpression ||
20580+
const assignmentKind = getAssignmentTargetKind(node);
20581+
if (node.kind !== SyntaxKind.ElementAccessExpression && node.kind !== SyntaxKind.PropertyAccessExpression ||
2059020582
assignmentKind === AssignmentKind.Definite ||
2059120583
prop && !(prop.flags & (SymbolFlags.Variable | SymbolFlags.Property | SymbolFlags.Accessor)) && !(prop.flags & SymbolFlags.Method && propType.flags & TypeFlags.Union)) {
2059220584
return propType;
@@ -20596,7 +20588,7 @@ namespace ts {
2059620588
// and if we are in a constructor of the same class as the property declaration, assume that
2059720589
// the property is uninitialized at the top of the control flow.
2059820590
let assumeUninitialized = false;
20599-
if (strictNullChecks && strictPropertyInitialization && left.kind === SyntaxKind.ThisKeyword) {
20591+
if (strictNullChecks && strictPropertyInitialization && node.expression.kind === SyntaxKind.ThisKeyword) {
2060020592
const declaration = prop && prop.valueDeclaration;
2060120593
if (declaration && isInstancePropertyWithoutInitializer(declaration)) {
2060220594
const flowContainer = getControlFlowContainer(node);
@@ -20613,7 +20605,7 @@ namespace ts {
2061320605
}
2061420606
const flowType = getFlowTypeOfReference(node, propType, assumeUninitialized ? getOptionalType(propType) : propType);
2061520607
if (assumeUninitialized && !(getFalsyFlags(propType) & TypeFlags.Undefined) && getFalsyFlags(flowType) & TypeFlags.Undefined) {
20616-
error(right, Diagnostics.Property_0_is_used_before_being_assigned, symbolToString(prop!)); // TODO: GH#18217
20608+
error(errorNode, Diagnostics.Property_0_is_used_before_being_assigned, symbolToString(prop!)); // TODO: GH#18217
2061720609
// Return the declared type to reduce follow-on errors
2061820610
return propType;
2061920611
}
@@ -20970,7 +20962,7 @@ namespace ts {
2097020962
AccessFlags.Writing | (isGenericObjectType(objectType) && !isThisTypeParameter(objectType) ? AccessFlags.NoIndexSignatures : 0) :
2097120963
AccessFlags.None;
2097220964
const indexedAccessType = getIndexedAccessTypeOrUndefined(objectType, effectiveIndexType, node, accessFlags) || errorType;
20973-
return checkIndexedAccessIndexType(indexedAccessType, node);
20965+
return checkIndexedAccessIndexType(getFlowTypeOfAccessExpression(node, indexedAccessType.symbol, indexedAccessType, indexExpression), node);
2097420966
}
2097520967

2097620968
function checkThatExpressionIsProperSymbolReference(expression: Expression, expressionType: Type, reportError: boolean): boolean {
@@ -23397,9 +23389,36 @@ namespace ts {
2339723389
}
2339823390

2339923391
function createGeneratorReturnType(yieldType: Type, returnType: Type, nextType: Type, isAsyncGenerator: boolean) {
23400-
return isAsyncGenerator
23401-
? createAsyncGeneratorType(yieldType, returnType, nextType)
23402-
: createGeneratorType(yieldType, returnType, nextType);
23392+
const resolver = isAsyncGenerator ? asyncIterationTypesResolver : syncIterationTypesResolver;
23393+
const globalGeneratorType = resolver.getGlobalGeneratorType(/*reportErrors*/ false);
23394+
yieldType = resolver.resolveIterationType(yieldType, /*errorNode*/ undefined) || unknownType;
23395+
returnType = resolver.resolveIterationType(returnType, /*errorNode*/ undefined) || unknownType;
23396+
nextType = resolver.resolveIterationType(nextType, /*errorNode*/ undefined) || unknownType;
23397+
if (globalGeneratorType === emptyGenericType) {
23398+
// Fall back to the global IterableIterator if returnType is assignable to the expected return iteration
23399+
// type of IterableIterator, and the expected next iteration type of IterableIterator is assignable to
23400+
// nextType.
23401+
const globalType = resolver.getGlobalIterableIteratorType(/*reportErrors*/ false);
23402+
const iterationTypes = globalType !== emptyGenericType ? getIterationTypesOfGlobalIterableType(globalType, resolver) : undefined;
23403+
const iterableIteratorReturnType = iterationTypes ? iterationTypes.returnType : anyType;
23404+
const iterableIteratorNextType = iterationTypes ? iterationTypes.nextType : undefinedType;
23405+
if (isTypeAssignableTo(returnType, iterableIteratorReturnType) &&
23406+
isTypeAssignableTo(iterableIteratorNextType, nextType)) {
23407+
if (globalType !== emptyGenericType) {
23408+
return createTypeFromGenericGlobalType(globalType, [yieldType]);
23409+
}
23410+
23411+
// The global IterableIterator type doesn't exist, so report an error
23412+
resolver.getGlobalIterableIteratorType(/*reportErrors*/ true);
23413+
return emptyObjectType;
23414+
}
23415+
23416+
// The global Generator type doesn't exist, so report an error
23417+
resolver.getGlobalGeneratorType(/*reportErrors*/ true);
23418+
return emptyObjectType;
23419+
}
23420+
23421+
return createTypeFromGenericGlobalType(globalGeneratorType, [yieldType, returnType, nextType]);
2340323422
}
2340423423

2340523424
function checkAndAggregateYieldOperandTypes(func: FunctionLikeDeclaration, checkMode: CheckMode | undefined) {
@@ -24719,6 +24738,12 @@ namespace ts {
2471924738
|| anyType;
2472024739
}
2472124740

24741+
const contextualReturnType = getContextualReturnType(func);
24742+
if (contextualReturnType) {
24743+
return getIterationTypeOfGeneratorFunctionReturnType(IterationTypeKind.Next, contextualReturnType, isAsync)
24744+
|| anyType;
24745+
}
24746+
2472224747
return anyType;
2472324748
}
2472424749

@@ -28240,6 +28265,13 @@ namespace ts {
2824028265
return (type as IterableOrIteratorType)[resolver.iterableCacheKey];
2824128266
}
2824228267

28268+
function getIterationTypesOfGlobalIterableType(globalType: Type, resolver: IterationTypesResolver) {
28269+
const globalIterationTypes =
28270+
getIterationTypesOfIterableCached(globalType, resolver) ||
28271+
getIterationTypesOfIterableSlow(globalType, resolver, /*errorNode*/ undefined);
28272+
return globalIterationTypes === noIterationTypes ? defaultIterationTypes : globalIterationTypes;
28273+
}
28274+
2824328275
/**
2824428276
* Gets the *yield*, *return*, and *next* types of an `Iterable`-like or `AsyncIterable`-like
2824528277
* type from from common heuristics.
@@ -28265,10 +28297,7 @@ namespace ts {
2826528297
// iteration types of their `[Symbol.iterator]()` method. The same is true for their async cousins.
2826628298
// While we define these as `any` and `undefined` in our libs by default, a custom lib *could* use
2826728299
// different definitions.
28268-
const globalIterationTypes =
28269-
getIterationTypesOfIterableCached(globalType, resolver) ||
28270-
getIterationTypesOfIterableSlow(globalType, resolver, /*errorNode*/ undefined);
28271-
const { returnType, nextType } = globalIterationTypes === noIterationTypes ? defaultIterationTypes : globalIterationTypes;
28300+
const { returnType, nextType } = getIterationTypesOfGlobalIterableType(globalType, resolver);
2827228301
return (type as IterableOrIteratorType)[resolver.iterableCacheKey] = createIterationTypes(yieldType, returnType, nextType);
2827328302
}
2827428303

src/compiler/emitter.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -411,7 +411,11 @@ namespace ts {
411411
}
412412
);
413413
if (emitOnlyDtsFiles && declarationTransform.transformed[0].kind === SyntaxKind.SourceFile) {
414-
const sourceFile = declarationTransform.transformed[0] as SourceFile;
414+
// Improved narrowing in master/3.6 makes this cast unnecessary, triggering a lint rule.
415+
// But at the same time, the LKG (3.5) necessitates it because it doesn’t narrow.
416+
// Once the LKG is updated to 3.6, this comment, the cast to `SourceFile`, and the
417+
// tslint directive can be all be removed.
418+
const sourceFile = declarationTransform.transformed[0] as SourceFile; // tslint:disable-line
415419
exportedModulesFromDeclarationEmit = sourceFile.exportedModulesFromDeclarationEmit;
416420
}
417421
}

src/compiler/factory.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4701,7 +4701,7 @@ namespace ts {
47014701
}
47024702
}
47034703

4704-
function getLeftmostExpression(node: Expression, stopAtCallExpressions: boolean) {
4704+
export function getLeftmostExpression(node: Expression, stopAtCallExpressions: boolean) {
47054705
while (true) {
47064706
switch (node.kind) {
47074707
case SyntaxKind.PostfixUnaryExpression:

src/compiler/scanner.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,7 @@ namespace ts {
197197
"|=": SyntaxKind.BarEqualsToken,
198198
"^=": SyntaxKind.CaretEqualsToken,
199199
"@": SyntaxKind.AtToken,
200+
"`": SyntaxKind.BacktickToken
200201
});
201202

202203
/*
@@ -298,7 +299,6 @@ namespace ts {
298299
}
299300

300301
const tokenStrings = makeReverseMap(textToToken);
301-
302302
export function tokenToString(t: SyntaxKind): string | undefined {
303303
return tokenStrings[t];
304304
}

src/compiler/utilities.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7494,7 +7494,7 @@ namespace ts {
74947494
export function getDirectoryPath(path: Path): Path;
74957495
/**
74967496
* Returns the path except for its basename. Semantics align with NodeJS's `path.dirname`
7497-
* except that we support URLs as well.
7497+
* except that we support URL's as well.
74987498
*
74997499
* ```ts
75007500
* getDirectoryPath("/path/to/file.ext") === "/path/to"

0 commit comments

Comments
 (0)