예제 #1
0
 internal TypeInference(ICompilation compilation, CSharpConversions conversions)
 {
     Debug.Assert(compilation != null);
     Debug.Assert(conversions != null);
     this.compilation = compilation;
     this.conversions = conversions;
 }
예제 #2
0
        public OverloadResolution(ICompilation compilation, ResolveResult[] arguments, string[] argumentNames = null, IType[] typeArguments = null, CSharpConversions conversions = null)
        {
            if (compilation == null)
            {
                throw new ArgumentNullException("compilation");
            }
            if (arguments == null)
            {
                throw new ArgumentNullException("arguments");
            }
            if (argumentNames == null)
            {
                argumentNames = new string[arguments.Length];
            }
            else if (argumentNames.Length != arguments.Length)
            {
                throw new ArgumentException("argumentsNames.Length must be equal to arguments.Length");
            }
            this.compilation   = compilation;
            this.arguments     = arguments;
            this.argumentNames = argumentNames;

            // keep explicitlyGivenTypeArguments==null when no type arguments were specified
            if (typeArguments != null && typeArguments.Length > 0)
            {
                this.explicitlyGivenTypeArguments = typeArguments;
            }

            this.conversions          = conversions ?? CSharpConversions.Get(compilation);
            this.AllowExpandingParams = true;
        }
예제 #3
0
 public TypeInference(ICompilation compilation)
 {
     if (compilation == null)
     {
         throw new ArgumentNullException("compilation");
     }
     this.compilation = compilation;
     this.conversions = CSharpConversions.Get(compilation);
 }
예제 #4
0
 /// <summary>
 /// Validates whether the given type argument satisfies the constraints for the given type parameter.
 /// </summary>
 /// <param name="typeParameter">The type parameter.</param>
 /// <param name="typeArgument">The type argument.</param>
 /// <param name="substitution">The substitution that defines how type parameters are replaced with type arguments.
 /// The substitution is used to check constraints that depend on other type parameters (or recursively on the same type parameter).
 /// May be null if no substitution should be used.</param>
 /// <returns>True if the constraints are satisfied; false otherwise.</returns>
 public static bool ValidateConstraints(ITypeParameter typeParameter, IType typeArgument, TypeVisitor substitution = null)
 {
     if (typeParameter == null)
     {
         throw new ArgumentNullException("typeParameter");
     }
     if (typeArgument == null)
     {
         throw new ArgumentNullException("typeArgument");
     }
     return(ValidateConstraints(typeParameter, typeArgument, substitution, CSharpConversions.Get(typeParameter.Owner.Compilation)));
 }
예제 #5
0
        /// <summary>
        /// Gets the Conversions instance for the specified <see cref="ICompilation"/>.
        /// This will make use of the context's cache manager to reuse the Conversions instance.
        /// </summary>
        public static CSharpConversions Get(ICompilation compilation)
        {
            if (compilation == null)
            {
                throw new ArgumentNullException("compilation");
            }
            CacheManager      cache     = compilation.CacheManager;
            CSharpConversions operators = (CSharpConversions)cache.GetShared(typeof(CSharpConversions));

            if (operators == null)
            {
                operators = (CSharpConversions)cache.GetOrAddShared(typeof(CSharpConversions), new CSharpConversions(compilation));
            }
            return(operators);
        }
예제 #6
0
 internal static bool ValidateConstraints(ITypeParameter typeParameter, IType typeArgument, TypeVisitor substitution, CSharpConversions conversions)
 {
     switch (typeArgument.Kind)               // void, null, and pointers cannot be used as type arguments
     {
     case TypeKind.Void:
     case TypeKind.Null:
     case TypeKind.Pointer:
         return(false);
     }
     if (typeParameter.HasReferenceTypeConstraint)
     {
         if (typeArgument.IsReferenceType != true)
         {
             return(false);
         }
     }
     if (typeParameter.HasValueTypeConstraint)
     {
         if (!NullableType.IsNonNullableValueType(typeArgument))
         {
             return(false);
         }
     }
     if (typeParameter.HasDefaultConstructorConstraint)
     {
         ITypeDefinition def = typeArgument.GetDefinition();
         if (def != null && def.IsAbstract)
         {
             return(false);
         }
         var ctors = typeArgument.GetConstructors(
             m => m.Parameters.Count == 0 && m.Accessibility == Accessibility.Public,
             GetMemberOptions.IgnoreInheritedMembers | GetMemberOptions.ReturnMemberDefinitions
             );
         if (!ctors.Any())
         {
             return(false);
         }
     }
     foreach (IType constraintType in typeParameter.DirectBaseTypes)
     {
         IType c = constraintType;
         if (substitution != null)
         {
             c = c.AcceptVisitor(substitution);
         }
         if (!conversions.IsConstraintConvertible(typeArgument, c))
         {
             return(false);
         }
     }
     return(true);
 }
