static AstFormattingVisitor GetFormattingChanges(PolicyContainer policyParent, IEnumerable <string> mimeTypeChain, MonoDevelop.Ide.Gui.Document document, string input, DomRegion formattingRegion) { using (var stubData = TextEditorData.CreateImmutable(input)) { stubData.Document.FileName = document.FileName; var parser = document.HasProject ? new ICSharpCode.NRefactory.CSharp.CSharpParser(TypeSystemParser.GetCompilerArguments(document.Project)) : new ICSharpCode.NRefactory.CSharp.CSharpParser(); var compilationUnit = parser.Parse(stubData); bool hadErrors = parser.HasErrors; if (hadErrors) { using (var stubData2 = TextEditorData.CreateImmutable(input + "}")) { compilationUnit = parser.Parse(stubData2); hadErrors = parser.HasErrors; } } // try it out, if the behavior is better when working only with correct code. if (hadErrors) { return(null); } var policy = policyParent.Get <CSharpFormattingPolicy> (mimeTypeChain); var formattingVisitor = new AstFormattingVisitor(policy.CreateOptions(), stubData.Document, document.Editor.CreateNRefactoryTextEditorOptions()) { HadErrors = hadErrors, FormattingRegion = formattingRegion }; compilationUnit.AcceptVisitor(formattingVisitor); return(formattingVisitor); } }
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 formattingVisitor = new AstFormattingVisitor(policy, data) { AutoAcceptChanges = false }; compilationUnit.AcceptVisitor(formattingVisitor, null); var changes = new List <Change> (); changes.AddRange(formattingVisitor.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 override void FormatText(AstNode node) { var segment = GetSegment(node); var cu = CompilationUnit.Parse(currentDocument, "dummy.cs"); var formatter = new AstFormattingVisitor(FormattingOptions, currentDocument, options); cu.AcceptVisitor(formatter); formatter.ApplyChanges(segment.Offset, segment.Length); }
/// <summary> /// Formats the specified part of the document. /// </summary> public static void Format(IDocument document, int offset, int length, CSharpFormattingOptions options) { var syntaxTree = new CSharpParser().Parse(document); var fv = new AstFormattingVisitor(options, document); // fv.FormattingRegion = new DomRegion(document.GetLocation(offset), document.GetLocation(offset + length)); syntaxTree.AcceptVisitor(fv); fv.ApplyChanges(offset, length); }
public override void FormatText(AstNode node) { var segment = GetSegment(node); var syntaxTree = SyntaxTree.Parse(currentDocument, "dummy.cs"); var formatter = new AstFormattingVisitor(FormattingOptions, currentDocument, Options); syntaxTree.AcceptVisitor(formatter); formatter.ApplyChanges(segment.Offset, segment.Length); }
protected static void Continue(CSharpFormattingOptions policy, ITextEditorAdapter adapter, string expectedOutput) { var visitior = new AstFormattingVisitor(policy, adapter); var compilationUnit = new CSharpParser().Parse(new StringReader(adapter.Text)); compilationUnit.AcceptVisitor(visitior, null); ((TextEditorTestAdapter)adapter).ApplyChanges(visitior.Changes); Assert.AreEqual(expectedOutput, adapter.Text); }
protected static IDocument GetResult(CSharpFormattingOptions policy, string input) { var adapter = new ReadOnlyDocument(input); var visitor = new AstFormattingVisitor(policy, adapter, factory); var compilationUnit = new CSharpParser().Parse(new StringReader(input)); compilationUnit.AcceptVisitor(visitor, null); return(new ReadOnlyDocument(ApplyChanges(input, visitor.Changes))); }
protected static ITextEditorAdapter GetResult(CSharpFormattingOptions policy, string input) { var adapter = new TextEditorTestAdapter(input); var visitior = new AstFormattingVisitor(policy, adapter); var compilationUnit = new CSharpParser().Parse(new StringReader(adapter.Text)); compilationUnit.AcceptVisitor(visitior, null); adapter.ApplyChanges(visitior.Changes); return(adapter); }
static AstFormattingVisitor GetFormattingChanges(PolicyContainer policyParent, IEnumerable <string> mimeTypeChain, MonoDevelop.Ide.Gui.Document document, string input, DomRegion formattingRegion, ref int formatStartOffset, ref int formatLength, bool formatLastStatementOnly) { using (var stubData = TextEditorData.CreateImmutable(input)) { stubData.Document.FileName = document.FileName; var parser = document.HasProject ? new PlayScriptParser(TypeSystemParser.GetCompilerArguments(document.Project)) : new PlayScriptParser(); var compilationUnit = parser.Parse(stubData); bool hadErrors = parser.HasErrors; if (hadErrors) { using (var stubData2 = TextEditorData.CreateImmutable(input + "}")) { compilationUnit = parser.Parse(stubData2); hadErrors = parser.HasErrors; } } // try it out, if the behavior is better when working only with correct code. if (hadErrors) { return(null); } var policy = policyParent.Get <PlayScriptFormattingPolicy> (mimeTypeChain); var formattingVisitor = new AstFormattingVisitor(policy.CreateOptions(), stubData.Document, document.Editor.CreateNRefactoryTextEditorOptions()) { HadErrors = hadErrors, }; formattingVisitor.AddFormattingRegion(formattingRegion); compilationUnit.AcceptVisitor(formattingVisitor); if (formatLastStatementOnly) { AstNode node = compilationUnit.GetAdjacentNodeAt <Statement> (stubData.OffsetToLocation(formatStartOffset + formatLength - 1)); if (node != null) { while (node.Role == Roles.EmbeddedStatement || node.Role == IfElseStatement.TrueRole || node.Role == IfElseStatement.FalseRole) { node = node.Parent; } var start = stubData.LocationToOffset(node.StartLocation); if (start > formatStartOffset) { var end = stubData.LocationToOffset(node.EndLocation); formatStartOffset = start; formatLength = end - start; } } } return(formattingVisitor); } }
public override void FormatText(IEnumerable<AstNode> nodes) { var syntaxTree = SyntaxTree.Parse(currentDocument, "dummy.cs"); foreach (var node in nodes.OrderByDescending (n => n.StartLocation)) { var segment = GetSegment(node); var formatter = new AstFormattingVisitor(FormattingOptions, currentDocument, Options); formatter.FormattingRegion = new ICSharpCode.NRefactory.TypeSystem.DomRegion ( currentDocument.GetLocation (segment.Offset), currentDocument.GetLocation (segment.EndOffset) ); syntaxTree.AcceptVisitor(formatter); formatter.ApplyChanges(segment.Offset, segment.Length); } }
protected static void Continue(CSharpFormattingOptions policy, IDocument document, string expectedOutput) { var visitior = new AstFormattingVisitor(policy, document, factory); var compilationUnit = new CSharpParser().Parse(new StringReader(document.Text)); compilationUnit.AcceptVisitor(visitior, null); string newText = ApplyChanges(document.Text, visitior.Changes); if (expectedOutput != newText) { Console.WriteLine(newText); } Assert.AreEqual(expectedOutput, newText); }
/*public static string ApplyChanges (string text, List<TextReplaceAction> changes) * { * changes.Sort ((x, y) => y.Offset.CompareTo (x.Offset)); * StringBuilder b = new StringBuilder(text); * foreach (var change in changes) { * //Console.WriteLine ("---- apply:" + change); * // Console.WriteLine (adapter.Text); * if (change.Offset > b.Length) * continue; * b.Remove(change.Offset, change.RemovedChars); * b.Insert(change.Offset, change.InsertedText); * } * // Console.WriteLine ("---result:"); * // Console.WriteLine (adapter.Text); * return b.ToString(); * }*/ protected static IDocument GetResult(CSharpFormattingOptions policy, string input, FormattingMode mode = FormattingMode.OnTheFly) { input = NormalizeNewlines(input); var document = new StringBuilderDocument(input); var options = new TextEditorOptions(); options.EolMarker = "\n"; var visitor = new AstFormattingVisitor(policy, document, options); visitor.FormattingMode = mode; var compilationUnit = new CSharpParser().Parse(document, "test.cs"); compilationUnit.AcceptVisitor(visitor); visitor.ApplyChanges(); return(document); }
protected static ITextEditorAdapter Test(CSharpFormattingOptions policy, string input, string expectedOutput) { var adapter = new TextEditorTestAdapter(input); var visitior = new AstFormattingVisitor(policy, adapter, factory); var compilationUnit = new CSharpParser().Parse(new StringReader(adapter.Text)); compilationUnit.AcceptVisitor(visitior, null); ApplyChanges(adapter, visitior.Changes); if (expectedOutput != adapter.Text) { Console.WriteLine(adapter.Text); } Assert.AreEqual(expectedOutput, adapter.Text); return(adapter); }
public CodeFormatResponse Format(Request request) { var document = new StringBuilderDocument(request.Buffer); var options = new TextEditorOptions(); options.EolMarker = Environment.NewLine; options.WrapLineLength = 80; var policy = FormattingOptionsFactory.CreateAllman(); var visitor = new AstFormattingVisitor(policy, document, options); visitor.FormattingMode = FormattingMode.Intrusive; var syntaxTree = new CSharpParser().Parse(document, request.FileName); syntaxTree.AcceptVisitor(visitor); visitor.ApplyChanges(); return(new CodeFormatResponse(document.Text)); }
public override void FormatText(IEnumerable <AstNode> nodes) { var syntaxTree = SyntaxTree.Parse(currentDocument, "dummy.cs"); foreach (var node in nodes.OrderByDescending(n => n.StartLocation)) { var segment = GetSegment(node); var formatter = new AstFormattingVisitor(FormattingOptions, currentDocument, Options); formatter.FormattingRegion = new ICSharpCode.NRefactory.TypeSystem.DomRegion( currentDocument.GetLocation(segment.Offset), currentDocument.GetLocation(segment.EndOffset) ); syntaxTree.AcceptVisitor(formatter); formatter.ApplyChanges(segment.Offset, segment.Length); } }
/*public static string ApplyChanges (string text, List<TextReplaceAction> changes) * { * changes.Sort ((x, y) => y.Offset.CompareTo (x.Offset)); * StringBuilder b = new StringBuilder(text); * foreach (var change in changes) { * //Console.WriteLine ("---- apply:" + change); * // Console.WriteLine (adapter.Text); * if (change.Offset > b.Length) * continue; * b.Remove(change.Offset, change.RemovedChars); * b.Insert(change.Offset, change.InsertedText); * } * // Console.WriteLine ("---result:"); * // Console.WriteLine (adapter.Text); * return b.ToString(); * }*/ protected static IDocument GetResult(CSharpFormattingOptions policy, string input, FormattingMode mode = FormattingMode.Intrusive) { input = NormalizeNewlines(input); var document = new StringBuilderDocument(input); var options = new TextEditorOptions(); options.EolMarker = "\n"; options.WrapLineLength = 80; var visitor = new AstFormattingVisitor(policy, document, options); visitor.FormattingMode = mode; var syntaxTree = new CSharpParser().Parse(document, "test.cs"); syntaxTree.AcceptVisitor(visitor); visitor.ApplyChanges(); return(document); }
protected static void Continue(CSharpFormattingOptions policy, IDocument document, string expectedOutput, FormattingMode formattingMode = FormattingMode.OnTheFly) { expectedOutput = NormalizeNewlines(expectedOutput); var options = new TextEditorOptions(); options.EolMarker = "\n"; var visitior = new AstFormattingVisitor(policy, document, options); visitior.FormattingMode = formattingMode; var syntaxTree = new CSharpParser().Parse(document, "test.cs"); syntaxTree.AcceptVisitor(visitior); visitior.ApplyChanges(); string newText = document.Text; if (expectedOutput != newText) { Console.WriteLine(newText); } Assert.AreEqual(expectedOutput, newText); }
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 formattingVisitor = new AstFormattingVisitor(policy, data) { AutoAcceptChanges = false, }; compilationUnit.AcceptVisitor(formattingVisitor, null); var changes = new List <Change> (); changes.AddRange(formattingVisitor.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); AstFormattingVisitor formattingVistior = new AstFormattingVisitor(policy, data); formattingVistior.AutoAcceptChanges = false; compilationUnit.AcceptVisitor(formattingVistior, null); List <Change> changes = new List <Change> (); changes.AddRange(formattingVistior.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(); Assert.AreEqual(expectedOutput, text); }
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; if (hadErrors) return null; var policy = policyParent.Get<CSharpFormattingPolicy> (mimeTypeChain); var formattingVisitor = new AstFormattingVisitor (policy, data) { AutoAcceptChanges = false }; compilationUnit.AcceptVisitor (formattingVisitor, null); var changes = new List<Change> (); changes.AddRange (formattingVisitor.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 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 formattingVisitor = new AstFormattingVisitor (policy, data) { AutoAcceptChanges = false, }; compilationUnit.AcceptVisitor (formattingVisitor, null); var changes = new List<Change> (); changes.AddRange (formattingVisitor.Changes. Where (c => c is TextReplaceChange && (startOffset <= ((TextReplaceChange)c).Offset && ((TextReplaceChange)c).Offset < endOffset))); RefactoringService.AcceptChanges (null, null, changes); }
public string FormatText(PlayScriptFormattingPolicy policy, TextStylePolicy textPolicy, string mimeType, string input, int startOffset, int endOffset) { var data = new TextEditorData(); data.Document.SuppressHighlightUpdate = true; data.Document.MimeType = mimeType; data.Document.FileName = "toformat.cs"; if (textPolicy != null) { data.Options.TabsToSpaces = textPolicy.TabsToSpaces; data.Options.TabSize = textPolicy.TabWidth; data.Options.IndentationSize = textPolicy.IndentWidth; data.Options.IndentStyle = textPolicy.RemoveTrailingWhitespace ? IndentStyle.Virtual : IndentStyle.Smart; } data.Text = input; // System.Console.WriteLine ("-----"); // System.Console.WriteLine (data.Text.Replace (" ", ".").Replace ("\t", "->")); // System.Console.WriteLine ("-----"); var parser = new PlayScriptParser(); var compilationUnit = parser.Parse(data); bool hadErrors = parser.HasErrors; if (hadErrors) { // foreach (var e in parser.ErrorReportPrinter.Errors) // Console.WriteLine (e.Message); return(input.Substring(startOffset, Math.Max(0, Math.Min(endOffset, input.Length) - startOffset))); } var originalVersion = data.Document.Version; var textEditorOptions = data.CreateNRefactoryTextEditorOptions(); var formattingVisitor = new AstFormattingVisitor( policy.CreateOptions(), data.Document, textEditorOptions ) { HadErrors = hadErrors, FormattingMode = FormattingMode.Intrusive }; compilationUnit.AcceptVisitor(formattingVisitor); try { formattingVisitor.ApplyChanges(startOffset, endOffset - startOffset); } catch (Exception e) { LoggingService.LogError("Error in code formatter", e); return(input.Substring(startOffset, Math.Max(0, Math.Min(endOffset, input.Length) - startOffset))); } // check if the formatter has produced errors parser = new PlayScriptParser(); parser.Parse(data); if (parser.HasErrors) { LoggingService.LogError("C# formatter produced source code errors. See console for output."); return(input.Substring(startOffset, Math.Max(0, Math.Min(endOffset, input.Length) - startOffset))); } var currentVersion = data.Document.Version; string result = data.GetTextBetween(startOffset, originalVersion.MoveOffsetTo(currentVersion, endOffset, ICSharpCode.NRefactory.Editor.AnchorMovementType.Default)); 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 || !u.ValidRegion.Contains(location)) { continue; } // indicates a parser error on namespace level. if (u.Namespaces.FirstOrDefault() == "<invalid>") { continue; } validRegion = u.ValidRegion; sb.Append("namespace Stub {"); sb.Append(data.Editor.EolMarker); closingBrackets++; } var parent = member.DeclaringType; while (parent != null) { sb.Append("class Stub {"); sb.Append(data.Editor.EolMarker); closingBrackets++; parent = parent.DeclaringType; } 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; } int startOffset = sb.Length; sb.Append(data.Editor.GetTextBetween(memberStart, memberEnd)); int endOffset = sb.Length; sb.Append(data.Editor.EolMarker); sb.Append(new string ('}', closingBrackets)); TextEditorData stubData = new TextEditorData() { Text = sb.ToString() }; stubData.Document.FileName = data.FileName; var parser = new ICSharpCode.NRefactory.CSharp.CSharpParser(); var compilationUnit = parser.Parse(stubData); bool hadErrors = parser.HasErrors; var policy = policyParent.Get <CSharpFormattingPolicy> (mimeTypeChain); var adapter = new TextEditorDataAdapter(stubData); var domSpacingVisitor = new AstFormattingVisitor(policy.CreateOptions(), adapter, new FormattingActionFactory(data.Editor)) { HadErrors = hadErrors }; compilationUnit.AcceptVisitor(domSpacingVisitor, null); var changes = new List <ICSharpCode.NRefactory.CSharp.Refactoring.Action> (); changes.AddRange(domSpacingVisitor.Changes.Cast <TextReplaceAction> ().Where(c => startOffset < c.Offset && c.Offset < endOffset)); int delta = memberStart - startOffset; HashSet <int> lines = new HashSet <int> (); foreach (TextReplaceAction change in changes) { 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 (hadErrors || data.ParsedDocument.Errors.Any(e => e.ErrorType == ErrorType.Error)) { var lastOffset = data.Editor.Caret.Offset; changes.RemoveAll(c => ((TextReplaceAction)c).Offset > lastOffset); } using (var undo = data.Editor.OpenUndoGroup()) { MDRefactoringContext.MdScript.RunActions(changes, null); 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*/) { 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; // indicates a parser error on namespace level. if (u.Namespaces.FirstOrDefault () == "<invalid>") 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 (); var compilationUnit = parser.Parse (stubData); bool hadErrors = parser.HasErrors; var policy = policyParent.Get<CSharpFormattingPolicy> (mimeTypeChain); var domSpacingVisitor = new AstFormattingVisitor (policy, stubData) { AutoAcceptChanges = false, HadErrors = hadErrors }; 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 (hadErrors || 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*/) { 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(); }