Пример #1
0
 public void SetUp()
 {
     compilation = new SimpleCompilation(TypeSystemLoaderTests.TestAssembly,
                                         TypeSystemLoaderTests.Mscorlib,
                                         TypeSystemLoaderTests.SystemCore);
     conversions = new CSharpConversions(compilation);
 }
            public override void VisitForeachStatement(ForeachStatement foreachStatement)
            {
                base.VisitForeachStatement(foreachStatement);
                var rr = ctx.Resolve(foreachStatement) as ForEachResolveResult;

                if (rr == null)
                {
                    return;
                }
                if (rr.ElementType.Kind == TypeKind.Unknown)
                {
                    return;
                }
                if (ReflectionHelper.GetTypeCode(rr.ElementType) == TypeCode.Object)
                {
                    return;
                }
                if (conversions == null)
                {
                    conversions = CSharpConversions.Get(ctx.Compilation);
                }
                Conversion c = conversions.ImplicitConversion(rr.ElementType, rr.ElementVariable.Type);

                if (c.IsValid)
                {
                    return;
                }
                var     csResolver   = ctx.GetResolverStateBefore(foreachStatement);
                var     builder      = new TypeSystemAstBuilder(csResolver);
                AstType elementType  = builder.ConvertType(rr.ElementType);
                AstType variableType = foreachStatement.VariableType;
                string  text         = ctx.TranslateString("Collection element type '{0}' is not implicitly convertible to '{1}'");

                AddIssue(variableType, string.Format(text, elementType.GetText(), variableType.GetText()));
            }
Пример #3
0
 public override Conversion IsValid(IType[] parameterTypes, IType returnType, CSharpConversions conversions)
 {
     if (this.Parameters.Count != parameterTypes.Length)
     {
         return(Conversion.None);
     }
     for (int i = 0; i < parameterTypes.Length; ++i)
     {
         if (!parameterTypes[i].Equals(this.Parameters[i].Type))
         {
             if (IsImplicitlyTyped)
             {
                 // it's possible that different parameter types also lead to a valid conversion
                 return(LambdaConversion.Instance);
             }
             else
             {
                 return(Conversion.None);
             }
         }
     }
     if (returnType.Equals(this.ReturnType))
     {
         return(LambdaConversion.Instance);
     }
     else
     {
         return(Conversion.None);
     }
 }
		internal TypeInference(ICompilation compilation, CSharpConversions conversions)
		{
			Debug.Assert(compilation != null);
			Debug.Assert(conversions != null);
			this.compilation = compilation;
			this.conversions = conversions;
		}
Пример #5
0
 public void Run(AstNode rootNode, TransformContext context)
 {
     this.context     = context;
     this.conversions = CSharpConversions.Get(context.TypeSystem);
     InitializeContext(rootNode.Annotation <UsingScope>());
     rootNode.AcceptVisitor(this);
 }
		public TypeInference(ICompilation compilation)
		{
			if (compilation == null)
				throw new ArgumentNullException("compilation");
			this.compilation = compilation;
			this.conversions = CSharpConversions.Get(compilation);
		}
Пример #7
0
 public override Conversion IsValid(IType[] parameterTypes, IType returnType, CSharpConversions conversions)
 {
     // Anonymous method expressions without parameter lists are applicable to any parameter list.
     if (HasParameterList)
     {
         if (this.Parameters.Count != parameterTypes.Length)
         {
             return(Conversion.None);
         }
         for (int i = 0; i < parameterTypes.Length; ++i)
         {
             if (!conversions.IdentityConversion(parameterTypes[i], this.Parameters[i].Type))
             {
                 if (IsImplicitlyTyped)
                 {
                     // it's possible that different parameter types also lead to a valid conversion
                     return(LambdaConversion.Instance);
                 }
                 else
                 {
                     return(Conversion.None);
                 }
             }
         }
     }
     if (conversions.IdentityConversion(this.ReturnType, returnType) ||
         conversions.ImplicitConversion(this.InferredReturnType, returnType).IsValid)
     {
         return(LambdaConversion.Instance);
     }
     else
     {
         return(Conversion.None);
     }
 }
 public override void VisitForeachStatement(ForeachStatement foreachStatement)
 {
     base.VisitForeachStatement(foreachStatement);
     var rr = ctx.Resolve(foreachStatement) as ForEachResolveResult;
     if (rr == null)
         return;
     if (rr.ElementType.Kind == TypeKind.Unknown)
         return;
     if (ReflectionHelper.GetTypeCode(rr.ElementType) == TypeCode.Object)
         return;
     if (conversions == null) {
         conversions = CSharpConversions.Get(ctx.Compilation);
     }
     Conversion c = conversions.ImplicitConversion(rr.ElementType, rr.ElementVariable.Type);
     if (c.IsValid)
         return;
     var csResolver = ctx.GetResolverStateBefore(foreachStatement);
     var builder = new TypeSystemAstBuilder(csResolver);
     AstType elementType = builder.ConvertType(rr.ElementType);
     AstType variableType = foreachStatement.VariableType;
     string issueText = ctx.TranslateString("Collection element type '{0}' is not implicitly convertible to '{1}'");
     string fixText = ctx.TranslateString("Use type '{0}'");
     AddIssue(variableType, string.Format(issueText, elementType.GetText(), variableType.GetText()),
              new CodeAction(string.Format(fixText, elementType.GetText()),
                             script => script.Replace(variableType, elementType)));
 }
