Пример #1
0
 public RelationsGetterVisitor(IClassVisitor cv, IEntityMetaData metaData, ValueHolderIEC valueHolderContainerHelper, IPropertyInfoProvider propertyInfoProvider)
     : base(cv)
 {
     this.metaData = metaData;
     this.valueHolderContainerHelper = valueHolderContainerHelper;
     this.propertyInfoProvider       = propertyInfoProvider;
 }
Пример #2
0
        protected FieldInstance GetInitializedFieldByPropertyName(String propertyName)
        {
            String fieldName = ValueHolderIEC.GetInitializedFieldName(propertyName);

            FieldInstance field = State.GetAlreadyImplementedField(fieldName);

            if (field == null)
            {
                field = new FieldInstance(FieldAttributes.Public, fieldName, typeof(ValueHolderState));
            }
            return(field);
        }
Пример #3
0
        public static FieldInstance GetInitializedField(String propertyName, bool expectExistance)
        {
            String        fieldName = ValueHolderIEC.GetInitializedFieldName(propertyName);
            FieldInstance field     = State.GetAlreadyImplementedField(fieldName);

            if (field == null && expectExistance)
            {
                throw new Exception("Field not defined in type hierarchy: " + State.NewType.ClassName + "."
                                    + fieldName);
            }
            return(field);
        }
Пример #4
0
        public void test_ValueHolderContainer_Embedded()
        {
            Material obj = EntityFactory.CreateEntity <Material>();

            // Test EmbMat.EmbMatType
            Assert.IsInstanceOfType(obj.EmbMat, typeof(IEmbeddedType));
            obj.EmbMat.Name = "Name2";
            Assert.AssertEquals("Name2", obj.EmbMat.Name);

            Assert.AssertEquals(0, ReflectUtil.GetDeclaredFieldInHierarchy(obj.GetType(), ValueHolderIEC.GetInitializedFieldName("EmbMat.EmbMatType")).Length);
            Assert.AssertEquals(1, ReflectUtil.GetDeclaredFieldInHierarchy(obj.EmbMat.GetType(), ValueHolderIEC.GetInitializedFieldName("EmbMatType")).Length);

            IObjRefContainer vhc = (IObjRefContainer)obj;

            IEntityMetaData metaData        = vhc.Get__EntityMetaData();
            int             embMatTypeIndex = metaData.GetIndexByRelationName("EmbMat.EmbMatType");

            Assert.AssertFalse(vhc.Is__Initialized(embMatTypeIndex));

            IObjRef[] emptyRefs = ObjRef.EMPTY_ARRAY;
            ((IObjRefContainer)obj).Set__ObjRefs(embMatTypeIndex, emptyRefs);
            IObjRef[] objRefs = vhc.Get__ObjRefs(embMatTypeIndex);
            Assert.AssertSame(emptyRefs, objRefs);

            Assert.AssertNull(obj.EmbMat.EmbMatType);
            Assert.AssertTrue(vhc.Is__Initialized(embMatTypeIndex));

            // Test EmbMat.EmbMat2.EmbMatType2
            Assert.IsInstanceOfType(obj.EmbMat.EmbMat2, typeof(IEmbeddedType));
            obj.EmbMat.EmbMat2.Name2 = "Name3";
            Assert.AssertEquals("Name3", obj.EmbMat.EmbMat2.Name2);

            Assert.AssertNull(obj.GetType().GetField(ValueHolderIEC.GetInitializedFieldName("EmbMat.EmbMat2.EmbMatType2")));
            Assert.AssertNull(obj.EmbMat.GetType().GetField(ValueHolderIEC.GetInitializedFieldName("EmbMat2.EmbMatType2")));
            Assert.AssertNotNull(obj.EmbMat.EmbMat2.GetType().GetField(ValueHolderIEC.GetInitializedFieldName("EmbMatType2")));

            embMatTypeIndex = metaData.GetIndexByRelationName("EmbMat.EmbMat2.EmbMatType2");

            Assert.AssertFalse(vhc.Is__Initialized(embMatTypeIndex));

            ((IObjRefContainer)obj).Set__ObjRefs(embMatTypeIndex, emptyRefs);
            objRefs = ((IObjRefContainer)obj).Get__ObjRefs(embMatTypeIndex);
            Assert.AssertSame(emptyRefs, objRefs);

            Assert.AssertNull(obj.EmbMat.EmbMat2.EmbMatType2);
            Assert.AssertTrue(vhc.Is__Initialized(embMatTypeIndex));

            // Test EmbMat3.EmbMatType
            Assert.IsInstanceOfType(obj.EmbMat3, typeof(IEmbeddedType));
        }
