public MemberResolveResult(ResolveResult targetResult, IMember member, IType returnType) : base(returnType)
		{
			if (member == null)
				throw new ArgumentNullException("member");
			this.targetResult = targetResult;
			this.member = member;
		}
Example #2
0
		public IMethod ResolveConstructor(ITypeResolveContext context)
		{
			CSharpResolver r = new CSharpResolver(context);
			IType type = attributeType.Resolve(context);
			int totalArgumentCount = 0;
			if (positionalArguments != null)
				totalArgumentCount += positionalArguments.Count;
			if (namedCtorArguments != null)
				totalArgumentCount += namedCtorArguments.Count;
			ResolveResult[] arguments = new ResolveResult[totalArgumentCount];
			string[] argumentNames = new string[totalArgumentCount];
			int i = 0;
			if (positionalArguments != null) {
				while (i < positionalArguments.Count) {
					IConstantValue cv = positionalArguments[i];
					arguments[i] = new ConstantResolveResult(cv.GetValueType(context), cv.GetValue(context));
					i++;
				}
			}
			if (namedCtorArguments != null) {
				foreach (var pair in namedCtorArguments) {
					argumentNames[i] = pair.Key;
					arguments[i] = new ConstantResolveResult(pair.Value.GetValueType(context), pair.Value.GetValue(context));
					i++;
				}
			}
			MemberResolveResult mrr = r.ResolveObjectCreation(type, arguments, argumentNames) as MemberResolveResult;
			return mrr != null ? mrr.Member as IMethod : null;
		}
Example #3
0
		public bool ImplicitConversion(ResolveResult resolveResult, IType toType)
		{
			if (resolveResult == null)
				throw new ArgumentNullException("resolveResult");
			if (resolveResult.IsCompileTimeConstant && (ImplicitEnumerationConversion(resolveResult, toType) || ImplicitConstantExpressionConversion(resolveResult, toType)))
				return true;
			return ImplicitConversion(resolveResult.Type, toType);
		}
		public ConversionResolveResult(IType targetType, ResolveResult input, Conversion conversion)
			: base(targetType)
		{
			if (input == null)
				throw new ArgumentNullException("input");
			this.Input = input;
			this.Conversion = conversion;
		}
		public UnaryOperatorResolveResult(IType resultType, UnaryOperatorType op, ResolveResult input)
			: base(resultType)
		{
			if (input == null)
				throw new ArgumentNullException("input");
			this.Operator = op;
			this.Input = input;
		}
		public MemberResolveResult(ResolveResult targetResult, IMember member, IType returnType, object constantValue) : base(returnType)
		{
			if (member == null)
				throw new ArgumentNullException("member");
			this.targetResult = targetResult;
			this.member = member;
			this.isConstant = true;
			this.constantValue = constantValue;
		}
		public BinaryOperatorResolveResult(IType resultType, ResolveResult lhs, BinaryOperatorType op, ResolveResult rhs)
			: base(resultType)
		{
			if (lhs == null)
				throw new ArgumentNullException("lhs");
			if (rhs == null)
				throw new ArgumentNullException("rhs");
			this.Left = lhs;
			this.Operator = op;
			this.Right = rhs;
		}
		public MemberResolveResult(ResolveResult targetResult, IMember member, ITypeResolveContext context) 
			: base(member.EntityType == EntityType.Constructor ? member.DeclaringType : member.ReturnType.Resolve(context))
		{
			this.targetResult = targetResult;
			this.member = member;
			IField field = member as IField;
			if (field != null) {
				isConstant = field.IsConst;
				if (isConstant)
					constantValue = field.ConstantValue.GetValue(context);
			}
		}
		public InvocationResolveResult(ResolveResult targetResult, OverloadResolution or, ITypeResolveContext context)
			: base(
				or.IsExtensionMethodInvocation ? null : targetResult,
				or.GetBestCandidateWithSubstitutedTypeArguments(),
				context)
		{
			this.OverloadResolutionErrors = or.BestCandidateErrors;
			this.argumentToParameterMap = or.GetArgumentToParameterMap();
			this.Arguments = or.GetArgumentsWithConversions();
			
			this.IsExtensionMethodInvocation = or.IsExtensionMethodInvocation;
			this.IsExpandedForm = or.BestCandidateIsExpandedForm;
			this.IsLiftedOperatorInvocation = or.BestCandidate is OverloadResolution.ILiftedOperator;
		}
Example #10
0
		public bool ImplicitConversion(ResolveResult resolveResult, IType toType)
		{
			if (resolveResult == null)
				throw new ArgumentNullException("resolveResult");
			if (resolveResult.IsCompileTimeConstant) {
				if (ImplicitEnumerationConversion(resolveResult, toType))
					return true;
				if (ImplicitConstantExpressionConversion(resolveResult, toType))
					return true;
			}
			if (ImplicitConversion(resolveResult.Type, toType))
				return true;
			// TODO: Anonymous function conversions
			// TODO: Method group conversions
			return false;
		}
		public InvocationResolveResult(
			ResolveResult targetResult, IParameterizedMember member, IType returnType,
			IList<ResolveResult> arguments,
			OverloadResolutionErrors overloadResolutionErrors = OverloadResolutionErrors.None,
			bool isExtensionMethodInvocation = false, 
			bool isExpandedForm = false,
			bool isLiftedOperatorInvocation = false,
			bool isDelegateInvocation = false,
			IList<int> argumentToParameterMap = null)
			: base(targetResult, member, returnType)
		{
			this.OverloadResolutionErrors = overloadResolutionErrors;
			this.Arguments = arguments ?? EmptyList<ResolveResult>.Instance;
			this.IsExtensionMethodInvocation = isExtensionMethodInvocation;
			this.IsExpandedForm = isExpandedForm;
			this.IsLiftedOperatorInvocation = isLiftedOperatorInvocation;
			this.IsDelegateInvocation = isDelegateInvocation;
			this.argumentToParameterMap = argumentToParameterMap;
		}
        public OverloadResolution(ITypeResolveContext context, ResolveResult[] arguments, string[] argumentNames = null, IType[] typeArguments = null)
        {
            if (context == null)
                throw new ArgumentNullException("context");
            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.context = context;
            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 = new Conversions(context);
        }
