Browse Source

More work on context actions.

newNRvisualizers
Daniel Grunwald 14 years ago
parent
commit
3ce7c07e75
  1. 55
      src/AddIns/BackendBindings/CSharpBinding/Project/Src/Refactoring/SDScript.cs
  2. 36
      src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/ContextActionsRenderer.cs
  3. 9
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Editing/Caret.cs
  4. 12
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Editing/SimpleSelection.cs
  5. 22
      src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/AstNode.cs
  6. 520
      src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Formatter/AstFormattingVisitor.cs
  7. 2
      src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/OutputVisitor/CSharpOutputVisitor.cs
  8. 2
      src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/ContextAction/AddAnotherAccessor.cs
  9. 16
      src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/ContextAction/CreateBackingStore.cs
  10. 22
      src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/Script.cs
  11. 5
      src/Libraries/NRefactory/ICSharpCode.NRefactory/Editor/ReadOnlyDocument.cs
  12. 10
      src/Main/Base/Project/Src/Services/RefactoringService/ContextActions/ContextActionsBulbViewModel.cs

55
src/AddIns/BackendBindings/CSharpBinding/Project/Src/Refactoring/SDScript.cs

@ -3,6 +3,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using CSharpBinding.Parser;
using ICSharpCode.AvalonEdit.Document; using ICSharpCode.AvalonEdit.Document;
using ICSharpCode.NRefactory; using ICSharpCode.NRefactory;
using ICSharpCode.NRefactory.CSharp; using ICSharpCode.NRefactory.CSharp;
@ -10,6 +11,7 @@ using ICSharpCode.NRefactory.CSharp.Refactoring;
using ICSharpCode.NRefactory.Editor; using ICSharpCode.NRefactory.Editor;
using ICSharpCode.NRefactory.TypeSystem; using ICSharpCode.NRefactory.TypeSystem;
using ICSharpCode.SharpDevelop.Editor; using ICSharpCode.SharpDevelop.Editor;
using ICSharpCode.SharpDevelop.Parser;
namespace CSharpBinding.Refactoring namespace CSharpBinding.Refactoring
{ {
@ -20,33 +22,32 @@ namespace CSharpBinding.Refactoring
{ {
int indentationSize = 4; int indentationSize = 4;
readonly ITextEditor editor; readonly ITextEditor editor;
readonly TextSegmentCollection<TextSegment> textSegmentCollection = new TextSegmentCollection<TextSegment>(); readonly IDocument originalDocument;
readonly OffsetChangeMap offsetChangeMap = new OffsetChangeMap(); readonly TextSegmentCollection<TextSegment> textSegmentCollection;
readonly List<Action> actions = new List<Action>(); readonly IDisposable undoGroup;
public SDScript(ITextEditor editor, string eolMarker) : base(eolMarker, new CSharpFormattingOptions()) public SDScript(ITextEditor editor, string eolMarker) : base(eolMarker, new CSharpFormattingOptions())
{ {
this.editor = editor; this.editor = editor;
this.textSegmentCollection = new TextSegmentCollection<TextSegment>((TextDocument)editor.Document);
this.originalDocument = editor.Document.CreateDocumentSnapshot();
undoGroup = editor.Document.OpenUndoGroup();
} }
public override int GetCurrentOffset(TextLocation originalDocumentLocation) public override int GetCurrentOffset(TextLocation originalDocumentLocation)
{ {
int offset = editor.Document.GetOffset(originalDocumentLocation); int offset = originalDocument.GetOffset(originalDocumentLocation);
return offsetChangeMap.GetNewOffset(offset, AnchorMovementType.Default); return GetCurrentOffset(offset);
} }
public override int GetCurrentOffset(int originalDocumentOffset) public override int GetCurrentOffset(int originalDocumentOffset)
{ {
return offsetChangeMap.GetNewOffset(originalDocumentOffset, AnchorMovementType.Default); return originalDocument.Version.MoveOffsetTo(editor.Document.Version, originalDocumentOffset, AnchorMovementType.Default);
} }
public override void Replace(int offset, int length, string newText) public override void Replace(int offset, int length, string newText)
{ {
var changeMapEntry = new OffsetChangeMapEntry(offset, length, newText.Length); editor.Document.Replace(offset, length, newText);
textSegmentCollection.UpdateOffsets(changeMapEntry);
offsetChangeMap.Add(changeMapEntry);
actions.Add(delegate { editor.Document.Replace(offset, length, newText); });
} }
protected override ISegment CreateTrackedSegment(int offset, int length) protected override ISegment CreateTrackedSegment(int offset, int length)
@ -60,7 +61,7 @@ namespace CSharpBinding.Refactoring
protected override int GetIndentLevelAt(int offset) protected override int GetIndentLevelAt(int offset)
{ {
int oldOffset = offsetChangeMap.Invert().GetNewOffset(offset, AnchorMovementType.Default); int oldOffset = editor.Document.Version.MoveOffsetTo(originalDocument.Version, offset, AnchorMovementType.Default);
var line = editor.Document.GetLineByOffset(oldOffset); var line = editor.Document.GetLineByOffset(oldOffset);
int spaces = 0; int spaces = 0;
int indentationLevel = 0; int indentationLevel = 0;
@ -84,29 +85,53 @@ namespace CSharpBinding.Refactoring
public override void Rename(IEntity entity, string name) public override void Rename(IEntity entity, string name)
{ {
// TODO
} }
public override void InsertWithCursor(string operation, AstNode node, InsertPosition defaultPosition) public override void InsertWithCursor(string operation, AstNode node, InsertPosition defaultPosition)
{ {
// TODO
} }
public override void FormatText(int offset, int length) public override void FormatText(int offset, int length)
{ {
var parseInfo = ParserService.Parse(editor.FileName, editor.Document) as CSharpFullParseInformation;
if (parseInfo != null) {
//var startLocation = editor.Document.GetLocation(offset);
//var endLocation = editor.Document.GetLocation(offset + length);
//var node = parseInfo.CompilationUnit.GetNodeContaining(startLocation, endLocation);
var formatter = new AstFormattingVisitor(new CSharpFormattingOptions(), editor.Document, false, 4);
parseInfo.CompilationUnit.AcceptVisitor(formatter);
formatter.ApplyChanges(offset, length);
}
}
public override void Select(AstNode node)
{
var segment = GetSegment(node);
int startOffset = segment.Offset;
int endOffset = segment.EndOffset;
// If the area to select includes a newline (e.g. node is a statement),
// exclude that newline from the selection.
if (endOffset > startOffset && editor.Document.GetLineByOffset(endOffset).Offset == endOffset) {
endOffset = editor.Document.GetLineByOffset(endOffset).PreviousLine.EndOffset;
}
editor.Select(startOffset, endOffset - startOffset);
} }
public override void Select(int offset, int length) public override void Select(int offset, int length)
{ {
actions.Add(delegate { editor.Select(offset, length); }); editor.Select(offset, length);
} }
public override void Link(params AstNode[] nodes) public override void Link(params AstNode[] nodes)
{ {
// TODO
} }
public override void Dispose() public override void Dispose()
{ {
foreach (var action in actions) undoGroup.Dispose();
action();
} }
} }
} }

36
src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/ContextActionsRenderer.cs

@ -67,7 +67,6 @@ namespace ICSharpCode.AvalonEdit.AddIn
public void Dispose() public void Dispose()
{ {
WorkbenchSingleton.Workbench.ActiveViewContentChanged -= WorkbenchSingleton_Workbench_ActiveViewContentChanged; WorkbenchSingleton.Workbench.ActiveViewContentChanged -= WorkbenchSingleton_Workbench_ActiveViewContentChanged;
delayMoveTimer.Stop();
ClosePopup(); ClosePopup();
} }
@ -75,8 +74,7 @@ namespace ICSharpCode.AvalonEdit.AddIn
{ {
if (this.popup == null) if (this.popup == null)
return; return;
if (e.Key == Key.T && Keyboard.Modifiers == ModifierKeys.Control) if (e.Key == Key.T && Keyboard.Modifiers == ModifierKeys.Control) {
{
if (popup.ViewModel != null && popup.ViewModel.Actions != null && popup.ViewModel.Actions.Count > 0) { if (popup.ViewModel != null && popup.ViewModel.Actions != null && popup.ViewModel.Actions.Count > 0) {
popup.IsDropdownOpen = true; popup.IsDropdownOpen = true;
popup.Focus(); popup.Focus();
@ -87,18 +85,20 @@ namespace ICSharpCode.AvalonEdit.AddIn
this.cancellationTokenSourceForPopupBeingOpened = new CancellationTokenSource(); this.cancellationTokenSourceForPopupBeingOpened = new CancellationTokenSource();
var cancellationToken = cancellationTokenSourceForPopupBeingOpened.Token; var cancellationToken = cancellationTokenSourceForPopupBeingOpened.Token;
try { try {
await Task.WhenAll(popupVM.LoadActionsAsync(cancellationToken), popupVM.LoadHiddenActionsAsync(cancellationToken)); await popupVM.LoadActionsAsync(cancellationToken);
if (popupVM.Actions.Count == 0)
await popupVM.LoadHiddenActionsAsync(cancellationToken);
} catch (OperationCanceledException) { } catch (OperationCanceledException) {
return; return;
} }
if (cancellationToken.IsCancellationRequested) if (cancellationToken.IsCancellationRequested)
return; return;
this.cancellationTokenSourceForPopupBeingOpened = null; this.cancellationTokenSourceForPopupBeingOpened = null;
if (popupVM.HiddenActions.Count == 0) if (popupVM.Actions.Count == 0 && popupVM.HiddenActions.Count == 0)
return; return;
this.popup.ViewModel = popupVM; this.popup.ViewModel = popupVM;
this.popup.IsDropdownOpen = true; this.popup.IsDropdownOpen = true;
this.popup.IsHiddenActionsExpanded = true; this.popup.IsHiddenActionsExpanded = popupVM.Actions.Count == 0;
this.popup.OpenAtLineStart(this.Editor); this.popup.OpenAtLineStart(this.Editor);
this.popup.Focus(); this.popup.Focus();
} }
@ -107,17 +107,18 @@ namespace ICSharpCode.AvalonEdit.AddIn
void ScrollChanged(object sender, EventArgs e) void ScrollChanged(object sender, EventArgs e)
{ {
ClosePopup(); StartTimer();
} }
CancellationTokenSource cancellationTokenSourceForPopupBeingOpened; CancellationTokenSource cancellationTokenSourceForPopupBeingOpened;
async void TimerMoveTick(object sender, EventArgs e) async void TimerMoveTick(object sender, EventArgs e)
{ {
this.delayMoveTimer.Stop(); if (!delayMoveTimer.IsEnabled)
if (!IsEnabled)
return; return;
ClosePopup(); ClosePopup();
if (!IsEnabled)
return;
ContextActionsBulbViewModel popupVM = BuildPopupViewModel(this.Editor); ContextActionsBulbViewModel popupVM = BuildPopupViewModel(this.Editor);
this.cancellationTokenSourceForPopupBeingOpened = new CancellationTokenSource(); this.cancellationTokenSourceForPopupBeingOpened = new CancellationTokenSource();
@ -144,10 +145,16 @@ namespace ICSharpCode.AvalonEdit.AddIn
} }
void CaretPositionChanged(object sender, EventArgs e) void CaretPositionChanged(object sender, EventArgs e)
{
StartTimer();
}
void StartTimer()
{ {
ClosePopup(); ClosePopup();
this.delayMoveTimer.Stop(); IViewContent activeViewContent = WorkbenchSingleton.Workbench.ActiveViewContent;
this.delayMoveTimer.Start(); if (activeViewContent != null && activeViewContent.PrimaryFileName == this.Editor.FileName)
delayMoveTimer.Start();
} }
void ClosePopup() void ClosePopup()
@ -158,6 +165,7 @@ namespace ICSharpCode.AvalonEdit.AddIn
cancellationTokenSourceForPopupBeingOpened = null; cancellationTokenSourceForPopupBeingOpened = null;
} }
this.delayMoveTimer.Stop();
this.popup.Close(); this.popup.Close();
this.popup.IsDropdownOpen = false; this.popup.IsDropdownOpen = false;
this.popup.IsHiddenActionsExpanded = false; this.popup.IsHiddenActionsExpanded = false;
@ -166,11 +174,7 @@ namespace ICSharpCode.AvalonEdit.AddIn
void WorkbenchSingleton_Workbench_ActiveViewContentChanged(object sender, EventArgs e) void WorkbenchSingleton_Workbench_ActiveViewContentChanged(object sender, EventArgs e)
{ {
// open the popup again if in current file // open the popup again if in current file
IViewContent activeViewContent = WorkbenchSingleton.Workbench.ActiveViewContent; StartTimer();
if (activeViewContent != null && activeViewContent.PrimaryFileName == this.Editor.FileName)
CaretPositionChanged(this, EventArgs.Empty);
else // otherwise close popup
ClosePopup();
} }
} }
} }

