1
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team
3
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
4
// software and associated documentation files (the "Software"), to deal in the Software
5
// without restriction, including without limitation the rights to use, copy, modify, merge,
6
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
7
// to whom the Software is furnished to do so, subject to the following conditions:
9
// The above copyright notice and this permission notice shall be included in all copies or
10
// substantial portions of the Software.
12
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
13
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
14
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
15
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
16
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
17
// DEALINGS IN THE SOFTWARE.
20
using System.Diagnostics;
21
using ICSharpCode.NRefactory.Editor;
23
namespace ICSharpCode.NRefactory.CSharp.Refactoring
26
/// Script implementation based on IDocument.
28
public class DocumentScript : Script
30
readonly IDocument currentDocument;
32
public IDocument CurrentDocument {
33
get { return currentDocument; }
35
readonly IDocument originalDocument;
37
public IDocument OriginalDocument {
38
get { return originalDocument; }
40
readonly IDisposable undoGroup;
43
public DocumentScript(IDocument document, CSharpFormattingOptions formattingOptions, TextEditorOptions options) : base(formattingOptions, options)
45
this.originalDocument = document.CreateDocumentSnapshot();
46
this.currentDocument = document;
47
Debug.Assert(currentDocument.Version.CompareAge(originalDocument.Version) == 0);
48
this.undoGroup = document.OpenUndoGroup();
51
public override void Dispose()
53
if (undoGroup != null)
58
public override void Remove(AstNode node, bool removeEmptyLine)
60
var segment = GetSegment (node);
61
int startOffset = segment.Offset;
62
int endOffset = segment.EndOffset;
63
var startLine = currentDocument.GetLineByOffset (startOffset);
64
var endLine = currentDocument.GetLineByOffset (endOffset);
66
if (startLine != null && endLine != null) {
67
bool removeStart = string.IsNullOrWhiteSpace (currentDocument.GetText (startLine.Offset, startOffset - startLine.Offset));
69
startOffset = startLine.Offset;
70
bool removeEnd = string.IsNullOrWhiteSpace (currentDocument.GetText (endOffset, endLine.EndOffset - endOffset));
72
endOffset = endLine.EndOffset;
74
// Remove delimiter if the whole line get's removed.
75
if (removeStart && removeEnd)
76
endOffset += endLine.DelimiterLength;
79
Replace (startOffset, endOffset - startOffset, string.Empty);
82
public override void Replace(int offset, int length, string newText)
84
currentDocument.Replace(offset, length, newText);
87
public override int GetCurrentOffset(TextLocation originalDocumentLocation)
89
int offset = originalDocument.GetOffset(originalDocumentLocation);
90
return GetCurrentOffset(offset);
93
public override int GetCurrentOffset(int originalDocumentOffset)
95
return originalDocument.Version.MoveOffsetTo(currentDocument.Version, originalDocumentOffset);
98
public override void FormatText(AstNode node)
100
var segment = GetSegment(node);
101
var cu = CompilationUnit.Parse(currentDocument, "dummy.cs");
102
var formatter = new AstFormattingVisitor(FormattingOptions, currentDocument, Options);
103
cu.AcceptVisitor(formatter);
104
formatter.ApplyChanges(segment.Offset, segment.Length);
107
protected override int GetIndentLevelAt(int offset)
109
var line = currentDocument.GetLineByOffset(offset);
111
int indentationLevel = 0;
112
for (int i = line.Offset; i < currentDocument.TextLength; i++) {
113
char c = currentDocument.GetCharAt(i);
117
} else if (c == ' ') {
127
return indentationLevel;
130
protected override ISegment CreateTrackedSegment(int offset, int length)
132
return new TrackedSegment(this, offset, offset + length);
135
sealed class TrackedSegment : ISegment
137
readonly DocumentScript script;
138
readonly ITextSourceVersion originalVersion;
139
readonly int originalStart;
140
readonly int originalEnd;
142
public TrackedSegment(DocumentScript script, int originalStart, int originalEnd)
144
this.script = script;
145
this.originalVersion = script.currentDocument.Version;
146
this.originalStart = originalStart;
147
this.originalEnd = originalEnd;
151
get { return originalVersion.MoveOffsetTo(script.currentDocument.Version, originalStart); }
155
get { return this.EndOffset - this.Offset; }
158
public int EndOffset {
159
get { return originalVersion.MoveOffsetTo(script.currentDocument.Version, originalEnd); }