Example #13
0
        /// <summary>
        /// Gets the better conversion (C# 4.0 spec, §7.5.3.3)
        /// </summary>
        /// <returns>0 = neither is better; 1 = t1 is better; 2 = t2 is better</returns>
        public int BetterConversion(ResolveResult resolveResult, IType t1, IType t2)
        {
            LambdaResolveResult lambda = resolveResult as LambdaResolveResult;

            if (lambda != null)
            {
                if (!lambda.IsAnonymousMethod)
                {
                    t1 = UnpackExpressionTreeType(t1);
                    t2 = UnpackExpressionTreeType(t2);
                }
                IMethod m1 = t1.GetDelegateInvokeMethod();
                IMethod m2 = t2.GetDelegateInvokeMethod();
                if (m1 == null || m2 == null)
                {
                    return(0);
                }
                int r = BetterConversionTarget(t1, t2);
                if (r != 0)
                {
                    return(r);
                }
                if (m1.Parameters.Count != m2.Parameters.Count)
                {
                    return(0);
                }
                IType[] parameterTypes = new IType[m1.Parameters.Count];
                for (int i = 0; i < parameterTypes.Length; i++)
                {
                    parameterTypes[i] = m1.Parameters[i].Type;
                    if (!parameterTypes[i].Equals(m2.Parameters[i].Type))
                    {
                        return(0);
                    }
                }
                if (lambda.HasParameterList && parameterTypes.Length != lambda.Parameters.Count)
                {
                    return(0);
                }

                IType ret1 = m1.ReturnType;
                IType ret2 = m2.ReturnType;
                if (ret1.Kind == TypeKind.Void && ret2.Kind != TypeKind.Void)
                {
                    return(2);
                }
                if (ret1.Kind != TypeKind.Void && ret2.Kind == TypeKind.Void)
                {
                    return(1);
                }

                IType inferredRet = lambda.GetInferredReturnType(parameterTypes);
                r = BetterConversion(inferredRet, ret1, ret2);
                if (r == 0 && lambda.IsAsync)
                {
                    ret1        = UnpackTask(ret1);
                    ret2        = UnpackTask(ret2);
                    inferredRet = UnpackTask(inferredRet);
                    if (ret1 != null && ret2 != null && inferredRet != null)
                    {
                        r = BetterConversion(inferredRet, ret1, ret2);
                    }
                }
                return(r);
            }
            else
            {
                return(BetterConversion(resolveResult.Type, t1, t2));
            }
        }
Example #14
0
        /// <summary>
        /// Performs a member lookup.
        /// </summary>
        public ResolveResult Lookup(ResolveResult targetResolveResult, string name, IList <IType> typeArguments, bool isInvocation)
        {
            if (targetResolveResult == null)
            {
                throw new ArgumentNullException("targetResolveResult");
            }
            if (name == null)
            {
                throw new ArgumentNullException("name");
            }
            if (typeArguments == null)
            {
                throw new ArgumentNullException("typeArguments");
            }

            bool targetIsTypeParameter = targetResolveResult.Type.Kind == TypeKind.TypeParameter;

            bool allowProtectedAccess = (targetResolveResult is ThisResolveResult || IsProtectedAccessAllowed(targetResolveResult.Type));
            Predicate <ITypeDefinition> nestedTypeFilter = delegate(ITypeDefinition entity) {
                return(entity.Name == name && IsAccessible(entity, allowProtectedAccess));
            };
            Predicate <IUnresolvedMember> memberFilter = delegate(IUnresolvedMember entity) {
                // NOTE: Atm destructors can be looked up with 'Finalize'
                return(entity.SymbolKind != SymbolKind.Indexer &&
                       entity.SymbolKind != SymbolKind.Operator &&
                       entity.Name == name);
            };

            List <LookupGroup> lookupGroups = new List <LookupGroup>();

            // This loop will handle base types before derived types.
            // The loop performs three jobs:
            // 1) It marks entries in lookup groups from base classes as removed when those members
            //    are hidden by a derived class.
            // 2) It adds a new lookup group with the members from a declaring type.
            // 3) It replaces virtual members with the overridden version, placing the override in the
            //    lookup group belonging to the base class.
            foreach (IType type in targetResolveResult.Type.GetNonInterfaceBaseTypes())
            {
                List <IType> newNestedTypes            = null;
                List <IParameterizedMember> newMethods = null;
                IMember newNonMethod = null;

                IEnumerable <IType> typeBaseTypes = null;

                if (!isInvocation && !targetIsTypeParameter)
                {
                    // Consider nested types only if it's not an invocation.
                    // type.GetNestedTypes() is checking the type parameter count for an exact match,
                    // so we don't need to do that in our filter.
                    var nestedTypes = type.GetNestedTypes(typeArguments, nestedTypeFilter, GetMemberOptions.IgnoreInheritedMembers);
                    AddNestedTypes(type, nestedTypes, typeArguments.Count, lookupGroups, ref typeBaseTypes, ref newNestedTypes);
                }

                IEnumerable <IMember> members;
                if (typeArguments.Count == 0)
                {
                    // Note: IsInvocable-checking cannot be done as part of the filter;
                    // because it must be done after type substitution.
                    members = type.GetMembers(memberFilter, GetMemberOptions.IgnoreInheritedMembers);
                    if (isInvocation)
                    {
                        members = members.Where(m => IsInvocable(m));
                    }
                }
                else
                {
                    // No need to check for isInvocation/isInvocable here:
                    // we only fetch methods
                    members = type.GetMethods(typeArguments, memberFilter, GetMemberOptions.IgnoreInheritedMembers);
                }
                AddMembers(type, members, allowProtectedAccess, lookupGroups, false, ref typeBaseTypes, ref newMethods, ref newNonMethod);

                if (newNestedTypes != null || newMethods != null || newNonMethod != null)
                {
                    lookupGroups.Add(new LookupGroup(type, newNestedTypes, newMethods, newNonMethod));
                }
            }

            // Remove interface members hidden by class members.
            if (targetIsTypeParameter)
            {
                // This can happen only with type parameters.
                RemoveInterfaceMembersHiddenByClassMembers(lookupGroups);
            }

            return(CreateResult(targetResolveResult, lookupGroups, name, typeArguments));
        }
Example #15
0
        void MakeOutputTypeInference(ResolveResult e, IType t)
        {
            Log.WriteLine(" MakeOutputTypeInference from " + e + " to " + t);
            // If E is an anonymous function with inferred return type  U (§7.5.2.12) and T is a delegate type or expression
            // tree type with return type Tb, then a lower-bound inference (§7.5.2.9) is made from U to Tb.
            LambdaResolveResult lrr = e as LambdaResolveResult;

            if (lrr != null)
            {
                IMethod m = GetDelegateOrExpressionTreeSignature(t);
                if (m != null)
                {
                    IType inferredReturnType;
                    if (lrr.IsImplicitlyTyped)
                    {
                        if (m.Parameters.Count != lrr.Parameters.Count)
                        {
                            return;                             // cannot infer due to mismatched parameter lists
                        }
                        TypeParameterSubstitution substitution = GetSubstitutionForFixedTPs();
                        IType[] inferredParameterTypes         = new IType[m.Parameters.Count];
                        for (int i = 0; i < inferredParameterTypes.Length; i++)
                        {
                            IType parameterType = m.Parameters[i].Type;
                            inferredParameterTypes[i] = parameterType.AcceptVisitor(substitution);
                        }
                        inferredReturnType = lrr.GetInferredReturnType(inferredParameterTypes);
                    }
                    else
                    {
                        inferredReturnType = lrr.GetInferredReturnType(null);
                    }
                    MakeLowerBoundInference(inferredReturnType, m.ReturnType);
                    return;
                }
            }
            // Otherwise, if E is a method group and T is a delegate type or expression tree type
            // with parameter types T1…Tk and return type Tb, and overload resolution
            // of E with the types T1…Tk yields a single method with return type U, then a lower­-bound
            // inference is made from U to Tb.
            MethodGroupResolveResult mgrr = e as MethodGroupResolveResult;

            if (mgrr != null)
            {
                IMethod m = GetDelegateOrExpressionTreeSignature(t);
                if (m != null)
                {
                    ResolveResult[]           args         = new ResolveResult[m.Parameters.Count];
                    TypeParameterSubstitution substitution = GetSubstitutionForFixedTPs();
                    for (int i = 0; i < args.Length; i++)
                    {
                        IParameter param         = m.Parameters[i];
                        IType      parameterType = param.Type.AcceptVisitor(substitution);
                        if ((param.IsRef || param.IsOut) && parameterType.Kind == TypeKind.ByReference)
                        {
                            parameterType = ((ByReferenceType)parameterType).ElementType;
                            args[i]       = new ByReferenceResolveResult(parameterType, param.IsOut);
                        }
                        else
                        {
                            args[i] = new ResolveResult(parameterType);
                        }
                    }
                    var or = mgrr.PerformOverloadResolution(compilation,
                                                            args,
                                                            allowExpandingParams: false, allowOptionalParameters: false);
                    if (or.FoundApplicableCandidate && or.BestCandidateAmbiguousWith == null)
                    {
                        IType returnType = or.GetBestCandidateWithSubstitutedTypeArguments().ReturnType;
                        MakeLowerBoundInference(returnType, m.ReturnType);
                    }
                }
                return;
            }
            // Otherwise, if E is an expression with type U, then a lower-bound inference is made from U to T.
            if (IsValidType(e.Type))
            {
                MakeLowerBoundInference(e.Type, t);
            }
        }
