/// <summary>
        /// Adds an implementation of the INotifyPropertyChanged interface to the given type.
        /// </summary>
        /// <param name="type">The type declaration</param>
        /// <returns>Type with INotifyPropertyChanged implemented.</returns>
        protected CodeTypeDeclaration ImplementINotifyPropertyChanged(CodeTypeDeclaration type)
        {
            //// This method will implement the INotifyPropertyChanged interface 
            //// Here's an example :
            //// public class Customer :INotifyPropertyChanged {
            ////      public PropertyChangedEventHandler PropertyChanged;
            ////      public void RaisePropertyChanged(string propertyName) {
            ////          if( this.PropertyChanged !=null ) {
            ////              this.PropertyChanged (this, new PropertyChangedEventArgs( propertyName ) );
            ////          }
            ////      }
            //// }
            CodeThisReferenceExpression thisReference = new CodeThisReferenceExpression();
            CodeTypeReference notifyPropertyChanged = Code.TypeRef(typeof(INotifyPropertyChanged));

            // Add the implements INotifyPropertyChanged statement
            // public class Customer :INotifyPropertyChanged {
            type.BaseTypes.Add(notifyPropertyChanged);

            // Add the PropertyChanged event as a field to the type
            // public PropertyChangedEventHandler PropertyChanged;
            CodeMemberEvent propertyChangedEvent = type.AddEvent(Code.TypeRef(typeof(PropertyChangedEventHandler)), "PropertyChanged");
            propertyChangedEvent.ImplementationTypes.Add(notifyPropertyChanged);

            // this.PropertyChanged
            CodeEventReferenceExpression eventFieldReference = new CodeEventReferenceExpression(thisReference, "PropertyChanged");

            // Add the RaisePropertyChanged Method which will invoke the PropertyChanged handler whenever a property value changes
            // if( this.PropertyChanged !=null )
            CodeConditionStatement invokeEventHandlersIfAny = new CodeConditionStatement(new CodeBinaryOperatorExpression(eventFieldReference, CodeBinaryOperatorType.IdentityInequality, new CodePrimitiveExpression(null)));

            // this.PropertyChanged (this, new PropertyChangedEventArgs( propertyName ) );
            invokeEventHandlersIfAny.TrueStatements.Add(
                new CodeDelegateInvokeExpression(eventFieldReference, new CodeExpression[] { thisReference, new CodeObjectCreateExpression("PropertyChangedEventArgs", new CodeArgumentReferenceExpression("propertyName")) }));

            // public void RaisePropertyChanged
            CodeMemberMethod method = type.AddMethod("RaisePropertyChanged", MemberAttributes.Public);

            method.Parameters.Add(new CodeParameterDeclarationExpression("System.String", "propertyName"));

            ////      public void RaisePropertyChanged(string propertyName) {
            ////          if( this.PropertyChanged !=null ) {
            ////              this.PropertyChanged (this, new PropertyChangedEventArgs( propertyName ) );
            ////          }
            ////      }
            method.Statements.Add(invokeEventHandlersIfAny);
            return type;
        }
Example #2
0
		static CodeTypeDeclaration CreateNotImplementedAstVisitorClass(List<Type> nodeTypes)
		{
			CodeTypeDeclaration td = new CodeTypeDeclaration("NotImplementedAstVisitor");
			td.TypeAttributes = TypeAttributes.Public | TypeAttributes.Class;
			td.BaseTypes.Add(new CodeTypeReference("IAstVisitor"));
			
			string comment = "<summary>\n " +
				"IAstVisitor implementation that always throws NotImplementedExceptions.\n " +
				"</summary>";
			td.Comments.Add(new CodeCommentStatement(comment, true));
			
			foreach (Type type in nodeTypes) {
				if (!type.IsAbstract) {
					
					EasyMethod m = td.AddMethod(typeof(object), VisitPrefix + type.Name);
					m.Attributes = MemberAttributes.Public;
					m.AddParameter(ConvertType(type), GetFieldName(type.Name));
					m.AddParameter(new CodeTypeReference(typeof(object)), "data");
					
					m.Body.Throw(Easy.New(typeof(NotImplementedException), Easy.Prim(type.Name)));
				}
			}
			
			return td;
		}
