/** * {@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 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 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(); } }