Revise binder logic to correctly find 'infer T' containers

This commit is contained in:
Anders Hejlsberg
2018-03-21 13:23:58 -07:00
committed by Daniel Rosenwasser
parent 12460d5b03
commit 150f437372

View File

@@ -101,7 +101,6 @@ namespace ts {
HasLocals = 1 << 5,
IsInterface = 1 << 6,
IsObjectLiteralOrClassExpressionMethod = 1 << 7,
IsInferenceContainer = 1 << 8,
}
const binder = createBinder();
@@ -120,7 +119,6 @@ namespace ts {
let parent: Node;
let container: Node;
let blockScopeContainer: Node;
let inferenceContainer: Node;
let lastContainer: Node;
let seenThisKeyword: boolean;
@@ -188,7 +186,6 @@ namespace ts {
parent = undefined;
container = undefined;
blockScopeContainer = undefined;
inferenceContainer = undefined;
lastContainer = undefined;
seenThisKeyword = false;
currentFlow = undefined;
@@ -570,13 +567,6 @@ namespace ts {
bindChildren(node);
node.flags = seenThisKeyword ? node.flags | NodeFlags.ContainsThis : node.flags & ~NodeFlags.ContainsThis;
}
else if (containerFlags & ContainerFlags.IsInferenceContainer) {
const saveInferenceContainer = inferenceContainer;
inferenceContainer = node;
node.locals = undefined;
bindChildren(node);
inferenceContainer = saveInferenceContainer;
}
else {
bindChildren(node);
}
@@ -1433,9 +1423,6 @@ namespace ts {
case SyntaxKind.MappedType:
return ContainerFlags.IsContainer | ContainerFlags.HasLocals;
case SyntaxKind.ConditionalType:
return ContainerFlags.IsInferenceContainer;
case SyntaxKind.SourceFile:
return ContainerFlags.IsContainer | ContainerFlags.IsControlFlowContainer | ContainerFlags.HasLocals;
@@ -2626,13 +2613,25 @@ namespace ts {
: declareSymbolAndAddToSymbolTable(node, symbolFlags, symbolExcludes);
}
function getInferTypeContainer(node: Node): ConditionalTypeNode {
while (node) {
const parent = node.parent;
if (parent && parent.kind === SyntaxKind.ConditionalType && (<ConditionalTypeNode>parent).extendsType === node) {
return <ConditionalTypeNode>parent;
}
node = parent;
}
return undefined;
}
function bindTypeParameter(node: TypeParameterDeclaration) {
if (node.parent.kind === SyntaxKind.InferType) {
if (inferenceContainer) {
if (!inferenceContainer.locals) {
inferenceContainer.locals = createSymbolTable();
const container = getInferTypeContainer(node.parent);
if (container) {
if (!container.locals) {
container.locals = createSymbolTable();
}
declareSymbol(inferenceContainer.locals, /*parent*/ undefined, node, SymbolFlags.TypeParameter, SymbolFlags.TypeParameterExcludes);
declareSymbol(container.locals, /*parent*/ undefined, node, SymbolFlags.TypeParameter, SymbolFlags.TypeParameterExcludes);
}
else {
bindAnonymousDeclaration(node, SymbolFlags.TypeParameter, getDeclarationName(node));