Example #3
0
		static CodeTypeDeclaration CreateNodeTrackingAstVisitorClass(List<Type> nodeTypes)
		{
			CodeTypeDeclaration td = new CodeTypeDeclaration("NodeTrackingAstVisitor");
			td.TypeAttributes = TypeAttributes.Public | TypeAttributes.Class | TypeAttributes.Abstract;
			td.BaseTypes.Add(new CodeTypeReference("AbstractAstVisitor"));
			
			string comment = "<summary>\n " +
				"The NodeTrackingAstVisitor will iterate through the whole Ast,\n " +
				"just like the AbstractAstVisitor, and calls the virtual methods\n " +
				"BeginVisit and EndVisit for each node being visited.\n " +
				"</summary>";
			td.Comments.Add(new CodeCommentStatement(comment, true));
			comment = "<remarks>\n " +
				"base.Visit(node, data) calls this.TrackedVisit(node, data), so if\n " +
				"you want to visit child nodes using the default visiting behaviour,\n " +
				"use base.TrackedVisit(parentNode, data).\n " +
				"</remarks>";
			td.Comments.Add(new CodeCommentStatement(comment, true));
			
			EasyMethod m = td.AddMethod("BeginVisit");
			m.Attributes = MemberAttributes.Family;
			m.AddParameter(Easy.TypeRef("INode"), "node");
			
			m = td.AddMethod("EndVisit");
			m.Attributes = MemberAttributes.Family;
			m.AddParameter(Easy.TypeRef("INode"), "node");
			
			foreach (Type type in nodeTypes) {
				if (!type.IsAbstract) {
					
					m = td.AddMethod(typeof(object), VisitPrefix + type.Name);
					m.Attributes = MemberAttributes.Public | MemberAttributes.Override;
					m.AddParameter(ConvertType(type), GetFieldName(type.Name));
					m.AddParameter(new CodeTypeReference(typeof(object)), "data");
					
					CodeExpression var = Easy.Var(GetFieldName(type.Name));
					
					m.Body.InvokeMethod(Easy.This, "BeginVisit", var);
					m.Body.DeclareVariable(typeof(object), "result").InitExpression
						= Easy.This.InvokeMethod("TrackedVisit" + type.Name, var, Easy.Var("data"));
					m.Body.InvokeMethod(Easy.This, "EndVisit", var);
					m.Body.Return(Easy.Var("result"));
				}
			}
			
			foreach (Type type in nodeTypes) {
				if (!type.IsAbstract) {
					
					m = td.AddMethod(typeof(object), "TrackedVisit" + type.Name);
					m.Attributes = MemberAttributes.Public;
					m.AddParameter(ConvertType(type), GetFieldName(type.Name));
					m.AddParameter(new CodeTypeReference(typeof(object)), "data");
					
					m.Body.Return(Easy.Base.InvokeMethod(VisitPrefix + type.Name, Easy.Var(GetFieldName(type.Name)), Easy.Var("data")));
				}
			}
			
			return td;
		}
Example #4
0
		static CodeTypeDeclaration CreateAstVisitorClass(List<Type> nodeTypes, bool transformer)
		{
			CodeTypeDeclaration td = new CodeTypeDeclaration(transformer ? "AbstractAstTransformer" : "AbstractAstVisitor");
			td.TypeAttributes = TypeAttributes.Public | TypeAttributes.Abstract;
			td.BaseTypes.Add(new CodeTypeReference("IAstVisitor"));
			
			if (transformer) {
				string comment =
					"The AbstractAstTransformer will iterate through the whole Ast,\n " +
					"just like the AbstractAstVisitor. However, the AbstractAstTransformer allows\n " +
					"you to modify the Ast at the same time: It does not use 'foreach' internally,\n " +
					"so you can add members to collections of parents of the current node (but\n " +
					"you cannot insert or delete items as that will make the index used invalid).\n " +
					"You can use the methods ReplaceCurrentNode and RemoveCurrentNode to replace\n " +
					"or remove the current node, totally independent from the type of the parent node.";
				Easy.AddSummary(td, comment);
				
				CodeMemberField field = td.AddField(Easy.TypeRef("Stack", "INode"), "nodeStack");
				field.InitExpression = Easy.New(field.Type);
				
				/*
				CodeExpression nodeStack = Easy.Var("nodeStack");
				CodeMemberProperty p = new CodeMemberProperty();
				p.Name = "CurrentNode";
				p.Type = new CodeTypeReference("INode");
				p.Attributes = MemberAttributes.Public | MemberAttributes.Final;
				p.GetStatements.Add(new CodeMethodReturnStatement(new CodeVariableReferenceExpression("currentNode")));
				p.SetStatements.Add(new CodeAssignStatement(new CodeVariableReferenceExpression("currentNode"),
				                                            new CodePropertySetValueReferenceExpression()));
				td.Members.Add(p);
				 */
				
				EasyMethod m = td.AddMethod("ReplaceCurrentNode");
				m.AddParameter(Easy.TypeRef("INode"), "newNode");
				m.Statements.Add(Easy.Var("nodeStack").InvokeMethod("Pop"));
				m.Statements.Add(Easy.Var("nodeStack").InvokeMethod("Push", Easy.Var("newNode")));
				
				m = td.AddMethod("RemoveCurrentNode");
				m.Statements.Add(Easy.Var("nodeStack").InvokeMethod("Pop"));
				m.Statements.Add(Easy.Var("nodeStack").InvokeMethod("Push", Easy.Null));
			}
			
			foreach (Type type in nodeTypes) {
				if (!type.IsAbstract) {
					EasyMethod m = td.AddMethod(typeof(object), VisitPrefix + type.Name);
					m.Attributes = MemberAttributes.Public;
					m.AddParameter(ConvertType(type), GetFieldName(type.Name));
					m.AddParameter(typeof(object), "data");
					
					List<CodeStatement> assertions = new List<CodeStatement>();
					string varVariableName = GetFieldName(type.Name);
					CodeExpression var = Easy.Var(varVariableName);
					assertions.Add(AssertIsNotNull(var));
					
					AddFieldVisitCode(m, type, var, assertions, transformer);
					
					if (type.GetCustomAttributes(typeof(HasChildrenAttribute), true).Length > 0) {
						if (transformer) {
							m.Statements.Add(new CodeSnippetStatement(CreateTransformerLoop(varVariableName + ".Children", "INode")));
							m.Body.Return(Easy.Null);
						} else {
							m.Body.Return(var.InvokeMethod("AcceptChildren", Easy.This, Easy.Var("data")));
						}
					} else {
						CodeExpressionStatement lastStatement = null;
						if (m.Statements.Count > 0) {
							lastStatement = m.Statements[m.Statements.Count - 1] as CodeExpressionStatement;
						}
						if (lastStatement != null) {
							m.Statements.RemoveAt(m.Statements.Count - 1);
							m.Body.Return(lastStatement.Expression);
						} else {
							m.Body.Return(Easy.Null);
						}
					}
					
					for (int i = 0; i < assertions.Count; i++) {
						m.Statements.Insert(i, assertions[i]);
					}
				}
			}
			return td;
		}