Пример #5
0
        /**
         * {@inheritDoc}
         */
        public override void VisitEnd()
        {
            FieldInstance    f_propertyChangeSupport  = GetPropertyChangeSupportField();
            PropertyInstance p_propertyChangeTemplate = GetPropertyChangeTemplatePI(this);

            ImplementPropertyChangeConfigurable();

            MethodInstance m_getPropertyChangeSupport = ImplementUsePropertyChangeSupport(p_propertyChangeTemplate, f_propertyChangeSupport);

            f_propertyChangeSupport = State.GetAlreadyImplementedField(f_propertyChangeSupport.Name);

            ImplementNotifyPropertyChanged(p_propertyChangeTemplate, m_getPropertyChangeSupport);

            MethodInstance m_firePropertyChange = ImplementFirePropertyChange(p_propertyChangeTemplate);

            ImplementNotifyPropertyChangedSource(p_propertyChangeTemplate, f_propertyChangeSupport);

            if (properties == null)
            {
                ImplementCollectionChanged(p_propertyChangeTemplate);
                ImplementPropertyChanged(p_propertyChangeTemplate);

                // handle all properties found
                IPropertyInfo[] props = PropertyInfoProvider.GetProperties(State.CurrentType);
                foreach (IPropertyInfo prop in props)
                {
                    if (prop.Name.EndsWith(ValueHolderIEC.GetNoInitSuffix()))
                    {
                        continue;
                    }
                    PropertyInstance propInfo = PropertyInstance.FindByTemplate(prop.Name, prop.PropertyType, true);
                    if (propInfo == null)
                    {
                        continue;
                    }
                    ImplementPropertyChangeOnProperty(propInfo, p_propertyChangeTemplate, m_firePropertyChange, f_propertyChangeSupport);
                }
            }
            else
            {
                foreach (String propertyName in properties)
                {
                    PropertyInstance propInfo = PropertyInstance.FindByTemplate(propertyName, (NewType)null, false);
                    ImplementPropertyChangeOnProperty(propInfo, p_propertyChangeTemplate, m_firePropertyChange, f_propertyChangeSupport);
                }
            }
            base.VisitEnd();
        }