Example #16
0
        bool PhaseTwo()
        {
            // C# 4.0 spec: §7.5.2.2 The second phase
            Log.WriteLine("Phase Two");
            // All unfixed type variables Xi which do not depend on any Xj are fixed.
            List <TP> typeParametersToFix = new List <TP>();

            foreach (TP Xi in typeParameters)
            {
                if (Xi.IsFixed == false)
                {
                    if (!typeParameters.Any((TP Xj) => !Xj.IsFixed && DependsOn(Xi, Xj)))
                    {
                        typeParametersToFix.Add(Xi);
                    }
                }
            }
            // If no such type variables exist, all unfixed type variables Xi are fixed for which all of the following hold:
            if (typeParametersToFix.Count == 0)
            {
                Log.WriteLine("Type parameters cannot be fixed due to dependency cycles");
                Log.WriteLine("Trying to break the cycle by fixing any TPs that have non-empty bounds...");
                foreach (TP Xi in typeParameters)
                {
                    // Xi has a non­empty set of bounds
                    if (!Xi.IsFixed && Xi.HasBounds)
                    {
                        // There is at least one type variable Xj that depends on Xi
                        if (typeParameters.Any((TP Xj) => DependsOn(Xj, Xi)))
                        {
                            typeParametersToFix.Add(Xi);
                        }
                    }
                }
            }
            // now fix 'em
            bool errorDuringFix = false;

            foreach (TP tp in typeParametersToFix)
            {
                if (!Fix(tp))
                {
                    errorDuringFix = true;
                }
            }
            if (errorDuringFix)
            {
                return(false);
            }
            bool unfixedTypeVariablesExist = typeParameters.Any((TP X) => X.IsFixed == false);

            if (typeParametersToFix.Count == 0 && unfixedTypeVariablesExist)
            {
                // If no such type variables exist and there are still unfixed type variables, type inference fails.
                Log.WriteLine("Type inference fails: there are still unfixed TPs remaining");
                return(false);
            }
            else if (!unfixedTypeVariablesExist)
            {
                // Otherwise, if no further unfixed type variables exist, type inference succeeds.
                return(true);
            }
            else
            {
                // Otherwise, for all arguments ei with corresponding parameter type Ti
                for (int i = 0; i < arguments.Length; i++)
                {
                    ResolveResult Ei = arguments[i];
                    IType         Ti = parameterTypes[i];
                    // where the output types (§7.4.2.4) contain unfixed type variables Xj
                    // but the input types (§7.4.2.3) do not
                    if (OutputTypeContainsUnfixed(Ei, Ti) && !InputTypesContainsUnfixed(Ei, Ti))
                    {
                        // an output type inference (§7.4.2.6) is made for ei with type Ti.
                        Log.WriteLine("MakeOutputTypeInference for argument #" + i);
                        MakeOutputTypeInference(Ei, Ti);
                    }
                }
                // Then the second phase is repeated.
                return(PhaseTwo());
            }
        }
		public ArrayCreateResolveResult(IType arrayType, ResolveResult[] sizeArguments, ResolveResult[] initializerElements,
		                                bool allowArrayConstants)
			: base(arrayType)
		{
			this.SizeArguments = sizeArguments;
			this.InitializerElements = initializerElements;
			if (allowArrayConstants) {
				this.constantArray = MakeConstantArray(sizeArguments, initializerElements);
			}
		}
