예제 #1
0
        public IExpression DetachFieldInitialization()
        {
            if (this.InitValue.IsUndef())
            {
                return(null);
            }

            if (this.InitValue == null)
            {
                // we need to save it for later to change the errors, user does not see this call, but she/he
                // sees the field
                this.autoFieldDefaultInit = FunctionCall.Constructor(NameReference.Create(fieldReference(),
                                                                                          NameFactory.InitConstructorName));
                return(this.autoFieldDefaultInit);
            }
            else if (!this.InitValue.IsUndef())
            {
                this.initValue.DetachFrom(this);

                IExpression init;

                // if the init value is constructor call, there is no point in creating around it
                // another constructor call. Instead get the init step and reuse it, this time
                // with given field directly, for example
                // x = Foo()
                // translates to
                // x = (__this__ = alloc Foo ; __this__.init() ; __this__)
                // so we rip off the init step and replace the object, which results in
                // x.init()
                if (this.initValue is New block
                    // do not use this optimization for heap objects!
                    && !block.IsHeapInitialization)
                {
                    FunctionCall cons_call = block.InitConstructorCall;
                    cons_call.DetachFrom(block);

                    cons_call.Name.ReplacePrefix(fieldReference());
                    init = cons_call;
                }
                else
                {
                    init = Assignment.CreateStatement(fieldReference(), this.initValue);
                }

                this.initValue = null;
                return(init);
            }