示例#1
0
        public override void OnTheFlyFormat(PolicyContainer policyParent, IEnumerable <string> mimeTypeChain,
                                            TextEditorData data, int startOffset, int endOffset)
        {
            var  parser            = new MonoDevelop.CSharp.Parser.CSharpParser();
            var  compilationUnit   = parser.Parse(data);
            bool hadErrors         = parser.ErrorReportPrinter.ErrorsCount + parser.ErrorReportPrinter.FatalCounter > 0;
            var  policy            = policyParent.Get <CSharpFormattingPolicy> (mimeTypeChain);
            var  domSpacingVisitor = new AstSpacingVisitor(policy, data)
            {
                AutoAcceptChanges = false,
            };

            compilationUnit.AcceptVisitor(domSpacingVisitor, null);

            var domIndentationVisitor = new AstIndentationVisitor(policy, data)
            {
                AutoAcceptChanges = false,
                HadErrors         = hadErrors
            };

            compilationUnit.AcceptVisitor(domIndentationVisitor, null);

            var changes = new List <Change> ();

            changes.AddRange(domSpacingVisitor.Changes.
                             Concat(domIndentationVisitor.Changes).
                             Where(c => c is TextReplaceChange && (startOffset <= ((TextReplaceChange)c).Offset && ((TextReplaceChange)c).Offset < endOffset)));

            RefactoringService.AcceptChanges(null, null, changes);
        }
        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 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 AstSpacingVisitor (policy, data) {
				AutoAcceptChanges = false,
			};
			compilationUnit.AcceptVisitor (domSpacingVisitor, null);
			
			var domIndentationVisitor = new AstIndentationVisitor (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);
		}