Пример #9
0
        /// <remarks>
        /// See $7.10.10 of C# 4 Spec for details.
        /// </remarks>
        Value Visit(TypeIsResolveResult result)
        {
            var  importedType = NullableType.GetUnderlyingType(Import(result.TargetType));
            var  val          = Convert(result.Input);
            var  conversions  = CSharpConversions.Get(debuggerTypeSystem);
            bool evalResult   = false;

            if (!val.IsNull)
            {
                IType inputType = NullableType.GetUnderlyingType(val.Type);
                if (inputType.Equals(importedType))
                {
                    evalResult = true;
                }
                else if (conversions.IsImplicitReferenceConversion(inputType, importedType))
                {
                    evalResult = true;
                }
                else if (conversions.IsBoxingConversion(inputType, importedType))
                {
                    evalResult = true;
                }
            }
            return(Eval.CreateValue(evalThread, evalResult));
        }
Пример #10
0
 internal TypeInference(ICompilation compilation, CSharpConversions conversions)
 {
     Debug.Assert(compilation != null);
     Debug.Assert(conversions != null);
     this.compilation = compilation;
     this.conversions = conversions;
 }
Пример #11
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;
            this.AllowOptionalParameters = true;
        }
Пример #12
0
		public CSharpResolver(ICompilation compilation)
		{
			if (compilation == null)
				throw new ArgumentNullException("compilation");
			this.compilation = compilation;
			this.conversions = CSharpConversions.Get(compilation);
			this.context = new CSharpTypeResolveContext(compilation.MainAssembly);
		}
Пример #13
0
 public TypeInference(ICompilation compilation)
 {
     if (compilation == null)
     {
         throw new ArgumentNullException("compilation");
     }
     this.compilation = compilation;
     this.conversions = CSharpConversions.Get(compilation);
 }
Пример #14
0
		public CSharpResolver(CSharpTypeResolveContext context)
		{
			if (context == null)
				throw new ArgumentNullException("context");
			this.compilation = context.Compilation;
			this.conversions = CSharpConversions.Get(compilation);
			this.context = context;
			if (context.CurrentTypeDefinition != null)
				currentTypeDefinitionCache = new TypeDefinitionCache(context.CurrentTypeDefinition);
		}
Пример #15
0
		private CSharpResolver(ICompilation compilation, CSharpConversions conversions, CSharpTypeResolveContext context, bool checkForOverflow, bool isWithinLambdaExpression, TypeDefinitionCache currentTypeDefinitionCache, ImmutableStack<IVariable> localVariableStack, ObjectInitializerContext objectInitializerStack)
		{
			this.compilation = compilation;
			this.conversions = conversions;
			this.context = context;
			this.checkForOverflow = checkForOverflow;
			this.isWithinLambdaExpression = isWithinLambdaExpression;
			this.currentTypeDefinitionCache = currentTypeDefinitionCache;
			this.localVariableStack = localVariableStack;
			this.objectInitializerStack = objectInitializerStack;
		}