Example #18
0
		// TODO: add support for user-defined conversions
		
		#region BetterConversion
		/// <summary>
		/// Gets the better conversion (C# 4.0 spec, §7.5.3.3)
		/// </summary>
		/// <returns>0 = neither is better; 1 = t1 is better; 2 = t2 is better</returns>
		public int BetterConversion(ResolveResult resolveResult, IType t1, IType t2)
		{
			// TODO: implement the special logic for anonymous functions
			return BetterConversion(resolveResult.Type, t1, t2);
		}
		public ByReferenceResolveResult(ResolveResult elementResult, bool isOut)
			: this(elementResult.Type, isOut)
		{
			this.ElementResult = elementResult;
		}
        public override IList <ResolveResult> GetArgumentsForCall()
        {
            ResolveResult[]      results         = new ResolveResult[Member.Parameters.Count];
            List <ResolveResult> paramsArguments = IsExpandedForm ? new List <ResolveResult>() : null;

            // map arguments to parameters:
            for (int i = 0; i < Arguments.Count; i++)
            {
                int mappedTo;
                if (argumentToParameterMap != null)
                {
                    mappedTo = argumentToParameterMap[i];
                }
                else
                {
                    mappedTo = IsExpandedForm ? Math.Min(i, results.Length - 1) : i;
                }

                if (mappedTo >= 0 && mappedTo < results.Length)
                {
                    if (IsExpandedForm && mappedTo == results.Length - 1)
                    {
                        paramsArguments.Add(Arguments[i]);
                    }
                    else
                    {
                        var narr = Arguments[i] as NamedArgumentResolveResult;
                        if (narr != null)
                        {
                            results[mappedTo] = narr.Argument;
                        }
                        else
                        {
                            results[mappedTo] = Arguments[i];
                        }
                    }
                }
            }
            if (IsExpandedForm)
            {
                IType           arrayType     = Member.Parameters.Last().Type;
                IType           int32         = Member.Compilation.FindType(KnownTypeCode.Int32);
                ResolveResult[] sizeArguments = { new ConstantResolveResult(int32, paramsArguments.Count) };
                results[results.Length - 1] = new ArrayCreateResolveResult(arrayType, sizeArguments, paramsArguments);
            }

            for (int i = 0; i < results.Length; i++)
            {
                if (results[i] == null)
                {
                    if (Member.Parameters[i].IsOptional)
                    {
                        results[i] = new ConstantResolveResult(Member.Parameters[i].Type, Member.Parameters[i].ConstantValue);
                    }
                    else
                    {
                        results[i] = ErrorResolveResult.UnknownError;
                    }
                }
            }

            return(results);
        }
        public static ResolveResult Resolve(Func <ICompilation> compilation, CSharpParsedFile parsedFile, CompilationUnit cu, TextLocation location, out AstNode node,
                                            CancellationToken cancellationToken = default(CancellationToken))
        {
            node = cu.GetNodeAt(location);
            if (node == null)
            {
                return(null);
            }
            if (CSharpAstResolver.IsUnresolvableNode(node))
            {
                if (node is Identifier)
                {
                    node = node.Parent;
                }
                else if (node.NodeType == NodeType.Token)
                {
                    if (node.Parent is IndexerExpression || node.Parent is ConstructorInitializer)
                    {
                        // There's no other place where one could hover to see the indexer's tooltip,
                        // so we need to resolve it when hovering over the '[' or ']'.
                        // For constructor initializer, the same applies to the 'base'/'this' token.
                        node = node.Parent;
                    }
                    else
                    {
                        return(null);
                    }
                }
                else
                {
                    // don't resolve arbitrary nodes - we don't want to show tooltips for everything
                    return(null);
                }
            }
            else
            {
                // It's a resolvable node.
                // However, we usually don't want to show the tooltip everywhere
                // For example, hovering with the mouse over an empty line between two methods causes
                // node==TypeDeclaration, but we don't want to show any tooltip.

                if (!node.GetChildByRole(Roles.Identifier).IsNull)
                {
                    // We'll suppress the tooltip for resolvable nodes if there is an identifier that
                    // could be hovered over instead:
                    return(null);
                }
            }
            if (node == null)
            {
                return(null);
            }

            if (node.Parent is ObjectCreateExpression && node.Role == Roles.Type)
            {
                node = node.Parent;
            }

            InvocationExpression parentInvocation = null;

            if ((node is IdentifierExpression || node is MemberReferenceExpression || node is PointerReferenceExpression) && node.Role != Roles.Argument)
            {
                // we also need to resolve the invocation
                parentInvocation = node.Parent as InvocationExpression;
            }

            CSharpAstResolver resolver = new CSharpAstResolver(compilation(), cu, parsedFile);

            resolver.ApplyNavigator(new NodeListResolveVisitorNavigator(node), cancellationToken);
            ResolveResult rr = resolver.Resolve(node, cancellationToken);

            if (rr is MethodGroupResolveResult && parentInvocation != null)
            {
                return(resolver.Resolve(parentInvocation));
            }
            else
            {
                return(rr);
            }
        }
Example #22
0
 public void Resolved(AstNode node, ResolveResult result)
 {
 }
Example #23
0
 protected void AssertError(Type expectedType, ResolveResult rr)
 {
     Assert.IsTrue(rr.IsError, rr.ToString() + " is not an error, but an error was expected");
     Assert.IsFalse(rr.IsCompileTimeConstant, rr.ToString() + " is a compile-time constant");
     Assert.AreEqual(expectedType.ToTypeReference().Resolve(context), rr.Type);
 }
		public AmbiguousMemberResolveResult(ResolveResult targetResult, IMember member, IType returnType) : base(targetResult, member, returnType)
		{
		}
		public ConditionalOperatorResolveResult(IType targetType, ResolveResult condition, ResolveResult @true, ResolveResult @false)
			: base(targetType)
		{
			if (condition == null)
				throw new ArgumentNullException("condition");
			if (@true == null)
				throw new ArgumentNullException("true");
			if (@false == null)
				throw new ArgumentNullException("false");
			this.Condition = condition;
			this.True = @true;
			this.False = @false;
		}
Example #26
0
		IType[] OutputTypes(ResolveResult e, IType t)
		{
			// C# 4.0 spec: §7.5.2.4 Output types
			LambdaResolveResult lrr = e as LambdaResolveResult;
			if (lrr != null && lrr.IsImplicitlyTyped || e is MethodGroupResolveResult) {
				IMethod m = GetDelegateOrExpressionTreeSignature(t);
				if (m != null) {
					return new[] { m.ReturnType.Resolve(context) };
				}
			}
			return emptyTypeArray;
		}
Example #27
0
		void MakeOutputTypeInference(ResolveResult e, IType t)
		{
			Log.WriteLine(" MakeOutputTypeInference from " + e + " to " + t);
			// If E is an anonymous function with inferred return type  U (§7.5.2.12) and T is a delegate type or expression
			// tree type with return type Tb, then a lower-bound inference (§7.5.2.9) is made from U to Tb.
			LambdaResolveResult lrr = e as LambdaResolveResult;
			if (lrr != null) {
				IMethod m = GetDelegateOrExpressionTreeSignature(t);
				if (m != null) {
					IType inferredReturnType;
					if (lrr.IsImplicitlyTyped) {
						if (m.Parameters.Count != lrr.Parameters.Count)
							return; // cannot infer due to mismatched parameter lists
						TypeParameterSubstitution substitution = GetSubstitutionForFixedTPs();
						IType[] inferredParameterTypes = new IType[m.Parameters.Count];
						for (int i = 0; i < inferredParameterTypes.Length; i++) {
							IType parameterType = m.Parameters[i].Type.Resolve(context);
							inferredParameterTypes[i] = parameterType.AcceptVisitor(substitution);
						}
						inferredReturnType = lrr.GetInferredReturnType(inferredParameterTypes);
					} else {
						inferredReturnType = lrr.GetInferredReturnType(null);
					}
					MakeLowerBoundInference(inferredReturnType, m.ReturnType.Resolve(context));
					return;
				}
			}
			// Otherwise, if E is a method group and T is a delegate type or expression tree type
			// with parameter types T1…Tk and return type Tb, and overload resolution
			// of E with the types T1…Tk yields a single method with return type U, then a lower­-bound
			// inference is made from U to Tb.
			MethodGroupResolveResult mgrr = e as MethodGroupResolveResult;
			if (mgrr != null) {
				IMethod m = GetDelegateOrExpressionTreeSignature(t);
				if (m != null) {
					ResolveResult[] args = new ResolveResult[m.Parameters.Count];
					TypeParameterSubstitution substitution = GetSubstitutionForFixedTPs();
					for (int i = 0; i < args.Length; i++) {
						IParameter param = m.Parameters[i];
						IType parameterType = param.Type.Resolve(context);
						parameterType = parameterType.AcceptVisitor(substitution);
						if ((param.IsRef || param.IsOut) && parameterType.Kind == TypeKind.ByReference) {
							parameterType = ((ByReferenceType)parameterType).ElementType;
							args[i] = new ByReferenceResolveResult(parameterType, param.IsOut);
						} else {
							args[i] = new ResolveResult(parameterType);
						}
					}
					var or = mgrr.PerformOverloadResolution(context, args,
					                                        allowExtensionMethods: false,
					                                        allowExpandingParams: false);
					if (or.FoundApplicableCandidate && or.BestCandidateAmbiguousWith == null) {
						IType returnType = or.BestCandidate.ReturnType.Resolve(context);
						MakeLowerBoundInference(returnType, m.ReturnType.Resolve(context));
					}
				}
				return;
			}
			// Otherwise, if E is an expression with type U, then a lower-bound inference is made from U to T.
			if (e.Type != SharedTypes.UnknownType) {
				MakeLowerBoundInference(e.Type, t);
			}
		}
