Browse Source
git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/branches/2.1@2673 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61shortcuts
5 changed files with 275 additions and 54 deletions
@ -0,0 +1,112 @@ |
|||||||
|
/* |
||||||
|
* Erstellt mit SharpDevelop. |
||||||
|
* Benutzer: grunwald |
||||||
|
* Datum: 27.08.2007 |
||||||
|
* Zeit: 14:25 |
||||||
|
* |
||||||
|
* Sie können diese Vorlage unter Extras > Optionen > Codeerstellung > Standardheader ändern. |
||||||
|
*/ |
||||||
|
|
||||||
|
using System; |
||||||
|
using ICSharpCode.TextEditor.Gui.CompletionWindow; |
||||||
|
using ICSharpCode.SharpDevelop.Dom; |
||||||
|
using ICSharpCode.SharpDevelop.Dom.CSharp; |
||||||
|
|
||||||
|
namespace CSharpEditor |
||||||
|
{ |
||||||
|
/// <summary>
|
||||||
|
/// Represents an item in the code completion window.
|
||||||
|
/// </summary>
|
||||||
|
class CodeCompletionData : DefaultCompletionData, ICompletionData |
||||||
|
{ |
||||||
|
IMember member; |
||||||
|
IClass c; |
||||||
|
|
||||||
|
public CodeCompletionData(IMember member) |
||||||
|
: base(member.Name, null, GetMemberImageIndex(member)) |
||||||
|
{ |
||||||
|
this.member = member; |
||||||
|
} |
||||||
|
|
||||||
|
public CodeCompletionData(IClass c) |
||||||
|
: base(c.Name, null, GetClassImageIndex(c)) |
||||||
|
{ |
||||||
|
this.c = c; |
||||||
|
} |
||||||
|
|
||||||
|
int overloads = 0; |
||||||
|
|
||||||
|
public void AddOverload() |
||||||
|
{ |
||||||
|
overloads++; |
||||||
|
} |
||||||
|
|
||||||
|
static int GetMemberImageIndex(IMember member) |
||||||
|
{ |
||||||
|
// Missing: different icons for private/public member
|
||||||
|
if (member is IMethod) |
||||||
|
return 1; |
||||||
|
if (member is IProperty) |
||||||
|
return 2; |
||||||
|
if (member is IField) |
||||||
|
return 3; |
||||||
|
if (member is IEvent) |
||||||
|
return 6; |
||||||
|
return 3; |
||||||
|
} |
||||||
|
|
||||||
|
static int GetClassImageIndex(IClass c) |
||||||
|
{ |
||||||
|
switch (c.ClassType) { |
||||||
|
case ClassType.Enum: |
||||||
|
return 4; |
||||||
|
default: |
||||||
|
return 0; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
string description; |
||||||
|
|
||||||
|
// DefaultCompletionData.Description is not virtual, but we can reimplement
|
||||||
|
// the interface to get the same effect as overriding.
|
||||||
|
string ICompletionData.Description { |
||||||
|
get { |
||||||
|
if (description == null) { |
||||||
|
IDecoration entity = (IDecoration)member ?? c; |
||||||
|
description = GetCSharpText(entity); |
||||||
|
if (overloads > 1) { |
||||||
|
description += " (+" + overloads + " overloads)"; |
||||||
|
} |
||||||
|
description += Environment.NewLine + XmlDocumentationToText(entity.Documentation); |
||||||
|
} |
||||||
|
return description; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Converts a member to text.
|
||||||
|
/// Returns the declaration of the member as C# code, e.g.
|
||||||
|
/// "public void MemberName(string parameter)"
|
||||||
|
/// </summary>
|
||||||
|
static string GetCSharpText(IDecoration entity) |
||||||
|
{ |
||||||
|
if (entity is IMethod) |
||||||
|
return CSharpAmbience.Instance.Convert(entity as IMethod); |
||||||
|
if (entity is IProperty) |
||||||
|
return CSharpAmbience.Instance.Convert(entity as IProperty); |
||||||
|
if (entity is IEvent) |
||||||
|
return CSharpAmbience.Instance.Convert(entity as IEvent); |
||||||
|
if (entity is IField) |
||||||
|
return CSharpAmbience.Instance.Convert(entity as IField); |
||||||
|
if (entity is IClass) |
||||||
|
return CSharpAmbience.Instance.Convert(entity as IClass); |
||||||
|
// unknown entity:
|
||||||
|
return entity.ToString(); |
||||||
|
} |
||||||
|
|
||||||
|
public static string XmlDocumentationToText(string xmlDoc) |
||||||
|
{ |
||||||
|
return xmlDoc; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,146 @@ |
|||||||
|
// CSharp Editor Example with Code Completion
|
||||||
|
// Copyright (c) 2007, Daniel Grunwald
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without modification, are
|
||||||
|
// permitted provided that the following conditions are met:
|
||||||
|
//
|
||||||
|
// - Redistributions of source code must retain the above copyright notice, this list
|
||||||
|
// of conditions and the following disclaimer.
|
||||||
|
//
|
||||||
|
// - Redistributions in binary form must reproduce the above copyright notice, this list
|
||||||
|
// of conditions and the following disclaimer in the documentation and/or other materials
|
||||||
|
// provided with the distribution.
|
||||||
|
//
|
||||||
|
// - Neither the name of the ICSharpCode team nor the names of its contributors may be used to
|
||||||
|
// endorse or promote products derived from this software without specific prior written
|
||||||
|
// permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS &AS IS& AND ANY EXPRESS
|
||||||
|
// OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||||
|
// AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||||
|
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
|
||||||
|
// IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||||
|
// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
using System; |
||||||
|
using System.Text; |
||||||
|
using ICSharpCode.SharpDevelop.Dom; |
||||||
|
using ICSharpCode.SharpDevelop.Dom.CSharp; |
||||||
|
using TextEditor = ICSharpCode.TextEditor; |
||||||
|
using NRefactoryResolver = ICSharpCode.SharpDevelop.Dom.NRefactoryResolver.NRefactoryResolver; |
||||||
|
|
||||||
|
namespace CSharpEditor |
||||||
|
{ |
||||||
|
sealed class ToolTipProvider |
||||||
|
{ |
||||||
|
MainForm mainForm; |
||||||
|
TextEditor.TextEditorControl editor; |
||||||
|
CSharpExpressionFinder expressionFinder = new CSharpExpressionFinder(MainForm.DummyFileName); |
||||||
|
|
||||||
|
private ToolTipProvider(MainForm mainForm, TextEditor.TextEditorControl editor) |
||||||
|
{ |
||||||
|
this.mainForm = mainForm; |
||||||
|
this.editor = editor; |
||||||
|
} |
||||||
|
|
||||||
|
public static void Attach(MainForm mainForm, TextEditor.TextEditorControl editor) |
||||||
|
{ |
||||||
|
ToolTipProvider tp = new ToolTipProvider(mainForm, editor); |
||||||
|
editor.ActiveTextAreaControl.TextArea.ToolTipRequest += tp.OnToolTipRequest; |
||||||
|
} |
||||||
|
|
||||||
|
void OnToolTipRequest(object sender, TextEditor.ToolTipRequestEventArgs e) |
||||||
|
{ |
||||||
|
if (e.InDocument && !e.ToolTipShown) { |
||||||
|
// SD2 requires subtracting 1 from the offset, this is fixed in the expression
|
||||||
|
// finder in SD3.
|
||||||
|
ExpressionResult expression = expressionFinder.FindFullExpression( |
||||||
|
editor.Text, |
||||||
|
editor.Document.PositionToOffset(e.LogicalPosition) - 1); |
||||||
|
|
||||||
|
TextEditor.TextArea textArea = editor.ActiveTextAreaControl.TextArea; |
||||||
|
NRefactoryResolver resolver = new NRefactoryResolver(mainForm.myProjectContent, mainForm.myProjectContent.Language); |
||||||
|
ResolveResult rr = resolver.Resolve(expression, |
||||||
|
textArea.Caret.Line, |
||||||
|
textArea.Caret.Column, |
||||||
|
MainForm.DummyFileName, |
||||||
|
textArea.MotherTextEditorControl.Text); |
||||||
|
string toolTipText = GetText(rr); |
||||||
|
if (toolTipText != null) { |
||||||
|
e.ShowToolTip(toolTipText); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
static string GetText(ResolveResult result) |
||||||
|
{ |
||||||
|
if (result == null) { |
||||||
|
return null; |
||||||
|
} |
||||||
|
if (result is MixedResolveResult) |
||||||
|
return GetText(((MixedResolveResult)result).PrimaryResult); |
||||||
|
IAmbience ambience = new CSharpAmbience(); |
||||||
|
ambience.ConversionFlags = ConversionFlags.StandardConversionFlags | ConversionFlags.ShowAccessibility; |
||||||
|
if (result is MemberResolveResult) { |
||||||
|
return GetMemberText(ambience, ((MemberResolveResult)result).ResolvedMember); |
||||||
|
} else if (result is LocalResolveResult) { |
||||||
|
LocalResolveResult rr = (LocalResolveResult)result; |
||||||
|
ambience.ConversionFlags = ConversionFlags.UseFullyQualifiedNames |
||||||
|
| ConversionFlags.ShowReturnType |
||||||
|
| ConversionFlags.QualifiedNamesOnlyForReturnTypes; |
||||||
|
StringBuilder b = new StringBuilder(); |
||||||
|
if (rr.IsParameter) |
||||||
|
b.Append("parameter "); |
||||||
|
else |
||||||
|
b.Append("local variable "); |
||||||
|
b.Append(ambience.Convert(rr.Field)); |
||||||
|
return b.ToString(); |
||||||
|
} else if (result is NamespaceResolveResult) { |
||||||
|
return "namespace " + ((NamespaceResolveResult)result).Name; |
||||||
|
} else if (result is TypeResolveResult) { |
||||||
|
IClass c = ((TypeResolveResult)result).ResolvedClass; |
||||||
|
if (c != null) |
||||||
|
return GetMemberText(ambience, c); |
||||||
|
else |
||||||
|
return ambience.Convert(result.ResolvedType); |
||||||
|
} else if (result is MethodResolveResult) { |
||||||
|
MethodResolveResult mrr = result as MethodResolveResult; |
||||||
|
IMethod m = mrr.GetMethodIfSingleOverload(); |
||||||
|
if (m != null) |
||||||
|
return GetMemberText(ambience, m); |
||||||
|
else |
||||||
|
return "Overload of " + ambience.Convert(mrr.ContainingType) + "." + mrr.Name; |
||||||
|
} else { |
||||||
|
return null; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
static string GetMemberText(IAmbience ambience, IDecoration member) |
||||||
|
{ |
||||||
|
StringBuilder text = new StringBuilder(); |
||||||
|
if (member is IField) { |
||||||
|
text.Append(ambience.Convert(member as IField)); |
||||||
|
} else if (member is IProperty) { |
||||||
|
text.Append(ambience.Convert(member as IProperty)); |
||||||
|
} else if (member is IEvent) { |
||||||
|
text.Append(ambience.Convert(member as IEvent)); |
||||||
|
} else if (member is IMethod) { |
||||||
|
text.Append(ambience.Convert(member as IMethod)); |
||||||
|
} else if (member is IClass) { |
||||||
|
text.Append(ambience.Convert(member as IClass)); |
||||||
|
} else { |
||||||
|
text.Append("unknown member "); |
||||||
|
text.Append(member.ToString()); |
||||||
|
} |
||||||
|
string documentation = member.Documentation; |
||||||
|
if (documentation != null && documentation.Length > 0) { |
||||||
|
text.Append('\n'); |
||||||
|
text.Append(CodeCompletionData.XmlDocumentationToText(documentation)); |
||||||
|
} |
||||||
|
return text.ToString(); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
Loading…
Reference in new issue