示例#4
0
        public override string FormatText(PolicyContainer policyParent, IEnumerable <string> mimeTypeChain,
                                          string input, int startOffset, int endOffset)
        {
            var data = new TextEditorData();

            data.Document.SuppressHighlightUpdate = true;
            data.Document.MimeType = mimeTypeChain.First();
            data.Document.FileName = "toformat.cs";
            var textPolicy = policyParent.Get <TextStylePolicy> (mimeTypeChain);

            data.Options.TabsToSpaces = textPolicy.TabsToSpaces;
            data.Options.TabSize      = textPolicy.TabWidth;
            data.Options.OverrideDocumentEolMarker = true;
            data.Options.DefaultEolMarker          = textPolicy.GetEolMarker();
            data.Text = input;

            //System.Console.WriteLine ("-----");
            //System.Console.WriteLine (data.Text.Replace (" ", ".").Replace ("\t", "->"));
            //System.Console.WriteLine ("-----");

            MonoDevelop.CSharp.Parser.CSharpParser parser = new MonoDevelop.CSharp.Parser.CSharpParser();
            var  compilationUnit = parser.Parse(data);
            bool hadErrors       = parser.ErrorReportPrinter.ErrorsCount + parser.ErrorReportPrinter.FatalCounter > 0;
            var  policy          = policyParent.Get <CSharpFormattingPolicy> (mimeTypeChain);

            var domSpacingVisitor = new AstSpacingVisitor(policy, data)
            {
                AutoAcceptChanges = false
            };

            compilationUnit.AcceptVisitor(domSpacingVisitor, null);

            var domIndentationVisitor = new AstIndentationVisitor(policy, data)
            {
                AutoAcceptChanges = false,
                HadErrors         = hadErrors
            };

            compilationUnit.AcceptVisitor(domIndentationVisitor, null);

            var changes = new List <Change> ();

            changes.AddRange(domSpacingVisitor.Changes.
                             Concat(domIndentationVisitor.Changes).
                             Where(c => c is TextReplaceChange && (startOffset <= ((TextReplaceChange)c).Offset && ((TextReplaceChange)c).Offset < endOffset)));

            RefactoringService.AcceptChanges(null, null, changes);
            int end = endOffset;

            foreach (TextReplaceChange c in changes)
            {
                end -= c.RemovedChars;
                if (c.InsertedText != null)
                {
                    end += c.InsertedText.Length;
                }
            }

            /*			System.Console.WriteLine ("-----");
             * System.Console.WriteLine (data.Text.Replace (" ", "^").Replace ("\t", "->"));
             * System.Console.WriteLine ("-----");*/
            string result = data.GetTextBetween(startOffset, Math.Min(data.Length, end));

            data.Dispose();
            return(result);
        }
		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 ();
		}
		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 override void OnTheFlyFormat (PolicyContainer policyParent, IEnumerable<string> mimeTypeChain,
			TextEditorData data, int startOffset, int endOffset)
		{
			var compilationUnit = new MonoDevelop.CSharp.Parser.CSharpParser ().Parse (data);
			var policy = policyParent.Get<CSharpFormattingPolicy> (mimeTypeChain);
			var domSpacingVisitor = new AstSpacingVisitor (policy, data) {
				AutoAcceptChanges = false,
			};
			compilationUnit.AcceptVisitor (domSpacingVisitor, null);

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

			var changes = new List<Change> ();

			changes.AddRange (domSpacingVisitor.Changes.
				Concat (domIndentationVisitor.Changes).
				Where (c => c is TextReplaceChange && (startOffset <= ((TextReplaceChange)c).Offset && ((TextReplaceChange)c).Offset < endOffset)));

			RefactoringService.AcceptChanges (null, null, changes);
			CorrectFormatting (data, startOffset, endOffset);
		}
		public override string FormatText (PolicyContainer policyParent, IEnumerable<string> mimeTypeChain,
			string input, int startOffset, int endOffset)
		{
			var data = new TextEditorData ();
			data.Document.SuppressHighlightUpdate = true;
			data.Document.MimeType = mimeTypeChain.First ();
			data.Document.FileName = "toformat.cs";
			var textPolicy = policyParent.Get<TextStylePolicy> (mimeTypeChain);
			data.Options.TabsToSpaces = textPolicy.TabsToSpaces;
			data.Options.TabSize = textPolicy.TabWidth;
			data.Options.OverrideDocumentEolMarker = true;
			data.Options.DefaultEolMarker = textPolicy.GetEolMarker ();
			data.Text = input;

			//			System.Console.WriteLine ("TABS:" + textPolicy.TabsToSpaces);
			endOffset += CorrectFormatting (data, startOffset, endOffset);
			
			/*			System.Console.WriteLine ("-----");
			System.Console.WriteLine (data.Text.Replace (" ", ".").Replace ("\t", "->"));
			System.Console.WriteLine ("-----");*/

			var compilationUnit = new MonoDevelop.CSharp.Parser.CSharpParser ().Parse (data);
			var policy = policyParent.Get<CSharpFormattingPolicy> (mimeTypeChain);

			var domSpacingVisitor = new AstSpacingVisitor (policy, data) {
				AutoAcceptChanges = false,
			};
			compilationUnit.AcceptVisitor (domSpacingVisitor, null);

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

			var changes = new List<Change> ();

			changes.AddRange (domSpacingVisitor.Changes.
				Concat (domIndentationVisitor.Changes).
				Where (c => c is TextReplaceChange && (startOffset <= ((TextReplaceChange)c).Offset && ((TextReplaceChange)c).Offset < endOffset)));

			RefactoringService.AcceptChanges (null, null, changes);
			int end = endOffset;
			foreach (TextReplaceChange c in changes) {
				end -= c.RemovedChars;
				if (c.InsertedText != null)
					end += c.InsertedText.Length;
			}
			/*			System.Console.WriteLine ("-----");
			System.Console.WriteLine (data.Text.Replace (" ", "^").Replace ("\t", "->"));
			System.Console.WriteLine ("-----");*/
			string result = data.GetTextBetween (startOffset, Math.Min (data.Length, end));
			data.Dispose ();
			return result;
		}
        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 AstSpacingVisitor(policy, stubData)
            {
                AutoAcceptChanges = false,
            };

            compilationUnit.AcceptVisitor(domSpacingVisitor, null);

            var domIndentationVisitor = new AstIndentationVisitor(policy, stubData)
            {
                AutoAcceptChanges = false,
                HadErrors         = hadErrors
            };

            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));
            }
            // 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 static void Format (PolicyContainer policyParent, IEnumerable<string> mimeTypeChain, 
			MonoDevelop.Ide.Gui.Document data, ProjectDom dom, DomLocation location, bool correctBlankLines, bool runAferCR = false)
		{
			var unit = data.ParsedDocument.CompilationUnit.Tag as MonoDevelop.CSharp.Ast.CompilationUnit;
			if (unit == null)
				return;

			AstLocation loc = new AstLocation (location.Line + (runAferCR ? -1 : 0), location.Column);
			AstNode member = null;
			foreach (AstNode node in MonoDevelop.CSharp.Ast.Utils.TreeTraversal.PreOrder (unit.Children, n => n.Parent != null && n.Parent.NodeType == NodeType.TypeDeclaration ? Enumerable.Empty<AstNode> () : n.Children)) {
				if (node.NodeType != NodeType.Member)
					continue;
				if (node.StartLocation < loc && loc <= node.EndLocation) {
					member = node;
					break;
				}
			}
			if (member == null)
				return;
			StringBuilder sb = new StringBuilder ();
			int closingBrackets = 0;
			var parent = member.Parent;
			while (parent != null) {
				if (parent.NodeType == NodeType.TypeDeclaration) {
					sb.Insert (0, "class Stub {");
					closingBrackets++;
				} else if (parent is NamespaceDeclaration) {
					sb.Insert (0, "namespace Stub {");
					closingBrackets++;
				}
				parent = parent.Parent;
			}
			sb.AppendLine ();
			System.Console.WriteLine ("caret offset:" + data.Editor.Caret.Offset);
			System.Console.WriteLine (data.Editor.Length);
			int startOffset = sb.Length;
			sb.Append (data.Editor.GetTextBetween (member.StartLocation.Line, 1, member.EndLocation.Line + (runAferCR ? 1 : 0), member.EndLocation.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.StartLocation.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 ();
		}