Example #1
0
        private void ProcessClosureInMethodInvocation(GenericParameterInferrer inferrer, BlockExpression closure, ICallableType formalType)
        {
            var sig = formalType.GetSignature();

            var replacer = new TypeReplacer();
            var collector = new TypeCollector(delegate(IType t)
            {
                IGenericParameter gp = t as IGenericParameter;
                if (gp == null) return false;
                return gp.DeclaringEntity == inferrer.GenericMethod;
            });

            collector.Visit(formalType);
            foreach (var typeParameter in collector.Matches)
            {
                var inferredType = inferrer.GetInferredType((IGenericParameter)typeParameter);
                if (inferredType != null)
                    replacer.Replace(typeParameter, inferredType);
            }

            for (var i = 0; i < sig.Parameters.Length; i++)
            {
                var pd = closure.Parameters[i];
                if (pd.Type != null) continue;
                pd.Type = CodeBuilder.CreateTypeReference(replacer.MapType(sig.Parameters[i].Type));
            }

            ProcessClosureBody(closure);
        }
Example #2
0
        private IEntity ResolveCallableReference(MethodInvocationExpression node, Ambiguous entity)
        {
            var genericService = My<GenericsServices>.Instance;
            var methods = entity.Entities
                .OfType<IMethod>()
                .Select(m => {
                    if (m.GenericInfo == null)
                        return m;

                    var inferrer = new GenericParameterInferrer(Context, m, node.Arguments);
                    inferrer.ResolveClosure += ProcessClosureInMethodInvocation;
                    if (!inferrer.Run())
                        return null;
                    var arguments = inferrer.GetInferredTypes();
                    if (arguments == null || !genericService.CheckGenericConstruction(m, arguments))
                        return null;
                    return m.GenericInfo.ConstructMethod(arguments);
                }).Where(m => m != null).ToArray();

            var resolved = CallableResolutionService.ResolveCallableReference(node.Arguments, methods);
            if (null == resolved)
                return null;

            IMember member = (IMember)resolved;
            if (NodeType.ReferenceExpression == node.Target.NodeType)
            {
                ResolveMemberInfo((ReferenceExpression)node.Target, member);
            }
            else
            {
                Bind(node.Target, member);
                BindExpressionType(node.Target, member.Type);
            }
            return resolved;
        }
Example #3
0
        private IMethod InferGenericMethodInvocation(MethodInvocationExpression node, IMethod targetMethod)
        {
            if (targetMethod.GenericInfo == null) return targetMethod;

            GenericParameterInferrer inferrer = new GenericParameterInferrer(Context, targetMethod, node.Arguments);
            inferrer.ResolveClosure += ProcessClosureInMethodInvocation;
            if (!inferrer.Run())
            {
                CannotInferGenericMethodArguments(node, targetMethod);
                return null;
            }

            IType[] inferredTypeArguments = inferrer.GetInferredTypes();
            if (!_genericServices.Instance.CheckGenericConstruction(node, targetMethod, inferredTypeArguments, true))
            {
                Error(node);
                return null;
            }

            IMethod constructedMethod = targetMethod.GenericInfo.ConstructMethod(inferredTypeArguments);
            Bind(node.Target, constructedMethod);
            BindExpressionType(node, GetInferredType(constructedMethod));

            return constructedMethod;
        }