Browse Source

Detecting all properties and fields and handling editor undo properly in InsertCtor/Override...Method dialogs.

pull/45/merge
Andreas Weizel 12 years ago
parent
commit
e0fb42221e
  1. 7
      src/AddIns/BackendBindings/CSharpBinding/Project/Src/Completion/OverrideEqualsGetHashCodeCompletionData.cs
  2. 13
      src/AddIns/BackendBindings/CSharpBinding/Project/Src/Completion/OverrideToStringCompletionData.cs
  3. 17
      src/AddIns/BackendBindings/CSharpBinding/Project/Src/Refactoring/AbstractInlineRefactorDialog.cs
  4. 48
      src/AddIns/BackendBindings/CSharpBinding/Project/Src/Refactoring/InsertCtorDialog.xaml.cs
  5. 48
      src/AddIns/BackendBindings/CSharpBinding/Project/Src/Refactoring/InsertCtorSnippetRefactoring.cs
  6. 24
      src/AddIns/BackendBindings/CSharpBinding/Project/Src/Refactoring/OverrideEqualsGetHashCodeMethodsDialog.xaml.cs
  7. 6
      src/AddIns/BackendBindings/CSharpBinding/Project/Src/Refactoring/OverrideToStringMethodDialog.xaml.cs

7
src/AddIns/BackendBindings/CSharpBinding/Project/Src/Completion/OverrideEqualsGetHashCodeCompletionData.cs

@ -73,6 +73,9 @@ namespace CSharpBinding.Completion @@ -73,6 +73,9 @@ namespace CSharpBinding.Completion
var segmentDict = SegmentTrackingOutputFormatter.WriteNode(w, entityDeclaration, formattingOptions, context.Editor.Options);
using (document.OpenUndoGroup()) {
InsertionContext insertionContext = new InsertionContext(context.Editor.GetService(typeof(TextArea)) as TextArea, declarationBegin);
insertionContext.InsertionPosition = context.Editor.Caret.Offset;
string newText = w.ToString().TrimEnd();
document.Replace(declarationBegin, context.EndOffset - declarationBegin, newText);
var throwStatement = entityDeclaration.Descendants.FirstOrDefault(n => n is ThrowStatement);
@ -99,10 +102,8 @@ namespace CSharpBinding.Completion @@ -99,10 +102,8 @@ namespace CSharpBinding.Completion
ITextAnchor insertionPos = context.Editor.Document.CreateAnchor(endAnchor.Offset);
insertionPos.MovementType = AnchorMovementType.BeforeInsertion;
InsertionContext insertionContext = new InsertionContext(context.Editor.GetService(typeof(TextArea)) as TextArea, startAnchor.Offset);
var current = typeResolveContext.CurrentTypeDefinition;
AbstractInlineRefactorDialog dialog = new OverrideEqualsGetHashCodeMethodsDialog(insertionContext, context.Editor, startAnchor, endAnchor, insertionPos, current, Entity as IMethod, baseCallStatement);
AbstractInlineRefactorDialog dialog = new OverrideEqualsGetHashCodeMethodsDialog(insertionContext, context.Editor, endAnchor, insertionPos, current, Entity as IMethod, baseCallStatement);
dialog.Element = uiService.CreateInlineUIElement(insertionPos, dialog);

13
src/AddIns/BackendBindings/CSharpBinding/Project/Src/Completion/OverrideToStringCompletionData.cs

@ -73,6 +73,9 @@ namespace CSharpBinding.Completion @@ -73,6 +73,9 @@ namespace CSharpBinding.Completion
var segmentDict = SegmentTrackingOutputFormatter.WriteNode(w, entityDeclaration, formattingOptions, context.Editor.Options);
using (document.OpenUndoGroup()) {
InsertionContext insertionContext = new InsertionContext(context.Editor.GetService(typeof(TextArea)) as TextArea, declarationBegin);
insertionContext.InsertionPosition = context.Editor.Caret.Offset;
string newText = w.ToString().TrimEnd();
document.Replace(declarationBegin, context.EndOffset - declarationBegin, newText);
var throwStatement = entityDeclaration.Descendants.FirstOrDefault(n => n is ThrowStatement);
@ -101,15 +104,11 @@ namespace CSharpBinding.Completion @@ -101,15 +104,11 @@ namespace CSharpBinding.Completion
ITextAnchor insertionPos = context.Editor.Document.CreateAnchor(endAnchor.Offset);
insertionPos.MovementType = AnchorMovementType.BeforeInsertion;
InsertionContext insertionContext = new InsertionContext(context.Editor.GetService(typeof(TextArea)) as TextArea, startAnchor.Offset);
AbstractInlineRefactorDialog dialog = new OverrideToStringMethodDialog(insertionContext, context.Editor, startAnchor, insertionPos, entities, baseCallStatement);
AbstractInlineRefactorDialog dialog = new OverrideToStringMethodDialog(insertionContext, context.Editor, insertionPos, entities, baseCallStatement);
dialog.Element = uiService.CreateInlineUIElement(insertionPos, dialog);
insertionContext.RegisterActiveElement(new InlineRefactorSnippetElement(cxt => null, ""), dialog);
insertionContext.RaiseInsertionCompleted(EventArgs.Empty);
}
else {
} else {
if (baseCallStatement != null) {
// Add default base call
MethodDeclaration insertedOverrideMethod = refactoringContext.GetNode().PrevSibling as MethodDeclaration;
@ -123,6 +122,8 @@ namespace CSharpBinding.Completion @@ -123,6 +122,8 @@ namespace CSharpBinding.Completion
}
}
}
insertionContext.RaiseInsertionCompleted(EventArgs.Empty);
}
}

