using System; using System.CodeDom; using System.Linq; using Chernobyl.Event; namespace Chernobyl.Reflection.Template.CodeDom { /// /// An that can take any /// instance that represents a property and generate CodeDom for it. /// public abstract class CodeDomAssignableMember : CodeDomMember { /// /// Initializes a new instance of the class. /// /// The instance to /// generate CodeDom for and provide the /// implementation for this class. protected CodeDomAssignableMember(IMember member) : base(member) { } /// /// The that is the parent to this /// . This will be /// added to the parent 's /// list. If this /// is already a child to another /// then it will be removed from that /// 's /// list. Setting null on this property will cause this /// to be removed from it's parent, if necessary. /// public override IComponent Parent { get { return base.Parent; } set { if (base.Parent != value) { base.Parent = value; if (base.Parent == value) Configure(); } } } /// /// An event handler that is invoked right after an argument /// s are added to the /// list. /// /// The instance that generated the event. /// The instance /// containing the event data. protected override void ArgumentExpressionAdded(object sender, ItemsEventArgs e) { if (MemberSetStatement != null || e.Items.Length > 1) throw new Exception("Unable to add new argument expression. This member only supports one argument."); _argument = e.Items.First(); Configure(); base.ArgumentExpressionAdded(sender, e); } /// /// An event handler that is invoked right after an argument /// s are removed from the /// list. /// /// The instance that generated the event. /// The instance /// containing the event data. protected override void ArgumentExpressionRemoved(object sender, ItemsEventArgs e) { InitializeMethod.Statements.Remove(MemberSetStatement); MemberSetStatement = null; _argument = null; base.ArgumentExpressionRemoved(sender, e); } /// /// Initializes the . Note to /// implementers: Base classes should invoke the base class /// method when their /// is initialized. /// protected virtual void Configure() { if(MemberSetStatement == null) { MemberSetStatement = new CodeAssignStatement(); InitializeMethod.Statements.Add(MemberSetStatement); } if (MemberSetStatement.Left == null && AssignableMemberReference != null) MemberSetStatement.Left = AssignableMemberReference; if (MemberSetStatement.Right == null && _argument != null) { MemberSetStatement.Right = _argument; // we don't need the argument variable anymore _argument = null; } } /// /// The reference to the assignable member as a code expression or null /// if it has not yet been set up. This reference will be used to /// generate code that can set the member. /// public abstract CodeExpression AssignableMemberReference { get; } /// /// The that represents the setting of the /// member or null if this hasn't been /// created yet because an argument hasn't been added. /// CodeAssignStatement MemberSetStatement { get; set; } /// /// The that represents the argument that /// is set on this member or null if the argument has not been added, /// it was removed, or it was finally set onto the /// 's /// property. /// CodeExpression _argument; } }