private void GenerateValueMemberBlock(TypeToken typeToken, IMethodBlock memberAccess, Method.BlockCollection block)
        {
            var instanceInitializer        = CreateInstanceInitializer(typeToken, memberAccess);
            var defaultInstanceInitializer = instanceInitializer == default(IMethodBlock);

            if (defaultInstanceInitializer && typeToken.IsClass)
            {
                instanceInitializer = new Method.Assignment(memberAccess, typeToken.NewExpression().ToMethodBlock());
            }

            if (instanceInitializer != default)
            {
                block.Children.Add(instanceInitializer);
            }

            if (!defaultInstanceInitializer)
            {
                return;
            }

            foreach (var subMemberToken in MemberProvider(typeToken))
            {
                GenerateMemberBlock(subMemberToken, memberAccess, block);
            }
        }
Пример #2
0
        public virtual Expression ToExpression()
        {
            var blockBody = new List <Expression>();

            // AccessExpression is null on the root node (It's a dummy node)
            // ReadExpression.Count > 1 can only happen if we decided to roll a loop, in which case all elements are identical.
            // ReadExpression.Count = 0 can happen if the type is a value type. Otherwise this is new T[...] or new T().
            if (AccessExpression != null)
            {
                if (ReadExpression.Count > 0)
                {
                    blockBody.Add(Expression.Assign(AccessExpression, ReadExpression[0]));
                }
                else if (TypeToken.IsArray)
                {
                    blockBody.Add(Expression.Assign(AccessExpression,
                                                    TypeToken.GetElementTypeToken().NewArrayBounds(Expression.Constant(MemberToken.Cardinality))));
                }
                else if (TypeToken.IsClass)
                {
                    if (!TypeToken.HasDefaultConstructor)
                    {
                        throw new InvalidOperationException("Missing default constructor for " + TypeToken.Name);
                    }

                    blockBody.Add(Expression.Assign(AccessExpression, TypeToken.NewExpression()));
                }
            }

            if (Children.Count > 0)
            {
                // Produce children if there are any
                foreach (var child in Children)
                {
                    blockBody.Add(child.ToExpression());
                }

                // Assert that there is at least one node in the block emitted.
                if (blockBody.Count == 0)
                {
                    throw new InvalidOperationException("Empty block");
                }
            }

            // We allow empty blocks if there are no children for primitive types
            if (blockBody.Count == 0)
            {
                return(Expression.Empty());
            }

            // If there's only one expression, just return it.
            if (blockBody.Count == 1)
            {
                return(blockBody[0]);
            }

            return(Expression.Block(blockBody));
        }