Merge branch 'improveImportHelpersDiagnostics' into asyncGenerators

This commit is contained in:
Ron Buckton 2016-11-16 12:36:27 -08:00
commit d6a5e39c3a
8 changed files with 132 additions and 13 deletions

View File

@ -518,7 +518,6 @@ namespace ts {
hasExplicitReturn = false;
bindChildren(node);
// Reset all reachability check related flags on node (for incremental scenarios)
// Reset all emit helper flags on node (for incremental scenarios)
node.flags &= ~NodeFlags.ReachabilityAndEmitFlags;
if (!(currentFlow.flags & FlowFlags.Unreachable) && containerFlags & ContainerFlags.IsFunctionLike && nodeIsPresent((<FunctionLikeDeclaration>node).body)) {
node.flags |= NodeFlags.HasImplicitReturn;

View File

@ -4489,6 +4489,8 @@ namespace ts {
const members: SymbolTable = createMap<Symbol>();
let stringIndexInfo: IndexInfo;
let numberIndexInfo: IndexInfo;
// Resolve upfront such that recursive references see an empty object type.
setStructuredTypeMembers(type, emptySymbols, emptyArray, emptyArray, undefined, undefined);
// In { [P in K]: T }, we refer to P as the type parameter type, K as the constraint type,
// and T as the template type.
const typeParameter = getTypeParameterFromMappedType(type);
@ -15160,7 +15162,7 @@ namespace ts {
}
const functionFlags = getFunctionFlags(<FunctionLikeDeclaration>node);
if ((functionFlags & FunctionFlags.InvalidAsyncOrAsyncGenerator) === FunctionFlags.Async) {
if ((functionFlags & FunctionFlags.InvalidAsyncOrAsyncGenerator) === FunctionFlags.Async && languageVersion < ScriptTarget.ES2017) {
checkExternalEmitHelpers(node, ExternalEmitHelpers.Awaiter);
if (languageVersion < ScriptTarget.ES2015) {
checkExternalEmitHelpers(node, ExternalEmitHelpers.Generator);
@ -15168,7 +15170,7 @@ namespace ts {
}
if ((functionFlags & FunctionFlags.InvalidGenerator) === FunctionFlags.Generator) {
if (functionFlags & FunctionFlags.Async) {
if (functionFlags & FunctionFlags.Async && languageVersion < ScriptTarget.ES2017) {
checkExternalEmitHelpers(node, ExternalEmitHelpers.AsyncGenerator);
}
else if (languageVersion < ScriptTarget.ES2015) {

View File

@ -417,15 +417,15 @@ namespace ts {
HasImplicitReturn = 1 << 7, // If function implicitly returns on one of codepaths (initialized by binding)
HasExplicitReturn = 1 << 8, // If function has explicit reachable return on one of codepaths (initialized by binding)
GlobalAugmentation = 1 << 9, // Set if module declaration is an augmentation for the global scope
HasAsyncFunctions = 1 << 13, // If the file has async functions (initialized by binding)
DisallowInContext = 1 << 16, // If node was parsed in a context where 'in-expressions' are not allowed
YieldContext = 1 << 17, // If node was parsed in the 'yield' context created when parsing a generator
DecoratorContext = 1 << 18, // If node was parsed as part of a decorator
AwaitContext = 1 << 19, // If node was parsed in the 'await' context created when parsing an async function
ThisNodeHasError = 1 << 20, // If the parser encountered an error when parsing the code that created this node
JavaScriptFile = 1 << 21, // If node was parsed in a JavaScript
ThisNodeOrAnySubNodesHasError = 1 << 22, // If this node or any of its children had an error
HasAggregatedChildData = 1 << 23, // If we've computed data from children and cached it in this node
HasAsyncFunctions = 1 << 10, // If the file has async functions (initialized by binding)
DisallowInContext = 1 << 11, // If node was parsed in a context where 'in-expressions' are not allowed
YieldContext = 1 << 12, // If node was parsed in the 'yield' context created when parsing a generator
DecoratorContext = 1 << 13, // If node was parsed as part of a decorator
AwaitContext = 1 << 14, // If node was parsed in the 'await' context created when parsing an async function
ThisNodeHasError = 1 << 15, // If the parser encountered an error when parsing the code that created this node
JavaScriptFile = 1 << 16, // If node was parsed in a JavaScript
ThisNodeOrAnySubNodesHasError = 1 << 17, // If this node or any of its children had an error
HasAggregatedChildData = 1 << 18, // If we've computed data from children and cached it in this node
BlockScoped = Let | Const,
@ -3697,6 +3697,10 @@ namespace ts {
readonly priority?: number; // Helpers with a higher priority are emitted earlier than other helpers on the node.
}
/**
* Used by the checker, this enum keeps track of external emit helpers that should be type
* checked.
*/
/* @internal */
export const enum ExternalEmitHelpers {
Extends = 1 << 0, // __extends (used by the ES2015 class transformation)
@ -3707,7 +3711,6 @@ namespace ts {
Param = 1 << 5, // __param (used by TypeScript decorators transformation)
Awaiter = 1 << 6, // __awaiter (used by ES2017 async functions transformation)
Generator = 1 << 7, // __generator (used by ES2015 generator transformation)
Values = 1 << 8, // __values (used by ES2015 for..of and yield* transformations)
Step = 1 << 9, // __step (used by ES2015 for..of transformation)
Close = 1 << 10, // __close (used by ES2015 for..of transformation)

View File

@ -423,6 +423,10 @@ namespace ts {
return false;
}
export function isEffectiveExternalModule(node: SourceFile, compilerOptions: CompilerOptions) {
return isExternalModule(node) || compilerOptions.isolatedModules;
}
export function isBlockScope(node: Node, parentNode: Node) {
switch (node.kind) {
case SyntaxKind.SourceFile:

View File

@ -0,0 +1,30 @@
//// [recursiveMappedTypes.ts]
// Recursive mapped types simply appear empty
type Recurse = {
[K in keyof Recurse]: Recurse[K]
}
type Recurse1 = {
[K in keyof Recurse2]: Recurse2[K]
}
type Recurse2 = {
[K in keyof Recurse1]: Recurse1[K]
}
//// [recursiveMappedTypes.js]
// Recursive mapped types simply appear empty
//// [recursiveMappedTypes.d.ts]
declare type Recurse = {
[K in keyof Recurse]: Recurse[K];
};
declare type Recurse1 = {
[K in keyof Recurse2]: Recurse2[K];
};
declare type Recurse2 = {
[K in keyof Recurse1]: Recurse1[K];
};

View File

@ -0,0 +1,33 @@
=== tests/cases/conformance/types/mapped/recursiveMappedTypes.ts ===
// Recursive mapped types simply appear empty
type Recurse = {
>Recurse : Symbol(Recurse, Decl(recursiveMappedTypes.ts, 0, 0))
[K in keyof Recurse]: Recurse[K]
>K : Symbol(K, Decl(recursiveMappedTypes.ts, 4, 5))
>Recurse : Symbol(Recurse, Decl(recursiveMappedTypes.ts, 0, 0))
>Recurse : Symbol(Recurse, Decl(recursiveMappedTypes.ts, 0, 0))
>K : Symbol(K, Decl(recursiveMappedTypes.ts, 4, 5))
}
type Recurse1 = {
>Recurse1 : Symbol(Recurse1, Decl(recursiveMappedTypes.ts, 5, 1))
[K in keyof Recurse2]: Recurse2[K]
>K : Symbol(K, Decl(recursiveMappedTypes.ts, 8, 5))
>Recurse2 : Symbol(Recurse2, Decl(recursiveMappedTypes.ts, 9, 1))
>Recurse2 : Symbol(Recurse2, Decl(recursiveMappedTypes.ts, 9, 1))
>K : Symbol(K, Decl(recursiveMappedTypes.ts, 8, 5))
}
type Recurse2 = {
>Recurse2 : Symbol(Recurse2, Decl(recursiveMappedTypes.ts, 9, 1))
[K in keyof Recurse1]: Recurse1[K]
>K : Symbol(K, Decl(recursiveMappedTypes.ts, 12, 5))
>Recurse1 : Symbol(Recurse1, Decl(recursiveMappedTypes.ts, 5, 1))
>Recurse1 : Symbol(Recurse1, Decl(recursiveMappedTypes.ts, 5, 1))
>K : Symbol(K, Decl(recursiveMappedTypes.ts, 12, 5))
}

View File

@ -0,0 +1,33 @@
=== tests/cases/conformance/types/mapped/recursiveMappedTypes.ts ===
// Recursive mapped types simply appear empty
type Recurse = {
>Recurse : Recurse
[K in keyof Recurse]: Recurse[K]
>K : K
>Recurse : Recurse
>Recurse : Recurse
>K : K
}
type Recurse1 = {
>Recurse1 : Recurse1
[K in keyof Recurse2]: Recurse2[K]
>K : K
>Recurse2 : Recurse2
>Recurse2 : Recurse2
>K : K
}
type Recurse2 = {
>Recurse2 : Recurse2
[K in keyof Recurse1]: Recurse1[K]
>K : K
>Recurse1 : Recurse1
>Recurse1 : Recurse1
>K : K
}

View File

@ -0,0 +1,15 @@
// @declaration: true
// Recursive mapped types simply appear empty
type Recurse = {
[K in keyof Recurse]: Recurse[K]
}
type Recurse1 = {
[K in keyof Recurse2]: Recurse2[K]
}
type Recurse2 = {
[K in keyof Recurse1]: Recurse1[K]
}