Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.CodeEditor/3.3/ToolTipProvider.cs @ 8344

Last change on this file since 8344 was 7746, checked in by epitzer, 13 years ago

#1826 check for null expression before resolving symbol for tool tip information

File size: 6.2 KB
Line 
1// CSharp Editor Example with Code Completion
2// Copyright (c) 2007, Daniel Grunwald
3// All rights reserved.
4//
5// Redistribution and use in source and binary forms, with or without modification, are
6// permitted provided that the following conditions are met:
7//
8// - Redistributions of source code must retain the above copyright notice, this list
9//   of conditions and the following disclaimer.
10//
11// - Redistributions in binary form must reproduce the above copyright notice, this list
12//   of conditions and the following disclaimer in the documentation and/or other materials
13//   provided with the distribution.
14//
15// - Neither the name of the ICSharpCode team nor the names of its contributors may be used to
16//   endorse or promote products derived from this software without specific prior written
17//   permission.
18//
19// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS &AS IS& AND ANY EXPRESS
20// OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
21// AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
22// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
25// IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
26// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28using System.Text;
29using ICSharpCode.SharpDevelop.Dom;
30using ICSharpCode.SharpDevelop.Dom.CSharp;
31using NRefactoryResolver = ICSharpCode.SharpDevelop.Dom.NRefactoryResolver.NRefactoryResolver;
32using TextEditor = ICSharpCode.TextEditor;
33
34namespace HeuristicLab.CodeEditor {
35  sealed class ToolTipProvider {
36    CodeEditor codeEditor;
37    TextEditor.TextEditorControl editor;
38
39    private ToolTipProvider(CodeEditor codeEditor, TextEditor.TextEditorControl editor) {
40      this.codeEditor = codeEditor;
41      this.editor = editor;
42    }
43
44    public static void Attach(CodeEditor codeEditor, TextEditor.TextEditorControl editor) {
45      ToolTipProvider tp = new ToolTipProvider(codeEditor, editor);
46      editor.ActiveTextAreaControl.TextArea.ToolTipRequest += tp.OnToolTipRequest;
47    }
48
49    void OnToolTipRequest(object sender, TextEditor.ToolTipRequestEventArgs e) {
50      if (e.InDocument && !e.ToolTipShown) {
51        IExpressionFinder expressionFinder;
52        expressionFinder = new CSharpExpressionFinder(codeEditor.parseInformation);
53        ExpressionResult expression = expressionFinder.FindFullExpression(
54          editor.Text,
55          editor.Document.PositionToOffset(e.LogicalPosition));
56        if (expression.Region.IsEmpty) {
57          expression.Region = new DomRegion(e.LogicalPosition.Line + 1, e.LogicalPosition.Column + 1);
58        }
59
60        TextEditor.TextArea textArea = editor.ActiveTextAreaControl.TextArea;
61        NRefactoryResolver resolver = new NRefactoryResolver(codeEditor.projectContent.Language);
62        if (expression.Expression != null) {
63          ResolveResult rr = resolver.Resolve(expression,
64            codeEditor.parseInformation,
65            textArea.MotherTextEditorControl.Text);
66          string toolTipText = GetText(rr);
67          if (toolTipText != null) {
68            e.ShowToolTip(toolTipText);
69          }
70        }
71      }
72    }
73
74    static string GetText(ResolveResult result) {
75      if (result == null) {
76        return null;
77      }
78      if (result is MixedResolveResult)
79        return GetText(((MixedResolveResult)result).PrimaryResult);
80      IAmbience ambience = new CSharpAmbience();
81      ambience.ConversionFlags = ConversionFlags.StandardConversionFlags | ConversionFlags.ShowAccessibility;
82      if (result is MemberResolveResult) {
83        return GetMemberText(ambience, ((MemberResolveResult)result).ResolvedMember);
84      } else if (result is LocalResolveResult) {
85        LocalResolveResult rr = (LocalResolveResult)result;
86        ambience.ConversionFlags = ConversionFlags.UseFullyQualifiedTypeNames
87          | ConversionFlags.ShowReturnType;
88        StringBuilder b = new StringBuilder();
89        if (rr.IsParameter)
90          b.Append("parameter ");
91        else
92          b.Append("local variable ");
93        b.Append(ambience.Convert(rr.Field));
94        return b.ToString();
95      } else if (result is NamespaceResolveResult) {
96        return "namespace " + ((NamespaceResolveResult)result).Name;
97      } else if (result is TypeResolveResult) {
98        IClass c = ((TypeResolveResult)result).ResolvedClass;
99        if (c != null)
100          return GetMemberText(ambience, c);
101        else
102          return ambience.Convert(result.ResolvedType);
103      } else if (result is MethodGroupResolveResult) {
104        MethodGroupResolveResult mrr = result as MethodGroupResolveResult;
105        IMethod m = mrr.GetMethodIfSingleOverload();
106        if (m != null)
107          return GetMemberText(ambience, m);
108        else
109          return "Overload of " + ambience.Convert(mrr.ContainingType) + "." + mrr.Name;
110      } else {
111        return null;
112      }
113    }
114
115    static string GetMemberText(IAmbience ambience, IEntity member) {
116      StringBuilder text = new StringBuilder();
117      if (member is IField) {
118        text.Append(ambience.Convert(member as IField));
119      } else if (member is IProperty) {
120        text.Append(ambience.Convert(member as IProperty));
121      } else if (member is IEvent) {
122        text.Append(ambience.Convert(member as IEvent));
123      } else if (member is IMethod) {
124        text.Append(ambience.Convert(member as IMethod));
125      } else if (member is IClass) {
126        text.Append(ambience.Convert(member as IClass));
127      } else {
128        text.Append("unknown member ");
129        text.Append(member.ToString());
130      }
131      string documentation = member.Documentation;
132      if (documentation != null && documentation.Length > 0) {
133        text.Append('\n');
134        text.Append(CodeCompletionData.XmlDocumentationToText(documentation));
135      }
136      return text.ToString();
137    }
138  }
139}
Note: See TracBrowser for help on using the repository browser.