Пример #6
0
        protected void ImplementRelationSetter(String propertyName, MethodInstance m_set_template, FieldInstance f_initialized, FieldInstance f_objRefs)
        {
            // public void setPropertyName(String propertyName)
            // {
            // PropertyName$initialized = true;
            // PropertyName$objRefs = null;
            // super.setPropertyName(propertyName);
            // }
            MethodInstance m_set;
            {
                IMethodVisitor mg = base.VisitMethod(m_set_template);
                m_set = mg.Method;
                mg.PutThisField(f_initialized, delegate(IMethodVisitor mv2)
                {
                    mg.PushEnum(ValueHolderState.INIT);
                });
                mg.PutThisField(f_objRefs, delegate(IMethodVisitor mv2)
                {
                    mv2.PushNull();
                });
                mg.LoadThis();
                mg.LoadArgs();
                mg.InvokeSuperOfCurrentMethod();
                mg.ReturnVoidOrThis();
                mg.EndMethod();
            }

            // public void setPropertyName$NoInit(String propertyName)
            // {
            // super.setPropertyName(propertyName);
            // }
            {
                String         noInitSetMethodName = ValueHolderIEC.GetSetterNameOfRelationPropertyWithNoInit(propertyName);
                IMethodVisitor mv = base.VisitMethod(m_set.Access, noInitSetMethodName, m_set.ReturnType, m_set.Parameters);
                mv.LoadThis();
                mv.LoadArgs();
                mv.InvokeSuper(m_set);
                mv.ReturnVoidOrThis();
                mv.EndMethod();
            }
        }
        protected override List <IMember> BuildMemberList()
        {
            List <IMember> list = new List <IMember>();

            if (_target == null)
            {
                return(list);
            }
            if (Context == null)
            {
                return(base.BuildMemberList());
            }
            IEntityMetaDataProvider entityMetaDataProvider = Context.GetService <IEntityMetaDataProvider>();

            Type            type     = _target.GetType();
            IEntityMetaData metaData = entityMetaDataProvider.GetMetaData(type, true);

            if (metaData == null)
            {
                return(base.BuildMemberList());
            }
            HashSet <String> suppressedPropertyNames = new HashSet <String>();

            foreach (RelationMember member in metaData.RelationMembers)
            {
                suppressedPropertyNames.Add(ValueHolderIEC.GetObjRefsFieldName(member.Name));
                suppressedPropertyNames.Add(ValueHolderIEC.GetInitializedFieldName(member.Name));
            }
            HashMap <String, RelationMember> nameToRelationMap = new HashMap <String, RelationMember>();

            foreach (RelationMember member in metaData.RelationMembers)
            {
                nameToRelationMap.Put(member.Name + ValueHolderIEC.GetNoInitSuffix(), member);
            }
            ITypeInfoItem[] members = Context.GetService <ITypeInfoProvider>().GetTypeInfo(type).Members;
            foreach (ITypeInfoItem member in members)
            {
                if (!member.CanRead)
                {
                    continue;
                }
                DebuggerBrowsableAttribute att = member.GetAnnotation <DebuggerBrowsableAttribute>();
                if (att != null && att.State == DebuggerBrowsableState.Never)
                {
                    continue;
                }
                String propertyName = member.Name;
                if (suppressedPropertyNames.Contains(propertyName))
                {
                    continue;
                }
                RelationMember relMember = nameToRelationMap.Get(propertyName);
                Object         value     = null;
                if (relMember != null)
                {
                    propertyName = relMember.Name;
                    int relationIndex      = metaData.GetIndexByRelationName(propertyName);
                    ValueHolderState state = ((IObjRefContainer)_target).Get__State(relationIndex);
                    if (!ValueHolderState.INIT.Equals(state))
                    {
                        IObjRef[] objRefs = ((IObjRefContainer)_target).Get__ObjRefs(relationIndex);
                        if (objRefs == null)
                        {
                            list.Add(new LazyUnknownMember(propertyName, state, member.RealType));
                        }
                        else
                        {
                            list.Add(new LazyMember(propertyName, state, objRefs, member.RealType));
                        }
                        continue;
                    }
                }
                if (value == null)
                {
                    try
                    {
                        value = member.GetValue(_target);
                    }
                    catch (Exception ex)
                    {
                        value = ex;
                    }
                }
                list.Add(new FHPMember(propertyName, value, member.RealType));
            }
            return(list.OrderBy(m => m.Name).ToList());
        }
