mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-13 16:34:39 -06:00
Persist inference context object throughout the signature, and add isFixed property
This commit is contained in:
parent
f6de919407
commit
df6f856ad5
@ -3505,6 +3505,7 @@ module ts {
|
||||
return t => {
|
||||
for (let i = 0; i < context.typeParameters.length; i++) {
|
||||
if (t === context.typeParameters[i]) {
|
||||
context.inferences[i].isFixed = true;
|
||||
return getInferredType(context, i);
|
||||
}
|
||||
}
|
||||
@ -4563,12 +4564,11 @@ module ts {
|
||||
function createInferenceContext(typeParameters: TypeParameter[], inferUnionTypes: boolean): InferenceContext {
|
||||
let inferences: TypeInferences[] = [];
|
||||
for (let unused of typeParameters) {
|
||||
inferences.push({ primary: undefined, secondary: undefined });
|
||||
inferences.push({ primary: undefined, secondary: undefined, isFixed: false });
|
||||
}
|
||||
return {
|
||||
typeParameters: typeParameters,
|
||||
inferUnionTypes: inferUnionTypes,
|
||||
inferenceCount: 0,
|
||||
inferences: inferences,
|
||||
inferredTypes: new Array(typeParameters.length),
|
||||
};
|
||||
@ -4615,11 +4615,13 @@ module ts {
|
||||
for (let i = 0; i < typeParameters.length; i++) {
|
||||
if (target === typeParameters[i]) {
|
||||
let inferences = context.inferences[i];
|
||||
let candidates = inferiority ?
|
||||
inferences.secondary || (inferences.secondary = []) :
|
||||
inferences.primary || (inferences.primary = []);
|
||||
if (!contains(candidates, source)) candidates.push(source);
|
||||
break;
|
||||
if (!inferences.isFixed) {
|
||||
let candidates = inferiority ?
|
||||
inferences.secondary || (inferences.secondary = []) :
|
||||
inferences.primary || (inferences.primary = []);
|
||||
if (!contains(candidates, source)) candidates.push(source);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -6336,11 +6338,15 @@ module ts {
|
||||
return getSignatureInstantiation(signature, getInferredTypes(context));
|
||||
}
|
||||
|
||||
function inferTypeArguments(signature: Signature, args: Expression[], excludeArgument: boolean[]): InferenceContext {
|
||||
function inferTypeArguments(signature: Signature, args: Expression[], excludeArgument: boolean[], context: InferenceContext): void {
|
||||
let typeParameters = signature.typeParameters;
|
||||
let context = createInferenceContext(typeParameters, /*inferUnionTypes*/ false);
|
||||
let inferenceMapper = createInferenceMapper(context);
|
||||
|
||||
// Clear out all the inference results from the last time inferTypeArguments was called on this context
|
||||
for (let i = 0; i < typeParameters.length; i++) {
|
||||
context.inferredTypes[i] = undefined;
|
||||
}
|
||||
|
||||
// We perform two passes over the arguments. In the first pass we infer from all arguments, but use
|
||||
// wildcards for all context sensitive function expressions.
|
||||
for (let i = 0; i < args.length; i++) {
|
||||
@ -6385,8 +6391,6 @@ module ts {
|
||||
inferredTypes[i] = unknownType;
|
||||
}
|
||||
}
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
function checkTypeArguments(signature: Signature, typeArguments: TypeNode[], typeArgumentResultTypes: Type[], reportErrors: boolean): boolean {
|
||||
@ -6620,15 +6624,17 @@ module ts {
|
||||
return resolveErrorCall(node);
|
||||
|
||||
function chooseOverload(candidates: Signature[], relation: Map<RelationComparisonResult>) {
|
||||
for (let current of candidates) {
|
||||
if (!hasCorrectArity(node, args, current)) {
|
||||
for (let originalCandidate of candidates) {
|
||||
if (!hasCorrectArity(node, args, originalCandidate)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
let originalCandidate = current;
|
||||
let inferenceResult: InferenceContext;
|
||||
|
||||
let candidate: Signature;
|
||||
let typeArgumentsAreValid: boolean;
|
||||
let inferenceContext = originalCandidate.typeParameters
|
||||
? createInferenceContext(originalCandidate.typeParameters, /*inferUnionTypes*/ false)
|
||||
: undefined;
|
||||
|
||||
while (true) {
|
||||
candidate = originalCandidate;
|
||||
if (candidate.typeParameters) {
|
||||
@ -6638,9 +6644,9 @@ module ts {
|
||||
typeArgumentsAreValid = checkTypeArguments(candidate, typeArguments, typeArgumentTypes, /*reportErrors*/ false)
|
||||
}
|
||||
else {
|
||||
inferenceResult = inferTypeArguments(candidate, args, excludeArgument);
|
||||
typeArgumentsAreValid = inferenceResult.failedTypeParameterIndex < 0;
|
||||
typeArgumentTypes = inferenceResult.inferredTypes;
|
||||
inferTypeArguments(candidate, args, excludeArgument, inferenceContext);
|
||||
typeArgumentsAreValid = inferenceContext.failedTypeParameterIndex < 0;
|
||||
typeArgumentTypes = inferenceContext.inferredTypes;
|
||||
}
|
||||
if (!typeArgumentsAreValid) {
|
||||
break;
|
||||
@ -6670,7 +6676,7 @@ module ts {
|
||||
else {
|
||||
candidateForTypeArgumentError = originalCandidate;
|
||||
if (!typeArguments) {
|
||||
resultOfFailedInference = inferenceResult;
|
||||
resultOfFailedInference = inferenceContext;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1485,6 +1485,8 @@ module ts {
|
||||
export interface TypeInferences {
|
||||
primary: Type[]; // Inferences made directly to a type parameter
|
||||
secondary: Type[]; // Inferences made to a type parameter in a union type
|
||||
isFixed: boolean; // Whether the type parameter is fixed, as defined in section 4.12.2 of the TypeScript spec
|
||||
// If a type parameter is fixed, no more inferences can be made for the type parameter
|
||||
}
|
||||
|
||||
export interface InferenceContext {
|
||||
|
||||
@ -1175,6 +1175,7 @@ declare module "typescript" {
|
||||
interface TypeInferences {
|
||||
primary: Type[];
|
||||
secondary: Type[];
|
||||
isFixed: boolean;
|
||||
}
|
||||
interface InferenceContext {
|
||||
typeParameters: TypeParameter[];
|
||||
|
||||
@ -3767,6 +3767,9 @@ declare module "typescript" {
|
||||
secondary: Type[];
|
||||
>secondary : Type[]
|
||||
>Type : Type
|
||||
|
||||
isFixed: boolean;
|
||||
>isFixed : boolean
|
||||
}
|
||||
interface InferenceContext {
|
||||
>InferenceContext : InferenceContext
|
||||
|
||||
@ -1206,6 +1206,7 @@ declare module "typescript" {
|
||||
interface TypeInferences {
|
||||
primary: Type[];
|
||||
secondary: Type[];
|
||||
isFixed: boolean;
|
||||
}
|
||||
interface InferenceContext {
|
||||
typeParameters: TypeParameter[];
|
||||
|
||||
@ -3913,6 +3913,9 @@ declare module "typescript" {
|
||||
secondary: Type[];
|
||||
>secondary : Type[]
|
||||
>Type : Type
|
||||
|
||||
isFixed: boolean;
|
||||
>isFixed : boolean
|
||||
}
|
||||
interface InferenceContext {
|
||||
>InferenceContext : InferenceContext
|
||||
|
||||
@ -1207,6 +1207,7 @@ declare module "typescript" {
|
||||
interface TypeInferences {
|
||||
primary: Type[];
|
||||
secondary: Type[];
|
||||
isFixed: boolean;
|
||||
}
|
||||
interface InferenceContext {
|
||||
typeParameters: TypeParameter[];
|
||||
|
||||
@ -3863,6 +3863,9 @@ declare module "typescript" {
|
||||
secondary: Type[];
|
||||
>secondary : Type[]
|
||||
>Type : Type
|
||||
|
||||
isFixed: boolean;
|
||||
>isFixed : boolean
|
||||
}
|
||||
interface InferenceContext {
|
||||
>InferenceContext : InferenceContext
|
||||
|
||||
@ -1244,6 +1244,7 @@ declare module "typescript" {
|
||||
interface TypeInferences {
|
||||
primary: Type[];
|
||||
secondary: Type[];
|
||||
isFixed: boolean;
|
||||
}
|
||||
interface InferenceContext {
|
||||
typeParameters: TypeParameter[];
|
||||
|
||||
@ -4036,6 +4036,9 @@ declare module "typescript" {
|
||||
secondary: Type[];
|
||||
>secondary : Type[]
|
||||
>Type : Type
|
||||
|
||||
isFixed: boolean;
|
||||
>isFixed : boolean
|
||||
}
|
||||
interface InferenceContext {
|
||||
>InferenceContext : InferenceContext
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user