Example #5
0
		static CodeTypeDeclaration CreateAstVisitorInterface(List<Type> nodeTypes)
		{
			CodeTypeDeclaration td = new CodeTypeDeclaration("IAstVisitor");
			td.IsInterface = true;
			
			foreach (Type t in nodeTypes) {
				if (!t.IsAbstract) {
					EasyMethod m = td.AddMethod(typeof(object), VisitPrefix + t.Name);
					m.AddParameter(ConvertType(t), GetFieldName(t.Name));
					m.AddParameter(typeof(object), "data");
				}
			}
			return td;
		}
Example #6
0
        static CodeTypeDeclaration CreateAstComparisonVisitorClass(List<Type> nodeTypes)
        {
            CodeTypeDeclaration td = new CodeTypeDeclaration("AstComparisonVisitor");
            td.TypeAttributes = TypeAttributes.Public;
            td.IsPartial = true;

            //td.BaseTypes.Add(new CodeTypeReference("IAstVisitor"));

            foreach (Type type in nodeTypes)
            {
                if (!type.IsAbstract)
                {
                    EasyMethod m = td.AddMethod(typeof(bool), VisitPrefix + type.Name);
                    m.Attributes = MemberAttributes.Public;
                    m.AddParameter(ConvertType(type), GetFieldName(type.Name));
                    const string right_hand_side_name = "d";
                    m.AddParameter(typeof(object), right_hand_side_name);

                    List<CodeStatement> assertions = new List<CodeStatement>();
                    string varVariableName = GetFieldName(type.Name);
                    CodeExpression var = Easy.Var(varVariableName);
                    assertions.Add(IfNullSetFailure(var));

                    if (varVariableName == "using")
                        varVariableName = "@using";

                    CodeExpression r_var = Easy.Var(right_hand_side_name);
                    assertions.Add(IfNullSetFailure(r_var));

                    // Confirm their types are the same.
                    m.Statements.Add(new CodeSnippetStatement("\t\t\tif(" + varVariableName + ".GetType() != " + right_hand_side_name + ".GetType()) {return SetFailure();}"));

                    // Cast the object parameter to whatever the other parameter is, and call the variable 'data'.
                    // Like so: AddHandlerStatement data = (AddHandlerStatement) d;
                    m.Statements.Add(new CodeSnippetStatement("\t\t\tvar data = (" + ConvertType(type).BaseType + ")d;"));

                    m.Statements.Add(new CodeConditionStatement(new CodeSnippetExpression("!IsMatch(" + varVariableName + ", data)"),
                                                                new CodeSnippetStatement("\t\t\t\treturn SetFailure();")));

                    AddFieldVisitCode(m, type, var, assertions, false);

                    if (type.GetCustomAttributes(typeof(HasChildrenAttribute), true).Length > 0)
                    {
                        m.Body.Return(var.InvokeMethod("AcceptChildren", Easy.This, Easy.Var(right_hand_side_name)));
                    }
                    else
                    {
                        CodeExpressionStatement lastStatement = null;
                        if (m.Statements.Count > 0)
                        {
                            lastStatement = m.Statements[m.Statements.Count - 1] as CodeExpressionStatement;
                        }
                        if (lastStatement != null)
                        {
                            m.Statements.RemoveAt(m.Statements.Count - 1);
                            m.Body.Return(lastStatement.Expression);
                        }
                        else
                        {
                            m.Body.Return(new CodeSnippetExpression("true"));
                        }
                    }

                    for (int i = 0; i < assertions.Count; i++)
                    {
                        m.Statements.Insert(i, assertions[i]);
                    }
                }
            }
            return td;
        }