Skip to content

Commit d6a5e39

Browse files
committed
Merge branch 'improveImportHelpersDiagnostics' into asyncGenerators
2 parents ab1dc52 + d775f0f commit d6a5e39

8 files changed

Lines changed: 132 additions & 13 deletions

File tree

src/compiler/binder.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -518,7 +518,6 @@ namespace ts {
518518
hasExplicitReturn = false;
519519
bindChildren(node);
520520
// Reset all reachability check related flags on node (for incremental scenarios)
521-
// Reset all emit helper flags on node (for incremental scenarios)
522521
node.flags &= ~NodeFlags.ReachabilityAndEmitFlags;
523522
if (!(currentFlow.flags & FlowFlags.Unreachable) && containerFlags & ContainerFlags.IsFunctionLike && nodeIsPresent((<FunctionLikeDeclaration>node).body)) {
524523
node.flags |= NodeFlags.HasImplicitReturn;

src/compiler/checker.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4489,6 +4489,8 @@ namespace ts {
44894489
const members: SymbolTable = createMap<Symbol>();
44904490
let stringIndexInfo: IndexInfo;
44914491
let numberIndexInfo: IndexInfo;
4492+
// Resolve upfront such that recursive references see an empty object type.
4493+
setStructuredTypeMembers(type, emptySymbols, emptyArray, emptyArray, undefined, undefined);
44924494
// In { [P in K]: T }, we refer to P as the type parameter type, K as the constraint type,
44934495
// and T as the template type.
44944496
const typeParameter = getTypeParameterFromMappedType(type);
@@ -15160,15 +15162,15 @@ namespace ts {
1516015162
}
1516115163

1516215164
const functionFlags = getFunctionFlags(<FunctionLikeDeclaration>node);
15163-
if ((functionFlags & FunctionFlags.InvalidAsyncOrAsyncGenerator) === FunctionFlags.Async) {
15165+
if ((functionFlags & FunctionFlags.InvalidAsyncOrAsyncGenerator) === FunctionFlags.Async && languageVersion < ScriptTarget.ES2017) {
1516415166
checkExternalEmitHelpers(node, ExternalEmitHelpers.Awaiter);
1516515167
if (languageVersion < ScriptTarget.ES2015) {
1516615168
checkExternalEmitHelpers(node, ExternalEmitHelpers.Generator);
1516715169
}
1516815170
}
1516915171

1517015172
if ((functionFlags & FunctionFlags.InvalidGenerator) === FunctionFlags.Generator) {
15171-
if (functionFlags & FunctionFlags.Async) {
15173+
if (functionFlags & FunctionFlags.Async && languageVersion < ScriptTarget.ES2017) {
1517215174
checkExternalEmitHelpers(node, ExternalEmitHelpers.AsyncGenerator);
1517315175
}
1517415176
else if (languageVersion < ScriptTarget.ES2015) {

src/compiler/types.ts

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -417,15 +417,15 @@ namespace ts {
417417
HasImplicitReturn = 1 << 7, // If function implicitly returns on one of codepaths (initialized by binding)
418418
HasExplicitReturn = 1 << 8, // If function has explicit reachable return on one of codepaths (initialized by binding)
419419
GlobalAugmentation = 1 << 9, // Set if module declaration is an augmentation for the global scope
420-
HasAsyncFunctions = 1 << 13, // If the file has async functions (initialized by binding)
421-
DisallowInContext = 1 << 16, // If node was parsed in a context where 'in-expressions' are not allowed
422-
YieldContext = 1 << 17, // If node was parsed in the 'yield' context created when parsing a generator
423-
DecoratorContext = 1 << 18, // If node was parsed as part of a decorator
424-
AwaitContext = 1 << 19, // If node was parsed in the 'await' context created when parsing an async function
425-
ThisNodeHasError = 1 << 20, // If the parser encountered an error when parsing the code that created this node
426-
JavaScriptFile = 1 << 21, // If node was parsed in a JavaScript
427-
ThisNodeOrAnySubNodesHasError = 1 << 22, // If this node or any of its children had an error
428-
HasAggregatedChildData = 1 << 23, // If we've computed data from children and cached it in this node
420+
HasAsyncFunctions = 1 << 10, // If the file has async functions (initialized by binding)
421+
DisallowInContext = 1 << 11, // If node was parsed in a context where 'in-expressions' are not allowed
422+
YieldContext = 1 << 12, // If node was parsed in the 'yield' context created when parsing a generator
423+
DecoratorContext = 1 << 13, // If node was parsed as part of a decorator
424+
AwaitContext = 1 << 14, // If node was parsed in the 'await' context created when parsing an async function
425+
ThisNodeHasError = 1 << 15, // If the parser encountered an error when parsing the code that created this node
426+
JavaScriptFile = 1 << 16, // If node was parsed in a JavaScript
427+
ThisNodeOrAnySubNodesHasError = 1 << 17, // If this node or any of its children had an error
428+
HasAggregatedChildData = 1 << 18, // If we've computed data from children and cached it in this node
429429

430430
BlockScoped = Let | Const,
431431

@@ -3697,6 +3697,10 @@ namespace ts {
36973697
readonly priority?: number; // Helpers with a higher priority are emitted earlier than other helpers on the node.
36983698
}
36993699

3700+
/**
3701+
* Used by the checker, this enum keeps track of external emit helpers that should be type
3702+
* checked.
3703+
*/
37003704
/* @internal */
37013705
export const enum ExternalEmitHelpers {
37023706
Extends = 1 << 0, // __extends (used by the ES2015 class transformation)
@@ -3707,7 +3711,6 @@ namespace ts {
37073711
Param = 1 << 5, // __param (used by TypeScript decorators transformation)
37083712
Awaiter = 1 << 6, // __awaiter (used by ES2017 async functions transformation)
37093713
Generator = 1 << 7, // __generator (used by ES2015 generator transformation)
3710-
37113714
Values = 1 << 8, // __values (used by ES2015 for..of and yield* transformations)
37123715
Step = 1 << 9, // __step (used by ES2015 for..of transformation)
37133716
Close = 1 << 10, // __close (used by ES2015 for..of transformation)

src/compiler/utilities.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -423,6 +423,10 @@ namespace ts {
423423
return false;
424424
}
425425

426+
export function isEffectiveExternalModule(node: SourceFile, compilerOptions: CompilerOptions) {
427+
return isExternalModule(node) || compilerOptions.isolatedModules;
428+
}
429+
426430
export function isBlockScope(node: Node, parentNode: Node) {
427431
switch (node.kind) {
428432
case SyntaxKind.SourceFile:
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
//// [recursiveMappedTypes.ts]
2+
3+
// Recursive mapped types simply appear empty
4+
5+
type Recurse = {
6+
[K in keyof Recurse]: Recurse[K]
7+
}
8+
9+
type Recurse1 = {
10+
[K in keyof Recurse2]: Recurse2[K]
11+
}
12+
13+
type Recurse2 = {
14+
[K in keyof Recurse1]: Recurse1[K]
15+
}
16+
17+
//// [recursiveMappedTypes.js]
18+
// Recursive mapped types simply appear empty
19+
20+
21+
//// [recursiveMappedTypes.d.ts]
22+
declare type Recurse = {
23+
[K in keyof Recurse]: Recurse[K];
24+
};
25+
declare type Recurse1 = {
26+
[K in keyof Recurse2]: Recurse2[K];
27+
};
28+
declare type Recurse2 = {
29+
[K in keyof Recurse1]: Recurse1[K];
30+
};
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
=== tests/cases/conformance/types/mapped/recursiveMappedTypes.ts ===
2+
3+
// Recursive mapped types simply appear empty
4+
5+
type Recurse = {
6+
>Recurse : Symbol(Recurse, Decl(recursiveMappedTypes.ts, 0, 0))
7+
8+
[K in keyof Recurse]: Recurse[K]
9+
>K : Symbol(K, Decl(recursiveMappedTypes.ts, 4, 5))
10+
>Recurse : Symbol(Recurse, Decl(recursiveMappedTypes.ts, 0, 0))
11+
>Recurse : Symbol(Recurse, Decl(recursiveMappedTypes.ts, 0, 0))
12+
>K : Symbol(K, Decl(recursiveMappedTypes.ts, 4, 5))
13+
}
14+
15+
type Recurse1 = {
16+
>Recurse1 : Symbol(Recurse1, Decl(recursiveMappedTypes.ts, 5, 1))
17+
18+
[K in keyof Recurse2]: Recurse2[K]
19+
>K : Symbol(K, Decl(recursiveMappedTypes.ts, 8, 5))
20+
>Recurse2 : Symbol(Recurse2, Decl(recursiveMappedTypes.ts, 9, 1))
21+
>Recurse2 : Symbol(Recurse2, Decl(recursiveMappedTypes.ts, 9, 1))
22+
>K : Symbol(K, Decl(recursiveMappedTypes.ts, 8, 5))
23+
}
24+
25+
type Recurse2 = {
26+
>Recurse2 : Symbol(Recurse2, Decl(recursiveMappedTypes.ts, 9, 1))
27+
28+
[K in keyof Recurse1]: Recurse1[K]
29+
>K : Symbol(K, Decl(recursiveMappedTypes.ts, 12, 5))
30+
>Recurse1 : Symbol(Recurse1, Decl(recursiveMappedTypes.ts, 5, 1))
31+
>Recurse1 : Symbol(Recurse1, Decl(recursiveMappedTypes.ts, 5, 1))
32+
>K : Symbol(K, Decl(recursiveMappedTypes.ts, 12, 5))
33+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
=== tests/cases/conformance/types/mapped/recursiveMappedTypes.ts ===
2+
3+
// Recursive mapped types simply appear empty
4+
5+
type Recurse = {
6+
>Recurse : Recurse
7+
8+
[K in keyof Recurse]: Recurse[K]
9+
>K : K
10+
>Recurse : Recurse
11+
>Recurse : Recurse
12+
>K : K
13+
}
14+
15+
type Recurse1 = {
16+
>Recurse1 : Recurse1
17+
18+
[K in keyof Recurse2]: Recurse2[K]
19+
>K : K
20+
>Recurse2 : Recurse2
21+
>Recurse2 : Recurse2
22+
>K : K
23+
}
24+
25+
type Recurse2 = {
26+
>Recurse2 : Recurse2
27+
28+
[K in keyof Recurse1]: Recurse1[K]
29+
>K : K
30+
>Recurse1 : Recurse1
31+
>Recurse1 : Recurse1
32+
>K : K
33+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// @declaration: true
2+
3+
// Recursive mapped types simply appear empty
4+
5+
type Recurse = {
6+
[K in keyof Recurse]: Recurse[K]
7+
}
8+
9+
type Recurse1 = {
10+
[K in keyof Recurse2]: Recurse2[K]
11+
}
12+
13+
type Recurse2 = {
14+
[K in keyof Recurse1]: Recurse1[K]
15+
}

0 commit comments

Comments
 (0)