Example #1
0
        public void WriteExpressions(LambdaDefinition definition)
        {
            // No next, not disposable

            var isDisposed = BuiltType.CanBeCastTo <IDisposable>() ||
                             BuiltType.CanBeCastTo <IAsyncDisposable>();

            var callCtor = Expression.New(Ctor, Parameters.Select(definition.ExpressionFor));

            if (Next == null && !isDisposed && !Setters.Any())
            {
                definition.Body.Add(callCtor);
            }
            else
            {
                var variableExpr = Expression.Parameter(BuiltType, Variable.Usage);
                definition.RegisterExpression(Variable, variableExpr);
                definition.Assign(variableExpr, callCtor);

                foreach (var setter in Setters)
                {
                    var setMethod = BuiltType.GetProperty(setter.PropertyName).SetMethod;

                    var value = definition.ExpressionFor(setter.Variable);
                    var call  = Expression.Call(variableExpr, setMethod, value);
                    definition.Body.Add(call);
                }

                if (isDisposed)
                {
                    definition.RegisterDisposable(variableExpr, Variable.VariableType);
                }

                if (Next == null)
                {
                    definition.Body.Add(definition.ExpressionFor(Variable));
                }
                else
                {
                    if (Next is IResolverFrame next)
                    {
                        next.WriteExpressions(definition);
                    }
                    else
                    {
                        throw new InvalidCastException($"{Next.GetType().GetFullName()} does not implement {nameof(IResolverFrame)}");
                    }
                }
            }
        }