Пример #8
0
            public PropertyEntry(Type type, String propertyName)
            {
                this.propertyName = propertyName;
                LinkedHashSet <String> propertyNames = new LinkedHashSet <String>();

                propertyNames.Add(propertyName);
                PropertyInfo prop = type.GetProperty(propertyName);

                doesModifyToBeUpdated        = !AnnotationUtil.IsAnnotationPresent <IgnoreToBeUpdated>(prop, false);
                isParentChildSetter          = AnnotationUtil.IsAnnotationPresent <ParentChild>(prop, false);
                isAddedRemovedCheckNecessary = !prop.PropertyType.IsPrimitive && ImmutableTypeSet.GetUnwrappedType(prop.PropertyType) == null &&
                                               !typeof(String).Equals(prop.PropertyType) && !prop.PropertyType.IsValueType;

                EvaluateDependentProperties(type, prop, propertyNames);

                while (true)
                {
                    int startCount = propertyNames.Count;

                    foreach (String currPropertyName in new List <String>(propertyNames))
                    {
                        PropertyInfo currProp = type.GetProperty(currPropertyName);
                        if (currProp.CanWrite)
                        {
                            continue;
                        }
                        // Is is just an evaluating property which has to be re-evaluated because of the change on the current property
                        EvaluateDependentProperties(type, currProp, propertyNames);
                    }
                    if (startCount == propertyNames.Count)
                    {
                        break;
                    }
                }
                this.propertyNames = propertyNames.ToArray();
                bool firesToBeCreatedPCE = false;

                unknownValues = CreateArrayOfValues(UNKNOWN_VALUE, this.propertyNames.Length);
                pceArgs       = new PropertyChangedEventArgs[propertyNames.Count];
                int index = 0;

                foreach (String invokedPropertyName in propertyNames)
                {
                    pceArgs[index] = new PropertyChangedEventArgs(invokedPropertyName);
                    index++;
                    firesToBeCreatedPCE |= "ToBeCreated".Equals(invokedPropertyName);
                }
                this.firesToBeCreatedPCE = firesToBeCreatedPCE;
                if (prop.CanRead)
                {
                    getDelegate = TypeUtility.GetMemberGetDelegate(type, ValueHolderIEC.GetGetterNameOfRelationPropertyWithNoInit(prop.Name), true);
                    if (getDelegate == null)
                    {
                        getDelegate = TypeUtility.GetMemberGetDelegate(type, prop.Name);
                    }
                }
                if (prop.CanWrite)
                {
                    setDelegate = TypeUtility.GetMemberSetDelegate(type, ValueHolderIEC.GetSetterNameOfRelationPropertyWithNoInit(prop.Name), true);
                    if (setDelegate == null)
                    {
                        setDelegate = TypeUtility.GetMemberSetDelegate(type, prop.Name);
                    }
                }
            }
Пример #9
0
 public static String GetGetterNameOfRelationPropertyWithNoInit(String propertyName)
 {
     return("get_" + propertyName + ValueHolderIEC.GetNoInitSuffix());
 }
