TypeInference CreateNestedInstance() { TypeInference c = new TypeInference(compilation, conversions); c.algorithm = algorithm; c.nestingLevel = nestingLevel + 1; return c; }
IEnumerable<ICompletionData> CreateTypeCompletionData(IType hintType) { var wrapper = new CompletionDataWrapper(this); var state = GetState(); Func<IType, IType> pred = null; Action<ICompletionData, IType> typeCallback = null; var inferredTypesCategory = new Category("Inferred Types", null); var derivedTypesCategory = new Category("Derived Types", null); if (hintType != null) { if (hintType.Kind != TypeKind.Unknown) { var lookup = new MemberLookup( ctx.CurrentTypeDefinition, Compilation.MainAssembly ); typeCallback = (data, t) => { //check if type is in inheritance tree. if (hintType.GetDefinition() != null && t.GetDefinition() != null && t.GetDefinition().IsDerivedFrom(hintType.GetDefinition())) { data.CompletionCategory = derivedTypesCategory; } }; pred = t => { if (t.Kind == TypeKind.Interface && hintType.Kind != TypeKind.Array) { return null; } // check for valid constructors if (t.GetConstructors().Count() > 0) { bool isProtectedAllowed = currentType != null ? currentType.Resolve(ctx).GetDefinition().IsDerivedFrom(t.GetDefinition()) : false; if (!t.GetConstructors().Any(m => lookup.IsAccessible(m, isProtectedAllowed))) { return null; } } // check derived types var typeDef = t.GetDefinition(); var hintDef = hintType.GetDefinition(); if (typeDef != null && hintDef != null && typeDef.IsDerivedFrom(hintDef)) { var newType = wrapper.AddType(t, true); if (newType != null) { newType.CompletionCategory = inferredTypesCategory; } } // check type inference var typeInference = new TypeInference(Compilation); typeInference.Algorithm = TypeInferenceAlgorithm.ImprovedReturnAllResults; var inferedType = typeInference.FindTypeInBounds (new [] { t }, new [] { hintType }); if (inferedType != SpecialType.UnknownType) { var newType = wrapper.AddType(inferedType, true); if (newType != null) { newType.CompletionCategory = inferredTypesCategory; } return null; } return t; }; if (!(hintType.Kind == TypeKind.Interface && hintType.Kind != TypeKind.Array)) { var hint = wrapper.AddType(hintType, true); DefaultCompletionString = hint.DisplayText; if (hint != null) { hint.CompletionCategory = derivedTypesCategory; } } if (hintType is ParameterizedType && hintType.TypeParameterCount == 1 && hintType.FullName == "System.Collections.Generic.IEnumerable") { var arg = ((ParameterizedType)hintType).TypeArguments.FirstOrDefault(); if (arg.Kind != TypeKind.TypeParameter) { var array = new ArrayType (ctx.Compilation, arg, 1); wrapper.AddType(array, true); } } } else { var hint = wrapper.AddType(hintType, true); if (hint != null) { DefaultCompletionString = hint.DisplayText; hint.CompletionCategory = derivedTypesCategory; } } } AddTypesAndNamespaces(wrapper, state, null, pred, m => false, typeCallback); if (hintType == null || hintType == SpecialType.UnknownType) { AddKeywords(wrapper, primitiveTypesKeywords.Where(k => k != "void")); } CloseOnSquareBrackets = true; AutoCompleteEmptyMatch = true; AutoCompleteEmptyMatchOnCurlyBracket = false; return wrapper.Result; }
void RunTypeInference(Candidate candidate) { if (candidate.TypeParameters == null) { if (explicitlyGivenTypeArguments != null) { // method does not expect type arguments, but was given some candidate.AddError(OverloadResolutionErrors.WrongNumberOfTypeArguments); } // Grab new parameter types: ResolveParameterTypes(candidate, true); return; } ParameterizedType parameterizedDeclaringType = candidate.Member.DeclaringType as ParameterizedType; IList<IType> classTypeArguments; if (parameterizedDeclaringType != null) { classTypeArguments = parameterizedDeclaringType.TypeArguments; } else { classTypeArguments = null; } // The method is generic: if (explicitlyGivenTypeArguments != null) { if (explicitlyGivenTypeArguments.Length == candidate.TypeParameters.Count) { candidate.InferredTypes = explicitlyGivenTypeArguments; } else { candidate.AddError(OverloadResolutionErrors.WrongNumberOfTypeArguments); // wrong number of type arguments given, so truncate the list or pad with UnknownType candidate.InferredTypes = new IType[candidate.TypeParameters.Count]; for (int i = 0; i < candidate.InferredTypes.Length; i++) { if (i < explicitlyGivenTypeArguments.Length) candidate.InferredTypes[i] = explicitlyGivenTypeArguments[i]; else candidate.InferredTypes[i] = SpecialType.UnknownType; } } } else { TypeInference ti = new TypeInference(compilation, conversions); bool success; candidate.InferredTypes = ti.InferTypeArguments(candidate.TypeParameters, arguments, candidate.ParameterTypes, out success, classTypeArguments); if (!success) candidate.AddError(OverloadResolutionErrors.TypeInferenceFailed); } // Now substitute in the formal parameters: var substitution = new ConstraintValidatingSubstitution(classTypeArguments, candidate.InferredTypes, this); for (int i = 0; i < candidate.ParameterTypes.Length; i++) { candidate.ParameterTypes[i] = candidate.ParameterTypes[i].AcceptVisitor(substitution); } if (!substitution.ConstraintsValid) candidate.AddError(OverloadResolutionErrors.ConstructedTypeDoesNotSatisfyConstraint); }
public OccursInVisitor(TypeInference typeInference) { this.tp = typeInference.typeParameters; this.Occurs = new bool[tp.Length]; }
public static IType GuessType(RefactoringContext context, AstNode expr) { if (expr is SimpleType && expr.Role == Roles.TypeArgument) { if (expr.Parent is MemberReferenceExpression || expr.Parent is IdentifierExpression) { var rr = context.Resolve (expr.Parent); var argumentNumber = expr.Parent.GetChildrenByRole (Roles.TypeArgument).TakeWhile (c => c != expr).Count (); var mgrr = rr as MethodGroupResolveResult; if (mgrr != null && mgrr.Methods.Any () && mgrr.Methods.First ().TypeArguments.Count > argumentNumber) return mgrr.Methods.First ().TypeParameters[argumentNumber]; } else if (expr.Parent is MemberType || expr.Parent is SimpleType) { var rr = context.Resolve (expr.Parent); var argumentNumber = expr.Parent.GetChildrenByRole (Roles.TypeArgument).TakeWhile (c => c != expr).Count (); var mgrr = rr as TypeResolveResult; if (mgrr != null && mgrr.Type.TypeParameterCount > argumentNumber) { return mgrr.Type.GetDefinition ().TypeParameters[argumentNumber]; } } } var type = GetValidTypes(context.Resolver, expr).ToArray(); var typeInference = new TypeInference(context.Compilation); typeInference.Algorithm = TypeInferenceAlgorithm.Improved; var inferedType = typeInference.FindTypeInBounds(type, emptyTypes); return inferedType; }
public static AstType GuessAstType(RefactoringContext context, AstNode expr) { var type = GetValidTypes(context.Resolver, expr).ToArray(); var typeInference = new TypeInference(context.Compilation); typeInference.Algorithm = TypeInferenceAlgorithm.Improved; var inferedType = typeInference.FindTypeInBounds(type, emptyTypes); if (inferedType.Kind == TypeKind.Unknown) return new PrimitiveType("object"); return context.CreateShortType(inferedType); }
void RunTypeInference(Candidate candidate) { if (candidate.TypeParameters == null) { if (explicitlyGivenTypeArguments != null) { // method does not expect type arguments, but was given some candidate.AddError(OverloadResolutionErrors.WrongNumberOfTypeArguments); } // Grab new parameter types: ResolveParameterTypes(candidate, true); return; } ParameterizedType parameterizedDeclaringType = candidate.Member.DeclaringType as ParameterizedType; IList <IType> classTypeArguments; if (parameterizedDeclaringType != null) { classTypeArguments = parameterizedDeclaringType.TypeArguments; } else { classTypeArguments = null; } // The method is generic: if (explicitlyGivenTypeArguments != null) { if (explicitlyGivenTypeArguments.Length == candidate.TypeParameters.Count) { candidate.InferredTypes = explicitlyGivenTypeArguments; } else { candidate.AddError(OverloadResolutionErrors.WrongNumberOfTypeArguments); // wrong number of type arguments given, so truncate the list or pad with UnknownType candidate.InferredTypes = new IType[candidate.TypeParameters.Count]; for (int i = 0; i < candidate.InferredTypes.Length; i++) { if (i < explicitlyGivenTypeArguments.Length) { candidate.InferredTypes[i] = explicitlyGivenTypeArguments[i]; } else { candidate.InferredTypes[i] = SpecialType.UnknownType; } } } } else { TypeInference ti = new TypeInference(compilation, conversions); bool success; candidate.InferredTypes = ti.InferTypeArguments(candidate.TypeParameters, arguments, candidate.ParameterTypes, out success, classTypeArguments); if (!success) { candidate.AddError(OverloadResolutionErrors.TypeInferenceFailed); } } // Now substitute in the formal parameters: var substitution = new ConstraintValidatingSubstitution(classTypeArguments, candidate.InferredTypes, this); for (int i = 0; i < candidate.ParameterTypes.Length; i++) { candidate.ParameterTypes[i] = candidate.ParameterTypes[i].AcceptVisitor(substitution); } if (!substitution.ConstraintsValid) { candidate.AddError(OverloadResolutionErrors.ConstructedTypeDoesNotSatisfyConstraint); } }
/// <summary> /// Resolves an array creation. /// </summary> /// <param name="elementType"> /// The array element type. /// Pass null to resolve an implicitly-typed array creation. /// </param> /// <param name="sizeArguments"> /// The size arguments. /// The length of this array will be used as the number of dimensions of the array type. /// The resolver may mutate this array to wrap elements in <see cref="ConversionResolveResult"/>s! /// </param> /// <param name="initializerElements"> /// The initializer elements. May be null if no array initializer was specified. /// The resolver may mutate this array to wrap elements in <see cref="ConversionResolveResult"/>s! /// </param> public ArrayCreateResolveResult ResolveArrayCreation(IType elementType, ResolveResult[] sizeArguments, ResolveResult[] initializerElements = null) { int dimensions = sizeArguments.Length; if (dimensions == 0) throw new ArgumentException("sizeArguments.Length must not be 0"); if (elementType == null) { TypeInference typeInference = new TypeInference(compilation, conversions); bool success; elementType = typeInference.GetBestCommonType(initializerElements, out success); } IType arrayType = new ArrayType(compilation, elementType, dimensions); AdjustArrayAccessArguments(sizeArguments); if (initializerElements != null) { for (int i = 0; i < initializerElements.Length; i++) { initializerElements[i] = Convert(initializerElements[i], elementType); } } return new ArrayCreateResolveResult(arrayType, sizeArguments, initializerElements); }
static bool IsEligibleExtensionMethod(ICompilation compilation, CSharpConversions conversions, IType targetType, IMethod method, bool useTypeInference, out IType[] outInferredTypes) { outInferredTypes = null; if (targetType == null) return true; if (method.Parameters.Count == 0) return false; IType thisParameterType = method.Parameters[0].Type; if (useTypeInference && method.TypeParameters.Count > 0) { // We need to infer type arguments from targetType: TypeInference ti = new TypeInference(compilation, conversions); ResolveResult[] arguments = { new ResolveResult(targetType) }; IType[] parameterTypes = { method.Parameters[0].Type }; bool success; var inferredTypes = ti.InferTypeArguments(method.TypeParameters, arguments, parameterTypes, out success); var substitution = new TypeParameterSubstitution(null, inferredTypes); // Validate that the types that could be inferred (aren't unknown) satisfy the constraints: bool hasInferredTypes = false; for (int i = 0; i < inferredTypes.Length; i++) { if (inferredTypes[i].Kind != TypeKind.Unknown && inferredTypes[i].Kind != TypeKind.UnboundTypeArgument) { hasInferredTypes = true; if (!OverloadResolution.ValidateConstraints(method.TypeParameters[i], inferredTypes[i], substitution, conversions)) return false; } else { inferredTypes[i] = method.TypeParameters[i]; // do not substitute types that could not be inferred } } if (hasInferredTypes) outInferredTypes = inferredTypes; thisParameterType = thisParameterType.AcceptVisitor(substitution); } Conversion c = conversions.ImplicitConversion(targetType, thisParameterType); return c.IsValid && (c.IsIdentityConversion || c.IsReferenceConversion || c.IsBoxingConversion); }