Browse Source

Fixed override completion.

newNRvisualizers
Daniel Grunwald 14 years ago
parent
commit
725bf76535
  1. 1
      src/AddIns/BackendBindings/CSharpBinding/Project/CSharpBinding.csproj
  2. 61
      src/AddIns/BackendBindings/CSharpBinding/Project/Src/Completion/OverrideCompletionData.cs
  3. 4
      src/AddIns/BackendBindings/CSharpBinding/Project/Src/Completion/SegmentTrackingOutputFormatter.cs
  4. 13
      src/AddIns/BackendBindings/CSharpBinding/Project/Src/ExtensionMethods.cs
  5. 26
      src/AddIns/BackendBindings/CSharpBinding/Project/Src/FormattingStrategy/CSharpFormatter.cs
  6. 35
      src/AddIns/BackendBindings/CSharpBinding/Tests/OverrideCompletionTests.cs

1
src/AddIns/BackendBindings/CSharpBinding/Project/CSharpBinding.csproj

@ -71,6 +71,7 @@ @@ -71,6 +71,7 @@
<Compile Include="Src\Completion\CSharpMethodInsight.cs" />
<Compile Include="Src\Completion\OverrideCompletionData.cs" />
<Compile Include="Src\Completion\SegmentTrackingOutputFormatter.cs" />
<Compile Include="Src\FormattingStrategy\CSharpFormatter.cs" />
<Compile Include="Src\Refactoring\InsertionPoint.cs" />
<Compile Include="Src\Refactoring\IssueOptions.xaml.cs">
<DependentUpon>IssueOptions.xaml</DependentUpon>

61
src/AddIns/BackendBindings/CSharpBinding/Project/Src/Completion/OverrideCompletionData.cs

@ -2,15 +2,19 @@ @@ -2,15 +2,19 @@
// 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 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;
namespace CSharpBinding.Completion
@ -47,14 +51,59 @@ namespace CSharpBinding.Completion @@ -47,14 +51,59 @@ namespace CSharpBinding.Completion
entityDeclaration.Modifiers &= ~(Modifiers.Virtual | Modifiers.Abstract);
entityDeclaration.Modifiers |= Modifiers.Override;
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, ParametersToExpressions(this.Entity));
var body = entityDeclaration.GetChildByRole(Roles.Body);
body.Statements.Clear();
if (((IMethod)this.Entity).ReturnType.IsKnownType(KnownTypeCode.Void))
body.Statements.Add(new ExpressionStatement(baseCall));
else
body.Statements.Add(new ReturnStatement(baseCall));
} else if (this.Entity.EntityType == EntityType.Indexer || this.Entity.EntityType == EntityType.Property) {
Expression baseCall;
if (this.Entity.EntityType == EntityType.Indexer)
baseCall = new BaseReferenceExpression().Indexer(ParametersToExpressions(this.Entity));
else
baseCall = new BaseReferenceExpression().Member(this.Entity.Name);
var getterBody = entityDeclaration.GetChildByRole(PropertyDeclaration.GetterRole).Body;
if (!getterBody.IsNull) {
getterBody.Statements.Clear();
getterBody.Add(new ReturnStatement(baseCall.Clone()));
}
var setterBody = entityDeclaration.GetChildByRole(PropertyDeclaration.SetterRole).Body;
if (!setterBody.IsNull) {
setterBody.Statements.Clear();
setterBody.Add(new AssignmentExpression(baseCall.Clone(), new IdentifierExpression("value")));
}
}
}
var document = context.Editor.Document;
StringWriter w = new StringWriter();
var segmentDict = SegmentTrackingOutputFormatter.WriteNode(w, entityDeclaration, FormattingOptionsFactory.CreateSharpDevelop());
var formattingOptions = FormattingOptionsFactory.CreateSharpDevelop();
var segmentDict = SegmentTrackingOutputFormatter.WriteNode(w, entityDeclaration, formattingOptions, context.Editor.Options);
context.Editor.Document.Replace(declarationBegin, context.EndOffset - declarationBegin, w.ToString().TrimEnd());
var throwStatement = entityDeclaration.Descendants.FirstOrDefault(n => n is ThrowStatement);
if (throwStatement != null) {
var segment = segmentDict[throwStatement];
context.Editor.Select(declarationBegin + segment.Offset, segment.Length);
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);
}
CSharpFormatter.Format(context.Editor, declarationBegin, newText.Length, formattingOptions);
}
}
IEnumerable<Expression> ParametersToExpressions(IEntity entity)
{
foreach (var p in ((IParameterizedMember)entity).Parameters) {
if (p.IsRef || p.IsOut)
yield return new DirectionExpression(p.IsOut ? FieldDirection.Out : FieldDirection.Ref, new IdentifierExpression(p.Name));
else
yield return new IdentifierExpression(p.Name);
}
}
}

4
src/AddIns/BackendBindings/CSharpBinding/Project/Src/Completion/SegmentTrackingOutputFormatter.cs

@ -8,6 +8,7 @@ using System.Text; @@ -8,6 +8,7 @@ using System.Text;
using ICSharpCode.AvalonEdit.Document;
using ICSharpCode.NRefactory.CSharp;
using ICSharpCode.NRefactory.Editor;
using ICSharpCode.SharpDevelop.Editor;
namespace CSharpBinding.Completion
{
@ -30,9 +31,10 @@ namespace CSharpBinding.Completion @@ -30,9 +31,10 @@ namespace CSharpBinding.Completion
this.stringWriter = stringWriter;
}
public static IReadOnlyDictionary<AstNode, ISegment> WriteNode(StringWriter writer, AstNode node, CSharpFormattingOptions policy)
public static IReadOnlyDictionary<AstNode, ISegment> WriteNode(StringWriter writer, AstNode node, CSharpFormattingOptions policy, ITextEditorOptions editorOptions)
{
var formatter = new SegmentTrackingOutputFormatter(writer);
formatter.IndentationString = editorOptions.IndentationString;
var visitor = new CSharpOutputVisitor(formatter, policy);
node.AcceptVisitor(visitor);
return formatter.Segments;

13
src/AddIns/BackendBindings/CSharpBinding/Project/Src/ExtensionMethods.cs

@ -7,6 +7,7 @@ using CSharpBinding.Parser; @@ -7,6 +7,7 @@ using CSharpBinding.Parser;
using ICSharpCode.NRefactory.CSharp;
using ICSharpCode.NRefactory.CSharp.Resolver;
using ICSharpCode.NRefactory.CSharp.TypeSystem;
using ICSharpCode.SharpDevelop.Editor;
using ICSharpCode.SharpDevelop.Refactoring;
namespace CSharpBinding
@ -16,6 +17,18 @@ namespace CSharpBinding @@ -16,6 +17,18 @@ namespace CSharpBinding
/// </summary>
public static class ExtensionMethods
{
public static TextEditorOptions ToEditorOptions(this ITextEditor editor)
{
return new TextEditorOptions {
TabsToSpaces = editor.Options.ConvertTabsToSpaces,
TabSize = editor.Options.IndentationSize,
IndentSize = editor.Options.IndentationSize,
ContinuationIndent = editor.Options.IndentationSize,
LabelIndent = -editor.Options.IndentationSize,
WrapLineLength = editor.Options.VerticalRulerColumn,
};
}
public static async Task<SyntaxTree> GetSyntaxTreeAsync(this EditorRefactoringContext editorContext)
{
var parseInfo = (await editorContext.GetParseInformationAsync().ConfigureAwait(false)) as CSharpFullParseInformation;

26
src/AddIns/BackendBindings/CSharpBinding/Project/Src/FormattingStrategy/CSharpFormatter.cs

@ -0,0 +1,26 @@ @@ -0,0 +1,26 @@
// 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 ICSharpCode.NRefactory.CSharp;
using ICSharpCode.NRefactory.Editor;
using ICSharpCode.NRefactory.TypeSystem;
using ICSharpCode.SharpDevelop.Editor;
namespace CSharpBinding.FormattingStrategy
{
public class CSharpFormatter
{
/// <summary>
/// Formats the specified part of the document.
/// </summary>
public static void Format(ITextEditor editor, int offset, int length, CSharpFormattingOptions options)
{
var syntaxTree = new CSharpParser().Parse(editor.Document);
var fv = new AstFormattingVisitor(options, editor.Document, editor.ToEditorOptions());
fv.FormattingRegion = new DomRegion(editor.Document.GetLocation(offset), editor.Document.GetLocation(offset + length));
syntaxTree.AcceptVisitor(fv);
fv.ApplyChanges(offset, length);
}
}
}

35
src/AddIns/BackendBindings/CSharpBinding/Tests/OverrideCompletionTests.cs

@ -2,6 +2,7 @@ @@ -2,6 +2,7 @@
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using CSharpBinding.Completion;
using CSharpBinding.Parser;
using ICSharpCode.AvalonEdit.Document;
using ICSharpCode.NRefactory.CSharp;
using ICSharpCode.NRefactory.TypeSystem;
@ -61,6 +62,11 @@ class DerivedClass : BaseClass { @@ -61,6 +62,11 @@ class DerivedClass : BaseClass {
SD.Services.AddService(typeof(IParserService), MockRepository.GenerateStrictMock<IParserService>());
SD.ParserService.Stub(p => p.GetCachedParseInformation(textEditor.FileName)).Return(parseInfo);
SD.ParserService.Stub(p => p.GetCompilationForFile(textEditor.FileName)).Return(compilation);
SD.ParserService.Stub(p => p.Parse(textEditor.FileName, textEditor.Document)).WhenCalled(
i => {
var syntaxTree = new CSharpParser().Parse(textEditor.Document, textEditor.FileName);
i.ReturnValue = new CSharpFullParseInformation(syntaxTree.ToTypeSystem(), null, syntaxTree);
});
CSharpCompletionBinding completion = new CSharpCompletionBinding();
keyPressResult = completion.HandleKeyPressed(textEditor, ' ');
}
@ -92,9 +98,9 @@ class DerivedClass : BaseClass { @@ -92,9 +98,9 @@ class DerivedClass : BaseClass {
Assert.AreEqual(
new string[] {
"AbstractEvent", "AbstractMethod()",
"Equals(object obj)", "GetHashCode()", "ProtectedWriteProperty",
"Equals(object obj)", "GetHashCode()", "ProtectedWriteProperty",
"ReadOnlyAbstractProperty", "ToString()",
"VirtualEvent", "VirtualMethod()", "VirtualProperty",
"VirtualEvent", "VirtualMethod()", "VirtualProperty",
}, itemNames);
}
@ -104,7 +110,6 @@ class DerivedClass : BaseClass { @@ -104,7 +110,6 @@ class DerivedClass : BaseClass {
}
[Test]
[Ignore("Implement formatter")]
public void OverrideAbstractMethod()
{
CompletionContext context = new CompletionContext();
@ -123,7 +128,6 @@ class DerivedClass : BaseClass { @@ -123,7 +128,6 @@ class DerivedClass : BaseClass {
}
[Test]
[Ignore("Implement formatter")]
public void OverrideVirtualMethod()
{
CompletionContext context = new CompletionContext();
@ -142,7 +146,6 @@ class DerivedClass : BaseClass { @@ -142,7 +146,6 @@ class DerivedClass : BaseClass {
}
[Test]
[Ignore("Implement formatter")]
public void OverrideReadOnlyAbstractProperty()
{
CompletionContext context = new CompletionContext();
@ -153,14 +156,15 @@ class DerivedClass : BaseClass { @@ -153,14 +156,15 @@ class DerivedClass : BaseClass {
textEditor.LastCompletionItemList.Complete(context, item);
Assert.AreEqual(Normalize(
programStart + "public override int ReadOnlyAbstractProperty {\n" +
" get { throw new NotImplementedException(); }\n" +
" get {\n" +
" throw new NotImplementedException();\n" +
" }\n" +
" }" + programEnd),
Normalize(textEditor.Document.Text)
);
}
[Test]
[Ignore("Implement formatter")]
public void OverrideVirtualProperty()
{
CompletionContext context = new CompletionContext();
@ -171,15 +175,18 @@ class DerivedClass : BaseClass { @@ -171,15 +175,18 @@ class DerivedClass : BaseClass {
textEditor.LastCompletionItemList.Complete(context, item);
Assert.AreEqual(Normalize(
programStart + "public override int VirtualProperty {\n" +
" get { return base.VirtualProperty; }\n" +
" set { base.VirtualProperty = value; }\n" +
" get {\n" +
" return base.VirtualProperty;\n" +
" }\n" +
" set {\n" +
" base.VirtualProperty = value;\n" +
" }\n" +
" }" + programEnd),
Normalize(textEditor.Document.Text)
);
}
[Test]
[Ignore("Implement formatter")]
public void OverrideProtectedWriteProperty()
{
CompletionContext context = new CompletionContext();
@ -190,8 +197,12 @@ class DerivedClass : BaseClass { @@ -190,8 +197,12 @@ class DerivedClass : BaseClass {
textEditor.LastCompletionItemList.Complete(context, item);
Assert.AreEqual(Normalize(
programStart + "public override int ProtectedWriteProperty {\n" +
" get { return base.ProtectedWriteProperty; }\n" +
" protected set { base.ProtectedWriteProperty = value; }\n" +
" get {\n" +
" return base.ProtectedWriteProperty;\n" +
" }\n" +
" protected set {\n" +
" base.ProtectedWriteProperty = value;\n" +
" }\n" +
" }" + programEnd),
Normalize(textEditor.Document.Text)
);

Loading…
Cancel
Save