Пример #16
0
        internal MetadataContext(HackedSimpleCompilation compilation, EmitSettings settings)
        {
            this.hackedCompilation = compilation;
            Settings          = settings ?? new EmitSettings();
            CSharpConversions = CSharpConversions.Get(compilation);
            moduleMap         = compilation.Modules.ToDictionary(m => new ModuleSignature(m.Name));
            Modules           = moduleMap.Keys.ToImmutableArray();
            MainModule        = Modules[0];
            mutableModule     = (VirtualModule)moduleMap[MainModule];

            Debug.Assert(MainModule.Name == this.Compilation.MainModule.Name);
        }
Пример #17
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)));
 }
Пример #18
0
        public CSharpResolver(ICompilation compilation)
        {
            if (compilation == null)
                throw new ArgumentNullException("compilation");
            this.compilation = compilation;
            this.conversions = CSharpConversions.Get(compilation);
            this.context = new CSharpTypeResolveContext(compilation.MainAssembly);

            var pc = compilation.MainAssembly.UnresolvedAssembly as CSharpProjectContent;
            if (pc != null) {
                this.checkForOverflow = pc.CompilerSettings.CheckForOverflow;
            }
        }
		public SupportsIndexingCriterion(IType returnType, IEnumerable<IType> argumentTypes, CSharpConversions conversions, bool isWriteAccess = false)
		{
			if (returnType == null)
				throw new ArgumentNullException("returnType");
			if (argumentTypes == null)
				throw new ArgumentNullException("argumentTypes");
			if (conversions == null)
				throw new ArgumentNullException("conversions");

			this.returnType = returnType;
			this.argumentTypes = argumentTypes.ToList();
			this.conversions = conversions;
			this.isWriteAccess = isWriteAccess;
		}
Пример #20
0
        private ExpressionWithResolveResult HandleImplicitConversion(IMethod method, TranslatedExpression argument)
        {
            var   conversions = CSharpConversions.Get(expressionBuilder.compilation);
            IType targetType  = method.ReturnType;
            var   conv        = conversions.ImplicitConversion(argument.Type, targetType);

            if (!(conv.IsUserDefined && conv.Method.Equals(method)))
            {
                // implicit conversion to targetType isn't directly possible, so first insert a cast to the argument type
                argument = argument.ConvertTo(method.Parameters[0].Type, expressionBuilder);
                conv     = conversions.ImplicitConversion(argument.Type, targetType);
            }
            return(new CastExpression(expressionBuilder.ConvertType(targetType), argument.Expression)
                   .WithRR(new ConversionResolveResult(targetType, argument.ResolveResult, conv)));
        }
Пример #21
0
        public SupportsIndexingCriterion(IType returnType, IEnumerable <IType> argumentTypes, CSharpConversions conversions, bool isWriteAccess = false)
        {
            if (returnType == null)
            {
                throw new ArgumentNullException("returnType");
            }
            if (argumentTypes == null)
            {
                throw new ArgumentNullException("argumentTypes");
            }
            if (conversions == null)
            {
                throw new ArgumentNullException("conversions");
            }

            this.returnType    = returnType;
            this.argumentTypes = argumentTypes.ToList();
            this.conversions   = conversions;
            this.isWriteAccess = isWriteAccess;
        }
Пример #22
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;
            this.AllowOptionalParameters = true;
        }
Пример #23
0
            public override void VisitIsExpression(IsExpression isExpression)
            {
                base.VisitIsExpression(isExpression);

                var conversions  = CSharpConversions.Get(ctx.Compilation);
                var exprType     = ctx.Resolve(isExpression.Expression).Type;
                var providedType = ctx.ResolveType(isExpression.Type);

                if (exprType.Kind == TypeKind.Unknown || providedType.Kind == TypeKind.Unknown)
                {
                    return;
                }
                if (IsValidReferenceOrBoxingConversion(exprType, providedType))
                {
                    return;
                }

                var exprTP     = exprType as ITypeParameter;
                var providedTP = providedType as ITypeParameter;

                if (exprTP != null)
                {
                    if (IsValidReferenceOrBoxingConversion(exprTP.EffectiveBaseClass, providedType) &&
                        exprTP.EffectiveInterfaceSet.All(i => IsValidReferenceOrBoxingConversion(i, providedType)))
                    {
                        return;
                    }
                }
                if (providedTP != null)
                {
                    if (IsValidReferenceOrBoxingConversion(exprType, providedTP.EffectiveBaseClass))
                    {
                        return;
                    }
                }

                AddIssue(isExpression, ctx.TranslateString("Given expression is never of the provided type"));
            }