17
src/AddIns/BackendBindings/CSharpBinding/Project/Src/Refactoring/AbstractInlineRefactorDialog.cs

@ -41,7 +41,6 @@ namespace CSharpBinding.Refactoring @@ -41,7 +41,6 @@ namespace CSharpBinding.Refactoring
this.anchor = insertionEndAnchor = anchor;
this.editor = editor;
this.insertionContext = context;
this.refactoringContext = SDRefactoringContext.Create(editor, CancellationToken.None);
this.Background = SystemColors.ControlBrush;
}
@ -51,18 +50,21 @@ namespace CSharpBinding.Refactoring @@ -51,18 +50,21 @@ namespace CSharpBinding.Refactoring
Dispatcher.BeginInvoke(DispatcherPriority.Background, new Action(delegate { this.MoveFocus(new TraversalRequest(FocusNavigationDirection.First)); }));
}
protected void AppendNewLine(Script script, AstNode afterNode, NewLineNode newLineNode)
{
if (newLineNode != null)
script.InsertAfter(afterNode, newLineNode.Clone());
}
protected abstract string GenerateCode(ITypeDefinition currentClass);
protected virtual void OKButtonClick(object sender, RoutedEventArgs e)
{
ParseInformation parseInfo = SD.ParserService.GetCachedParseInformation(editor.FileName);
if (optionBindings != null) {
foreach (OptionBinding binding in optionBindings)
binding.Save();
}
if (parseInfo != null) {
var typeResolveContext = refactoringContext.GetTypeResolveContext();
if (typeResolveContext == null) {
return;
@ -74,7 +76,6 @@ namespace CSharpBinding.Refactoring @@ -74,7 +76,6 @@ namespace CSharpBinding.Refactoring
// So read anchor.Offset after code generation.
GenerateCode(current);
}
}
Deactivate();
}
@ -122,8 +123,14 @@ namespace CSharpBinding.Refactoring @@ -122,8 +123,14 @@ namespace CSharpBinding.Refactoring
OnInsertionCompleted();
}
protected virtual void Initialize()
{
this.refactoringContext = SDRefactoringContext.Create(editor, CancellationToken.None);
}
protected virtual void OnInsertionCompleted()
{
Initialize();
FocusFirstElement();
}

48
src/AddIns/BackendBindings/CSharpBinding/Project/Src/Refactoring/InsertCtorDialog.xaml.cs