Example #28
0
            internal override bool IsMatch(ResolveResult rr)
            {
                ConversionResolveResult crr = rr as ConversionResolveResult;

                return(crr != null && crr.Conversion.IsUserDefined && crr.Conversion.Method.MemberDefinition == op);
            }
Example #29
0
		bool ImplicitConstantExpressionConversion(ResolveResult rr, IType toType)
		{
			// C# 4.0 spec: §6.1.9
			TypeCode fromTypeCode = ReflectionHelper.GetTypeCode(rr.Type);
			TypeCode toTypeCode = ReflectionHelper.GetTypeCode(NullableType.GetUnderlyingType(toType));
			if (fromTypeCode == TypeCode.Int64) {
				long val = (long)rr.ConstantValue;
				return val >= 0 && toTypeCode == TypeCode.UInt64;
			} else if (fromTypeCode == TypeCode.Int32) {
				int val = (int)rr.ConstantValue;
				switch (toTypeCode) {
					case TypeCode.SByte:
						return val >= SByte.MinValue && val <= SByte.MaxValue;
					case TypeCode.Byte:
						return val >= Byte.MinValue && val <= Byte.MaxValue;
					case TypeCode.Int16:
						return val >= Int16.MinValue && val <= Int16.MaxValue;
					case TypeCode.UInt16:
						return val >= UInt16.MinValue && val <= UInt16.MaxValue;
					case TypeCode.UInt32:
						return val >= 0;
					case TypeCode.UInt64:
						return val >= 0;
				}
			}
			return false;
		}
Example #30
0
            internal override bool IsMatch(ResolveResult rr)
            {
                var lrr = rr as LocalResolveResult;

                return(lrr != null && lrr.Variable.Name == variable.Name && lrr.Variable.Region == variable.Region);
            }
Example #31
0
 internal abstract bool IsMatch(ResolveResult rr);
Example #32
0
 public virtual void ProcessConversion(Expression expression, ResolveResult result, Conversion conversion, IType targetType)
 {
 }
Example #33
0
 public DynamicMemberResolveResult(ResolveResult target, string member) : base(SpecialType.Dynamic)
 {
     this.Target = target;
     this.Member = member;
 }
Example #34
0
            internal override bool IsMatch(ResolveResult rr)
            {
                TypeResolveResult trr = rr as TypeResolveResult;

                return(trr != null && typeDefinition.Equals(trr.Type.GetDefinition()));
            }
Example #35
0
 bool OutputTypeContainsUnfixed(ResolveResult argument, IType parameterType)
 {
     return(AnyTypeContainsUnfixedParameter(OutputTypes(argument, parameterType)));
 }
Example #36
0
            internal override bool IsMatch(ResolveResult rr)
            {
                var mrr = rr as MemberResolveResult;

                return(mrr != null && method == mrr.Member.MemberDefinition);
            }
Example #37
0
        /// <summary>
        /// Retrieves all members that are accessible and not hidden (by being overridden or shadowed).
        /// Returns both members and nested type definitions. Does not include extension methods.
        /// </summary>
        public IEnumerable <IEntity> GetAccessibleMembers(ResolveResult targetResolveResult)
        {
            if (targetResolveResult == null)
            {
                throw new ArgumentNullException("targetResolveResult");
            }

            bool targetIsTypeParameter = targetResolveResult.Type.Kind == TypeKind.TypeParameter;
            bool allowProtectedAccess  = (targetResolveResult is ThisResolveResult || IsProtectedAccessAllowed(targetResolveResult.Type));

            // maps the member name to the list of lookup groups
            var lookupGroupDict = new Dictionary <string, List <LookupGroup> >();

            // This loop will handle base types before derived types.
            // The loop performs three jobs:
            // 1) It marks entries in lookup groups from base classes as removed when those members
            //    are hidden by a derived class.
            // 2) It adds a new lookup group with the members from a declaring type.
            // 3) It replaces virtual members with the overridden version, placing the override in the
            //    lookup group belonging to the base class.
            foreach (IType type in targetResolveResult.Type.GetNonInterfaceBaseTypes())
            {
                List <IEntity> entities = new List <IEntity>();
                entities.AddRange(type.GetMembers(options: GetMemberOptions.IgnoreInheritedMembers));
                if (!targetIsTypeParameter)
                {
                    var nestedTypes = type.GetNestedTypes(options: GetMemberOptions.IgnoreInheritedMembers | GetMemberOptions.ReturnMemberDefinitions);
                    // GetDefinition() might return null if some IType has a strange implementation of GetNestedTypes.
                    entities.AddRange(nestedTypes.Select(t => t.GetDefinition()).Where(td => td != null));
                }

                foreach (var entityGroup in entities.GroupBy(e => e.Name))
                {
                    List <LookupGroup> lookupGroups = new List <LookupGroup>();
                    if (!lookupGroupDict.TryGetValue(entityGroup.Key, out lookupGroups))
                    {
                        lookupGroupDict.Add(entityGroup.Key, lookupGroups = new List <LookupGroup>());
                    }

                    List <IType> newNestedTypes            = null;
                    List <IParameterizedMember> newMethods = null;
                    IMember newNonMethod = null;

                    IEnumerable <IType> typeBaseTypes = null;

                    if (!targetIsTypeParameter)
                    {
                        AddNestedTypes(type, entityGroup.OfType <IType>(), 0, lookupGroups, ref typeBaseTypes, ref newNestedTypes);
                    }
                    AddMembers(type, entityGroup.OfType <IMember>(), allowProtectedAccess, lookupGroups, false, ref typeBaseTypes, ref newMethods, ref newNonMethod);

                    if (newNestedTypes != null || newMethods != null || newNonMethod != null)
                    {
                        lookupGroups.Add(new LookupGroup(type, newNestedTypes, newMethods, newNonMethod));
                    }
                }
            }

            foreach (List <LookupGroup> lookupGroups in lookupGroupDict.Values)
            {
                // Remove interface members hidden by class members.
                if (targetIsTypeParameter)
                {
                    // This can happen only with type parameters.
                    RemoveInterfaceMembersHiddenByClassMembers(lookupGroups);
                }

                // Now report the results:
                foreach (LookupGroup lookupGroup in lookupGroups)
                {
                    if (!lookupGroup.MethodsAreHidden)
                    {
                        foreach (IMethod method in lookupGroup.Methods)
                        {
                            yield return(method);
                        }
                    }
                    if (!lookupGroup.NonMethodIsHidden)
                    {
                        yield return(lookupGroup.NonMethod);
                    }
                    if (lookupGroup.NestedTypes != null)
                    {
                        foreach (IType type in lookupGroup.NestedTypes)
                        {
                            ITypeDefinition typeDef = type.GetDefinition();
                            if (typeDef != null)
                            {
                                yield return(typeDef);
                            }
                        }
                    }
                }
            }
        }