Пример #24
0
 public override Conversion IsValid(IType[] parameterTypes, IType returnType, CSharpConversions conversions)
 {
     return(conversions.ImplicitConversion(inferredReturnType, returnType));
 }
Пример #25
0
 public ConstraintValidatingSubstitution(IReadOnlyList <IType> classTypeArguments, IReadOnlyList <IType> methodTypeArguments, OverloadResolution overloadResolution)
     : base(classTypeArguments, methodTypeArguments)
 {
     this.conversions = overloadResolution.conversions;
 }
		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;
		}
			public ConstraintValidatingSubstitution(IList<IType> classTypeArguments, IList<IType> methodTypeArguments, OverloadResolution overloadResolution)
				: base(classTypeArguments, methodTypeArguments)
			{
				this.conversions = overloadResolution.conversions;
			}
Пример #28
0
        public override void VisitIndexerExpression(IndexerExpression indexerExpression)
        {
            base.VisitIndexerExpression(indexerExpression);

            var localResolveResult = context.Resolve(indexerExpression.Target) as LocalResolveResult;

            if (localResolveResult == null)
            {
                return;
            }
            var resolveResult = context.Resolve(indexerExpression);

            if (localResolveResult == null)
            {
                return;
            }
            var parent = indexerExpression.Parent;

            while (parent is ParenthesizedExpression)
            {
                parent = parent.Parent;
            }
            if (parent is DirectionExpression)
            {
                // The only types which are indexable and where the indexing expression
                // results in a variable is an actual array type
                AddCriterion(localResolveResult.Variable, new IsArrayTypeCriterion());
            }
            else if (resolveResult is ArrayAccessResolveResult)
            {
                var arrayResolveResult = (ArrayAccessResolveResult)resolveResult;
                var arrayType          = arrayResolveResult.Array.Type as ArrayType;
                if (arrayType != null)
                {
                    var parameterTypes = arrayResolveResult.Indexes.Select(index => index.Type);
                    var criterion      = new SupportsIndexingCriterion(arrayType.ElementType, parameterTypes, CSharpConversions.Get(context.Compilation));
                    AddCriterion(localResolveResult.Variable, criterion);
                }
            }
            else if (resolveResult is CSharpInvocationResolveResult)
            {
                var invocationResolveResult = (CSharpInvocationResolveResult)resolveResult;
                var parameterTypes          = invocationResolveResult.Arguments.Select(arg => arg.Type);
                var criterion = new SupportsIndexingCriterion(invocationResolveResult.Member.ReturnType, parameterTypes, CSharpConversions.Get(context.Compilation));
                AddCriterion(localResolveResult.Variable, criterion);
            }
        }
Пример #29
0
			public override Conversion IsValid(IType[] parameterTypes, IType returnType, CSharpConversions conversions)
			{
				return conversions.ImplicitConversion(inferredReturnType, returnType);
			}
Пример #30
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);
Пример #31
0
		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);
		}
Пример #32
0
 public override void SetUp()
 {
     base.SetUp();
     conversions = new CSharpConversions(compilation);
 }
Пример #33
0
        void AssertDoesNotMatch(IType candidateType, IType elementType, bool isWriteAccess, params IType[] indexTypes)
        {
            var criterion = new SupportsIndexingCriterion(elementType, indexTypes, CSharpConversions.Get(compilation), isWriteAccess);

            Assert.IsFalse(criterion.SatisfiedBy(candidateType));
        }
Пример #34
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);
Пример #35
0
			public override Conversion IsValid(IType[] parameterTypes, IType returnType, CSharpConversions conversions)
			{
				Assert.AreEqual(expectedParameterTypes, parameterTypes);
				return conversions.ImplicitConversion(inferredReturnType, returnType);
			}
Пример #36
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);
 }
 public GatherVisitor(BaseRefactoringContext ctx)
     : base(ctx)
 {
     conversions = CSharpConversions.Get(ctx.Compilation);
 }
Пример #38
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);
        }
			public GatherVisitor (BaseRefactoringContext ctx)
				: base (ctx)
			{
				conversions = CSharpConversions.Get(ctx.Compilation);
			}
Пример #40
0
		public void SetUp()
		{
			compilation = new SimpleCompilation(CecilLoaderTests.Mscorlib);
			conversions = new CSharpConversions(compilation);
		}