@ -7,12 +7,14 @@ using System.Globalization; @@ -7,12 +7,14 @@ using System.Globalization;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Input;
using System.Windows.Threading;
using ICSharpCode.AvalonEdit.Snippets;
using ICSharpCode.NRefactory;
using ICSharpCode.NRefactory.CSharp;
using ICSharpCode.NRefactory.CSharp.Refactoring;
using ICSharpCode.NRefactory.CSharp.Resolver;
@ -20,6 +22,7 @@ using ICSharpCode.NRefactory.Editor; @@ -20,6 +22,7 @@ using ICSharpCode.NRefactory.Editor;
using ICSharpCode.NRefactory.TypeSystem;
using ICSharpCode.SharpDevelop;
using ICSharpCode.SharpDevelop.Editor;
using ICSharpCode.SharpDevelop.Parser;
namespace CSharpBinding.Refactoring
{
@ -30,24 +33,59 @@ namespace CSharpBinding.Refactoring @@ -30,24 +33,59 @@ namespace CSharpBinding.Refactoring
{
IList<PropertyOrFieldWrapper> parameterList;
public InsertCtorDialog(InsertionContext context, ITextEditor editor, ITextAnchor anchor, IUnresolvedTypeDefinition current, IList<PropertyOrFieldWrapper> possibleParameters)
public InsertCtorDialog(InsertionContext context, ITextEditor editor, ITextAnchor anchor)
: base(context, editor, anchor)
{
InitializeComponent();
this.varList.ItemsSource = parameterList = possibleParameters;
if (!parameterList.Any())
Visibility = System.Windows.Visibility.Collapsed;
}
protected override void Initialize()
{
base.Initialize();
var typeResolveContext = refactoringContext.GetTypeResolveContext();
if (typeResolveContext == null) {
return;
}
var resolvedCurrent = typeResolveContext.CurrentTypeDefinition;
parameterList = CreateCtorParams(resolvedCurrent).ToList();
this.varList.ItemsSource = parameterList;
if (parameterList.Any())
Visibility = System.Windows.Visibility.Visible;
}
IEnumerable<PropertyOrFieldWrapper> CreateCtorParams(IType sourceType)
{
int i = 0;
foreach (var f in sourceType.GetFields().Where(field => !field.IsConst
&& field.IsStatic == sourceType.GetDefinition().IsStatic
&& field.ReturnType != null)) {
yield return new PropertyOrFieldWrapper(f) { Index = i };
i++;
}
foreach (var p in sourceType.GetProperties().Where(prop => prop.CanSet && !prop.IsIndexer
&& prop.IsAutoImplemented()
&& prop.IsStatic == sourceType.GetDefinition().IsStatic
&& prop.ReturnType != null)) {
yield return new PropertyOrFieldWrapper(p) { Index = i };
i++;
}
}
protected override string GenerateCode(ITypeDefinition currentClass)
{
List<PropertyOrFieldWrapper> filtered = this.varList.SelectedItems.OfType<PropertyOrFieldWrapper>()
.OrderBy(p => p.Index)
.ToList();
var insertedConstructor = refactoringContext.GetNode<ConstructorDeclaration>();
var test = refactoringContext.GetNode();
var insertedConstructor = refactoringContext.GetNode().PrevSibling as ConstructorDeclaration;
if (insertedConstructor == null)
{
// We are not inside of a constructor declaration

48
src/AddIns/BackendBindings/CSharpBinding/Project/Src/Refactoring/InsertCtorSnippetRefactoring.cs

@ -39,60 +39,14 @@ namespace CSharpBinding.Refactoring @@ -39,60 +39,14 @@ namespace CSharpBinding.Refactoring
if (uiService == null)
return null;
ParseInformation parseInfo = SD.ParserService.GetCachedParseInformation(textEditor.FileName);
if (parseInfo == null)
return null;
// cannot use insertion position at this point, because it might not be
// valid, because we are still generating the elements.
// DOM is not updated
TextLocation loc = context.Document.GetLocation(context.StartPosition);
IUnresolvedTypeDefinition current = parseInfo.UnresolvedFile.GetInnermostTypeDefinition(loc);
if (current == null)
return null;
var refactoringContext = SDRefactoringContext.Create(textEditor, CancellationToken.None);
var typeResolveContext = refactoringContext.GetTypeResolveContext();
if (typeResolveContext == null) {
return null;
}
var resolvedCurrent = typeResolveContext.CurrentTypeDefinition;
List<PropertyOrFieldWrapper> parameters = CreateCtorParams(resolvedCurrent).ToList();
if (!parameters.Any())
return null;
ITextAnchor anchor = textEditor.Document.CreateAnchor(context.InsertionPosition);
anchor.MovementType = AnchorMovementType.BeforeInsertion;
InsertCtorDialog dialog = new InsertCtorDialog(context, textEditor, anchor, current, parameters);
InsertCtorDialog dialog = new InsertCtorDialog(context, textEditor, anchor);
dialog.Element = uiService.CreateInlineUIElement(anchor, dialog);
return dialog;
}
IEnumerable<PropertyOrFieldWrapper> CreateCtorParams(IType sourceType)
{
int i = 0;
foreach (var f in sourceType.GetFields().Where(field => !field.IsConst
&& field.IsStatic == sourceType.GetDefinition().IsStatic
&& field.ReturnType != null)) {
yield return new PropertyOrFieldWrapper(f) { Index = i };
i++;
}
foreach (var p in sourceType.GetProperties().Where(prop => prop.CanSet && !prop.IsIndexer
&& prop.IsAutoImplemented()
&& prop.IsStatic == sourceType.GetDefinition().IsStatic
&& prop.ReturnType != null)) {
yield return new PropertyOrFieldWrapper(p) { Index = i };
i++;
}
}
}
}

24
src/AddIns/BackendBindings/CSharpBinding/Project/Src/Refactoring/OverrideEqualsGetHashCodeMethodsDialog.xaml.cs

@ -24,11 +24,10 @@ namespace CSharpBinding.Refactoring @@ -24,11 +24,10 @@ namespace CSharpBinding.Refactoring
public partial class OverrideEqualsGetHashCodeMethodsDialog : AbstractInlineRefactorDialog
{
ITypeDefinition selectedClass;
ITextAnchor startAnchor;
IMethod selectedMethod;
AstNode baseCallNode;
public OverrideEqualsGetHashCodeMethodsDialog(InsertionContext context, ITextEditor editor, ITextAnchor startAnchor, ITextAnchor endAnchor,
public OverrideEqualsGetHashCodeMethodsDialog(InsertionContext context, ITextEditor editor, ITextAnchor endAnchor,
ITextAnchor insertionPosition, ITypeDefinition selectedClass, IMethod selectedMethod, AstNode baseCallNode)
: base(context, editor, insertionPosition)
{
@ -38,7 +37,6 @@ namespace CSharpBinding.Refactoring @@ -38,7 +37,6 @@ namespace CSharpBinding.Refactoring
InitializeComponent();
this.selectedClass = selectedClass;
this.startAnchor = startAnchor;
this.insertionEndAnchor = endAnchor;
this.selectedMethod = selectedMethod;
this.baseCallNode = baseCallNode;
@ -57,12 +55,6 @@ namespace CSharpBinding.Refactoring @@ -57,12 +55,6 @@ namespace CSharpBinding.Refactoring
if (type.FullName != "System.IEquatable")
return false;
return type.TypeArguments.First().FullName == selectedClass.FullName;
// var genericType = type.CastToGenericReturnType();
// var boundTo = genericType.TypeParameter.BoundTo;
// if (boundTo == null)
// return false;
// return boundTo.Name == selectedClass.Name;
}
);
}
@ -132,14 +124,6 @@ namespace CSharpBinding.Refactoring @@ -132,14 +124,6 @@ namespace CSharpBinding.Refactoring
protected override string GenerateCode(ITypeDefinition currentClass)
{
StringBuilder code = new StringBuilder();
var line = editor.Document.GetLineByOffset(startAnchor.Offset);
string indent = DocumentUtilities.GetWhitespaceAfter(editor.Document, line.Offset);
// CodeGenerator generator = language.CodeGenerator;
MethodDeclaration insertedOverrideMethod = refactoringContext.GetNode().PrevSibling as MethodDeclaration;
if (insertedOverrideMethod == null)
{
@ -288,12 +272,6 @@ namespace CSharpBinding.Refactoring @@ -288,12 +272,6 @@ namespace CSharpBinding.Refactoring
return null;
}
void AppendNewLine(Script script, AstNode afterNode, NewLineNode newLineNode)
{
if (newLineNode != null)
script.InsertAfter(afterNode, newLineNode.Clone());
}
List<MethodDeclaration> CreateEqualsOverrides(IType currentClass)
{
List<MethodDeclaration> methods = new List<MethodDeclaration>();

6
src/AddIns/BackendBindings/CSharpBinding/Project/Src/Refactoring/OverrideToStringMethodDialog.xaml.cs

@ -24,9 +24,8 @@ namespace CSharpBinding.Refactoring @@ -24,9 +24,8 @@ namespace CSharpBinding.Refactoring
public partial class OverrideToStringMethodDialog : AbstractInlineRefactorDialog
{
AstNode baseCallNode;
string insertedCode;
public OverrideToStringMethodDialog(InsertionContext context, ITextEditor editor, ITextAnchor startAnchor, ITextAnchor anchor, IList<PropertyOrFieldWrapper> fields, AstNode baseCallNode)
public OverrideToStringMethodDialog(InsertionContext context, ITextEditor editor, ITextAnchor anchor, IList<PropertyOrFieldWrapper> fields, AstNode baseCallNode)
: base(context, editor, anchor)
{
InitializeComponent();
@ -56,8 +55,11 @@ namespace CSharpBinding.Refactoring @@ -56,8 +55,11 @@ namespace CSharpBinding.Refactoring
}
using (Script script = refactoringContext.StartScript()) {
NewLineNode nextNewLineNode = insertedOverrideMethod.NextSibling as NewLineNode;
// Find base method call and replace it by return statement
script.AddTo(insertedOverrideMethod.Body, ret);
AppendNewLine(script, insertedOverrideMethod, nextNewLineNode);
}
}

Loading…
Cancel
Save