Example #38
0
            internal override bool IsMatch(ResolveResult rr)
            {
                MemberResolveResult mrr = rr as MemberResolveResult;

                return(mrr != null && indexer == mrr.Member.MemberDefinition);
            }
Example #39
0
        ResolveResult CreateResult(ResolveResult targetResolveResult, List <LookupGroup> lookupGroups, string name, IList <IType> typeArguments)
        {
            // Remove all hidden groups
            lookupGroups.RemoveAll(g => g.AllHidden);

            if (lookupGroups.Count == 0)
            {
                // No members found
                return(new UnknownMemberResolveResult(targetResolveResult.Type, name, typeArguments));
            }

            if (lookupGroups.Any(g => !g.MethodsAreHidden && g.Methods.Count > 0))
            {
                // If there are methods, make a MethodGroupResolveResult.
                // Note that a conflict between a member and a method (possible with multiple interface inheritance)
                // is only a warning, not an error, and the C# compiler will prefer the method group.
                List <MethodListWithDeclaringType> methodLists = new List <MethodListWithDeclaringType>();
                foreach (var lookupGroup in lookupGroups)
                {
                    if (!lookupGroup.MethodsAreHidden && lookupGroup.Methods.Count > 0)
                    {
                        var methodListWithDeclType = new MethodListWithDeclaringType(lookupGroup.DeclaringType);
                        foreach (var method in lookupGroup.Methods)
                        {
                            methodListWithDeclType.Add((IMethod)method);
                        }
                        methodLists.Add(methodListWithDeclType);
                    }
                }

                return(new MethodGroupResolveResult(targetResolveResult, name, methodLists, typeArguments));
            }

            // If there are ambiguities, report the most-derived result (last group)
            LookupGroup resultGroup = lookupGroups[lookupGroups.Count - 1];

            if (resultGroup.NestedTypes != null && resultGroup.NestedTypes.Count > 0)
            {
                if (resultGroup.NestedTypes.Count > 1 || !resultGroup.NonMethodIsHidden || lookupGroups.Count > 1)
                {
                    return(new AmbiguousTypeResolveResult(resultGroup.NestedTypes[0]));
                }
                else
                {
                    return(new TypeResolveResult(resultGroup.NestedTypes[0]));
                }
            }

            if (resultGroup.NonMethod.IsStatic && targetResolveResult is ThisResolveResult)
            {
                targetResolveResult = new TypeResolveResult(targetResolveResult.Type);
            }

            if (lookupGroups.Count > 1)
            {
                return(new AmbiguousMemberResolveResult(targetResolveResult, resultGroup.NonMethod));
            }
            else
            {
                if (isInEnumMemberInitializer)
                {
                    IField field = resultGroup.NonMethod as IField;
                    if (field != null && field.DeclaringTypeDefinition != null && field.DeclaringTypeDefinition.Kind == TypeKind.Enum)
                    {
                        return(new MemberResolveResult(
                                   targetResolveResult, field,
                                   field.DeclaringTypeDefinition.EnumUnderlyingType,
                                   field.IsConst, field.ConstantValue));
                    }
                }
                return(new MemberResolveResult(targetResolveResult, resultGroup.NonMethod));
            }
        }
		public ArrayAccessResolveResult(IType elementType, ResolveResult array, ResolveResult[] indices) : base(elementType)
		{
			if (array == null)
				throw new ArgumentNullException("array");
			if (indices == null)
				throw new ArgumentNullException("indices");
			this.Array = array;
			this.Indices = indices;
		}
Example #41
0
		IType[] InputTypes(ResolveResult e, IType t)
		{
			// C# 4.0 spec: §7.5.2.3 Input types
			LambdaResolveResult lrr = e as LambdaResolveResult;
			if (lrr != null && lrr.IsImplicitlyTyped || e is MethodGroupResolveResult) {
				IMethod m = GetDelegateOrExpressionTreeSignature(t);
				if (m != null) {
					IType[] inputTypes = new IType[m.Parameters.Count];
					for (int i = 0; i < inputTypes.Length; i++) {
						inputTypes[i] = m.Parameters[i].Type.Resolve(context);
					}
					return inputTypes;
				}
			}
			return emptyTypeArray;
		}
Example #42
0
 public CastResolveResult(IType targetType, ResolveResult input, Conversion conversion, bool checkForOverflow)
     : base(targetType, input, conversion, checkForOverflow)
 {
 }
Example #43
0
		bool OutputTypeContainsUnfixed(ResolveResult argument, IType parameterType)
		{
			return AnyTypeContainsUnfixedParameter(OutputTypes(argument, parameterType));
		}
Example #44
0
 /// <summary>
 /// Gets whether access to protected instance members of the target expression is possible.
 /// </summary>
 public bool IsProtectedAccessAllowed(ResolveResult targetResolveResult)
 {
     return(targetResolveResult is ThisResolveResult || IsProtectedAccessAllowed(targetResolveResult.Type));
 }
		public IList<ResolveResult> GetArgumentsWithConversions()
		{
			if (bestCandidate == null)
				return arguments;
			var conversions = this.ArgumentConversions;
			ResolveResult[] args = new ResolveResult[arguments.Length];
			for (int i = 0; i < args.Length; i++) {
				if (conversions[i] == Conversion.IdentityConversion || conversions[i] == Conversion.None) {
					args[i] = arguments[i];
				} else {
					int parameterIndex = bestCandidate.ArgumentToParameterMap[i];
					IType parameterType;
					if (parameterIndex >= 0)
						parameterType = bestCandidate.ParameterTypes[parameterIndex];
					else
						parameterType = SharedTypes.UnknownType;
					args[i] = new ConversionResolveResult(parameterType, arguments[i], conversions[i]);
				}
			}
			return args;
		}
