public void TestIndentClassBody ()
		{
			TextEditorData data = new TextEditorData ();
			data.Document.FileName = "a.cs";
			data.Document.Text = 
@"class Test
{
				Test a;
}";
			
			CSharpFormattingPolicy policy = new CSharpFormattingPolicy ();
			policy.IndentClassBody = true;
			
			CSharp.Dom.CompilationUnit compilationUnit = new CSharpParser ().Parse (data);
			compilationUnit.AcceptVisitor (new DomIndentationVisitor (policy, data), null);
			Assert.AreEqual (@"class Test
{
	Test a;
}", data.Document.Text);
			policy.IndentClassBody = false;
			compilationUnit = new CSharpParser ().Parse (data);
			compilationUnit.AcceptVisitor (new DomIndentationVisitor (policy, data), null);
			Assert.AreEqual (@"class Test
{
Test a;
}", data.Document.Text);
		}
		public void TestNamespaceBraceStyle ()
		{
			TextEditorData data = new TextEditorData ();
			data.Document.FileName = "a.cs";
			data.Document.Text = @"namespace A
{
namespace B {
	class Test {}
}
}";
			
			CSharpFormattingPolicy policy = new CSharpFormattingPolicy ();
			policy.NamespaceBraceStyle = BraceStyle.EndOfLine;
			policy.ClassBraceStyle = BraceStyle.DoNotChange;
			
			CSharp.Dom.CompilationUnit compilationUnit = new CSharpParser ().Parse (data);
			compilationUnit.AcceptVisitor (new DomIndentationVisitor (policy, data), null);
			Assert.AreEqual (@"namespace A {
	namespace B {
		class Test {}
	}
}", data.Document.Text);
			
			policy.NamespaceBraceStyle = BraceStyle.NextLineShifted;
			compilationUnit = new CSharpParser ().Parse (data);
			compilationUnit.AcceptVisitor (new DomIndentationVisitor (policy, data), null);
			Assert.AreEqual (@"namespace A
	{
	namespace B
		{
		class Test {}
		}
	}", data.Document.Text);
		}
		public void TestBlankLinesAfterUsings ()
		{
			TextEditorData data = new TextEditorData ();
			data.Document.FileName = "a.cs";
			data.Document.Text = @"using System;
using System.Text;
namespace Test
{
}";
			
			CSharpFormattingPolicy policy = new CSharpFormattingPolicy ();
			policy.BlankLinesAfterUsings = 2;
			var compilationUnit = new CSharpParser ().Parse (data);
			compilationUnit.AcceptVisitor (new AstIndentationVisitor (policy, data), null);
			Assert.AreEqual (@"using System;
using System.Text;


namespace Test
{
}", data.Document.Text);
			
		policy.BlankLinesAfterUsings = 0;
		compilationUnit = new CSharpParser ().Parse (data);
		compilationUnit.AcceptVisitor (new AstIndentationVisitor (policy, data), null);
		Assert.AreEqual (@"using System;
using System.Text;
namespace Test
{
}", data.Document.Text);
		}
		public void TestClassIndentation ()
		{
			TextEditorData data = new TextEditorData ();
			data.Document.FileName = "a.cs";
			data.Document.Text = 
@"			class Test {}";
			
			CSharpFormattingPolicy policy = new CSharpFormattingPolicy ();
			policy.ClassBraceStyle = BraceStyle.DoNotChange;
			
			var compilationUnit = new CSharpParser ().Parse (data);
			compilationUnit.AcceptVisitor (new AstIndentationVisitor (policy, data), null);
			Assert.AreEqual (@"class Test {}", data.Document.Text);
		}
Beispiel #5
0
		public static void Format (TextEditorData data, ProjectDom dom)
		{
			CSharp.Dom.CompilationUnit compilationUnit = new MonoDevelop.CSharp.Parser.CSharpParser ().Parse (data);
			IEnumerable<string> types = DesktopService.GetMimeTypeInheritanceChain (CSharpFormatter.MimeType);
			CSharpFormattingPolicy policy = dom.Project.Policies != null ? dom.Project.Policies.Get<CSharpFormattingPolicy> (types) : MonoDevelop.Projects.Policies.PolicyService.GetDefaultPolicy<CSharpFormattingPolicy> (types);
			DomSpacingVisitor domSpacingVisitor = new DomSpacingVisitor (policy, data);
			domSpacingVisitor.AutoAcceptChanges = false;
			compilationUnit.AcceptVisitor (domSpacingVisitor, null);
			
			DomIndentationVisitor domIndentationVisitor = new DomIndentationVisitor (policy, data);
			domIndentationVisitor.AutoAcceptChanges = false;
			compilationUnit.AcceptVisitor (domIndentationVisitor, null);
			
			List<Change> changes = new List<Change> ();
			changes.AddRange (domSpacingVisitor.Changes);
			changes.AddRange (domIndentationVisitor.Changes);
			RefactoringService.AcceptChanges (null, null, changes);
		}
		public void TestFieldSpacesBeforeComma2 ()
		{
			TextEditorData data = new TextEditorData ();
			data.Document.FileName = "a.cs";
			data.Document.Text = @"class Test {
	int a           ,                   b,          c;
}";
			
			CSharpFormattingPolicy policy = new CSharpFormattingPolicy ();
			policy.ClassBraceStyle =  BraceStyle.EndOfLine;
			policy.BeforeFieldDeclarationComma = true;
			policy.AfterFieldDeclarationComma = true;
			
			var compilationUnit = new CSharpParser ().Parse (data);
			compilationUnit.AcceptVisitor (new AstSpacingVisitor (policy, data), null);
			Assert.AreEqual (@"class Test {
	int a , b , c;
}", data.Document.Text);
		}
		public static void Format (PolicyContainer policyParent, IEnumerable<string> mimeTypeChain,
			TextEditorData data, ProjectDom dom, DomLocation location, bool correctBlankLines)
		{
			var compilationUnit = new MonoDevelop.CSharp.Parser.CSharpParser ().Parse (data);
			var policy = policyParent.Get<CSharpFormattingPolicy> (mimeTypeChain);
			var domSpacingVisitor = new DomSpacingVisitor (policy, data) {
				AutoAcceptChanges = false,
			};
			compilationUnit.AcceptVisitor (domSpacingVisitor, null);
			
			var domIndentationVisitor = new DomIndentationVisitor (policy, data) {
				AutoAcceptChanges = false,
			};
			domIndentationVisitor.CorrectBlankLines = correctBlankLines;
			compilationUnit.AcceptVisitor (domIndentationVisitor, null);
			
			var changes = new List<Change> ();
			changes.AddRange (domSpacingVisitor.Changes);
			changes.AddRange (domIndentationVisitor.Changes);
			RefactoringService.AcceptChanges (null, null, changes);
		}
		public void TestInvocationIndentation ()
		{
			TextEditorData data = new TextEditorData ();
			data.Document.FileName = "a.cs";
			data.Document.Text = @"class Test {
	Test TestMethod ()
	{
this.TestMethod ();
	}
}";
			
			CSharpFormattingPolicy policy = new CSharpFormattingPolicy ();
			
			policy.ClassBraceStyle = BraceStyle.EndOfLine;
			var compilationUnit = new CSharpParser ().Parse (data);
			compilationUnit.AcceptVisitor (new AstFormattingVisitor (policy, data), null);
			Assert.AreEqual (@"class Test {
	Test TestMethod ()
	{
		this.TestMethod ();
	}
}", data.Document.Text);
		}
		public void TestIndentPropertyBodyIndexerCase ()
		{
			TextEditorData data = new TextEditorData ();
			data.Document.FileName = "a.cs";
			data.Document.Text = 
@"class Test
{
	Test this[int a] {
			get {
	return null;
}
set {
	;
}
	}
}";
			
			CSharpFormattingPolicy policy = new CSharpFormattingPolicy ();
			policy.IndentPropertyBody = true;
			
			CSharp.Dom.CompilationUnit compilationUnit = new CSharpParser ().Parse (data);
			compilationUnit.AcceptVisitor (new DomIndentationVisitor (policy, data), null);
			Assert.AreEqual (@"class Test
{
	Test this[int a] {
		get {
			return null;
		}
		set {
			;
		}
	}
}", data.Document.Text);
			policy.IndentPropertyBody = false;
			compilationUnit = new CSharpParser ().Parse (data);
			compilationUnit.AcceptVisitor (new DomIndentationVisitor (policy, data), null);
			Assert.AreEqual (@"class Test
{
	Test this[int a] {
	get {
		return null;
	}
	set {
		;
	}
	}
}", data.Document.Text);
		}
		public void TestIndentPropertyOneLineCase2 ()
		{
			TextEditorData data = new TextEditorData ();
			data.Document.FileName = "a.cs";
			data.Document.Text = 
@"class Test
{
	Test TestMe {      get { ; }set{;}                  }
}";
			
			CSharpFormattingPolicy policy = new CSharpFormattingPolicy ();
			policy.PropertyFormatting = PropertyFormatting.AllowOneLine;
			policy.AllowPropertyGetBlockInline = true;
			policy.AllowPropertySetBlockInline = true;
			
			CSharp.Dom.CompilationUnit compilationUnit = new CSharpParser ().Parse (data);
			compilationUnit.AcceptVisitor (new DomIndentationVisitor (policy, data), null);
			Assert.AreEqual (@"class Test
{
	Test TestMe { get { ; } set { ; } }
}", data.Document.Text);
		}
		public void TestIndentMethodBodyOperatorCase ()
		{
			TextEditorData data = new TextEditorData ();
			data.Document.FileName = "a.cs";
			data.Document.Text = 
@"class Test
{
	static Test operator+(Test left, Test right)
	{
;
								;
	}
}";
			
			CSharpFormattingPolicy policy = new CSharpFormattingPolicy ();
			policy.IndentMethodBody = true;
			
			CSharp.Dom.CompilationUnit compilationUnit = new CSharpParser ().Parse (data);
			compilationUnit.AcceptVisitor (new DomIndentationVisitor (policy, data), null);
			Assert.AreEqual (@"class Test
{
	static Test operator+(Test left, Test right)
	{
		;
		;
	}
}", data.Document.Text);
			policy.IndentMethodBody = false;
			compilationUnit = new CSharpParser ().Parse (data);
			compilationUnit.AcceptVisitor (new DomIndentationVisitor (policy, data), null);
			Assert.AreEqual (@"class Test
{
	static Test operator+(Test left, Test right)
	{
	;
	;
	}
}", data.Document.Text);
		}
		public void TestClassIndentationInNamespacesCase2 ()
		{
			TextEditorData data = new TextEditorData ();
			data.Document.FileName = "a.cs";
			data.Document.Text = 
@"using System;

namespace MonoDevelop.CSharp.Formatting {
	public class FormattingProfileService {
		public FormattingProfileService () {
		}
	}
}";
			
			CSharpFormattingPolicy policy = new CSharpFormattingPolicy ();
			policy.NamespaceBraceStyle = BraceStyle.NextLine;
			policy.ClassBraceStyle = BraceStyle.NextLine;
			policy.ConstructorBraceStyle = BraceStyle.NextLine;
			
			CSharp.Dom.CompilationUnit compilationUnit = new CSharpParser ().Parse (data);
			compilationUnit.AcceptVisitor (new DomIndentationVisitor (policy, data), null);
			Assert.AreEqual (@"using System;

namespace MonoDevelop.CSharp.Formatting
{
	public class FormattingProfileService
	{
		public FormattingProfileService ()
		{
		}
	}
}", data.Document.Text);
		}
		public void TestBug670213 ()
		{
			TextEditorData data = new TextEditorData ();
			data.Document.FileName = "a.cs";
			data.Document.Text = @"class Test
{
	Test MyMethod() // Comment
	{
	}
}";
			
			CSharpFormattingPolicy policy = new CSharpFormattingPolicy ();
			policy.MethodBraceStyle = BraceStyle.EndOfLine;
			
			var compilationUnit = new CSharpParser ().Parse (data);
			compilationUnit.AcceptVisitor (new AstIndentationVisitor (policy, data), null);
			
			Assert.AreEqual (@"class Test
{
	Test MyMethod() { // Comment
	}
}", data.Document.Text);
		}
		public void TestPropertySetBraceStyle ()
		{
			TextEditorData data = new TextEditorData ();
			data.Document.FileName = "a.cs";
			data.Document.Text = @"class Test
{
	Test A {
		get;
		set {
			;
		}
	}
}";
			
			CSharpFormattingPolicy policy = new CSharpFormattingPolicy ();
			policy.PropertySetBraceStyle = BraceStyle.NextLine;
			
			CSharp.Dom.CompilationUnit compilationUnit = new CSharpParser ().Parse (data);
			compilationUnit.AcceptVisitor (new DomIndentationVisitor (policy, data), null);
			
			Console.WriteLine (data.Document.Text);
			Assert.AreEqual (@"class Test
{
	Test A {
		get;
		set
		{
			;
		}
	}
}", data.Document.Text);
		}
		public void TestPropertyIndentationCase2 ()
		{
			TextEditorData data = new TextEditorData ();
			data.Document.FileName = "a.cs";
			data.Document.Text = 
@"class Test
{
				public int Prop {
 get;
set;
}
}";
			
			CSharpFormattingPolicy policy = new CSharpFormattingPolicy ();
			
			
			CSharp.Dom.CompilationUnit compilationUnit = new CSharpParser ().Parse (data);
			compilationUnit.AcceptVisitor (new DomIndentationVisitor (policy, data), null);
			Assert.AreEqual (@"class Test
{
	public int Prop {
		get;
		set;
	}
}", data.Document.Text);
		}
		public void TestAllowEventRemoveBlockInline ()
		{
			TextEditorData data = new TextEditorData ();
			data.Document.FileName = "a.cs";
			data.Document.Text = @"class Test
{
	public event EventHandler Handler {
		add { ; }
		remove { ; }
	}
}";
			
			CSharpFormattingPolicy policy = new CSharpFormattingPolicy ();
			policy.AllowEventAddBlockInline = false;
			policy.AllowEventRemoveBlockInline = true;
			
			CSharp.Dom.CompilationUnit compilationUnit = new CSharpParser ().Parse (data);
			compilationUnit.AcceptVisitor (new DomIndentationVisitor (policy, data), null);
			
			Console.WriteLine (data.Document.Text);
			Assert.AreEqual (@"class Test
{
	public event EventHandler Handler {
		add {
			;
		}
		remove { ; }
	}
}", data.Document.Text);
		}
		public void TestBlankLinesBetweenMembers ()
		{
			TextEditorData data = new TextEditorData ();
			data.Document.FileName = "a.cs";
			data.Document.Text = @"class Test
{
	void AMethod ()
	{
	}
	void BMethod ()
	{
	}
	void CMethod ()
	{
	}
}";
			
			CSharpFormattingPolicy policy = new CSharpFormattingPolicy ();
			policy.BlankLinesBetweenMembers = 1;
			var compilationUnit = new CSharpParser ().Parse (data);
			compilationUnit.AcceptVisitor (new AstIndentationVisitor (policy, data), null);
			Console.WriteLine (data.Text);
			Assert.AreEqual (@"class Test
{
	void AMethod ()
	{
	}

	void BMethod ()
	{
	}

	void CMethod ()
	{
	}
}", data.Document.Text);
			
		policy.BlankLinesBetweenMembers = 0;
		compilationUnit = new CSharpParser ().Parse (data);
		compilationUnit.AcceptVisitor (new AstIndentationVisitor (policy, data), null);
		Assert.AreEqual (@"class Test
{
	void AMethod ()
	{
	}
	void BMethod ()
	{
	}
	void CMethod ()
	{
	}
}", data.Document.Text);
		}
		public void TestWithinCheckedExpressionParanthesesSpace ()
		{
			TextEditorData data = new TextEditorData ();
			data.Document.FileName = "a.cs";
			data.Document.Text = @"class Test {
	void TestMe ()
	{
		a = checked(a + b);
	}
}";
			CSharpFormattingPolicy policy = new CSharpFormattingPolicy ();
			policy.WithinCheckedExpressionParantheses = true;
			
			var compilationUnit = new CSharpParser ().Parse (data);
			compilationUnit.AcceptVisitor (new AstSpacingVisitor (policy, data), null);
			int i1 = data.Document.Text.LastIndexOf ("(");
			int i2 = data.Document.Text.LastIndexOf (")") + ")".Length;
			Assert.AreEqual (@"( a + b )", data.Document.GetTextBetween (i1, i2));
			
			data.Document.Text = @"class Test {
	void TestMe ()
	{
		a = unchecked(a + b);
	}
}";
			
			compilationUnit = new CSharpParser ().Parse (data);
			compilationUnit.AcceptVisitor (new AstSpacingVisitor (policy, data), null);
			i1 = data.Document.Text.LastIndexOf ("(");
			i2 = data.Document.Text.LastIndexOf (")") + ")".Length;
			Assert.AreEqual (@"( a + b )", data.Document.GetTextBetween (i1, i2));
		}
		public void TestBlankLinesBetweenEventFields ()
		{
			TextEditorData data = new TextEditorData ();
			data.Document.FileName = "a.cs";
			data.Document.Text = @"class Test
{
	public event EventHandler a;
	public event EventHandler b;
	public event EventHandler c;
}";
			
			CSharpFormattingPolicy policy = new CSharpFormattingPolicy ();
			policy.BlankLinesBetweenEventFields = 1;
			var compilationUnit = new CSharpParser ().Parse (data);
			compilationUnit.AcceptVisitor (new AstIndentationVisitor (policy, data), null);
			Assert.AreEqual (@"class Test
{
	public event EventHandler a;

	public event EventHandler b;

	public event EventHandler c;
}", data.Document.Text);
			
		policy.BlankLinesBetweenEventFields = 0;
		compilationUnit = new CSharpParser ().Parse (data);
		compilationUnit.AcceptVisitor (new AstIndentationVisitor (policy, data), null);
		Assert.AreEqual (@"class Test
{
	public event EventHandler a;
	public event EventHandler b;
	public event EventHandler c;
}", data.Document.Text);
		}
		public void TestBlankLinesBetweenTypes ()
		{
			TextEditorData data = new TextEditorData ();
			data.Document.FileName = "a.cs";
			data.Document.Text = @"namespace Test
{
	class Test1
	{
	}
	class Test2
	{
	}
	class Test3
	{
	}
}";
			
			CSharpFormattingPolicy policy = new CSharpFormattingPolicy ();
			policy.BlankLinesBetweenTypes = 1;
			var compilationUnit = new CSharpParser ().Parse (data);
			compilationUnit.AcceptVisitor (new AstIndentationVisitor (policy, data), null);
			Assert.AreEqual (@"namespace Test
{
	class Test1
	{
	}

	class Test2
	{
	}

	class Test3
	{
	}
}", data.Document.Text);
			
		policy.BlankLinesBetweenTypes = 0;
		compilationUnit = new CSharpParser ().Parse (data);
		compilationUnit.AcceptVisitor (new AstIndentationVisitor (policy, data), null);
		Assert.AreEqual (@"namespace Test
{
	class Test1
	{
	}
	class Test2
	{
	}
	class Test3
	{
	}
}", data.Document.Text);
		}
		public static void Format (PolicyContainer policyParent, IEnumerable<string> mimeTypeChain, MonoDevelop.Ide.Gui.Document data, ProjectDom dom, DomLocation location, bool correctBlankLines, bool runAferCR = false)
		{
			if (data.ParsedDocument == null || data.ParsedDocument.CompilationUnit == null)
				return;
			var member = data.ParsedDocument.CompilationUnit.GetMemberAt (location.Line + (runAferCR ? -1 : 0), location.Column);
			if (member == null || member.Location.IsEmpty || member.BodyRegion.End.IsEmpty)
				return;
			
			StringBuilder sb = new StringBuilder ();
			int closingBrackets = 0;
			DomRegion validRegion = DomRegion.Empty;
			foreach (var u in data.ParsedDocument.CompilationUnit.Usings.Where (us => us.IsFromNamespace)) {
				// the dom parser breaks A.B.C into 3 namespaces with the same region, this is filtered here
				if (u.ValidRegion == validRegion)
					continue;
				validRegion = u.ValidRegion;
				sb.Append ("namespace Stub {");
				closingBrackets++;
			}
			
			var parent = member.DeclaringType;
			while (parent != null) {
				sb.Append ("class Stub {");
				closingBrackets++;
				parent = parent.DeclaringType;
			}
			sb.AppendLine ();
			int startOffset = sb.Length;
			sb.Append (data.Editor.GetTextBetween (member.Location.Line, 1, member.BodyRegion.End.Line + (runAferCR ? 1 : 0), member.BodyRegion.End.Column));
			int endOffset = sb.Length;
			sb.AppendLine ();
			sb.Append (new string ('}', closingBrackets));

			TextEditorData stubData = new TextEditorData () { Text = sb.ToString () };
			stubData.Document.FileName = data.FileName;
			var compilationUnit = new MonoDevelop.CSharp.Parser.CSharpParser ().Parse (stubData);

			var policy = policyParent.Get<CSharpFormattingPolicy> (mimeTypeChain);
			var domSpacingVisitor = new AstSpacingVisitor (policy, stubData) {
				AutoAcceptChanges = false,
			};
			compilationUnit.AcceptVisitor (domSpacingVisitor, null);

			var domIndentationVisitor = new AstIndentationVisitor (policy, stubData) {
				AutoAcceptChanges = false,
			};
			domIndentationVisitor.CorrectBlankLines = correctBlankLines;
			compilationUnit.AcceptVisitor (domIndentationVisitor, null);

			var changes = new List<Change> ();
			changes.AddRange (domSpacingVisitor.Changes.Cast<TextReplaceChange> ().Where (c => startOffset < c.Offset && c.Offset < endOffset));
			changes.AddRange (domIndentationVisitor.Changes.Cast<TextReplaceChange> ().Where (c => startOffset < c.Offset && c.Offset < endOffset));
			int delta = data.Editor.LocationToOffset (member.Location.Line, 1) - startOffset;
			HashSet<int> lines = new HashSet<int> ();
			foreach (TextReplaceChange change in changes) {
				if (change is AstSpacingVisitor.MyTextReplaceChange) 
					((AstSpacingVisitor.MyTextReplaceChange)change).SetTextEditorData (data.Editor);
				change.Offset += delta;
				lines.Add (data.Editor.OffsetToLineNumber (change.Offset));
			}
			RefactoringService.AcceptChanges (null, null, changes);
			foreach (int line in lines)
				data.Editor.Document.CommitLineUpdate (line);
			stubData.Dispose ();
		}
		public void TestPropertyAlignment ()
		{
			TextEditorData data = new TextEditorData ();
			data.Document.FileName = "a.cs";
			data.Document.Text = 
@"class Test
{
	Test TestMe { get; set; }
}";
			
			CSharpFormattingPolicy policy = new CSharpFormattingPolicy ();
			policy.PropertyFormatting = PropertyFormatting.AllowOneLine;
				
			CSharp.Dom.CompilationUnit compilationUnit = new CSharpParser ().Parse (data);
			compilationUnit.AcceptVisitor (new DomIndentationVisitor (policy, data), null);
			Assert.AreEqual (@"class Test
{
	Test TestMe { get; set; }
}", data.Document.Text);
			policy.PropertyFormatting = PropertyFormatting.ForceNewLine;
			
			compilationUnit = new CSharpParser ().Parse (data);
			compilationUnit.AcceptVisitor (new DomIndentationVisitor (policy, data), null);
			Assert.AreEqual (@"class Test
{
	Test TestMe {
		get;
		set;
	}
}", data.Document.Text);
			policy.PropertyFormatting = PropertyFormatting.ForceOneLine;
			
			compilationUnit = new CSharpParser ().Parse (data);
			compilationUnit.AcceptVisitor (new DomIndentationVisitor (policy, data), null);
			Assert.AreEqual (@"class Test
{
	Test TestMe { get; set; }
}", data.Document.Text);
		}
Beispiel #23
0
        public static void Format(PolicyContainer policyParent, IEnumerable <string> mimeTypeChain, MonoDevelop.Ide.Gui.Document data, ProjectDom dom, DomLocation location, bool correctBlankLines, bool runAferCR /* = false*/)
        {
            if (data.ParsedDocument == null || data.ParsedDocument.CompilationUnit == null)
            {
                return;
            }
            var member = data.ParsedDocument.CompilationUnit.GetMemberAt(location.Line + (runAferCR ? -1 : 0), location.Column);

            if (member == null || member.Location.IsEmpty || member.BodyRegion.End.IsEmpty)
            {
                return;
            }

            StringBuilder sb = new StringBuilder();
            int           closingBrackets = 0;
            DomRegion     validRegion     = DomRegion.Empty;

            foreach (var u in data.ParsedDocument.CompilationUnit.Usings.Where(us => us.IsFromNamespace))
            {
                // the dom parser breaks A.B.C into 3 namespaces with the same region, this is filtered here
                if (u.ValidRegion == validRegion)
                {
                    continue;
                }
                validRegion = u.ValidRegion;
                sb.Append("namespace Stub {");
                closingBrackets++;
            }

            var parent = member.DeclaringType;

            while (parent != null)
            {
                sb.Append("class Stub {");
                closingBrackets++;
                parent = parent.DeclaringType;
            }
            sb.AppendLine();
            int startOffset = sb.Length;
            int memberStart = data.Editor.LocationToOffset(member.Location.Line, 1);
            int memberEnd   = data.Editor.LocationToOffset(member.BodyRegion.End.Line + (runAferCR ? 1 : 0), member.BodyRegion.End.Column);

            if (memberEnd < 0)
            {
                memberEnd = data.Editor.Length;
            }
            sb.Append(data.Editor.GetTextBetween(memberStart, memberEnd));
            int endOffset = sb.Length;

            sb.AppendLine();
            sb.Append(new string ('}', closingBrackets));
            TextEditorData stubData = new TextEditorData()
            {
                Text = sb.ToString()
            };

            stubData.Document.FileName = data.FileName;
            var  parser          = new MonoDevelop.CSharp.Parser.CSharpParser();
            bool hadErrors       = parser.ErrorReportPrinter.ErrorsCount + parser.ErrorReportPrinter.FatalCounter > 0;
            var  compilationUnit = parser.Parse(stubData);

            var policy            = policyParent.Get <CSharpFormattingPolicy> (mimeTypeChain);
            var domSpacingVisitor = new AstFormattingVisitor(policy, stubData)
            {
                AutoAcceptChanges = false,
            };

            compilationUnit.AcceptVisitor(domSpacingVisitor, null);


            var changes = new List <Change> ();

            changes.AddRange(domSpacingVisitor.Changes.Cast <TextReplaceChange> ().Where(c => startOffset < c.Offset && c.Offset < endOffset));
            int           delta = data.Editor.LocationToOffset(member.Location.Line, 1) - startOffset;
            HashSet <int> lines = new HashSet <int> ();

            foreach (TextReplaceChange change in changes)
            {
                if (change is AstFormattingVisitor.MyTextReplaceChange)
                {
                    ((AstFormattingVisitor.MyTextReplaceChange)change).SetTextEditorData(data.Editor);
                }
                change.Offset += delta;
                lines.Add(data.Editor.OffsetToLineNumber(change.Offset));
            }
            // be sensible in documents with parser errors - only correct up to the caret position.
            if (parser.ErrorReportPrinter.Errors.Any(e => e.ErrorType == ErrorType.Error) || data.ParsedDocument.Errors.Any(e => e.ErrorType == ErrorType.Error))
            {
                var lastOffset = data.Editor.Caret.Offset;
                changes.RemoveAll(c => ((TextReplaceChange)c).Offset > lastOffset);
            }
            RefactoringService.AcceptChanges(null, null, changes);
            foreach (int line in lines)
            {
                data.Editor.Document.CommitLineUpdate(line);
            }
            stubData.Dispose();
        }
		public void TestMethodIndentation ()
		{
			TextEditorData data = new TextEditorData ();
			data.Document.FileName = "a.cs";
			data.Document.Text = 
@"class Test
{
MyType TestMethod () {}
}";
			
			CSharpFormattingPolicy policy = new CSharpFormattingPolicy ();
			policy.MethodBraceStyle = BraceStyle.DoNotChange;
			
			CSharp.Dom.CompilationUnit compilationUnit = new CSharpParser ().Parse (data);
			compilationUnit.AcceptVisitor (new DomIndentationVisitor (policy, data), null);
			Assert.AreEqual (@"class Test
{
	MyType TestMethod () {}
}", data.Document.Text);
		}
		public void TestIndentEventBody ()
		{
			TextEditorData data = new TextEditorData ();
			data.Document.FileName = "a.cs";
			data.Document.Text = 
@"class Test
{
	public event EventHandler TestMe {
								add {
							;
						}
remove {
	;
}
	}
}";
			
			CSharpFormattingPolicy policy = new CSharpFormattingPolicy ();
			policy.IndentEventBody = true;
			
			var compilationUnit = new CSharpParser ().Parse (data);
			compilationUnit.AcceptVisitor (new AstIndentationVisitor (policy, data), null);
			Assert.AreEqual (@"class Test
{
	public event EventHandler TestMe {
		add {
			;
		}
		remove {
			;
		}
	}
}", data.Document.Text);
			policy.IndentEventBody = false;
			compilationUnit = new CSharpParser ().Parse (data);
			compilationUnit.AcceptVisitor (new AstIndentationVisitor (policy, data), null);
			Assert.AreEqual (@"class Test
{
	public event EventHandler TestMe {
	add {
		;
	}
	remove {
		;
	}
	}
}", data.Document.Text);
		}
		public void TestAllowPropertySetBlockInline ()
		{
			TextEditorData data = new TextEditorData ();
			data.Document.FileName = "a.cs";
			data.Document.Text = @"class Test
{
	Test A {
		get { return null; }
		set { ; }
	}
}";
			
			CSharpFormattingPolicy policy = new CSharpFormattingPolicy ();
			policy.PropertyBraceStyle = BraceStyle.DoNotChange;
			policy.AllowPropertyGetBlockInline = false;
			policy.AllowPropertySetBlockInline = true;
			
			CSharp.Dom.CompilationUnit compilationUnit = new CSharpParser ().Parse (data);
			compilationUnit.AcceptVisitor (new DomIndentationVisitor (policy, data), null);
			
			Console.WriteLine (data.Document.Text);
			Assert.AreEqual (@"class Test
{
	Test A {
		get {
			return null;
		}
		set { ; }
	}
}", data.Document.Text);
			
			policy.AllowPropertySetBlockInline = false;
			compilationUnit = new CSharpParser ().Parse (data);
			compilationUnit.AcceptVisitor (new DomIndentationVisitor (policy, data), null);
			
			Assert.AreEqual (@"class Test
{
	Test A {
		get {
			return null;
		}
		set {
			;
		}
	}
}", data.Document.Text);
		}
		public void TestNoIndentationInNamespaces ()
		{
			TextEditorData data = new TextEditorData ();
			data.Document.FileName = "a.cs";
			data.Document.Text = 
@"namespace A { class Test {} }";
			
			CSharpFormattingPolicy policy = new CSharpFormattingPolicy ();
			policy.NamespaceBraceStyle = BraceStyle.EndOfLine;
			policy.ClassBraceStyle = BraceStyle.DoNotChange;
			policy.IndentNamespaceBody = false;
			
			var compilationUnit = new CSharpParser ().Parse (data);
			compilationUnit.AcceptVisitor (new AstIndentationVisitor (policy, data), null);
			Assert.AreEqual (@"namespace A {
class Test {}
}", data.Document.Text);
		}
		public bool Analyze (RefactoringOptions options)
		{
			var data = options.GetTextEditorData ();
			if (data.Document.MimeType != CSharpFormatter.MimeType)
				return false;
			var parser = new CSharpParser ();
			var unit = parser.Parse (data);
			if (unit == null)
				return false;
			resolvePosition = new DomLocation (data.Caret.Line, data.Caret.Column);
			
			if (!AnalyzeTargetExpression (options, unit))
				return false;
			
			invocation = GetInvocation (unit, data);
			if (invocation != null) 
				return AnalyzeInvocation (options);
			delegateType = GetDelegateType (options, unit);
			return delegateType != null;
		}
		static void TestStatementFormatting (CSharpFormattingPolicy policy, string input, string expectedOutput)
		{
			TextEditorData data = new TextEditorData ();
			data.Document.FileName = "a.cs";
			data.Document.Text =
@"class Test
{
	MyType TestMethod ()
	{
		" + input + @"
	}
}";
			var compilationUnit = new CSharpParser ().Parse (data);
			AstSpacingVisitor domSpacingVisitor = new AstSpacingVisitor (policy, data);
			domSpacingVisitor.AutoAcceptChanges = false;
			compilationUnit.AcceptVisitor (domSpacingVisitor, null);
			
			AstIndentationVisitor domIndentationVisitor = new AstIndentationVisitor (policy, data);
			domIndentationVisitor.AutoAcceptChanges = false;
			compilationUnit.AcceptVisitor (domIndentationVisitor, null);
			
			List<Change> changes = new List<Change> ();
			changes.AddRange (domSpacingVisitor.Changes);
			changes.AddRange (domIndentationVisitor.Changes);
			RefactoringService.AcceptChanges (null, null, changes);
			
			for (int i = 1; i <= data.Document.LineCount; i++) {
				LineSegment line = data.Document.GetLine (i);
				if (line.EditableLength < 2)
					continue;
				data.Remove (line.Offset, 2);
			}
			string text = data.Document.GetTextBetween (data.Document.GetLine (5).Offset,
			                                            data.Document.GetLine (data.Document.LineCount - 1).Offset).Trim ();
			Console.WriteLine (text);
			Assert.AreEqual (expectedOutput, text);
		}
		public void TestStructBraceStyle ()
		{
			TextEditorData data = new TextEditorData ();
			data.Document.FileName = "a.cs";
			data.Document.Text = @"struct Test {}";
			
			CSharpFormattingPolicy policy = new CSharpFormattingPolicy ();
			policy.StructBraceStyle =  BraceStyle.NextLine;
			
			CSharp.Dom.CompilationUnit compilationUnit = new CSharpParser ().Parse (data);
			compilationUnit.AcceptVisitor (new DomIndentationVisitor (policy, data), null);
			Assert.AreEqual (@"struct Test
{
}", data.Document.Text);
		}
		public void TestIndentInterfaceBody ()
		{
			TextEditorData data = new TextEditorData ();
			data.Document.FileName = "a.cs";
			data.Document.Text = 
@"interface Test
{
				Test Foo ();
}";
			
			CSharpFormattingPolicy policy = new CSharpFormattingPolicy ();
			policy.IndentInterfaceBody = true;
			
			var compilationUnit = new CSharpParser ().Parse (data);
			compilationUnit.AcceptVisitor (new AstIndentationVisitor (policy, data), null);
			Assert.AreEqual (@"interface Test
{
	Test Foo ();
}", data.Document.Text);
			policy.IndentInterfaceBody = false;
			compilationUnit = new CSharpParser ().Parse (data);
			compilationUnit.AcceptVisitor (new AstIndentationVisitor (policy, data), null);
			Assert.AreEqual (@"interface Test
{
Test Foo ();
}", data.Document.Text);
		}