public RelationsGetterVisitor(IClassVisitor cv, IEntityMetaData metaData, ValueHolderIEC valueHolderContainerHelper, IPropertyInfoProvider propertyInfoProvider) : base(cv) { this.metaData = metaData; this.valueHolderContainerHelper = valueHolderContainerHelper; this.propertyInfoProvider = propertyInfoProvider; }
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); }
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); }
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)); }
/** * {@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(); }
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()); }
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); } } }
public static String GetGetterNameOfRelationPropertyWithNoInit(String propertyName) { return("get_" + propertyName + ValueHolderIEC.GetNoInitSuffix()); }
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(); }
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(); } }
public ValueHolderContainerEntryValueResolver(ValueHolderIEC valueHolderContainerHelper) { this.valueHolderContainerHelper = valueHolderContainerHelper; }
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(); }); }