Skip to content

Implement Visitor pattern for Walkers and Re-writers #110

Description

@nathanwinder

I still need to think through some of this design, particularly the VisitChildren and RewriteChildren but I wanted to get this on your radar.

        public interface IVisitor
	{
		void DefaultVisit(IAcceptVisitor obj);
	}

	public interface IVisitor<TResult>
	{
		TResult DefaultVisit(IAcceptVisitor obj);
	}

	public interface IAcceptVisitor
	{
		void Accept(IVisitor visitor);

		TResult Accept<TResult>(IVisitor<TResult> visitor);

		void VisitChildren(IVisitor visitor);

	}

	public interface IAcceptRewriter<T,TResult>
	{
		T RewriteChildren(IVisitor<TResult> visitor);
	}

	public interface IPersonVisitor<TResult> : IVisitor<TResult>
	{
		TResult VisitPerson(Person node);
	}

	public interface IPersonVisitor : IVisitor
	{
		void VisitPerson(Person node);
	}

	public partial class Person
	{
		private readonly Person mother;
		private readonly Person father;
	}

	public partial class Person : IAcceptVisitor, IAcceptRewriter<Person, object>
	{
		[DebuggerStepThrough]
		public void Accept(IVisitor visitor)
		{
			if (visitor is IPersonVisitor personVisitor)
			{
				personVisitor.VisitPerson(this);
			}
			else
			{
				visitor.DefaultVisit(this);
			}
		}

		[DebuggerStepThrough]
		public T Accept<T>(IVisitor<T> visitor)
		{
			if (visitor is IPersonVisitor<T> personVisitor)
			{
				return personVisitor.VisitPerson(this);
			}
			else
			{
				return visitor.DefaultVisit(this);
			}
		}

		[DebuggerStepThrough]
		public void VisitChildren(IVisitor visitor)
		{
			mother.Accept(visitor);
			father.Accept(visitor);
		}

		[DebuggerStepThrough]
		public Person RewriteChildren(IVisitor<object> visitor)
		{
			var mother = (Person)this.mother.Accept(visitor);
			var father = (Person)this.father.Accept(visitor);
			return With(mother, father);
		}
	}

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions