diff --git a/src/AddIns/BackendBindings/CSharpBinding/Project/CSharpBinding.csproj b/src/AddIns/BackendBindings/CSharpBinding/Project/CSharpBinding.csproj
index 00027765d5..3a9759177f 100644
--- a/src/AddIns/BackendBindings/CSharpBinding/Project/CSharpBinding.csproj
+++ b/src/AddIns/BackendBindings/CSharpBinding/Project/CSharpBinding.csproj
@@ -73,6 +73,7 @@
+
@@ -95,6 +96,9 @@
+
+ OverrideEqualsGetHashCodeMethodsDialog.xaml
+
OverrideToStringMethodDialog.xaml
@@ -196,6 +200,7 @@
+
diff --git a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Completion/CSharpCompletionDataFactory.cs b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Completion/CSharpCompletionDataFactory.cs
index 1c1e8ff6f5..b981593f37 100644
--- a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Completion/CSharpCompletionDataFactory.cs
+++ b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Completion/CSharpCompletionDataFactory.cs
@@ -97,6 +97,8 @@ namespace CSharpBinding.Completion
{
if ((m.EntityType == EntityType.Method) && (m.Name == "ToString"))
return new OverrideToStringCompletionData(declarationBegin, m, contextAtCaret);
+ else if ((m.EntityType == EntityType.Method) && (m.Name == "GetHashCode"))
+ return new OverrideToStringCompletionData(declarationBegin, m, contextAtCaret);
else
return new OverrideCompletionData(declarationBegin, m, contextAtCaret);
}
diff --git a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Completion/OverrideGetHashCodeCompletionData.cs b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Completion/OverrideGetHashCodeCompletionData.cs
new file mode 100644
index 0000000000..2b2c8a5a6b
--- /dev/null
+++ b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Completion/OverrideGetHashCodeCompletionData.cs
@@ -0,0 +1,148 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Threading;
+using ICSharpCode.AvalonEdit.Editing;
+using ICSharpCode.AvalonEdit.Snippets;
+using ICSharpCode.NRefactory.Editor;
+using ICSharpCode.SharpDevelop.Parser;
+using CSharpBinding.FormattingStrategy;
+using CSharpBinding.Parser;
+using ICSharpCode.NRefactory.CSharp;
+using ICSharpCode.NRefactory.CSharp.Refactoring;
+using ICSharpCode.NRefactory.CSharp.Resolver;
+using ICSharpCode.NRefactory.CSharp.TypeSystem;
+using ICSharpCode.NRefactory.TypeSystem;
+using ICSharpCode.SharpDevelop;
+using ICSharpCode.SharpDevelop.Editor;
+using ICSharpCode.SharpDevelop.Editor.CodeCompletion;
+using CSharpBinding.Refactoring;
+
+namespace CSharpBinding.Completion
+{
+ ///
+ /// Item for 'override' completion of "GetHashCode()" methods.
+ ///
+ class OverrideGetHashCodeCompletionData : OverrideCompletionData
+ {
+ public OverrideGetHashCodeCompletionData(int declarationBegin, IMember m, CSharpTypeResolveContext contextAtCaret)
+ : base(declarationBegin, m, contextAtCaret)
+ {
+ }
+
+ public override void Complete(CompletionContext context)
+ {
+ if (declarationBegin > context.StartOffset) {
+ base.Complete(context);
+ return;
+ }
+
+ TypeSystemAstBuilder b = new TypeSystemAstBuilder(new CSharpResolver(contextAtCaret));
+ b.ShowTypeParameterConstraints = false;
+ b.GenerateBody = true;
+
+ var entityDeclaration = b.ConvertEntity(this.Entity);
+ entityDeclaration.Modifiers &= ~(Modifiers.Virtual | Modifiers.Abstract);
+ entityDeclaration.Modifiers |= Modifiers.Override;
+
+ var body = entityDeclaration.GetChildByRole(Roles.Body);
+ Statement baseCallStatement = body.Children.OfType().FirstOrDefault();
+
+ if (!this.Entity.IsAbstract) {
+ // modify body to call the base method
+ if (this.Entity.EntityType == EntityType.Method) {
+ var baseCall = new BaseReferenceExpression().Invoke(this.Entity.Name, new Expression[] { });
+ if (((IMethod)this.Entity).ReturnType.IsKnownType(KnownTypeCode.Void))
+ baseCallStatement = new ExpressionStatement(baseCall);
+ else
+ baseCallStatement = new ReturnStatement(baseCall);
+
+ // Clear body of inserted method
+ entityDeclaration.GetChildByRole(Roles.Body).Statements.Clear();
+ }
+ }
+
+ var document = context.Editor.Document;
+ StringWriter w = new StringWriter();
+ var formattingOptions = FormattingOptionsFactory.CreateSharpDevelop();
+ var segmentDict = SegmentTrackingOutputFormatter.WriteNode(w, entityDeclaration, formattingOptions, context.Editor.Options);
+
+ using (document.OpenUndoGroup()) {
+ string newText = w.ToString().TrimEnd();
+ document.Replace(declarationBegin, context.EndOffset - declarationBegin, newText);
+ var throwStatement = entityDeclaration.Descendants.FirstOrDefault(n => n is ThrowStatement);
+ if (throwStatement != null) {
+ var segment = segmentDict[throwStatement];
+ context.Editor.Select(declarationBegin + segment.Offset, segment.Length);
+ }
+ CSharpFormatterHelper.Format(context.Editor, declarationBegin, newText.Length, formattingOptions);
+
+ var refactoringContext = SDRefactoringContext.Create(context.Editor, CancellationToken.None);
+ var typeResolveContext = refactoringContext.GetTypeResolveContext();
+ if (typeResolveContext == null) {
+ return;
+ }
+ var resolvedCurrent = typeResolveContext.CurrentTypeDefinition;
+ var entities = FindFieldsAndProperties(resolvedCurrent).ToList();
+ if (entities.Any()) {
+ IEditorUIService uiService = context.Editor.GetService(typeof(IEditorUIService)) as IEditorUIService;
+
+ ITextAnchor endAnchor = context.Editor.Document.CreateAnchor(context.Editor.Caret.Offset);
+ endAnchor.MovementType = AnchorMovementType.AfterInsertion;
+
+ ITextAnchor startAnchor = context.Editor.Document.CreateAnchor(context.Editor.Caret.Offset);
+ startAnchor.MovementType = AnchorMovementType.BeforeInsertion;
+
+ 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);
+// dialog.Element = uiService.CreateInlineUIElement(insertionPos, dialog);
+
+ insertionContext.RegisterActiveElement(new InlineRefactorSnippetElement(cxt => null, ""), dialog);
+ insertionContext.RaiseInsertionCompleted(EventArgs.Empty);
+ }
+ else {
+ if (baseCallStatement != null) {
+ // Add default base call
+ MethodDeclaration insertedOverrideMethod = refactoringContext.GetNode().PrevSibling as MethodDeclaration;
+ if (insertedOverrideMethod == null)
+ {
+ // We are not inside of a method declaration
+ return;
+ }
+ using (Script script = refactoringContext.StartScript()) {
+ script.AddTo(insertedOverrideMethod.Body, baseCallStatement);
+ }
+ }
+ }
+ }
+ }
+
+ IEnumerable FindFieldsAndProperties(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.CanGet && !prop.IsIndexer
+ && prop.IsStatic == sourceType.GetDefinition().IsStatic
+ && prop.ReturnType != null)) {
+ yield return new PropertyOrFieldWrapper(p) { Index = i };
+ i++;
+ }
+ }
+ }
+}
diff --git a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Refactoring/AbstractInlineRefactorDialog.cs b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Refactoring/AbstractInlineRefactorDialog.cs
index 6140d3af60..480a48ef9b 100644
--- a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Refactoring/AbstractInlineRefactorDialog.cs
+++ b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Refactoring/AbstractInlineRefactorDialog.cs
@@ -50,7 +50,7 @@ namespace CSharpBinding.Refactoring
Dispatcher.BeginInvoke(DispatcherPriority.Background, new Action(delegate { this.MoveFocus(new TraversalRequest(FocusNavigationDirection.First)); }));
}
- protected abstract string GenerateCode(IUnresolvedTypeDefinition currentClass);
+ protected abstract string GenerateCode(ITypeDefinition currentClass);
protected virtual void OKButtonClick(object sender, RoutedEventArgs e)
{
@@ -62,7 +62,11 @@ namespace CSharpBinding.Refactoring
}
if (parseInfo != null) {
- IUnresolvedTypeDefinition current = parseInfo.UnresolvedFile.GetInnermostTypeDefinition(anchor.Line, anchor.Column);
+ var typeResolveContext = refactoringContext.GetTypeResolveContext();
+ if (typeResolveContext == null) {
+ return;
+ }
+ var current = typeResolveContext.CurrentTypeDefinition;
using (editor.Document.OpenUndoGroup()) {
// GenerateCode could modify the document.
diff --git a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Refactoring/InsertCtorDialog.xaml.cs b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Refactoring/InsertCtorDialog.xaml.cs
index 6ab730907e..1e80c9324d 100644
--- a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Refactoring/InsertCtorDialog.xaml.cs
+++ b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Refactoring/InsertCtorDialog.xaml.cs
@@ -41,7 +41,7 @@ namespace CSharpBinding.Refactoring
Visibility = System.Windows.Visibility.Collapsed;
}
- protected override string GenerateCode(IUnresolvedTypeDefinition currentClass)
+ protected override string GenerateCode(ITypeDefinition currentClass)
{
List filtered = this.varList.SelectedItems.OfType()
.OrderBy(p => p.Index)
diff --git a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Refactoring/OverrideEqualsGetHashCodeMethodsDialog.xaml.cs b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Refactoring/OverrideEqualsGetHashCodeMethodsDialog.xaml.cs
index acbadda73f..d16d4623f5 100644
--- a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Refactoring/OverrideEqualsGetHashCodeMethodsDialog.xaml.cs
+++ b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Refactoring/OverrideEqualsGetHashCodeMethodsDialog.xaml.cs
@@ -8,6 +8,9 @@ using System.Text;
using ICSharpCode.AvalonEdit.Snippets;
using ICSharpCode.Core;
+using ICSharpCode.NRefactory.CSharp;
+using ICSharpCode.NRefactory.Editor;
+using ICSharpCode.NRefactory.TypeSystem;
using ICSharpCode.NRefactory.Ast;
using ICSharpCode.SharpDevelop.Dom;
using ICSharpCode.SharpDevelop.Dom.Refactoring;
@@ -21,13 +24,13 @@ namespace CSharpBinding.Refactoring
///
public partial class OverrideEqualsGetHashCodeMethodsDialog : AbstractInlineRefactorDialog
{
- IClass selectedClass;
+ IType selectedClass;
ITextAnchor startAnchor;
IMethod selectedMethod;
- string baseCall;
+ AstNode baseCallNode;
public OverrideEqualsGetHashCodeMethodsDialog(InsertionContext context, ITextEditor editor, ITextAnchor startAnchor, ITextAnchor endAnchor,
- ITextAnchor insertionPosition, IClass selectedClass, IMethod selectedMethod, string baseCall)
+ ITextAnchor insertionPosition, IType selectedClass, IMethod selectedMethod, AstNode baseCallNode)
: base(context, editor, insertionPosition)
{
if (selectedClass == null)
@@ -39,7 +42,7 @@ namespace CSharpBinding.Refactoring
this.startAnchor = startAnchor;
this.insertionEndAnchor = endAnchor;
this.selectedMethod = selectedMethod;
- this.baseCall = baseCall;
+ this.baseCallNode = baseCallNode;
addIEquatable.Content = string.Format(StringParser.Parse("${res:AddIns.SharpRefactoring.OverrideEqualsGetHashCodeMethods.AddInterface}"),
"IEquatable<" + selectedClass.Name + ">");
@@ -72,23 +75,15 @@ namespace CSharpBinding.Refactoring
1000000483, 1000000513, 1000000531, 1000000579
};
- static bool IsValueType(IReturnType type)
- {
- IClass c = type.GetUnderlyingClass();
- return c != null && (c.ClassType == Dom.ClassType.Struct || c.ClassType == Dom.ClassType.Enum);
- }
-
- static bool CanCompareEqualityWithOperator(IReturnType type)
+ static bool CanCompareEqualityWithOperator(IType type)
{
// return true for value types except float and double
// return false for reference types except string.
- IClass c = type.GetUnderlyingClass();
- return c != null
- && c.FullyQualifiedName != "System.Single"
- && c.FullyQualifiedName != "System.Double"
- && (c.ClassType == Dom.ClassType.Struct
- || c.ClassType == Dom.ClassType.Enum
- || c.FullyQualifiedName == "System.String");
+ return type != null
+ && type.FullName != "System.Single"
+ && type.FullName != "System.Double"
+ && (!type.IsReferenceType
+ || type.FullName == "System.String");
}
static Expression TestEquality(string other, IField field)
@@ -115,7 +110,7 @@ namespace CSharpBinding.Refactoring
new MemberReferenceExpression(new IdentifierExpression(other), property.Name));
} else {
InvocationExpression ie = new InvocationExpression(
- new MemberReferenceExpression(new TypeReferenceExpression(new TypeReference("System.Object", true)), "Equals")
+ new MemberReferenceExpression(new TypeReferenceExpression(new SimpleType("System.Object")), "Equals")
);
ie.Arguments.Add(new MemberReferenceExpression(new ThisReferenceExpression(), property.Name));
ie.Arguments.Add(new MemberReferenceExpression(new IdentifierExpression(other), property.Name));
@@ -123,17 +118,17 @@ namespace CSharpBinding.Refactoring
}
}
- protected override string GenerateCode(LanguageProperties language, IClass currentClass)
+ protected override string GenerateCode(ITypeDefinition currentClass)
{
StringBuilder code = new StringBuilder();
- var line = editor.Document.GetLineForOffset(startAnchor.Offset);
+ var line = editor.Document.GetLineByOffset(startAnchor.Offset);
string indent = DocumentUtilitites.GetWhitespaceAfter(editor.Document, line.Offset);
CodeGenerator generator = language.CodeGenerator;
- if (Options.AddIEquatableInterface) {
+// if (Options.AddIEquatableInterface) {
// TODO : add IEquatable to class
// IAmbience ambience = currentClass.CompilationUnit.Language.GetAmbience();
//
@@ -156,7 +151,7 @@ namespace CSharpBinding.Refactoring
// int endOffset = editor.Document.PositionToOffset(currentClass.BodyRegion.EndLine, currentClass.BodyRegion.EndColumn);
//
// editor.Document.Replace(startOffset, endOffset - startOffset, a);
- }
+// }
if (Options.SurroundWithRegion) {
editor.Document.InsertNormalized(startAnchor.Offset, "#region Equals and GetHashCode implementation\n" + indent);
@@ -265,28 +260,28 @@ namespace CSharpBinding.Refactoring
return codeForMethodBody;
}
- List CreateEqualsOverrides(IClass currentClass)
+ List CreateEqualsOverrides(IType currentClass)
{
List methods = new List();
- TypeReference boolReference = new TypeReference("System.Boolean", true);
- TypeReference objectReference = new TypeReference("System.Object", true);
+ AstType boolReference = new SimpleType("System.Boolean");
+ AstType objectReference = new SimpleType("System.Object", true);
MethodDeclaration method = new MethodDeclaration {
Name = "Equals",
- Modifier = Modifiers.Public | Modifiers.Override,
- TypeReference = boolReference
+ Modifiers = Modifiers.Public | Modifiers.Override,
+ ReturnType = boolReference
};
- method.Parameters.Add(new ParameterDeclarationExpression(objectReference, "obj"));
+ method.Parameters.Add(new ParameterDeclaration(objectReference, "obj"));
method.Body = new BlockStatement();
- TypeReference currentType = ConvertType(currentClass.DefaultReturnType);
+ AstType currentType = ConvertType(currentClass.DefaultReturnType);
Expression expr = null;
if (currentClass.ClassType == Dom.ClassType.Struct) {
// return obj is CurrentType && Equals((CurrentType)obj);
- expr = new TypeOfIsExpression(new IdentifierExpression("obj"), currentType);
+ expr = new IsExpression(new IdentifierExpression("obj"), currentType);
expr = new ParenthesizedExpression(expr);
expr = new BinaryOperatorExpression(
expr, BinaryOperatorType.LogicalAnd,
@@ -302,18 +297,18 @@ namespace CSharpBinding.Refactoring
// IEquatable implementation:
method = new MethodDeclaration {
Name = "Equals",
- Modifier = Modifiers.Public,
- TypeReference = boolReference
+ Modifiers = Modifiers.Public,
+ ReturnType = boolReference
};
- method.Parameters.Add(new ParameterDeclarationExpression(currentType, "other"));
+ method.Parameters.Add(new ParameterDeclaration(currentType, "other"));
method.Body = new BlockStatement();
} else {
- method.Body.AddChild(new LocalVariableDeclaration(new VariableDeclaration(
+ method.Body.AddChild(new VariableDeclaration(
"other",
- new CastExpression(currentType, new IdentifierExpression("obj"), CastType.TryCast),
- currentType)));
+ new CastExpression(currentType, new IdentifierExpression("obj")),
+ currentType));
method.Body.AddChild(new IfElseStatement(
- new BinaryOperatorExpression(new IdentifierExpression("other"), BinaryOperatorType.ReferenceEquality, new PrimitiveExpression(null, "null")),
+ new BinaryOperatorExpression(new IdentifierExpression("other"), BinaryOperatorType.Equality, new PrimitiveExpression(null, "null")),
new ReturnStatement(new PrimitiveExpression(false, "false"))));
// expr = new BinaryOperatorExpression(new ThisReferenceExpression(),
diff --git a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Refactoring/OverrideToStringMethodDialog.xaml.cs b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Refactoring/OverrideToStringMethodDialog.xaml.cs
index 22ae595fc1..c4afba82fc 100644
--- a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Refactoring/OverrideToStringMethodDialog.xaml.cs
+++ b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Refactoring/OverrideToStringMethodDialog.xaml.cs
@@ -39,7 +39,7 @@ namespace CSharpBinding.Refactoring
listBox.SelectAll();
}
- protected override string GenerateCode(IUnresolvedTypeDefinition currentClass)
+ protected override string GenerateCode(ITypeDefinition currentClass)
{
string[] fields = listBox.SelectedItems.OfType().Select(f2 => f2.MemberName).ToArray();
PrimitiveExpression formatString = new PrimitiveExpression(GenerateFormatString(currentClass, editor.Language.CodeGenerator, fields));
@@ -66,7 +66,7 @@ namespace CSharpBinding.Refactoring
return null;
}
- string GenerateFormatString(IUnresolvedTypeDefinition currentClass, ICodeGenerator generator, string[] fields)
+ string GenerateFormatString(ITypeDefinition currentClass, ICodeGenerator generator, string[] fields)
{
string fieldsString = "";