Пример #10
0
        protected void ImplementPropertyChangeOnProperty(PropertyInstance propertyInfo,
                                                         PropertyInstance p_propertyChangeTemplate, MethodInstance m_firePropertyChange, FieldInstance f_propertyChangeSupport)
        {
            // add property change detection and notification
            if (propertyInfo.Getter == null || propertyInfo.Setter == null)
            {
                return;
            }
            if (InitializeEmbeddedMemberVisitor.IsEmbeddedMember(metaData, propertyInfo.Name))
            {
                return;
            }
            PropertyInstance p_getterMethodHandle = ImplementAssignedReadonlyProperty(propertyInfo.Name + "$MethodHandle",
                                                                                      new MethodHandleValueResolver(PropertyInfoProvider, propertyInfo.Name));
            Type           propertyType         = propertyInfo.PropertyType.Type;
            MethodInstance m_hasPropertyChanged = GetApplicableHasPropertyChangedOverload(propertyType);

            // check value type of last parameter
            bool isBoxingNeededForHasPropertyChanged = IsBoxingNeededForHasPropertyChangedOverload(m_hasPropertyChanged, propertyType);

            IMethodVisitor    mg              = VisitMethod(propertyInfo.Setter);
            Label             l_finish        = mg.NewLabel();
            Label             l_noOldValue    = mg.NewLabel();
            Label             l_noChangeCheck = mg.NewLabel();
            LocalVariableInfo loc_oldValue;

            if (isBoxingNeededForHasPropertyChanged)
            {
                loc_oldValue = mg.NewLocal(typeof(Object));
            }
            else
            {
                loc_oldValue = mg.NewLocal(propertyType);
            }
            LocalVariableInfo loc_valueChanged = mg.NewLocal <bool>();

            MethodInstance m_getSuper       = EnhancerUtil.GetSuperGetter(propertyInfo);
            bool           relationProperty = m_getSuper.Name.EndsWith(ValueHolderIEC.GetNoInitSuffix());

            // initialize flag with false
            mg.Push(false);
            mg.StoreLocal(loc_valueChanged);

            // initialize oldValue with null
            mg.PushNullOrZero(loc_oldValue.LocalType);
            mg.StoreLocal(loc_oldValue);

            if (relationProperty)
            {
                // check if a setter call to an UNINITIALIZED relation occured with value null
                // if it the case there would be no PCE because oldValue & newValue are both null
                // but we need a PCE in this special case
                Label         l_noSpecialHandling = mg.NewLabel();
                FieldInstance f_state             = State.GetAlreadyImplementedField(ValueHolderIEC.GetInitializedFieldName(propertyInfo.Name));
                mg.GetThisField(f_state);
                mg.PushEnum(ValueHolderState.INIT);
                mg.IfCmp(typeof(ValueHolderState), CompareOperator.EQ, l_noSpecialHandling);
                mg.Push(true);
                mg.StoreLocal(loc_valueChanged);
                mg.Mark(l_noSpecialHandling);
            }

            // check if value should be checked to decide for a PCE
            mg.LoadLocal(loc_valueChanged);
            mg.IfZCmp(CompareOperator.NE, l_noOldValue);

            // get old field value calling super property getter
            mg.LoadThis();
            mg.InvokeOnExactOwner(m_getSuper);
            if (isBoxingNeededForHasPropertyChanged)
            {
                mg.Box(propertyType);
            }
            mg.StoreLocal(loc_oldValue);

            mg.Mark(l_noOldValue);

            // set new field value calling super property setter
            mg.LoadThis();
            mg.LoadArg(0);
            mg.InvokeOnExactOwner(EnhancerUtil.GetSuperSetter(propertyInfo));
            mg.PopIfReturnValue(EnhancerUtil.GetSuperSetter(propertyInfo));

            // check if value should be checked to decide for a PCE
            mg.LoadLocal(loc_valueChanged);
            mg.IfZCmp(CompareOperator.NE, l_noChangeCheck);

            LocalVariableInfo loc_newValue = null;

            if (isBoxingNeededForHasPropertyChanged)
            {
                loc_newValue = mg.NewLocal(typeof(Object)); // loc_1  Object newValue
                // Object loc_1 = (Object)value;
                mg.LoadArg(0);
                mg.Box(propertyType);
                mg.StoreLocal(loc_newValue);
            }
            mg.CallThisGetter(p_propertyChangeTemplate);
            // call HasPropertyChanged (static)
            mg.LoadThis();              // "this" as Object obj
            mg.Push(propertyInfo.Name); // String propertyName
            mg.LoadLocal(loc_oldValue);
            if (loc_newValue != null)
            {
                mg.LoadLocal(loc_newValue);
            }
            else
            {
                mg.LoadArg(0);
            }
            mg.InvokeVirtual(m_hasPropertyChanged);
            //// if (!result)
            //// { return; }
            mg.IfZCmp(CompareOperator.EQ, l_finish);

            mg.Mark(l_noChangeCheck);
            // call firePropertyChange on this
            mg.LoadThis();
            // propertyChangeSupport
            mg.GetThisField(f_propertyChangeSupport);
            // property
            mg.CallThisGetter(p_getterMethodHandle);
            // oldValue
            mg.LoadLocal(loc_oldValue);
            if (!isBoxingNeededForHasPropertyChanged && propertyType.IsValueType)
            {
                // old value has not already been boxed but it is now necessary
                mg.ValueOf(propertyType);
            }
            // newValue
            if (loc_newValue != null)
            {
                mg.LoadLocal(loc_newValue);
            }
            else
            {
                mg.LoadArg(0);
                if (propertyType.IsValueType)
                {
                    mg.ValueOf(propertyType);
                }
            }
            // firePropertyChange(propertyChangeSupport, property, oldValue, newValue)
            mg.InvokeVirtual(m_firePropertyChange);

            // return
            mg.Mark(l_finish);
            mg.ReturnVoidOrThis();
            mg.EndMethod();
        }