예제 #7
0
 public ConstraintValidatingSubstitution(IList <IType> classTypeArguments, IList <IType> methodTypeArguments, OverloadResolution overloadResolution)
     : base(classTypeArguments, methodTypeArguments)
 {
     this.conversions = overloadResolution.conversions;
 }
예제 #8
0
 public override Conversion IsValid(IType[] parameterTypes, IType returnType, CSharpConversions conversions)
 {
     Assert.AreEqual(expectedParameterTypes, parameterTypes);
     return(conversions.ImplicitConversion(inferredReturnType, returnType));
 }
예제 #9
0
 public DynamicErasure(CSharpConversions conversions)
 {
     this.objectType = conversions.objectType;
 }
예제 #10
0
        public OverloadResolution PerformOverloadResolution(ICompilation compilation, ResolveResult[] arguments, string[] argumentNames = null,
                                                            bool allowExtensionMethods   = true,
                                                            bool allowExpandingParams    = true,
                                                            bool allowOptionalParameters = true,
                                                            bool checkForOverflow        = false, CSharpConversions conversions = null)
        {
            Log.WriteLine("Performing overload resolution for " + this);
            Log.WriteCollection("  Arguments: ", arguments);

            var typeArgumentArray = this.TypeArguments.ToArray();
            OverloadResolution or = new OverloadResolution(compilation, arguments, argumentNames, typeArgumentArray, conversions);

            or.AllowExpandingParams    = allowExpandingParams;
            or.AllowOptionalParameters = allowOptionalParameters;
            or.CheckForOverflow        = checkForOverflow;

            or.AddMethodLists(methodLists);

            if (allowExtensionMethods && !or.FoundApplicableCandidate)
            {
                // No applicable match found, so let's try extension methods.

                var extensionMethods = this.GetExtensionMethods();

                if (extensionMethods.Any())
                {
                    Log.WriteLine("No candidate is applicable, trying {0} extension methods groups...", extensionMethods.Count());
                    ResolveResult[] extArguments = new ResolveResult[arguments.Length + 1];
                    extArguments[0] = new ResolveResult(this.TargetType);
                    arguments.CopyTo(extArguments, 1);
                    string[] extArgumentNames = null;
                    if (argumentNames != null)
                    {
                        extArgumentNames = new string[argumentNames.Length + 1];
                        argumentNames.CopyTo(extArgumentNames, 1);
                    }
                    var extOr = new OverloadResolution(compilation, extArguments, extArgumentNames, typeArgumentArray, conversions);
                    extOr.AllowExpandingParams        = allowExpandingParams;
                    extOr.AllowOptionalParameters     = allowOptionalParameters;
                    extOr.IsExtensionMethodInvocation = true;
                    extOr.CheckForOverflow            = checkForOverflow;

                    foreach (var g in extensionMethods)
                    {
                        foreach (var method in g)
                        {
                            Log.Indent();
                            OverloadResolutionErrors errors = extOr.AddCandidate(method);
                            Log.Unindent();
                            or.LogCandidateAddingResult("  Extension", method, errors);
                        }
                        if (extOr.FoundApplicableCandidate)
                        {
                            break;
                        }
                    }
                    // For the lack of a better comparison function (the one within OverloadResolution
                    // cannot be used as it depends on the argument set):
                    if (extOr.FoundApplicableCandidate || or.BestCandidate == null)
                    {
                        // Consider an extension method result better than the normal result only
                        // if it's applicable; or if there is no normal result.
                        or = extOr;
                    }
                }
            }
            Log.WriteLine("Overload resolution finished, best candidate is {0}.", or.GetBestCandidateWithSubstitutedTypeArguments());
            return(or);
        }
예제 #11
0
 public override Conversion IsValid(IType[] parameterTypes, IType returnType, CSharpConversions conversions)
 {
     return(conversions.ImplicitConversion(inferredReturnType, returnType));
 }
예제 #12
0
 public void SetUp()
 {
     compilation = new SimpleCompilation(CecilLoaderTests.Mscorlib);
     conversions = new CSharpConversions(compilation);
 }
예제 #13
0
 /// <summary>
 /// Gets whether the lambda body is valid for the given parameter types and return type.
 /// </summary>
 /// <returns>
 /// Produces a conversion with <see cref="Conversion.IsAnonymousFunctionConversion"/>=<c>true</c> if the lambda is valid;
 /// otherwise returns <see cref="Conversion.None"/>.
 /// </returns>
 public abstract Conversion IsValid(IType[] parameterTypes, IType returnType, CSharpConversions conversions);
 public override void SetUp()
 {
     base.SetUp();
     conversions = new CSharpConversions(compilation);
 }