From a0c29fe4e50256a33d0a3f3fafbd47acc404433b Mon Sep 17 00:00:00 2001 From: Armando Aguirre Date: Fri, 23 Aug 2019 15:42:03 -0700 Subject: [PATCH 1/2] Added optional trailing slash regex --- src/services/navigationBar.ts | 2 +- ...gationBarItemsMultilineStringIdentifiers2.ts | 17 +++++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/src/services/navigationBar.ts b/src/services/navigationBar.ts index 5f826a1a78f..57bf910efda 100644 --- a/src/services/navigationBar.ts +++ b/src/services/navigationBar.ts @@ -713,6 +713,6 @@ namespace ts.NavigationBar { // \r - Carriage Return // \u2028 - Line separator // \u2029 - Paragraph separator - return text.replace(/\\(\r?\n|\r|\u2028|\u2029)/g, ""); + return text.replace(/\\?(\r?\n|\r|\u2028|\u2029)/g, ""); } } diff --git a/tests/cases/fourslash/navigationBarItemsMultilineStringIdentifiers2.ts b/tests/cases/fourslash/navigationBarItemsMultilineStringIdentifiers2.ts index 8c3fe8b4c09..0aef520785a 100644 --- a/tests/cases/fourslash/navigationBarItemsMultilineStringIdentifiers2.ts +++ b/tests/cases/fourslash/navigationBarItemsMultilineStringIdentifiers2.ts @@ -8,6 +8,10 @@ //// const a = ' ''line1\ //// line2'; //// } +//// +//// f(() => { }, `unterminated backtick 1 +//// unterminated backtick 2 +//// unterminated backtick 3 verify.navigationTree({ "text": "", @@ -34,6 +38,10 @@ verify.navigationTree({ { "text": "f(`line1line2line3`) callback", "kind": "function" + }, + { + "text": "f(`unterminated backtick 1unterminated backtick 2unterminated backtick 3) callback", + "kind": "function" } ] }); @@ -54,6 +62,10 @@ verify.navigationBar([ { "text": "f(`line1line2line3`) callback", "kind": "function" + }, + { + "text": "f(`unterminated backtick 1unterminated backtick 2unterminated backtick 3) callback", + "kind": "function" } ] }, @@ -81,5 +93,10 @@ verify.navigationBar([ "text": "f(`line1line2line3`) callback", "kind": "function", "indent": 1 + }, + { + "text": "f(`unterminated backtick 1unterminated backtick 2unterminated backtick 3) callback", + "kind": "function", + "indent": 1 } ]); From e9073a863d1d99d292a80028a71fe008dbe17808 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Mon, 26 Aug 2019 13:20:42 -0700 Subject: [PATCH 2/2] Improve names in infer-from-usage (#33090) Basically, drop "Context" from all names, because it just indicates that it's an implementation of the State monad. --- src/services/codefixes/inferFromUsage.ts | 238 +++++++++++------------ 1 file changed, 119 insertions(+), 119 deletions(-) diff --git a/src/services/codefixes/inferFromUsage.ts b/src/services/codefixes/inferFromUsage.ts index 396d7f44fa8..417ed5c625c 100644 --- a/src/services/codefixes/inferFromUsage.ts +++ b/src/services/codefixes/inferFromUsage.ts @@ -359,7 +359,7 @@ namespace ts.codefix { const references = getReferences(token, program, cancellationToken); const checker = program.getTypeChecker(); const types = InferFromReference.inferTypesFromReferences(references, checker, cancellationToken); - return InferFromReference.unifyFromContext(types, checker); + return InferFromReference.unifyFromUsage(types, checker); } function inferFunctionReferencesFromUsage(containingFunction: FunctionLike, sourceFile: SourceFile, program: Program, cancellationToken: CancellationToken): ReadonlyArray | undefined { @@ -395,33 +395,33 @@ namespace ts.codefix { } namespace InferFromReference { - interface CallContext { + interface CallUsage { argumentTypes: Type[]; - returnType: UsageContext; + returnType: Usage; } - interface UsageContext { + interface Usage { isNumber?: boolean; isString?: boolean; /** Used ambiguously, eg x + ___ or object[___]; results in string | number if no other evidence exists */ isNumberOrString?: boolean; candidateTypes?: Type[]; - properties?: UnderscoreEscapedMap; - callContexts?: CallContext[]; - constructContexts?: CallContext[]; - numberIndexContext?: UsageContext; - stringIndexContext?: UsageContext; + properties?: UnderscoreEscapedMap; + calls?: CallUsage[]; + constructs?: CallUsage[]; + numberIndex?: Usage; + stringIndex?: Usage; candidateThisTypes?: Type[]; } export function inferTypesFromReferences(references: ReadonlyArray, checker: TypeChecker, cancellationToken: CancellationToken): Type[] { - const usageContext: UsageContext = {}; + const usage: Usage = {}; for (const reference of references) { cancellationToken.throwIfCancellationRequested(); - inferTypeFromContext(reference, checker, usageContext); + calculateUsageOfNode(reference, checker, usage); } - return inferFromContext(usageContext, checker); + return inferFromUsage(usage, checker); } export function inferTypeForParametersFromReferences(references: ReadonlyArray | undefined, declaration: FunctionLike, program: Program, cancellationToken: CancellationToken): ParameterInference[] | undefined { @@ -430,35 +430,35 @@ namespace ts.codefix { } const checker = program.getTypeChecker(); - const usageContext: UsageContext = {}; + const usage: Usage = {}; for (const reference of references) { cancellationToken.throwIfCancellationRequested(); - inferTypeFromContext(reference, checker, usageContext); + calculateUsageOfNode(reference, checker, usage); } - const callContexts = [...usageContext.constructContexts || [], ...usageContext.callContexts || []]; + const calls = [...usage.constructs || [], ...usage.calls || []]; return declaration.parameters.map((parameter, parameterIndex): ParameterInference => { const types = []; const isRest = isRestParameter(parameter); let isOptional = false; - for (const callContext of callContexts) { - if (callContext.argumentTypes.length <= parameterIndex) { + for (const call of calls) { + if (call.argumentTypes.length <= parameterIndex) { isOptional = isInJSFile(declaration); types.push(checker.getUndefinedType()); } else if (isRest) { - for (let i = parameterIndex; i < callContext.argumentTypes.length; i++) { - types.push(checker.getBaseTypeOfLiteralType(callContext.argumentTypes[i])); + for (let i = parameterIndex; i < call.argumentTypes.length; i++) { + types.push(checker.getBaseTypeOfLiteralType(call.argumentTypes[i])); } } else { - types.push(checker.getBaseTypeOfLiteralType(callContext.argumentTypes[parameterIndex])); + types.push(checker.getBaseTypeOfLiteralType(call.argumentTypes[parameterIndex])); } } if (isIdentifier(parameter.name)) { const inferred = inferTypesFromReferences(getReferences(parameter.name, program, cancellationToken), checker, cancellationToken); types.push(...(isRest ? mapDefined(inferred, checker.getElementTypeOfArrayType) : inferred)); } - const type = unifyFromContext(types, checker); + const type = unifyFromUsage(types, checker); return { type: isRest ? checker.createArrayType(type) : type, isOptional: isOptional && !isRest, @@ -473,89 +473,89 @@ namespace ts.codefix { } const checker = program.getTypeChecker(); - const usageContext: UsageContext = {}; + const usage: Usage = {}; for (const reference of references) { cancellationToken.throwIfCancellationRequested(); - inferTypeFromContext(reference, checker, usageContext); + calculateUsageOfNode(reference, checker, usage); } - return unifyFromContext(usageContext.candidateThisTypes || emptyArray, checker); + return unifyFromUsage(usage.candidateThisTypes || emptyArray, checker); } - function inferTypeFromContext(node: Expression, checker: TypeChecker, usageContext: UsageContext): void { + function calculateUsageOfNode(node: Expression, checker: TypeChecker, usage: Usage): void { while (isRightSideOfQualifiedNameOrPropertyAccess(node)) { node = node.parent; } switch (node.parent.kind) { case SyntaxKind.PostfixUnaryExpression: - usageContext.isNumber = true; + usage.isNumber = true; break; case SyntaxKind.PrefixUnaryExpression: - inferTypeFromPrefixUnaryExpressionContext(node.parent, usageContext); + inferTypeFromPrefixUnaryExpression(node.parent, usage); break; case SyntaxKind.BinaryExpression: - inferTypeFromBinaryExpressionContext(node, node.parent, checker, usageContext); + inferTypeFromBinaryExpression(node, node.parent, checker, usage); break; case SyntaxKind.CaseClause: case SyntaxKind.DefaultClause: - inferTypeFromSwitchStatementLabelContext(node.parent, checker, usageContext); + inferTypeFromSwitchStatementLabel(node.parent, checker, usage); break; case SyntaxKind.CallExpression: case SyntaxKind.NewExpression: if ((node.parent).expression === node) { - inferTypeFromCallExpressionContext(node.parent, checker, usageContext); + inferTypeFromCallExpression(node.parent, checker, usage); } else { - inferTypeFromContextualType(node, checker, usageContext); + inferTypeFromContextualType(node, checker, usage); } break; case SyntaxKind.PropertyAccessExpression: - inferTypeFromPropertyAccessExpressionContext(node.parent, checker, usageContext); + inferTypeFromPropertyAccessExpression(node.parent, checker, usage); break; case SyntaxKind.ElementAccessExpression: - inferTypeFromPropertyElementExpressionContext(node.parent, node, checker, usageContext); + inferTypeFromPropertyElementExpression(node.parent, node, checker, usage); break; case SyntaxKind.PropertyAssignment: case SyntaxKind.ShorthandPropertyAssignment: - inferTypeFromPropertyAssignment(node.parent, checker, usageContext); + inferTypeFromPropertyAssignment(node.parent, checker, usage); break; case SyntaxKind.PropertyDeclaration: - inferTypeFromPropertyDeclaration(node.parent, checker, usageContext); + inferTypeFromPropertyDeclaration(node.parent, checker, usage); break; case SyntaxKind.VariableDeclaration: { const { name, initializer } = node.parent as VariableDeclaration; if (node === name) { if (initializer) { // This can happen for `let x = null;` which still has an implicit-any error. - addCandidateType(usageContext, checker.getTypeAtLocation(initializer)); + addCandidateType(usage, checker.getTypeAtLocation(initializer)); } break; } } // falls through default: - return inferTypeFromContextualType(node, checker, usageContext); + return inferTypeFromContextualType(node, checker, usage); } } - function inferTypeFromContextualType(node: Expression, checker: TypeChecker, usageContext: UsageContext): void { + function inferTypeFromContextualType(node: Expression, checker: TypeChecker, usage: Usage): void { if (isExpressionNode(node)) { - addCandidateType(usageContext, checker.getContextualType(node)); + addCandidateType(usage, checker.getContextualType(node)); } } - function inferTypeFromPrefixUnaryExpressionContext(node: PrefixUnaryExpression, usageContext: UsageContext): void { + function inferTypeFromPrefixUnaryExpression(node: PrefixUnaryExpression, usage: Usage): void { switch (node.operator) { case SyntaxKind.PlusPlusToken: case SyntaxKind.MinusMinusToken: case SyntaxKind.MinusToken: case SyntaxKind.TildeToken: - usageContext.isNumber = true; + usage.isNumber = true; break; case SyntaxKind.PlusToken: - usageContext.isNumberOrString = true; + usage.isNumberOrString = true; break; // case SyntaxKind.ExclamationToken: @@ -563,7 +563,7 @@ namespace ts.codefix { } } - function inferTypeFromBinaryExpressionContext(node: Expression, parent: BinaryExpression, checker: TypeChecker, usageContext: UsageContext): void { + function inferTypeFromBinaryExpression(node: Expression, parent: BinaryExpression, checker: TypeChecker, usage: Usage): void { switch (parent.operatorToken.kind) { // ExponentiationOperator case SyntaxKind.AsteriskAsteriskToken: @@ -606,10 +606,10 @@ namespace ts.codefix { case SyntaxKind.GreaterThanEqualsToken: const operandType = checker.getTypeAtLocation(parent.left === node ? parent.right : parent.left); if (operandType.flags & TypeFlags.EnumLike) { - addCandidateType(usageContext, operandType); + addCandidateType(usage, operandType); } else { - usageContext.isNumber = true; + usage.isNumber = true; } break; @@ -617,16 +617,16 @@ namespace ts.codefix { case SyntaxKind.PlusToken: const otherOperandType = checker.getTypeAtLocation(parent.left === node ? parent.right : parent.left); if (otherOperandType.flags & TypeFlags.EnumLike) { - addCandidateType(usageContext, otherOperandType); + addCandidateType(usage, otherOperandType); } else if (otherOperandType.flags & TypeFlags.NumberLike) { - usageContext.isNumber = true; + usage.isNumber = true; } else if (otherOperandType.flags & TypeFlags.StringLike) { - usageContext.isString = true; + usage.isString = true; } else { - usageContext.isNumberOrString = true; + usage.isNumberOrString = true; } break; @@ -636,12 +636,12 @@ namespace ts.codefix { case SyntaxKind.EqualsEqualsEqualsToken: case SyntaxKind.ExclamationEqualsEqualsToken: case SyntaxKind.ExclamationEqualsToken: - addCandidateType(usageContext, checker.getTypeAtLocation(parent.left === node ? parent.right : parent.left)); + addCandidateType(usage, checker.getTypeAtLocation(parent.left === node ? parent.right : parent.left)); break; case SyntaxKind.InKeyword: if (node === parent.left) { - usageContext.isString = true; + usage.isString = true; } break; @@ -651,7 +651,7 @@ namespace ts.codefix { (node.parent.parent.kind === SyntaxKind.VariableDeclaration || isAssignmentExpression(node.parent.parent, /*excludeCompoundAssignment*/ true))) { // var x = x || {}; // TODO: use getFalsyflagsOfType - addCandidateType(usageContext, checker.getTypeAtLocation(parent.right)); + addCandidateType(usage, checker.getTypeAtLocation(parent.right)); } break; @@ -663,68 +663,68 @@ namespace ts.codefix { } } - function inferTypeFromSwitchStatementLabelContext(parent: CaseOrDefaultClause, checker: TypeChecker, usageContext: UsageContext): void { - addCandidateType(usageContext, checker.getTypeAtLocation(parent.parent.parent.expression)); + function inferTypeFromSwitchStatementLabel(parent: CaseOrDefaultClause, checker: TypeChecker, usage: Usage): void { + addCandidateType(usage, checker.getTypeAtLocation(parent.parent.parent.expression)); } - function inferTypeFromCallExpressionContext(parent: CallExpression | NewExpression, checker: TypeChecker, usageContext: UsageContext): void { - const callContext: CallContext = { + function inferTypeFromCallExpression(parent: CallExpression | NewExpression, checker: TypeChecker, usage: Usage): void { + const call: CallUsage = { argumentTypes: [], returnType: {} }; if (parent.arguments) { for (const argument of parent.arguments) { - callContext.argumentTypes.push(checker.getTypeAtLocation(argument)); + call.argumentTypes.push(checker.getTypeAtLocation(argument)); } } - inferTypeFromContext(parent, checker, callContext.returnType); + calculateUsageOfNode(parent, checker, call.returnType); if (parent.kind === SyntaxKind.CallExpression) { - (usageContext.callContexts || (usageContext.callContexts = [])).push(callContext); + (usage.calls || (usage.calls = [])).push(call); } else { - (usageContext.constructContexts || (usageContext.constructContexts = [])).push(callContext); + (usage.constructs || (usage.constructs = [])).push(call); } } - function inferTypeFromPropertyAccessExpressionContext(parent: PropertyAccessExpression, checker: TypeChecker, usageContext: UsageContext): void { + function inferTypeFromPropertyAccessExpression(parent: PropertyAccessExpression, checker: TypeChecker, usage: Usage): void { const name = escapeLeadingUnderscores(parent.name.text); - if (!usageContext.properties) { - usageContext.properties = createUnderscoreEscapedMap(); + if (!usage.properties) { + usage.properties = createUnderscoreEscapedMap(); } - const propertyUsageContext = usageContext.properties.get(name) || { }; - inferTypeFromContext(parent, checker, propertyUsageContext); - usageContext.properties.set(name, propertyUsageContext); + const propertyUsage = usage.properties.get(name) || { }; + calculateUsageOfNode(parent, checker, propertyUsage); + usage.properties.set(name, propertyUsage); } - function inferTypeFromPropertyElementExpressionContext(parent: ElementAccessExpression, node: Expression, checker: TypeChecker, usageContext: UsageContext): void { + function inferTypeFromPropertyElementExpression(parent: ElementAccessExpression, node: Expression, checker: TypeChecker, usage: Usage): void { if (node === parent.argumentExpression) { - usageContext.isNumberOrString = true; + usage.isNumberOrString = true; return; } else { const indexType = checker.getTypeAtLocation(parent.argumentExpression); - const indexUsageContext = {}; - inferTypeFromContext(parent, checker, indexUsageContext); + const indexUsage = {}; + calculateUsageOfNode(parent, checker, indexUsage); if (indexType.flags & TypeFlags.NumberLike) { - usageContext.numberIndexContext = indexUsageContext; + usage.numberIndex = indexUsage; } else { - usageContext.stringIndexContext = indexUsageContext; + usage.stringIndex = indexUsage; } } } - function inferTypeFromPropertyAssignment(assignment: PropertyAssignment | ShorthandPropertyAssignment, checker: TypeChecker, usageContext: UsageContext) { + function inferTypeFromPropertyAssignment(assignment: PropertyAssignment | ShorthandPropertyAssignment, checker: TypeChecker, usage: Usage) { const nodeWithRealType = isVariableDeclaration(assignment.parent.parent) ? assignment.parent.parent : assignment.parent; - addCandidateThisType(usageContext, checker.getTypeAtLocation(nodeWithRealType)); + addCandidateThisType(usage, checker.getTypeAtLocation(nodeWithRealType)); } - function inferTypeFromPropertyDeclaration(declaration: PropertyDeclaration, checker: TypeChecker, usageContext: UsageContext) { - addCandidateThisType(usageContext, checker.getTypeAtLocation(declaration.parent)); + function inferTypeFromPropertyDeclaration(declaration: PropertyDeclaration, checker: TypeChecker, usage: Usage) { + addCandidateThisType(usage, checker.getTypeAtLocation(declaration.parent)); } interface Priority { @@ -745,7 +745,7 @@ namespace ts.codefix { return inferences.filter(i => toRemove.every(f => !f(i))); } - export function unifyFromContext(inferences: ReadonlyArray, checker: TypeChecker, fallback = checker.getAnyType()): Type { + export function unifyFromUsage(inferences: ReadonlyArray, checker: TypeChecker, fallback = checker.getAnyType()): Type { if (!inferences.length) return fallback; // 1. string or number individually override string | number @@ -815,82 +815,82 @@ namespace ts.codefix { numberIndices.length ? checker.createIndexInfo(checker.getUnionType(numberIndices), numberIndexReadonly) : undefined); } - function inferFromContext(usageContext: UsageContext, checker: TypeChecker) { + function inferFromUsage(usage: Usage, checker: TypeChecker) { const types = []; - if (usageContext.isNumber) { + if (usage.isNumber) { types.push(checker.getNumberType()); } - if (usageContext.isString) { + if (usage.isString) { types.push(checker.getStringType()); } - if (usageContext.isNumberOrString) { + if (usage.isNumberOrString) { types.push(checker.getUnionType([checker.getStringType(), checker.getNumberType()])); } - types.push(...(usageContext.candidateTypes || []).map(t => checker.getBaseTypeOfLiteralType(t))); + types.push(...(usage.candidateTypes || []).map(t => checker.getBaseTypeOfLiteralType(t))); - if (usageContext.properties && hasCallContext(usageContext.properties.get("then" as __String))) { - const paramType = getParameterTypeFromCallContexts(0, usageContext.properties.get("then" as __String)!.callContexts!, /*isRestParameter*/ false, checker)!; // TODO: GH#18217 + if (usage.properties && hasCalls(usage.properties.get("then" as __String))) { + const paramType = getParameterTypeFromCalls(0, usage.properties.get("then" as __String)!.calls!, /*isRestParameter*/ false, checker)!; // TODO: GH#18217 const types = paramType.getCallSignatures().map(c => c.getReturnType()); types.push(checker.createPromiseType(types.length ? checker.getUnionType(types, UnionReduction.Subtype) : checker.getAnyType())); } - else if (usageContext.properties && hasCallContext(usageContext.properties.get("push" as __String))) { - types.push(checker.createArrayType(getParameterTypeFromCallContexts(0, usageContext.properties.get("push" as __String)!.callContexts!, /*isRestParameter*/ false, checker)!)); + else if (usage.properties && hasCalls(usage.properties.get("push" as __String))) { + types.push(checker.createArrayType(getParameterTypeFromCalls(0, usage.properties.get("push" as __String)!.calls!, /*isRestParameter*/ false, checker)!)); } - if (usageContext.numberIndexContext) { - types.push(checker.createArrayType(recur(usageContext.numberIndexContext))); + if (usage.numberIndex) { + types.push(checker.createArrayType(recur(usage.numberIndex))); } - else if (usageContext.properties || usageContext.callContexts || usageContext.constructContexts || usageContext.stringIndexContext) { + else if (usage.properties || usage.calls || usage.constructs || usage.stringIndex) { const members = createUnderscoreEscapedMap(); const callSignatures: Signature[] = []; const constructSignatures: Signature[] = []; let stringIndexInfo: IndexInfo | undefined; - if (usageContext.properties) { - usageContext.properties.forEach((context, name) => { + if (usage.properties) { + usage.properties.forEach((u, name) => { const symbol = checker.createSymbol(SymbolFlags.Property, name); - symbol.type = recur(context); + symbol.type = recur(u); members.set(name, symbol); }); } - if (usageContext.callContexts) { - for (const callContext of usageContext.callContexts) { - callSignatures.push(getSignatureFromCallContext(callContext, checker)); + if (usage.calls) { + for (const call of usage.calls) { + callSignatures.push(getSignatureFromCall(call, checker)); } } - if (usageContext.constructContexts) { - for (const constructContext of usageContext.constructContexts) { - constructSignatures.push(getSignatureFromCallContext(constructContext, checker)); + if (usage.constructs) { + for (const construct of usage.constructs) { + constructSignatures.push(getSignatureFromCall(construct, checker)); } } - if (usageContext.stringIndexContext) { - stringIndexInfo = checker.createIndexInfo(recur(usageContext.stringIndexContext), /*isReadonly*/ false); + if (usage.stringIndex) { + stringIndexInfo = checker.createIndexInfo(recur(usage.stringIndex), /*isReadonly*/ false); } types.push(checker.createAnonymousType(/*symbol*/ undefined!, members, callSignatures, constructSignatures, stringIndexInfo, /*numberIndexInfo*/ undefined)); // TODO: GH#18217 } return types; - function recur(innerContext: UsageContext): Type { - return unifyFromContext(inferFromContext(innerContext, checker), checker); + function recur(innerUsage: Usage): Type { + return unifyFromUsage(inferFromUsage(innerUsage, checker), checker); } } - function getParameterTypeFromCallContexts(parameterIndex: number, callContexts: CallContext[], isRestParameter: boolean, checker: TypeChecker) { + function getParameterTypeFromCalls(parameterIndex: number, calls: CallUsage[], isRestParameter: boolean, checker: TypeChecker) { let types: Type[] = []; - if (callContexts) { - for (const callContext of callContexts) { - if (callContext.argumentTypes.length > parameterIndex) { + if (calls) { + for (const call of calls) { + if (call.argumentTypes.length > parameterIndex) { if (isRestParameter) { - types = concatenate(types, map(callContext.argumentTypes.slice(parameterIndex), a => checker.getBaseTypeOfLiteralType(a))); + types = concatenate(types, map(call.argumentTypes.slice(parameterIndex), a => checker.getBaseTypeOfLiteralType(a))); } else { - types.push(checker.getBaseTypeOfLiteralType(callContext.argumentTypes[parameterIndex])); + types.push(checker.getBaseTypeOfLiteralType(call.argumentTypes[parameterIndex])); } } } @@ -903,32 +903,32 @@ namespace ts.codefix { return undefined; } - function getSignatureFromCallContext(callContext: CallContext, checker: TypeChecker): Signature { + function getSignatureFromCall(call: CallUsage, checker: TypeChecker): Signature { const parameters: Symbol[] = []; - for (let i = 0; i < callContext.argumentTypes.length; i++) { + for (let i = 0; i < call.argumentTypes.length; i++) { const symbol = checker.createSymbol(SymbolFlags.FunctionScopedVariable, escapeLeadingUnderscores(`arg${i}`)); - symbol.type = checker.getWidenedType(checker.getBaseTypeOfLiteralType(callContext.argumentTypes[i])); + symbol.type = checker.getWidenedType(checker.getBaseTypeOfLiteralType(call.argumentTypes[i])); parameters.push(symbol); } - const returnType = unifyFromContext(inferFromContext(callContext.returnType, checker), checker, checker.getVoidType()); + const returnType = unifyFromUsage(inferFromUsage(call.returnType, checker), checker, checker.getVoidType()); // TODO: GH#18217 - return checker.createSignature(/*declaration*/ undefined!, /*typeParameters*/ undefined, /*thisParameter*/ undefined, parameters, returnType, /*typePredicate*/ undefined, callContext.argumentTypes.length, /*hasRestParameter*/ false, /*hasLiteralTypes*/ false); + return checker.createSignature(/*declaration*/ undefined!, /*typeParameters*/ undefined, /*thisParameter*/ undefined, parameters, returnType, /*typePredicate*/ undefined, call.argumentTypes.length, /*hasRestParameter*/ false, /*hasLiteralTypes*/ false); } - function addCandidateType(context: UsageContext, type: Type | undefined) { + function addCandidateType(usage: Usage, type: Type | undefined) { if (type && !(type.flags & TypeFlags.Any) && !(type.flags & TypeFlags.Never)) { - (context.candidateTypes || (context.candidateTypes = [])).push(type); + (usage.candidateTypes || (usage.candidateTypes = [])).push(type); } } - function addCandidateThisType(context: UsageContext, type: Type | undefined) { + function addCandidateThisType(usage: Usage, type: Type | undefined) { if (type && !(type.flags & TypeFlags.Any) && !(type.flags & TypeFlags.Never)) { - (context.candidateThisTypes || (context.candidateThisTypes = [])).push(type); + (usage.candidateThisTypes || (usage.candidateThisTypes = [])).push(type); } } - function hasCallContext(usageContext: UsageContext | undefined): boolean { - return !!usageContext && !!usageContext.callContexts; + function hasCalls(usage: Usage | undefined): boolean { + return !!usage && !!usage.calls; } } }