Пример #11
0
        protected void ImplementRelationGetter(String propertyName, MethodInstance m_getMethod_template, MethodInstance m_setMethod, int relationIndex,
                                               PropertyInstance p_valueHolderContainerTemplate, PropertyInstance p_targetCache, PropertyInstance p_relationMembers, FieldInstance f_initialized,
                                               FieldInstance f_objRefs)
        {
            // public String getPropertyName()
            // {
            // if (!PropertyName$initialized)
            // {
            // setPropertyName(RelationsGetterVisitor.valueHolderContainer_getValue(this, $relationMembers, get__IndexOfPropertyName(), $targetCache, $beanContext,
            // propertyName$objRefs));
            // }
            // return super.getPropertyName();
            // }
            Script script_getVHC;

            if (EmbeddedEnhancementHint.HasMemberPath(State.Context))
            {
                PropertyInstance p_rootEntity = EmbeddedTypeVisitor.GetRootEntityProperty(this);
                script_getVHC = delegate(IMethodVisitor mv)
                {
                    mv.CallThisGetter(p_rootEntity);
                };
            }
            else
            {
                script_getVHC = delegate(IMethodVisitor mv)
                {
                    // this
                    mv.LoadThis();
                };
            }

            MethodInstance m_getMethod;
            {
                PropertyInstance p_cacheModification = SetCacheModificationMethodCreator.GetCacheModificationPI(this);
                MethodInstance   m_getMethod_scoped  = new MethodInstance(State.NewType,
                                                                          MethodAttributes.HideBySig | MethodAttributes.Private | MethodAttributes.Final, NewType.VOID_TYPE, propertyName + "$DoInitialize");
                {
                    IMethodVisitor mg = VisitMethod(m_getMethod_scoped);

                    // this => for this.setPropertyName(...)
                    mg.LoadThis();
                    // call template.getValue(..)
                    mg.CallThisGetter(p_valueHolderContainerTemplate);
                    // getVhc()
                    script_getVHC.Invoke(mg);
                    // $relationMembers
                    mg.CallThisGetter(p_relationMembers);
                    // get__IndexOfPropertyName()
                    mg.Push(relationIndex);
                    // $targetCache
                    mg.CallThisGetter(p_targetCache);
                    // propertyName$objRefs
                    mg.GetThisField(f_objRefs);
                    mg.InvokeVirtual(m_template_getValue);
                    mg.CheckCast(m_setMethod.Parameters[0].Type);
                    mg.InvokeVirtual(m_setMethod);
                    mg.ReturnValue();
                    mg.EndMethod();
                }
                {
                    IMethodVisitor mg = base.VisitMethod(m_getMethod_template);
                    m_getMethod = mg.Method;
                    HideFromDebug(m_getMethod);
                    Label l_initialized = mg.NewLabel();
                    mg.GetThisField(f_initialized);
                    mg.PushEnum(ValueHolderState.INIT);
                    mg.IfCmp(typeof(ValueHolderState), CompareOperator.EQ, l_initialized);

                    SetCacheModificationMethodCreator.CacheModificationInternalUpdate(p_cacheModification, mg,
                                                                                      delegate(IMethodVisitor mv2)
                    {
                        mv2.LoadThis();
                        mv2.InvokeOnExactOwner(m_getMethod_scoped);
                    });

                    mg.Mark(l_initialized);
                    mg.LoadThis();
                    mg.InvokeSuperOfCurrentMethod();
                    mg.ReturnValue();
                    mg.EndMethod();
                }
            }

            // public String getPropertyName$NoInit()
            // {
            // return super.getPropertyName();
            // }
            {
                MethodInstance   m_getNoInit = m_getMethod_template.DeriveName(ValueHolderIEC.GetGetterNameOfRelationPropertyWithNoInit(propertyName));
                IMethodVisitor   mg          = base.VisitMethod(m_getNoInit);
                PropertyInstance p_getNoInit = PropertyInstance.FindByTemplate(propertyName + ValueHolderIEC.GetNoInitSuffix(), m_getNoInit.ReturnType, false);
                p_getNoInit.AddAnnotation(c_fireThisOPC, propertyName);
                p_getNoInit.AddAnnotation(c_fireTargetOPC, propertyName);
                mg.LoadThis();
                mg.InvokeSuper(m_getMethod);
                mg.ReturnValue();
                mg.EndMethod();
            }
        }
