Skip to content

Commit 7608dc2

Browse files
committed
Merge branch 'master' into fix29666
2 parents 0075b0a + c7b8b2a commit 7608dc2

File tree

97 files changed

+12500
-10526
lines changed

Some content is hidden

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

97 files changed

+12500
-10526
lines changed

src/compiler/checker.ts

Lines changed: 64 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
}
@@ -13450,7 +13436,8 @@ namespace ts {
1345013436
if (includeOptional
1345113437
? !(filteredByApplicability!.flags & TypeFlags.Never)
1345213438
: isRelatedTo(targetConstraint, sourceKeys)) {
13453-
const indexingType = filteredByApplicability || getTypeParameterFromMappedType(target);
13439+
const typeParameter = getTypeParameterFromMappedType(target);
13440+
const indexingType = filteredByApplicability ? getIntersectionType([filteredByApplicability, typeParameter]) : typeParameter;
1345413441
const indexedAccessType = getIndexedAccessType(source, indexingType);
1345513442
const templateType = getTemplateTypeFromMappedType(target);
1345613443
if (result = isRelatedTo(indexedAccessType, templateType, reportErrors)) {
@@ -15265,15 +15252,23 @@ namespace ts {
1526515252
const inference = inferences[i];
1526615253
if (t === inference.typeParameter) {
1526715254
if (fix && !inference.isFixed) {
15255+
clearCachedInferences(inferences);
1526815256
inference.isFixed = true;
15269-
inference.inferredType = undefined;
1527015257
}
1527115258
return getInferredType(context, i);
1527215259
}
1527315260
}
1527415261
return t;
1527515262
}
1527615263

15264+
function clearCachedInferences(inferences: InferenceInfo[]) {
15265+
for (const inference of inferences) {
15266+
if (!inference.isFixed) {
15267+
inference.inferredType = undefined;
15268+
}
15269+
}
15270+
}
15271+
1527715272
function createInferenceInfo(typeParameter: TypeParameter): InferenceInfo {
1527815273
return {
1527915274
typeParameter,
@@ -15553,17 +15548,17 @@ namespace ts {
1555315548
if (contravariant && !bivariant) {
1555415549
if (!contains(inference.contraCandidates, candidate)) {
1555515550
inference.contraCandidates = append(inference.contraCandidates, candidate);
15556-
inference.inferredType = undefined;
15551+
clearCachedInferences(inferences);
1555715552
}
1555815553
}
1555915554
else if (!contains(inference.candidates, candidate)) {
1556015555
inference.candidates = append(inference.candidates, candidate);
15561-
inference.inferredType = undefined;
15556+
clearCachedInferences(inferences);
1556215557
}
1556315558
}
1556415559
if (!(priority & InferencePriority.ReturnType) && target.flags & TypeFlags.TypeParameter && inference.topLevel && !isTypeParameterAtTopLevel(originalTarget, <TypeParameter>target)) {
1556515560
inference.topLevel = false;
15566-
inference.inferredType = undefined;
15561+
clearCachedInferences(inferences);
1556715562
}
1556815563
}
1556915564
return;
@@ -20714,7 +20709,8 @@ namespace ts {
2071420709
else {
2071520710
const promisedType = getPromisedTypeOfPromise(containingType);
2071620711
if (promisedType && getPropertyOfType(promisedType, propNode.escapedText)) {
20717-
errorInfo = chainDiagnosticMessages(errorInfo, Diagnostics.Property_0_does_not_exist_on_type_1_Did_you_forget_to_use_await, declarationNameToString(propNode), typeToString(containingType));
20712+
errorInfo = chainDiagnosticMessages(errorInfo, Diagnostics.Property_0_does_not_exist_on_type_1, declarationNameToString(propNode), typeToString(containingType));
20713+
relatedInfo = createDiagnosticForNode(propNode, Diagnostics.Did_you_forget_to_use_await);
2071820714
}
2071920715
else {
2072020716
const suggestion = getSuggestedSymbolForNonexistentProperty(propNode, containingType);
@@ -22748,7 +22744,7 @@ namespace ts {
2274822744
isVariableDeclaration(decl.parent) && getSymbolOfNode(decl.parent));
2274922745
const prototype = assignmentSymbol && assignmentSymbol.exports && assignmentSymbol.exports.get("prototype" as __String);
2275022746
const init = prototype && prototype.valueDeclaration && getAssignedJSPrototype(prototype.valueDeclaration);
22751-
return init ? checkExpression(init) : undefined;
22747+
return init ? getWidenedType(checkExpressionCached(init)) : undefined;
2275222748
}
2275322749

2275422750
function getAssignedJSPrototype(node: Node) {
@@ -23391,9 +23387,36 @@ namespace ts {
2339123387
}
2339223388

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

2339923422
function checkAndAggregateYieldOperandTypes(func: FunctionLikeDeclaration, checkMode: CheckMode | undefined) {
@@ -26401,7 +26424,11 @@ namespace ts {
2640126424
* The runtime behavior of the `await` keyword.
2640226425
*/
2640326426
function checkAwaitedType(type: Type, errorNode: Node, diagnosticMessage: DiagnosticMessage, arg0?: string | number): Type {
26404-
return getAwaitedType(type, errorNode, diagnosticMessage, arg0) || errorType;
26427+
const awaitedType = getAwaitedType(type, errorNode, diagnosticMessage, arg0);
26428+
if (awaitedType === type && !(type.flags & TypeFlags.AnyOrUnknown)) {
26429+
addErrorOrSuggestion(/*isError*/ false, createDiagnosticForNode(errorNode, Diagnostics.await_has_no_effect_on_the_type_of_this_expression));
26430+
}
26431+
return awaitedType || errorType;
2640526432
}
2640626433

2640726434
function getAwaitedType(type: Type, errorNode?: Node, diagnosticMessage?: DiagnosticMessage, arg0?: string | number): Type | undefined {
@@ -28226,6 +28253,13 @@ namespace ts {
2822628253
return (type as IterableOrIteratorType)[resolver.iterableCacheKey];
2822728254
}
2822828255

28256+
function getIterationTypesOfGlobalIterableType(globalType: Type, resolver: IterationTypesResolver) {
28257+
const globalIterationTypes =
28258+
getIterationTypesOfIterableCached(globalType, resolver) ||
28259+
getIterationTypesOfIterableSlow(globalType, resolver, /*errorNode*/ undefined);
28260+
return globalIterationTypes === noIterationTypes ? defaultIterationTypes : globalIterationTypes;
28261+
}
28262+
2822928263
/**
2823028264
* Gets the *yield*, *return*, and *next* types of an `Iterable`-like or `AsyncIterable`-like
2823128265
* type from from common heuristics.
@@ -28251,10 +28285,7 @@ namespace ts {
2825128285
// iteration types of their `[Symbol.iterator]()` method. The same is true for their async cousins.
2825228286
// While we define these as `any` and `undefined` in our libs by default, a custom lib *could* use
2825328287
// different definitions.
28254-
const globalIterationTypes =
28255-
getIterationTypesOfIterableCached(globalType, resolver) ||
28256-
getIterationTypesOfIterableSlow(globalType, resolver, /*errorNode*/ undefined);
28257-
const { returnType, nextType } = globalIterationTypes === noIterationTypes ? defaultIterationTypes : globalIterationTypes;
28288+
const { returnType, nextType } = getIterationTypesOfGlobalIterableType(globalType, resolver);
2825828289
return (type as IterableOrIteratorType)[resolver.iterableCacheKey] = createIterationTypes(yieldType, returnType, nextType);
2825928290
}
2826028291

@@ -33011,9 +33042,6 @@ namespace ts {
3301133042
return grammarErrorAtPos(node, node.end - 1, ";".length, Diagnostics._0_expected, "{");
3301233043
}
3301333044
}
33014-
else if (isClassLike(node.parent) && isStringLiteral(node.name) && node.name.text === "constructor" && (!compilerOptions.target || compilerOptions.target < ScriptTarget.ES5)) {
33015-
return grammarErrorOnNode(node.name, Diagnostics.Quoted_constructors_have_previously_been_interpreted_as_methods_which_is_incorrect_In_TypeScript_3_6_they_will_be_correctly_parsed_as_constructors_In_the_meantime_consider_using_constructor_to_write_a_constructor_or_constructor_to_write_a_method);
33016-
}
3301733045
if (checkGrammarForGenerator(node)) {
3301833046
return true;
3301933047
}

src/compiler/diagnosticMessages.json

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2076,10 +2076,6 @@
20762076
"category": "Error",
20772077
"code": 2569
20782078
},
2079-
"Property '{0}' does not exist on type '{1}'. Did you forget to use 'await'?": {
2080-
"category": "Error",
2081-
"code": 2570
2082-
},
20832079
"Object is of type 'unknown'.": {
20842080
"category": "Error",
20852081
"code": 2571
@@ -4639,6 +4635,11 @@
46394635
"category": "Suggestion",
46404636
"code": 80006
46414637
},
4638+
"'await' has no effect on the type of this expression.": {
4639+
"category": "Suggestion",
4640+
"code": 80007
4641+
},
4642+
46424643
"Add missing 'super()' call": {
46434644
"category": "Message",
46444645
"code": 90001
@@ -5087,14 +5088,31 @@
50875088
"category": "Message",
50885089
"code": 95082
50895090
},
5091+
"Add 'await'": {
5092+
"category": "Message",
5093+
"code": 95083
5094+
},
5095+
"Add 'await' to initializer for '{0}'": {
5096+
"category": "Message",
5097+
"code": 95084
5098+
},
5099+
"Fix all expressions possibly missing 'await'": {
5100+
"category": "Message",
5101+
"code": 95085
5102+
},
5103+
"Remove unnecessary 'await'": {
5104+
"category": "Message",
5105+
"code": 95086
5106+
},
5107+
"Remove all unnecessary uses of 'await'": {
5108+
"category": "Message",
5109+
"code": 95087
5110+
},
5111+
50905112
"No value exists in scope for the shorthand property '{0}'. Either declare one or provide an initializer.": {
50915113
"category": "Error",
50925114
"code": 18004
50935115
},
5094-
"Quoted constructors have previously been interpreted as methods, which is incorrect. In TypeScript 3.6, they will be correctly parsed as constructors. In the meantime, consider using 'constructor()' to write a constructor, or '[\"constructor\"]()' to write a method.": {
5095-
"category": "Error",
5096-
"code": 18005
5097-
},
50985116
"Classes may not have a field named 'constructor'.": {
50995117
"category": "Error",
51005118
"code": 18006

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/parser.ts

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5656,12 +5656,27 @@ namespace ts {
56565656
return finishNode(node);
56575657
}
56585658

5659-
function parseConstructorDeclaration(node: ConstructorDeclaration): ConstructorDeclaration {
5660-
node.kind = SyntaxKind.Constructor;
5661-
parseExpected(SyntaxKind.ConstructorKeyword);
5662-
fillSignature(SyntaxKind.ColonToken, SignatureFlags.None, node);
5663-
node.body = parseFunctionBlockOrSemicolon(SignatureFlags.None, Diagnostics.or_expected);
5664-
return finishNode(node);
5659+
function parseConstructorName() {
5660+
if (token() === SyntaxKind.ConstructorKeyword) {
5661+
return parseExpected(SyntaxKind.ConstructorKeyword);
5662+
}
5663+
if (token() === SyntaxKind.StringLiteral && lookAhead(nextToken) === SyntaxKind.OpenParenToken) {
5664+
return tryParse(() => {
5665+
const literalNode = parseLiteralNode();
5666+
return literalNode.text === "constructor" ? literalNode : undefined;
5667+
});
5668+
}
5669+
}
5670+
5671+
function tryParseConstructorDeclaration(node: ConstructorDeclaration): ConstructorDeclaration | undefined {
5672+
return tryParse(() => {
5673+
if (parseConstructorName()) {
5674+
node.kind = SyntaxKind.Constructor;
5675+
fillSignature(SyntaxKind.ColonToken, SignatureFlags.None, node);
5676+
node.body = parseFunctionBlockOrSemicolon(SignatureFlags.None, Diagnostics.or_expected);
5677+
return finishNode(node);
5678+
}
5679+
});
56655680
}
56665681

56675682
function parseMethodDeclaration(node: MethodDeclaration, asteriskToken: AsteriskToken, diagnosticMessage?: DiagnosticMessage): MethodDeclaration {
@@ -5867,8 +5882,11 @@ namespace ts {
58675882
return parseAccessorDeclaration(<AccessorDeclaration>node, SyntaxKind.SetAccessor);
58685883
}
58695884

5870-
if (token() === SyntaxKind.ConstructorKeyword) {
5871-
return parseConstructorDeclaration(<ConstructorDeclaration>node);
5885+
if (token() === SyntaxKind.ConstructorKeyword || token() === SyntaxKind.StringLiteral) {
5886+
const constructorDeclaration = tryParseConstructorDeclaration(<ConstructorDeclaration>node);
5887+
if (constructorDeclaration) {
5888+
return constructorDeclaration;
5889+
}
58725890
}
58735891

58745892
if (isIndexSignature()) {

src/compiler/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1882,6 +1882,7 @@ namespace ts {
18821882
}
18831883

18841884
export interface JsxAttributes extends ObjectLiteralExpressionBase<JsxAttributeLike> {
1885+
kind: SyntaxKind.JsxAttributes;
18851886
parent: JsxOpeningLikeElement;
18861887
}
18871888

src/compiler/utilities.ts

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3150,6 +3150,23 @@ namespace ts {
31503150
return s.replace(escapedCharsRegExp, getReplacement);
31513151
}
31523152

3153+
/**
3154+
* Strip off existed single quotes or double quotes from a given string
3155+
*
3156+
* @return non-quoted string
3157+
*/
3158+
export function stripQuotes(name: string) {
3159+
const length = name.length;
3160+
if (length >= 2 && name.charCodeAt(0) === name.charCodeAt(length - 1) && startsWithQuote(name)) {
3161+
return name.substring(1, length - 1);
3162+
}
3163+
return name;
3164+
}
3165+
3166+
export function startsWithQuote(name: string): boolean {
3167+
return isSingleOrDoubleQuote(name.charCodeAt(0));
3168+
}
3169+
31533170
function getReplacement(c: string, offset: number, input: string) {
31543171
if (c.charCodeAt(0) === CharacterCodes.nullCharacter) {
31553172
const lookAhead = input.charCodeAt(offset + c.length);
@@ -7468,7 +7485,7 @@ namespace ts {
74687485
export function getDirectoryPath(path: Path): Path;
74697486
/**
74707487
* Returns the path except for its basename. Semantics align with NodeJS's `path.dirname`
7471-
* except that we support URL's as well.
7488+
* except that we support URLs as well.
74727489
*
74737490
* ```ts
74747491
* getDirectoryPath("/path/to/file.ext") === "/path/to"

0 commit comments

Comments
 (0)