XSpect.Yacq.Expressions.DispatchExpression.InferTypeArguments C# (CSharp) Méthode

InferTypeArguments() private méthode

private InferTypeArguments ( Candidate candidate, Type>.IDictionary typeArgumentMap, SymbolTable symbols ) : Candidate
candidate Candidate
typeArgumentMap Type>.IDictionary
symbols XSpect.Yacq.Symbols.SymbolTable
Résultat Candidate
        private Candidate InferTypeArguments(Candidate candidate, IDictionary<Type, Type> typeArgumentMap, SymbolTable symbols)
        {
            return this.DispatchType != DispatchTypes.Method
                ? candidate
                : new Dictionary<Type, Type>(typeArgumentMap).Let(map =>
                  {
                      if (map.Count == candidate.Method.GetGenericArguments().Length)
                      {
                          return candidate.Clone(
                              member: candidate.Method != null && candidate.Method.IsGenericMethodDefinition
                                  ? candidate.Method.MakeGenericMethod(typeArgumentMap.ToArgumentArray())
                                  : candidate.Member,
                              arguments: candidate.ParameterMap
                                  .Select(_ => _.Item2 is AmbiguousLambdaExpression && _.Item1.GetDelegateSignature() != null
                                      ? ((AmbiguousLambdaExpression) _.Item2)
                                            .ApplyTypeArguments(_.Item1)
                                            .ApplyTypeArguments(map)
                                            .Reduce(symbols, _.Item1.ReplaceGenericArguments(map))
                                      : _.Item2
                                  )
                                  .ToArray()
                          );
                      }
                      else
                      {
                          candidate.ParameterMap
                              .Where(_ => !(_.Item1.IsGenericParameter
                                  ? EnumerableEx.Return(_.Item1)
                                  : _.Item1.GetGenericArguments()
                              ).All(map.ContainsKey))
                              .ForEach(_ =>
                              {
                                  if (_.Item1.GetDelegateSignature() != null)
                                  {
                                      if (_.Item2 is AmbiguousLambdaExpression)
                                      {
                                          var method = _.Item1.GetDelegateSignature();
                                          if (!method.ReturnType.Let(r =>
                                              (r.IsGenericParameter ? new [] { r, } : r.GetGenericArguments()).Let(ts => ts.All(map.ContainsKey))
                                          ))
                                          {
                                              method.GetParameters()
                                                  .Select(p => p.ParameterType.Let(t => t.IsGenericParameter
                                                      ? map.GetValue(t)
                                                      : t
                                                  ))
                                                  .If(ts => ts.All(t => t != null), ts =>
                                                      map = new TypeNode(method.ReturnType).Match(map, ((AmbiguousLambdaExpression) _.Item2)
                                                          .ApplyTypeArguments(ts)
                                                          .Type(symbols)
                                                          .GetDelegateSignature()
                                                          .ReturnType
                                                      )
                                                  );
                                          }
                                      }
                                      else if (_.Item2 is LambdaExpression)
                                      {
                                          map = new TypeNode(_.Item1).Match(map, _.Item2.Type.GetDelegateSignature().GetDelegateType());
                                      }
                                  }
                                  else if (_.Item1.ContainsGenericParameters)
                                  {
                                      (_.Item1.IsGenericParameter
                                          ? EnumerableEx.Return(Tuple.Create(_.Item1, _.Item2.Type))
                                          : _.Item1.GetAppearingTypes()
                                                .Zip(_.Item2.Type.GetCorrespondingType(_.Item1).GetAppearingTypes(), Tuple.Create)
                                                .Where(t => t.Item1.IsGenericParameter)
                                      ).ForEach(t => map = new TypeNode(t.Item1).Match(map, t.Item2));
                                  }
                              });
                          return map.Keys.All(typeArgumentMap.ContainsKey)
                              ? null
                              : this.InferTypeArguments(candidate, map, symbols);
                    }
                  });
        }