9
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Editing/Caret.cs

@ -167,7 +167,14 @@ namespace ICSharpCode.AvalonEdit.Editing
{ {
InvalidateVisualColumn(); InvalidateVisualColumn();
if (storedCaretOffset >= 0) { if (storedCaretOffset >= 0) {
int newCaretOffset = e.GetNewOffset(storedCaretOffset, AnchorMovementType.Default); // If the caret is at the end of a selection, we don't expand the selection if something
// is inserted at the end. Thus we also need to keep the caret in front of the insertion.
AnchorMovementType caretMovementType;
if (!textArea.Selection.IsEmpty && storedCaretOffset == textArea.Selection.SurroundingSegment.EndOffset)
caretMovementType = AnchorMovementType.BeforeInsertion;
else
caretMovementType = AnchorMovementType.Default;
int newCaretOffset = e.GetNewOffset(storedCaretOffset, caretMovementType);
TextDocument document = textArea.Document; TextDocument document = textArea.Document;
if (document != null) { if (document != null) {
// keep visual column // keep visual column

12
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Editing/SimpleSelection.cs

@ -89,10 +89,18 @@ namespace ICSharpCode.AvalonEdit.Editing
{ {
if (e == null) if (e == null)
throw new ArgumentNullException("e"); throw new ArgumentNullException("e");
int newStartOffset, newEndOffset;
if (startOffset <= endOffset) {
newStartOffset = e.GetNewOffset(startOffset, AnchorMovementType.Default);
newEndOffset = Math.Max(newStartOffset, e.GetNewOffset(endOffset, AnchorMovementType.BeforeInsertion));
} else {
newEndOffset = e.GetNewOffset(endOffset, AnchorMovementType.Default);
newStartOffset = Math.Max(newEndOffset, e.GetNewOffset(startOffset, AnchorMovementType.BeforeInsertion));
}
return Selection.Create( return Selection.Create(
textArea, textArea,
new TextViewPosition(textArea.Document.GetLocation(e.GetNewOffset(startOffset, AnchorMovementType.Default)), start.VisualColumn), new TextViewPosition(textArea.Document.GetLocation(newStartOffset), start.VisualColumn),
new TextViewPosition(textArea.Document.GetLocation(e.GetNewOffset(endOffset, AnchorMovementType.Default)), end.VisualColumn) new TextViewPosition(textArea.Document.GetLocation(newEndOffset), end.VisualColumn)
); );
} }

22
src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/AstNode.cs

@ -169,6 +169,13 @@ namespace ICSharpCode.NRefactory.CSharp
public Role Role { public Role Role {
get { return role; } get { return role; }
set {
if (value == null)
throw new ArgumentNullException("value");
if (!value.IsValid(this))
throw new ArgumentException("This node is not valid in the new role.");
role = value;
}
} }
public AstNode NextSibling { public AstNode NextSibling {
@ -350,7 +357,6 @@ namespace ICSharpCode.NRefactory.CSharp
parent.lastChild = prevSibling; parent.lastChild = prevSibling;
} }
parent = null; parent = null;
role = Roles.Root;
prevSibling = null; prevSibling = null;
nextSibling = null; nextSibling = null;
} }
@ -408,7 +414,6 @@ namespace ICSharpCode.NRefactory.CSharp
parent = null; parent = null;
prevSibling = null; prevSibling = null;
nextSibling = null; nextSibling = null;
role = Roles.Root;
} }
} }
@ -450,7 +455,6 @@ namespace ICSharpCode.NRefactory.CSharp
AstNode copy = (AstNode)MemberwiseClone (); AstNode copy = (AstNode)MemberwiseClone ();
// First, reset the shallow pointer copies // First, reset the shallow pointer copies
copy.parent = null; copy.parent = null;
copy.role = Roles.Root;
copy.firstChild = null; copy.firstChild = null;
copy.lastChild = null; copy.lastChild = null;
copy.prevSibling = null; copy.prevSibling = null;
@ -590,6 +594,18 @@ namespace ICSharpCode.NRefactory.CSharp
return result; return result;
} }
/// <summary>
/// Gets the node that fully contains the range from startLocation to endLocation.
/// </summary>
public AstNode GetNodeContaining(TextLocation startLocation, TextLocation endLocation)
{
for (AstNode child = firstChild; child != null; child = child.nextSibling) {
if (child.StartLocation <= startLocation && endLocation <= child.EndLocation)
return child.GetNodeContaining(startLocation, endLocation);
}
return this;
}
public IEnumerable<AstNode> GetNodesBetween (int startLine, int startColumn, int endLine, int endColumn) public IEnumerable<AstNode> GetNodesBetween (int startLine, int startColumn, int endLine, int endColumn)
{ {
return GetNodesBetween (new TextLocation (startLine, startColumn), new TextLocation (endLine, endColumn)); return GetNodesBetween (new TextLocation (startLine, startColumn), new TextLocation (endLine, endColumn));

520
src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Formatter/AstFormattingVisitor.cs

@ -1,6 +1,6 @@
// //
// AstFormattingVisitor.cs // AstFormattingVisitor.cs
// //
// Author: // Author:
// Mike Krüger <mkrueger@novell.com> // Mike Krüger <mkrueger@novell.com>
// //
@ -24,6 +24,7 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE. // THE SOFTWARE.
using System; using System;
using System.Diagnostics;
using System.Text; using System.Text;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
@ -35,10 +36,23 @@ namespace ICSharpCode.NRefactory.CSharp
{ {
public class AstFormattingVisitor : DepthFirstAstVisitor<object, object> public class AstFormattingVisitor : DepthFirstAstVisitor<object, object>
{ {
struct TextReplaceAction
{
internal readonly int Offset;
internal readonly int RemovalLength;
internal readonly string NewText;
public TextReplaceAction(int offset, int removalLength, string newText)
{
this.Offset = offset;
this.RemovalLength = removalLength;
this.NewText = newText;
}
}
CSharpFormattingOptions policy; CSharpFormattingOptions policy;
IDocument document; IDocument document;
Script script; List<TextReplaceAction> changes = new List<TextReplaceAction> ();
//List<TextReplaceAction> changes = new List<TextReplaceAction> ();
Indent curIndent = new Indent (); Indent curIndent = new Indent ();
public int IndentLevel { public int IndentLevel {
@ -67,22 +81,70 @@ namespace ICSharpCode.NRefactory.CSharp
public string EolMarker { get; set; } public string EolMarker { get; set; }
public AstFormattingVisitor (CSharpFormattingOptions policy, IDocument document, Script script, bool tabsToSpaces = false, int indentationSize = 4) public AstFormattingVisitor (CSharpFormattingOptions policy, IDocument document, bool tabsToSpaces = false, int indentationSize = 4)
{ {
if (policy == null) if (policy == null)
throw new ArgumentNullException("policy"); throw new ArgumentNullException("policy");
if (document == null) if (document == null)
throw new ArgumentNullException("document"); throw new ArgumentNullException("document");
if (script == null)
throw new ArgumentNullException("script");
this.policy = policy; this.policy = policy;
this.document = document; this.document = document;
this.script = script;
this.curIndent.TabsToSpaces = tabsToSpaces; this.curIndent.TabsToSpaces = tabsToSpaces;
this.curIndent.TabSize = indentationSize; this.curIndent.TabSize = indentationSize;
this.EolMarker = Environment.NewLine; this.EolMarker = Environment.NewLine;
CorrectBlankLines = true; CorrectBlankLines = true;
} }
/// <summary>
/// Applies the changes to the input document.
/// </summary>
public void ApplyChanges()
{
ApplyChanges(0, document.TextLength, document.Replace);
}
public void ApplyChanges(int startOffset, int length)
{
ApplyChanges(startOffset, length, document.Replace);
}
/// <summary>
/// Applies the changes to the given Script instance.
/// </summary>
public void ApplyChanges(Script script)
{
ApplyChanges(0, document.TextLength, script.Replace);
}
public void ApplyChanges(int startOffset, int length, Script script)
{
ApplyChanges(startOffset, length, script.Replace);
}
void ApplyChanges(int startOffset, int length, Action<int, int, string> documentReplace)
{
int endOffset = startOffset + length;
int lastChangeEnd = 0;
int delta = 0;
foreach (var change in changes.OrderBy(c => c.Offset)) {
if (change.Offset < lastChangeEnd) {
Debug.Fail("Detected overlapping change");
continue;
}
lastChangeEnd = change.Offset + change.RemovalLength;
if (change.Offset < startOffset) {
// skip all changes in front of the begin offset
continue;
} else if (change.Offset > endOffset) {
// skip this change unless it depends on one that we already applied
continue;
}
documentReplace(change.Offset + delta, change.RemovalLength, change.NewText);
delta += change.NewText.Length - change.RemovalLength;
}
changes.Clear();
}
public override object VisitCompilationUnit (CompilationUnit unit, object data) public override object VisitCompilationUnit (CompilationUnit unit, object data)
{ {
@ -137,9 +199,9 @@ namespace ICSharpCode.NRefactory.CSharp
public override object VisitUsingDeclaration (UsingDeclaration usingDeclaration, object data) public override object VisitUsingDeclaration (UsingDeclaration usingDeclaration, object data)
{ {
if (!(usingDeclaration.PrevSibling is UsingDeclaration || usingDeclaration.PrevSibling is UsingAliasDeclaration)) if (!(usingDeclaration.PrevSibling is UsingDeclaration || usingDeclaration.PrevSibling is UsingAliasDeclaration))
EnsureBlankLinesBefore (usingDeclaration, policy.BlankLinesBeforeUsings); EnsureBlankLinesBefore (usingDeclaration, policy.BlankLinesBeforeUsings);
if (!(usingDeclaration.NextSibling is UsingDeclaration || usingDeclaration.NextSibling is UsingAliasDeclaration)) if (!(usingDeclaration.NextSibling is UsingDeclaration || usingDeclaration.NextSibling is UsingAliasDeclaration))
EnsureBlankLinesAfter (usingDeclaration, policy.BlankLinesAfterUsings); EnsureBlankLinesAfter (usingDeclaration, policy.BlankLinesAfterUsings);
return null; return null;
@ -147,9 +209,9 @@ namespace ICSharpCode.NRefactory.CSharp
public override object VisitUsingAliasDeclaration (UsingAliasDeclaration usingDeclaration, object data) public override object VisitUsingAliasDeclaration (UsingAliasDeclaration usingDeclaration, object data)
{ {
if (!(usingDeclaration.PrevSibling is UsingDeclaration || usingDeclaration.PrevSibling is UsingAliasDeclaration)) if (!(usingDeclaration.PrevSibling is UsingDeclaration || usingDeclaration.PrevSibling is UsingAliasDeclaration))
EnsureBlankLinesBefore (usingDeclaration, policy.BlankLinesBeforeUsings); EnsureBlankLinesBefore (usingDeclaration, policy.BlankLinesBeforeUsings);
if (!(usingDeclaration.NextSibling is UsingDeclaration || usingDeclaration.NextSibling is UsingAliasDeclaration)) if (!(usingDeclaration.NextSibling is UsingDeclaration || usingDeclaration.NextSibling is UsingAliasDeclaration))
EnsureBlankLinesAfter (usingDeclaration, policy.BlankLinesAfterUsings); EnsureBlankLinesAfter (usingDeclaration, policy.BlankLinesAfterUsings);
return null; return null;
} }
@ -176,24 +238,24 @@ namespace ICSharpCode.NRefactory.CSharp
BraceStyle braceStyle; BraceStyle braceStyle;
bool indentBody = false; bool indentBody = false;
switch (typeDeclaration.ClassType) { switch (typeDeclaration.ClassType) {
case ClassType.Class: case ClassType.Class:
braceStyle = policy.ClassBraceStyle; braceStyle = policy.ClassBraceStyle;
indentBody = policy.IndentClassBody; indentBody = policy.IndentClassBody;
break; break;
case ClassType.Struct: case ClassType.Struct:
braceStyle = policy.StructBraceStyle; braceStyle = policy.StructBraceStyle;
indentBody = policy.IndentStructBody; indentBody = policy.IndentStructBody;
break; break;
case ClassType.Interface: case ClassType.Interface:
braceStyle = policy.InterfaceBraceStyle; braceStyle = policy.InterfaceBraceStyle;
indentBody = policy.IndentInterfaceBody; indentBody = policy.IndentInterfaceBody;
break; break;
case ClassType.Enum: case ClassType.Enum:
braceStyle = policy.EnumBraceStyle; braceStyle = policy.EnumBraceStyle;
indentBody = policy.IndentEnumBody; indentBody = policy.IndentEnumBody;
break; break;
default: default:
throw new InvalidOperationException ("unsupported class type : " + typeDeclaration.ClassType); throw new InvalidOperationException ("unsupported class type : " + typeDeclaration.ClassType);
} }
EnforceBraceStyle (braceStyle, typeDeclaration.LBraceToken, typeDeclaration.RBraceToken); EnforceBraceStyle (braceStyle, typeDeclaration.LBraceToken, typeDeclaration.RBraceToken);
@ -302,10 +364,10 @@ namespace ICSharpCode.NRefactory.CSharp
// if (n == null || n.IsNull) // if (n == null || n.IsNull)
// return 0; // return 0;
// AstLocation location = n.StartLocation; // AstLocation location = n.StartLocation;
// //
// int offset = data.LocationToOffset (location.Line, location.Column); // int offset = data.LocationToOffset (location.Line, location.Column);
// int i = offset - 1; // int i = offset - 1;
// //
// while (i >= 0 && IsSpacing (data.GetCharAt (i))) { // while (i >= 0 && IsSpacing (data.GetCharAt (i))) {
// i--; // i--;
// } // }
@ -321,7 +383,7 @@ namespace ICSharpCode.NRefactory.CSharp
// respect manual line breaks. // respect manual line breaks.
if (location.Column <= 1 || GetIndentation (location.Line).Length == location.Column - 1) if (location.Column <= 1 || GetIndentation (location.Line).Length == location.Column - 1)
return 0; return 0;
int offset = document.GetOffset (location); int offset = document.GetOffset (location);
int i = offset - 1; int i = offset - 1;
while (i >= 0 && IsSpacing (document.GetCharAt (i))) { while (i >= 0 && IsSpacing (document.GetCharAt (i))) {
@ -336,39 +398,39 @@ namespace ICSharpCode.NRefactory.CSharp
FormatAttributedNode (propertyDeclaration); FormatAttributedNode (propertyDeclaration);
bool oneLine = false; bool oneLine = false;
switch (policy.PropertyFormatting) { switch (policy.PropertyFormatting) {
case PropertyFormatting.AllowOneLine: case PropertyFormatting.AllowOneLine:
bool isSimple = IsSimpleAccessor (propertyDeclaration.Getter) && IsSimpleAccessor (propertyDeclaration.Setter); bool isSimple = IsSimpleAccessor (propertyDeclaration.Getter) && IsSimpleAccessor (propertyDeclaration.Setter);
if (!isSimple || propertyDeclaration.LBraceToken.StartLocation.Line != propertyDeclaration.RBraceToken.StartLocation.Line) { if (!isSimple || propertyDeclaration.LBraceToken.StartLocation.Line != propertyDeclaration.RBraceToken.StartLocation.Line) {
EnforceBraceStyle (policy.PropertyBraceStyle, propertyDeclaration.LBraceToken, propertyDeclaration.RBraceToken); EnforceBraceStyle (policy.PropertyBraceStyle, propertyDeclaration.LBraceToken, propertyDeclaration.RBraceToken);
} else { } else {
ForceSpacesBefore (propertyDeclaration.Getter, true); ForceSpacesBefore (propertyDeclaration.Getter, true);
ForceSpacesBefore (propertyDeclaration.Setter, true); ForceSpacesBefore (propertyDeclaration.Setter, true);
ForceSpacesBefore (propertyDeclaration.RBraceToken, true); ForceSpacesBefore (propertyDeclaration.RBraceToken, true);
oneLine = true; oneLine = true;
} }
break; break;
case PropertyFormatting.ForceNewLine: case PropertyFormatting.ForceNewLine:
EnforceBraceStyle (policy.PropertyBraceStyle, propertyDeclaration.LBraceToken, propertyDeclaration.RBraceToken);
break;
case PropertyFormatting.ForceOneLine:
isSimple = IsSimpleAccessor (propertyDeclaration.Getter) && IsSimpleAccessor (propertyDeclaration.Setter);
if (isSimple) {
int offset = this.document.GetOffset (propertyDeclaration.LBraceToken.StartLocation);
int start = SearchWhitespaceStart (offset);
int end = SearchWhitespaceEnd (offset);
AddChange (start, offset - start, " ");
AddChange (offset + 1, end - offset - 2, " ");
offset = this.document.GetOffset (propertyDeclaration.RBraceToken.StartLocation);
start = SearchWhitespaceStart (offset);
AddChange (start, offset - start, " ");
oneLine = true;
} else {
EnforceBraceStyle (policy.PropertyBraceStyle, propertyDeclaration.LBraceToken, propertyDeclaration.RBraceToken); EnforceBraceStyle (policy.PropertyBraceStyle, propertyDeclaration.LBraceToken, propertyDeclaration.RBraceToken);
} break;
break; case PropertyFormatting.ForceOneLine:
isSimple = IsSimpleAccessor (propertyDeclaration.Getter) && IsSimpleAccessor (propertyDeclaration.Setter);
if (isSimple) {
int offset = this.document.GetOffset (propertyDeclaration.LBraceToken.StartLocation);
int start = SearchWhitespaceStart (offset);
int end = SearchWhitespaceEnd (offset);
AddChange (start, offset - start, " ");
AddChange (offset + 1, end - offset - 2, " ");
offset = this.document.GetOffset (propertyDeclaration.RBraceToken.StartLocation);
start = SearchWhitespaceStart (offset);
AddChange (start, offset - start, " ");
oneLine = true;
} else {
EnforceBraceStyle (policy.PropertyBraceStyle, propertyDeclaration.LBraceToken, propertyDeclaration.RBraceToken);
}
break;
} }
if (policy.IndentPropertyBody) if (policy.IndentPropertyBody)
IndentLevel++; IndentLevel++;
@ -686,7 +748,7 @@ namespace ICSharpCode.NRefactory.CSharp
ForceSpacesBefore (constructorDeclaration.RParToken, policy.SpaceBetweenEmptyConstructorDeclarationParentheses); ForceSpacesBefore (constructorDeclaration.RParToken, policy.SpaceBetweenEmptyConstructorDeclarationParentheses);
} }
FormatCommas (constructorDeclaration, policy.SpaceBeforeConstructorDeclarationParameterComma, policy.SpaceAfterConstructorDeclarationParameterComma); FormatCommas (constructorDeclaration, policy.SpaceBeforeConstructorDeclarationParameterComma, policy.SpaceAfterConstructorDeclarationParameterComma);
object result = null; object result = null;
if (!constructorDeclaration.Body.IsNull) { if (!constructorDeclaration.Body.IsNull) {
EnforceBraceStyle (policy.ConstructorBraceStyle, constructorDeclaration.Body.LBraceToken, constructorDeclaration.Body.RBraceToken); EnforceBraceStyle (policy.ConstructorBraceStyle, constructorDeclaration.Body.LBraceToken, constructorDeclaration.Body.RBraceToken);
@ -809,53 +871,53 @@ namespace ICSharpCode.NRefactory.CSharp
int originalLevel = curIndent.Level; int originalLevel = curIndent.Level;
bool isBlock = node is BlockStatement; bool isBlock = node is BlockStatement;
switch (braceForcement) { switch (braceForcement) {
case BraceForcement.DoNotChange: case BraceForcement.DoNotChange:
//nothing //nothing
break; break;
case BraceForcement.AddBraces: case BraceForcement.AddBraces:
if (!isBlock) { if (!isBlock) {
AstNode n = node.Parent.GetCSharpNodeBefore (node); AstNode n = node.Parent.GetCSharpNodeBefore (node);
int start = document.GetOffset (n.EndLocation); int start = document.GetOffset (n.EndLocation);
var next = n.GetNextNode (); var next = n.GetNextNode ();
int offset = document.GetOffset (next.StartLocation); int offset = document.GetOffset (next.StartLocation);
string startBrace = ""; string startBrace = "";
switch (braceStyle) { switch (braceStyle) {
case BraceStyle.EndOfLineWithoutSpace: case BraceStyle.EndOfLineWithoutSpace:
startBrace = "{"; startBrace = "{";
break; break;
case BraceStyle.EndOfLine: case BraceStyle.EndOfLine:
startBrace = " {"; startBrace = " {";
break; break;
case BraceStyle.NextLine: case BraceStyle.NextLine:
startBrace = this.EolMarker + curIndent.IndentString + "{"; startBrace = this.EolMarker + curIndent.IndentString + "{";
break; break;
case BraceStyle.NextLineShifted2: case BraceStyle.NextLineShifted2:
case BraceStyle.NextLineShifted: case BraceStyle.NextLineShifted:
startBrace = this.EolMarker + curIndent.IndentString + curIndent.SingleIndent + "{"; startBrace = this.EolMarker + curIndent.IndentString + curIndent.SingleIndent + "{";
break; break;
}
if (IsLineIsEmptyUpToEol (document.GetOffset (node.StartLocation)))
startBrace += this.EolMarker + GetIndentation (node.StartLocation.Line);
AddChange (start, offset - start, startBrace);
} }
if (IsLineIsEmptyUpToEol (document.GetOffset (node.StartLocation))) break;
startBrace += this.EolMarker + GetIndentation (node.StartLocation.Line); case BraceForcement.RemoveBraces:
AddChange (start, offset - start, startBrace); if (isBlock) {
} BlockStatement block = node as BlockStatement;
break; if (block.Statements.Count () == 1) {
case BraceForcement.RemoveBraces: int offset1 = document.GetOffset (node.StartLocation);
if (isBlock) { int start = SearchWhitespaceStart (offset1);
BlockStatement block = node as BlockStatement;
if (block.Statements.Count () == 1) { int offset2 = document.GetOffset (node.EndLocation);
int offset1 = document.GetOffset (node.StartLocation); int end = SearchWhitespaceStart (offset2 - 1);
int start = SearchWhitespaceStart (offset1);
AddChange (start, offset1 - start + 1, null);
int offset2 = document.GetOffset (node.EndLocation); AddChange (end + 1, offset2 - end, null);
int end = SearchWhitespaceStart (offset2 - 1); node = block.FirstChild;
isBlock = false;
AddChange (start, offset1 - start + 1, null); }
AddChange (end + 1, offset2 - end, null);
node = block.FirstChild;
isBlock = false;
} }
} break;
break;
} }
if (isBlock) { if (isBlock) {
BlockStatement block = node as BlockStatement; BlockStatement block = node as BlockStatement;
@ -873,42 +935,42 @@ namespace ICSharpCode.NRefactory.CSharp
} }
} }
if (policy.IndentBlocks && if (policy.IndentBlocks &&
!(policy.AlignEmbeddedIfStatements && node is IfElseStatement && node.Parent is IfElseStatement || !(policy.AlignEmbeddedIfStatements && node is IfElseStatement && node.Parent is IfElseStatement ||
policy.AlignEmbeddedUsingStatements && node is UsingStatement && node.Parent is UsingStatement)) policy.AlignEmbeddedUsingStatements && node is UsingStatement && node.Parent is UsingStatement))
curIndent.Level++; curIndent.Level++;
object result = isBlock ? base.VisitBlockStatement ((BlockStatement)node, null) : node.AcceptVisitor (this, null); object result = isBlock ? base.VisitBlockStatement ((BlockStatement)node, null) : node.AcceptVisitor (this, null);
curIndent.Level = originalLevel; curIndent.Level = originalLevel;
switch (braceForcement) { switch (braceForcement) {
case BraceForcement.DoNotChange: case BraceForcement.DoNotChange:
break; break;
case BraceForcement.AddBraces: case BraceForcement.AddBraces:
if (!isBlock) { if (!isBlock) {
int offset = document.GetOffset (node.EndLocation); int offset = document.GetOffset (node.EndLocation);
if (!char.IsWhiteSpace (document.GetCharAt (offset))) if (!char.IsWhiteSpace (document.GetCharAt (offset)))
offset++; offset++;
string startBrace = ""; string startBrace = "";
switch (braceStyle) { switch (braceStyle) {
case BraceStyle.DoNotChange: case BraceStyle.DoNotChange:
startBrace = null; startBrace = null;
break; break;
case BraceStyle.EndOfLineWithoutSpace: case BraceStyle.EndOfLineWithoutSpace:
startBrace = this.EolMarker + curIndent.IndentString + "}"; startBrace = this.EolMarker + curIndent.IndentString + "}";
break; break;
case BraceStyle.EndOfLine: case BraceStyle.EndOfLine:
startBrace = this.EolMarker + curIndent.IndentString + "}"; startBrace = this.EolMarker + curIndent.IndentString + "}";
break; break;
case BraceStyle.NextLine: case BraceStyle.NextLine:
startBrace = this.EolMarker + curIndent.IndentString + "}"; startBrace = this.EolMarker + curIndent.IndentString + "}";
break; break;
case BraceStyle.NextLineShifted2: case BraceStyle.NextLineShifted2:
case BraceStyle.NextLineShifted: case BraceStyle.NextLineShifted:
startBrace = this.EolMarker + curIndent.IndentString + curIndent.SingleIndent + "}"; startBrace = this.EolMarker + curIndent.IndentString + curIndent.SingleIndent + "}";
break; break;
}
if (startBrace != null)
AddChange (offset, 0, startBrace);
} }
if (startBrace != null) break;
AddChange (offset, 0, startBrace);
}
break;
} }
return result; return result;
} }
@ -928,39 +990,39 @@ namespace ICSharpCode.NRefactory.CSharp
string startIndent = ""; string startIndent = "";
string endIndent = ""; string endIndent = "";
switch (braceStyle) { switch (braceStyle) {
case BraceStyle.DoNotChange: case BraceStyle.DoNotChange:
startIndent = endIndent = null; startIndent = endIndent = null;
break; break;
case BraceStyle.EndOfLineWithoutSpace: case BraceStyle.EndOfLineWithoutSpace:
startIndent = ""; startIndent = "";
endIndent = IsLineIsEmptyUpToEol (rbraceOffset) ? curIndent.IndentString : this.EolMarker + curIndent.IndentString; endIndent = IsLineIsEmptyUpToEol (rbraceOffset) ? curIndent.IndentString : this.EolMarker + curIndent.IndentString;
break; break;
case BraceStyle.EndOfLine: case BraceStyle.EndOfLine:
var prevNode = lbrace.GetPrevNode (); var prevNode = lbrace.GetPrevNode ();
if (prevNode is Comment) { if (prevNode is Comment) {
// delete old bracket // delete old bracket
AddChange (whitespaceStart, lbraceOffset - whitespaceStart + 1, ""); AddChange (whitespaceStart, lbraceOffset - whitespaceStart + 1, "");
while (prevNode is Comment) { while (prevNode is Comment) {
prevNode = prevNode.GetPrevNode (); prevNode = prevNode.GetPrevNode ();
}
whitespaceStart = document.GetOffset (prevNode.EndLocation);
lbraceOffset = whitespaceStart;
startIndent = " {";
} else {
startIndent = " ";
} }
whitespaceStart = document.GetOffset (prevNode.EndLocation); endIndent = IsLineIsEmptyUpToEol (rbraceOffset) ? curIndent.IndentString : this.EolMarker + curIndent.IndentString;
lbraceOffset = whitespaceStart; break;
startIndent = " {"; case BraceStyle.NextLine:
} else { startIndent = this.EolMarker + curIndent.IndentString;
startIndent = " "; endIndent = IsLineIsEmptyUpToEol (rbraceOffset) ? curIndent.IndentString : this.EolMarker + curIndent.IndentString;
} break;
endIndent = IsLineIsEmptyUpToEol (rbraceOffset) ? curIndent.IndentString : this.EolMarker + curIndent.IndentString; case BraceStyle.NextLineShifted2:
break; case BraceStyle.NextLineShifted:
case BraceStyle.NextLine: startIndent = this.EolMarker + curIndent.IndentString + curIndent.SingleIndent;
startIndent = this.EolMarker + curIndent.IndentString; endIndent = IsLineIsEmptyUpToEol (rbraceOffset) ? curIndent.IndentString + curIndent.SingleIndent : this.EolMarker + curIndent.IndentString + curIndent.SingleIndent;
endIndent = IsLineIsEmptyUpToEol (rbraceOffset) ? curIndent.IndentString : this.EolMarker + curIndent.IndentString; break;
break;
case BraceStyle.NextLineShifted2:
case BraceStyle.NextLineShifted:
startIndent = this.EolMarker + curIndent.IndentString + curIndent.SingleIndent;
endIndent = IsLineIsEmptyUpToEol (rbraceOffset) ? curIndent.IndentString + curIndent.SingleIndent : this.EolMarker + curIndent.IndentString + curIndent.SingleIndent;
break;
} }
if (lbraceOffset > 0 && startIndent != null) if (lbraceOffset > 0 && startIndent != null)
@ -971,35 +1033,7 @@ namespace ICSharpCode.NRefactory.CSharp
void AddChange (int offset, int removedChars, string insertedText) void AddChange (int offset, int removedChars, string insertedText)
{ {
script.Replace(offset, removedChars, insertedText); changes.Add(new TextReplaceAction(offset, removedChars, insertedText));
// if (changes.Any (c => c.Offset == offset && c.RemovedChars == removedChars
// && c.InsertedText == insertedText))
// return;
// string currentText = document.GetText (offset, removedChars);
// if (currentText == insertedText)
// return;
// if (currentText.Any (c => !(char.IsWhiteSpace (c) || c == '\r' || c == '\t' || c == '{' || c == '}')))
// throw new InvalidOperationException ("Tried to remove non ws chars: '" + currentText + "'");
// foreach (var change in changes) {
// if (change.Offset == offset) {
// if (removedChars > 0 && insertedText == change.InsertedText) {
// change.RemovedChars = removedChars;
//// change.InsertedText = insertedText;
// return;
// }
// if (!string.IsNullOrEmpty (change.InsertedText)) {
// change.InsertedText += insertedText;
// } else {
// change.InsertedText = insertedText;
// }
// change.RemovedChars = System.Math.Max (removedChars, change.RemovedChars);
// return;
// }
// }
// //Console.WriteLine ("offset={0}, removedChars={1}, insertedText={2}", offset, removedChars, insertedText == null ? "<null>" : insertedText.Replace ("\n", "\\n").Replace ("\r", "\\r").Replace ("\t", "\\t").Replace (" ", "."));
// //Console.WriteLine (Environment.StackTrace);
//
// changes.Add (factory.CreateTextReplaceAction (offset, removedChars, insertedText));
} }
public bool IsLineIsEmptyUpToEol (TextLocation startLocation) public bool IsLineIsEmptyUpToEol (TextLocation startLocation)
@ -1169,7 +1203,7 @@ namespace ICSharpCode.NRefactory.CSharp
} }
if (policy.IndentCaseBody) if (policy.IndentCaseBody)
curIndent.Level--; curIndent.Level--;
if (policy.IndentSwitchBody) if (policy.IndentSwitchBody)
curIndent.Level--; curIndent.Level--;
return null; return null;
@ -1322,41 +1356,41 @@ namespace ICSharpCode.NRefactory.CSharp
{ {
bool forceSpaces = false; bool forceSpaces = false;
switch (binaryOperatorExpression.Operator) { switch (binaryOperatorExpression.Operator) {
case BinaryOperatorType.Equality: case BinaryOperatorType.Equality:
case BinaryOperatorType.InEquality: case BinaryOperatorType.InEquality:
forceSpaces = policy.SpaceAroundEqualityOperator; forceSpaces = policy.SpaceAroundEqualityOperator;
break; break;
case BinaryOperatorType.GreaterThan: case BinaryOperatorType.GreaterThan:
case BinaryOperatorType.GreaterThanOrEqual: case BinaryOperatorType.GreaterThanOrEqual:
case BinaryOperatorType.LessThan: case BinaryOperatorType.LessThan:
case BinaryOperatorType.LessThanOrEqual: case BinaryOperatorType.LessThanOrEqual:
forceSpaces = policy.SpaceAroundRelationalOperator; forceSpaces = policy.SpaceAroundRelationalOperator;
break; break;
case BinaryOperatorType.ConditionalAnd: case BinaryOperatorType.ConditionalAnd:
case BinaryOperatorType.ConditionalOr: case BinaryOperatorType.ConditionalOr:
forceSpaces = policy.SpaceAroundLogicalOperator; forceSpaces = policy.SpaceAroundLogicalOperator;
break; break;
case BinaryOperatorType.BitwiseAnd: case BinaryOperatorType.BitwiseAnd:
case BinaryOperatorType.BitwiseOr: case BinaryOperatorType.BitwiseOr:
case BinaryOperatorType.ExclusiveOr: case BinaryOperatorType.ExclusiveOr:
forceSpaces = policy.SpaceAroundBitwiseOperator; forceSpaces = policy.SpaceAroundBitwiseOperator;
break; break;
case BinaryOperatorType.Add: case BinaryOperatorType.Add:
case BinaryOperatorType.Subtract: case BinaryOperatorType.Subtract:
forceSpaces = policy.SpaceAroundAdditiveOperator; forceSpaces = policy.SpaceAroundAdditiveOperator;
break; break;
case BinaryOperatorType.Multiply: case BinaryOperatorType.Multiply:
case BinaryOperatorType.Divide: case BinaryOperatorType.Divide:
case BinaryOperatorType.Modulus: case BinaryOperatorType.Modulus:
forceSpaces = policy.SpaceAroundMultiplicativeOperator; forceSpaces = policy.SpaceAroundMultiplicativeOperator;
break; break;
case BinaryOperatorType.ShiftLeft: case BinaryOperatorType.ShiftLeft:
case BinaryOperatorType.ShiftRight: case BinaryOperatorType.ShiftRight:
forceSpaces = policy.SpaceAroundShiftOperator; forceSpaces = policy.SpaceAroundShiftOperator;
break; break;
case BinaryOperatorType.NullCoalescing: case BinaryOperatorType.NullCoalescing:
forceSpaces = policy.SpaceAroundNullCoalescingOperator; forceSpaces = policy.SpaceAroundNullCoalescingOperator;
break; break;
} }
ForceSpacesAround (binaryOperatorExpression.OperatorToken, forceSpaces); ForceSpacesAround (binaryOperatorExpression.OperatorToken, forceSpaces);
@ -1554,7 +1588,7 @@ namespace ICSharpCode.NRefactory.CSharp
} }
return result; return result;
} }
*/ */
public void FixSemicolon (CSharpTokenNode semicolon) public void FixSemicolon (CSharpTokenNode semicolon)
@ -1569,7 +1603,7 @@ namespace ICSharpCode.NRefactory.CSharp
if (offset < endOffset) { if (offset < endOffset) {
AddChange (offset, endOffset - offset, null); AddChange (offset, endOffset - offset, null);
} }
} }
void PlaceOnNewLine (bool newLine, AstNode keywordNode) void PlaceOnNewLine (bool newLine, AstNode keywordNode)
{ {
@ -1611,7 +1645,7 @@ namespace ICSharpCode.NRefactory.CSharp
Console.WriteLine (Environment.StackTrace); Console.WriteLine (Environment.StackTrace);
return; return;
} }
string lineIndent = GetIndentation (location.Line); string lineIndent = GetIndentation (location.Line);
string indentString = this.curIndent.IndentString; string indentString = this.curIndent.IndentString;
if (indentString != lineIndent && location.Column - 1 + relOffset == lineIndent.Length) { if (indentString != lineIndent && location.Column - 1 + relOffset == lineIndent.Length) {
@ -1625,10 +1659,10 @@ namespace ICSharpCode.NRefactory.CSharp
string indentString = this.curIndent.IndentString; string indentString = this.curIndent.IndentString;
if (location.Column - 1 == lineIndent.Length) { if (location.Column - 1 == lineIndent.Length) {
AddChange (document.GetOffset (location.Line, 1), lineIndent.Length, indentString); AddChange (document.GetOffset (location.Line, 1), lineIndent.Length, indentString);
} else { } else {
int offset = document.GetOffset (location); int offset = document.GetOffset (location);
int start = SearchWhitespaceLineStart (offset); int start = SearchWhitespaceLineStart (offset);
if (start > 0) { if (start > 0) {
char ch = document.GetCharAt (start - 1); char ch = document.GetCharAt (start - 1);
if (ch == '\n') { if (ch == '\n') {
start--; start--;

2
src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/OutputVisitor/CSharpOutputVisitor.cs

@ -1510,7 +1510,7 @@ namespace ICSharpCode.NRefactory.CSharp
else if (blockStatement.Parent.Role == CustomEventDeclaration.RemoveAccessorRole) else if (blockStatement.Parent.Role == CustomEventDeclaration.RemoveAccessorRole)
style = policy.EventRemoveBraceStyle; style = policy.EventRemoveBraceStyle;
else else
throw new NotSupportedException ("Unknown type of accessor"); style = policy.StatementBraceStyle;
} else { } else {
style = policy.StatementBraceStyle; style = policy.StatementBraceStyle;
} }

2
src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/ContextAction/AddAnotherAccessor.cs

@ -52,7 +52,7 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
Body = new BlockStatement { accessorStatement } Body = new BlockStatement { accessorStatement }
}; };
pdecl.AddChild (accessor, pdecl.Setter.IsNull ? PropertyDeclaration.SetterRole : PropertyDeclaration.GetterRole); accessor.Role = pdecl.Setter.IsNull ? PropertyDeclaration.SetterRole : PropertyDeclaration.GetterRole;
using (var script = context.StartScript ()) { using (var script = context.StartScript ()) {
script.InsertBefore (pdecl.RBraceToken, accessor); script.InsertBefore (pdecl.RBraceToken, accessor);

16
src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/ContextAction/CreateBackingStore.cs

@ -1,6 +1,6 @@
// //
// CreateBackingStore.cs // CreateBackingStore.cs
// //
// Author: // Author:
// Mike Krüger <mkrueger@novell.com> // Mike Krüger <mkrueger@novell.com>
// //
@ -32,7 +32,7 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
public bool IsValid (RefactoringContext context) public bool IsValid (RefactoringContext context)
{ {
var propertyDeclaration = context.GetNode<PropertyDeclaration> (); var propertyDeclaration = context.GetNode<PropertyDeclaration> ();
return propertyDeclaration != null && return propertyDeclaration != null &&
!propertyDeclaration.Getter.IsNull && !propertyDeclaration.Setter.IsNull && // automatic properties always need getter & setter !propertyDeclaration.Getter.IsNull && !propertyDeclaration.Setter.IsNull && // automatic properties always need getter & setter
propertyDeclaration.Getter.Body.IsNull && propertyDeclaration.Getter.Body.IsNull &&
propertyDeclaration.Setter.Body.IsNull; propertyDeclaration.Setter.Body.IsNull;
@ -53,13 +53,17 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
// create new property & implement the get/set bodies // create new property & implement the get/set bodies
var newProperty = (PropertyDeclaration)property.Clone (); var newProperty = (PropertyDeclaration)property.Clone ();
var id1 = new IdentifierExpression (backingStoreName); Expression id1;
var id2 = new IdentifierExpression (backingStoreName); if (backingStoreName == "value")
id1 = new ThisReferenceExpression().Member("value");
else
id1 = new IdentifierExpression (backingStoreName);
Expression id2 = id1.Clone();
newProperty.Getter.Body = new BlockStatement () { newProperty.Getter.Body = new BlockStatement () {
new ReturnStatement (id1) new ReturnStatement (id1)
}; };
newProperty.Setter.Body = new BlockStatement () { newProperty.Setter.Body = new BlockStatement () {
new ExpressionStatement (new AssignmentExpression (id2, AssignmentOperatorType.Assign, new IdentifierExpression ("value"))) new AssignmentExpression (id2, AssignmentOperatorType.Assign, new IdentifierExpression ("value"))
}; };
using (var script = context.StartScript ()) { using (var script = context.StartScript ()) {

22
src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/Script.cs

@ -178,15 +178,33 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
output.RegisterTrackedSegments(this, startOffset); output.RegisterTrackedSegments(this, startOffset);
} }
public void FormatText (AstNode node) public virtual void FormatText (AstNode node)
{ {
var segment = GetSegment(node); var segment = GetSegment(node);
FormatText(segment.Offset, segment.Length); FormatText(segment.Offset, segment.Length);
} }
/// <summary>
/// Format the specified node and surrounding whitespace.
/// </summary>
public virtual void FormatTextAround (AstNode node)
{
int startOffset;
if (node.PrevSibling != null)
startOffset = GetSegment(node.PrevSibling).EndOffset;
else
startOffset = GetSegment(node).Offset;
int endOffset;
if (node.NextSibling != null)
endOffset = GetSegment(node.NextSibling).Offset;
else
endOffset = GetSegment(node).EndOffset;
FormatText(startOffset, endOffset - startOffset);
}
public abstract void FormatText (int offset, int length); public abstract void FormatText (int offset, int length);
public void Select (AstNode node) public virtual void Select (AstNode node)
{ {
var segment = GetSegment(node); var segment = GetSegment(node);
Select(segment.Offset, segment.Length); Select(segment.Offset, segment.Length);

5
src/Libraries/NRefactory/ICSharpCode.NRefactory/Editor/ReadOnlyDocument.cs

@ -220,8 +220,9 @@ namespace ICSharpCode.NRefactory.Editor
get { return lines.Length; } get { return lines.Length; }
} }
ITextSourceVersion ITextSource.Version { /// <inheritdoc/>
get { return null; } public ITextSourceVersion Version {
get { return textSource.Version; }
} }
/// <inheritdoc/> /// <inheritdoc/>

10
src/Main/Base/Project/Src/Services/RefactoringService/ContextActions/ContextActionsBulbViewModel.cs

@ -39,16 +39,26 @@ namespace ICSharpCode.SharpDevelop.Refactoring
this.ActionVisibleChangedCommand = new ActionVisibleChangedCommand(model); this.ActionVisibleChangedCommand = new ActionVisibleChangedCommand(model);
} }
bool actionsLoaded;
public async Task LoadActionsAsync(CancellationToken cancellationToken) public async Task LoadActionsAsync(CancellationToken cancellationToken)
{ {
if (actionsLoaded)
return;
actionsLoaded = true;
this.Actions.Clear(); this.Actions.Clear();
foreach (var action in await Model.GetVisibleActionsAsync(cancellationToken)) { foreach (var action in await Model.GetVisibleActionsAsync(cancellationToken)) {
this.Actions.Add(new ContextActionViewModel(action, this.Model.EditorContext) { IsVisible = true }); this.Actions.Add(new ContextActionViewModel(action, this.Model.EditorContext) { IsVisible = true });
} }
} }
bool hiddenActionsLoaded;
public async Task LoadHiddenActionsAsync(CancellationToken cancellationToken) public async Task LoadHiddenActionsAsync(CancellationToken cancellationToken)
{ {
if (hiddenActionsLoaded)
return;
hiddenActionsLoaded = true;
this.HiddenActions.Clear(); this.HiddenActions.Clear();
foreach (var action in await Model.GetHiddenActionsAsync(cancellationToken)) { foreach (var action in await Model.GetHiddenActionsAsync(cancellationToken)) {
this.HiddenActions.Add(new ContextActionViewModel(action, this.Model.EditorContext) { IsVisible = false }); this.HiddenActions.Add(new ContextActionViewModel(action, this.Model.EditorContext) { IsVisible = false });

Loading…
Cancel
Save