Пример #12
0
 public ValueHolderContainerEntryValueResolver(ValueHolderIEC valueHolderContainerHelper)
 {
     this.valueHolderContainerHelper = valueHolderContainerHelper;
 }
Пример #13
0
        protected void ImplementConstructors()
        {
            if (metaData.RelationMembers.Length == 0)
            {
                return;
            }
            RelationMember[]       relationMembers = metaData.RelationMembers;
            List <FieldInstance[]> fieldsList      = new List <FieldInstance[]>();

            for (int a = relationMembers.Length; a-- > 0;)
            {
                RelationMember relationMember = relationMembers[a];
                relationMember = (RelationMember)GetApplicableMember(relationMember);
                if (relationMember == null)
                {
                    // member is handled in another type
                    continue;
                }
                String        propertyName = relationMember.Name;
                String        fieldName    = ValueHolderIEC.GetObjRefsFieldName(propertyName);
                FieldInstance field        = State.GetAlreadyImplementedField(fieldName);

                String        fieldName2 = ValueHolderIEC.GetInitializedFieldName(propertyName);
                FieldInstance field2     = State.GetAlreadyImplementedField(fieldName2);

                fieldsList.Add(new FieldInstance[] { field, field2 });
            }
            if (fieldsList.Count == 0)
            {
                return;
            }
            PropertyInstance p_emptyRelations = ImplementAssignedReadonlyProperty("EmptyRelations", ObjRef.EMPTY_ARRAY);

            OverrideConstructors(delegate(IClassVisitor cv, ConstructorInstance superConstructor)
            {
                IMethodVisitor mv = cv.VisitMethod(superConstructor);
                mv.LoadThis();
                mv.LoadArgs();
                mv.InvokeSuperOfCurrentMethod();

                LocalVariableInfo loc_emptyRelations = mv.NewLocal <IObjRef[]>();
                LocalVariableInfo loc_lazyState      = mv.NewLocal <ValueHolderState>();
                mv.CallThisGetter(p_emptyRelations);
                mv.StoreLocal(loc_emptyRelations);
                mv.PushEnum(ValueHolderState.LAZY);
                mv.StoreLocal(loc_lazyState);
                foreach (FieldInstance[] fields in fieldsList)
                {
                    mv.PutThisField(fields[0], delegate(IMethodVisitor mv2)
                    {
                        mv2.LoadLocal(loc_emptyRelations);
                    });
                    mv.PutThisField(fields[1], delegate(IMethodVisitor mv2)
                    {
                        mv2.LoadLocal(loc_lazyState);
                    });
                }
                mv.ReturnValue();
                mv.EndMethod();
            });
        }