Example #46
0
		/// <summary>
		/// Performs a member lookup.
		/// </summary>
		public ResolveResult Lookup(ResolveResult targetResolveResult, string name, IList<IType> typeArguments, bool isInvocation)
		{
			bool targetIsTypeParameter = targetResolveResult.Type.Kind == TypeKind.TypeParameter;
			
			bool allowProtectedAccess = IsProtectedAccessAllowed(targetResolveResult.Type);
			Predicate<IEntity> filter = delegate(IEntity entity) {
				return entity.Name == name && IsAccessible(entity, allowProtectedAccess);
			};
			
			List<LookupGroup> lookupGroups = new List<LookupGroup>();
			// This loop will handle base types before derived types.
			// The loop performs three jobs:
			// 1) It marks entries in lookup groups from base classes as removed when those members
			//    are hidden by a derived class.
			// 2) It adds a new lookup group with the members from a declaring type.
			// 3) It replaces virtual members with the overridden version, placing the override in the
			//    lookup group belonging to the base class.
			foreach (IType type in targetResolveResult.Type.GetNonInterfaceBaseTypes(context)) {
				
				List<IType> newNestedTypes = null;
				List<IParameterizedMember> newMethods = null;
				IMember newNonMethod = null;
				
				IEnumerable<IType> typeBaseTypes = null;
				
				if (!isInvocation && !targetIsTypeParameter) {
					// Consider nested types only if it's not an invocation.
					// type.GetNestedTypes() is checking the type parameter count for an exact match,
					// so we don't need to do that in our filter.
					var nestedTypes = type.GetNestedTypes(typeArguments, context, filter, GetMemberOptions.IgnoreInheritedMembers);
					AddNestedTypes(type, nestedTypes, typeArguments.Count, lookupGroups, ref typeBaseTypes, ref newNestedTypes);
				}
				
				IEnumerable<IMember> members;
				if (typeArguments.Count == 0) {
					// Note: IsInvocable-checking cannot be done as part of the filter;
					// because it must be done after type substitution.
					members = type.GetMembers(context, filter, GetMemberOptions.IgnoreInheritedMembers);
					if (isInvocation)
						members = members.Where(m => IsInvocable(m, context));
				} else {
					// No need to check for isInvocation/isInvocable here:
					// we only fetch methods
					members = type.GetMethods(typeArguments, context, filter, GetMemberOptions.IgnoreInheritedMembers);
				}
				AddMembers(type, members, lookupGroups, false, ref typeBaseTypes, ref newMethods, ref newNonMethod);
				
				if (newNestedTypes != null || newMethods != null || newNonMethod != null)
					lookupGroups.Add(new LookupGroup(type, newNestedTypes, newMethods, newNonMethod));
			}
			
			// Remove interface members hidden by class members.
			if (targetIsTypeParameter) {
				// This can happen only with type parameters.
				RemoveInterfaceMembersHiddenByClassMembers(lookupGroups);
			}
			
			return CreateResult(targetResolveResult, lookupGroups, name, typeArguments);
		}
Example #47
0
		bool ImplicitEnumerationConversion(ResolveResult rr, IType toType)
		{
			// C# 4.0 spec: §6.1.3
			TypeCode constantType = ReflectionHelper.GetTypeCode(rr.Type);
			if (constantType >= TypeCode.SByte && constantType <= TypeCode.Decimal && Convert.ToDouble(rr.ConstantValue) == 0) {
				return NullableType.GetUnderlyingType(toType).IsEnum();
			}
			return false;
		}
 public BinaryOperatorResolveResult(IType resultType, ResolveResult lhs, BinaryOperatorType op, ResolveResult rhs)
     : base(resultType)
 {
     if (lhs == null)
     {
         throw new ArgumentNullException("lhs");
     }
     if (rhs == null)
     {
         throw new ArgumentNullException("rhs");
     }
     this.Left     = lhs;
     this.Operator = op;
     this.Right    = rhs;
 }
Example #49
0
        // TODO: add support for user-defined conversions

        #region BetterConversion
        /// <summary>
        /// Gets the better conversion (C# 4.0 spec, §7.5.3.3)
        /// </summary>
        /// <returns>0 = neither is better; 1 = t1 is better; 2 = t2 is better</returns>
        public int BetterConversion(ResolveResult resolveResult, IType t1, IType t2)
        {
            // TODO: implement the special logic for anonymous functions
            return(BetterConversion(resolveResult.Type, t1, t2));
        }
Example #50
0
        Conversion AnonymousFunctionConversion(ResolveResult resolveResult, IType toType)
        {
            // C# 4.0 spec §6.5 Anonymous function conversions
            LambdaResolveResult f = resolveResult as LambdaResolveResult;

            if (f == null)
            {
                return(Conversion.None);
            }
            if (!f.IsAnonymousMethod)
            {
                // It's a lambda, so conversions to expression trees exist
                // (even if the conversion leads to a compile-time error, e.g. for statement lambdas)
                toType = UnpackExpressionTreeType(toType);
            }
            IMethod d = toType.GetDelegateInvokeMethod();

            if (d == null)
            {
                return(Conversion.None);
            }

            IType[] dParamTypes = new IType[d.Parameters.Count];
            for (int i = 0; i < dParamTypes.Length; i++)
            {
                dParamTypes[i] = d.Parameters[i].Type.Resolve(context);
            }
            IType dReturnType = d.ReturnType.Resolve(context);

            if (f.HasParameterList)
            {
                // If F contains an anonymous-function-signature, then D and F have the same number of parameters.
                if (d.Parameters.Count != f.Parameters.Count)
                {
                    return(Conversion.None);
                }

                if (f.IsImplicitlyTyped)
                {
                    // If F has an implicitly typed parameter list, D has no ref or out parameters.
                    foreach (IParameter p in d.Parameters)
                    {
                        if (p.IsOut || p.IsRef)
                        {
                            return(Conversion.None);
                        }
                    }
                }
                else
                {
                    // If F has an explicitly typed parameter list, each parameter in D has the same type
                    // and modifiers as the corresponding parameter in F.
                    for (int i = 0; i < f.Parameters.Count; i++)
                    {
                        IParameter pD = d.Parameters[i];
                        IParameter pF = f.Parameters[i];
                        if (pD.IsRef != pF.IsRef || pD.IsOut != pF.IsOut)
                        {
                            return(Conversion.None);
                        }
                        if (!dParamTypes[i].Equals(pF.Type.Resolve(context)))
                        {
                            return(Conversion.None);
                        }
                    }
                }
            }
            else
            {
                // If F does not contain an anonymous-function-signature, then D may have zero or more parameters of any
                // type, as long as no parameter of D has the out parameter modifier.
                foreach (IParameter p in d.Parameters)
                {
                    if (p.IsOut)
                    {
                        return(Conversion.None);
                    }
                }
            }

            return(f.IsValid(dParamTypes, dReturnType, this));
        }
 public ConditionalOperatorResolveResult(IType targetType, ResolveResult condition, ResolveResult @true, ResolveResult @false)
     : base(targetType)
 {
     if (condition == null)
     {
         throw new ArgumentNullException("condition");
     }
     if (@true == null)
     {
         throw new ArgumentNullException("true");
     }
     if (@false == null)
     {
         throw new ArgumentNullException("false");
     }
     this.Condition = condition;
     this.True      = @true;
     this.False     = @false;
 }
