Revise binder logic to correctly find 'infer T' containers

This commit is contained in:
Anders Hejlsberg
2018-03-21 13:23:58 -07:00
parent a75449cabc
commit 9083f6cf18

View File

@@ -101,7 +101,6 @@ namespace ts {
HasLocals = 1 << 5,
IsInterface = 1 << 6,
IsObjectLiteralOrClassExpressionMethod = 1 << 7,
IsInferenceContainer = 1 << 8,
}
const binder = createBinder();
@@ -121,7 +120,6 @@ namespace ts {
let container: Node;
let containerContainer: Node; // Container one level up
let blockScopeContainer: Node;
let inferenceContainer: Node;
let lastContainer: Node;
let seenThisKeyword: boolean;
@@ -190,7 +188,6 @@ namespace ts {
container = undefined;
containerContainer = undefined;
blockScopeContainer = undefined;
inferenceContainer = undefined;
lastContainer = undefined;
seenThisKeyword = false;
currentFlow = undefined;
@@ -569,13 +566,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);
}
@@ -1434,9 +1424,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;
@@ -2638,13 +2625,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));