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); }
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; }
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; }