Example #52
0
 protected void AssertError(Type expectedType, ResolveResult rr)
 {
     Assert.IsTrue(rr.IsError, rr.ToString() + " is not an error, but an error was expected");
     Assert.IsFalse(rr.IsCompileTimeConstant, rr.ToString() + " is a compile-time constant");
     Assert.AreEqual(compilation.FindType(expectedType), rr.Type);
 }
		/// <inheritdoc/>
		public void Resolved(AstNode node, ResolveResult result)
		{
			navigator.Resolved(node, result);
		}
		static object[] MakeConstantArray(ResolveResult[] sizeArguments, ResolveResult[] initializerElements)
		{
			if (initializerElements == null)
				return null;
			
			for (int i = 0; i < initializerElements.Length; i++) {
				if (!initializerElements[i].IsCompileTimeConstant)
					return null;
			}
			
			if (sizeArguments != null && sizeArguments.Length > 0) {
				if (sizeArguments.Length > 1) {
					// 2D-arrays can't be constant
					return null;
				}
				if (!sizeArguments[0].IsCompileTimeConstant)
					return null;
				
				int expectedSize;
				try {
					expectedSize = (int)CSharpPrimitiveCast.Cast(TypeCode.Int32, sizeArguments[0].ConstantValue, true);
				} catch (InvalidCastException) {
					return null;
				} catch (OverflowException) {
					return null;
				}
				if (expectedSize != initializerElements.Length)
					return null;
			}
			
			object[] constants = new object[initializerElements.Length];
			for (int i = 0; i < initializerElements.Length; i++) {
				constants[i] = initializerElements[i].ConstantValue;
			}
			return constants;
		}
Example #55
0
 /// <inheritdoc/>
 public void Resolved(AstNode node, ResolveResult result)
 {
     navigator.Resolved(node, result);
 }
Example #56
0
 /// <inheritdoc/>
 public void ProcessConversion(Expression expression, ResolveResult result, Conversion conversion, IType targetType)
 {
     navigator.ProcessConversion(expression, result, conversion, targetType);
 }
Example #57
0
		static string GetText(ResolveResult result, string expression, out bool debuggerCanShowValue)
		{
			debuggerCanShowValue = false;
			return "FIXME";
			
			// FIXME
//			debuggerCanShowValue = false;
//			if (result == null) {
//				// when pressing control, show the expression even when it could not be resolved
//				return (Control.ModifierKeys == Keys.Control) ? "" : null;
//			}
//			if (result is MixedResolveResult)
//				return GetText(((MixedResolveResult)result).PrimaryResult, expression, out debuggerCanShowValue);
//			else if (result is DelegateCallResolveResult)
//				return GetText(((DelegateCallResolveResult)result).Target, expression, out debuggerCanShowValue);
//
//			IAmbience ambience = AmbienceService.GetCurrentAmbience();
//			ambience.ConversionFlags = ConversionFlags.StandardConversionFlags | ConversionFlags.UseFullyQualifiedMemberNames;
//			if (result is MemberResolveResult) {
//				return GetMemberText(ambience, ((MemberResolveResult)result).ResolvedMember, expression, out debuggerCanShowValue);
//			} else if (result is LocalResolveResult) {
//				LocalResolveResult rr = (LocalResolveResult)result;
//				ambience.ConversionFlags = ConversionFlags.UseFullyQualifiedTypeNames
//					| ConversionFlags.ShowReturnType | ConversionFlags.ShowDefinitionKeyWord;
//				StringBuilder b = new StringBuilder();
//				if (rr.IsParameter)
//					b.Append("parameter ");
//				else
//					b.Append("local variable ");
//				b.Append(ambience.Convert(rr.Field));
//				if (currentDebugger != null) {
//					string currentValue = currentDebugger.GetValueAsString(rr.VariableName);
//					if (currentValue != null) {
//						debuggerCanShowValue = true;
//						b.Append(" = ");
//						if (currentValue.Length > 256)
//							currentValue = currentValue.Substring(0, 256) + "...";
//						b.Append(currentValue);
//					}
//				}
//				return b.ToString();
//			} else if (result is NamespaceResolveResult) {
//				return "namespace " + ((NamespaceResolveResult)result).Name;
//			} else if (result is TypeResolveResult) {
//				IClass c = ((TypeResolveResult)result).ResolvedClass;
//				if (c != null)
//					return GetMemberText(ambience, c, expression, out debuggerCanShowValue);
//				else
//					return ambience.Convert(result.ResolvedType);
//			} else if (result is MethodGroupResolveResult) {
//				MethodGroupResolveResult mrr = result as MethodGroupResolveResult;
//				IMethod m = mrr.GetMethodIfSingleOverload();
//				IMethod m2 = mrr.GetMethodWithEmptyParameterList();
//				if (m != null)
//					return GetMemberText(ambience, m, expression, out debuggerCanShowValue);
//				else if (ambience is VBNetAmbience && m2 != null)
//					return GetMemberText(ambience, m2, expression, out debuggerCanShowValue);
//				else
//					return "Overload of " + ambience.Convert(mrr.ContainingType) + "." + mrr.Name;
//			} else {
//				if (Control.ModifierKeys == Keys.Control) {
//					if (result.ResolvedType != null)
//						return "expression of type " + ambience.Convert(result.ResolvedType);
//					else
//						return "ResolveResult without ResolvedType";
//				} else {
//					return null;
//				}
//			}
		}
        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);
        }
Example #59
0
		ResolveResult CreateResult(ResolveResult targetResolveResult, List<LookupGroup> lookupGroups, string name, IList<IType> typeArguments)
		{
			// Remove all hidden groups
			lookupGroups.RemoveAll(g => g.AllHidden);
			
			if (lookupGroups.Count == 0) {
				// No members found
				return new UnknownMemberResolveResult(targetResolveResult.Type, name, typeArguments);
			}
			
			if (lookupGroups.Any(g => !g.MethodsAreHidden && g.Methods.Count > 0)) {
				// If there are methods, make a MethodGroupResolveResult.
				// Note that a conflict between a member and a method (possible with multiple interface inheritance)
				// is only a warning, not an error, and the C# compiler will prefer the method group.
				List<MethodListWithDeclaringType> methodLists = new List<MethodListWithDeclaringType>();
				foreach (var lookupGroup in lookupGroups) {
					if (!lookupGroup.MethodsAreHidden && lookupGroup.Methods.Count > 0) {
						var methodListWithDeclType = new MethodListWithDeclaringType(lookupGroup.DeclaringType);
						foreach (var method in lookupGroup.Methods) {
							methodListWithDeclType.Add((IMethod)method);
						}
						methodLists.Add(methodListWithDeclType);
					}
				}
				
				return new MethodGroupResolveResult(targetResolveResult, name, methodLists, typeArguments);
			}
			
			// If there are ambiguities, report the most-derived result (last group)
			LookupGroup resultGroup = lookupGroups[lookupGroups.Count - 1];
			if (resultGroup.NestedTypes != null && resultGroup.NestedTypes.Count > 0) {
				if (resultGroup.NestedTypes.Count > 1 || !resultGroup.NonMethodIsHidden || lookupGroups.Count > 1)
					return new AmbiguousTypeResolveResult(resultGroup.NestedTypes[0]);
				else
					return new TypeResolveResult(resultGroup.NestedTypes[0]);
			}
			
			if (lookupGroups.Count > 1) {
				return new AmbiguousMemberResolveResult(targetResolveResult, resultGroup.NonMethod,
				                                        resultGroup.NonMethod.ReturnType.Resolve(context));
			} else {
				return new MemberResolveResult(targetResolveResult, resultGroup.NonMethod, context);
			}
		}
 void IResolveVisitorNavigator.Resolved(AstNode node, ResolveResult result)
 {
 }