~ubuntu-branches/ubuntu/trusty/monodevelop/trusty-proposed

« back to all changes in this revision

Viewing changes to external/nrefactory/ICSharpCode.NRefactory.Demo/CSDemo.cs

  • Committer: Package Import Robot
  • Author(s): Jo Shields
  • Date: 2013-05-12 09:46:03 UTC
  • mto: This revision was merged to the branch mainline in revision 29.
  • Revision ID: package-import@ubuntu.com-20130512094603-mad323bzcxvmcam0
Tags: upstream-4.0.5+dfsg
ImportĀ upstreamĀ versionĀ 4.0.5+dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
ļ»æ// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team
 
2
// 
 
3
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
 
4
// software and associated documentation files (the "Software"), to deal in the Software
 
5
// without restriction, including without limitation the rights to use, copy, modify, merge,
 
6
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
 
7
// to whom the Software is furnished to do so, subject to the following conditions:
 
8
// 
 
9
// The above copyright notice and this permission notice shall be included in all copies or
 
10
// substantial portions of the Software.
 
11
// 
 
12
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
 
13
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
 
14
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
 
15
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
 
16
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 
17
// DEALINGS IN THE SOFTWARE.
 
18
 
 
19
using System;
 
20
using System.Collections.Generic;
 
21
using System.ComponentModel;
 
22
using System.Diagnostics;
 
23
using System.IO;
 
24
using System.Linq;
 
25
using System.Reflection;
 
26
using System.Text;
 
27
using System.Threading;
 
28
using System.Threading.Tasks;
 
29
using System.Windows.Forms;
 
30
 
 
31
using ICSharpCode.NRefactory.CSharp;
 
32
using ICSharpCode.NRefactory.CSharp.Resolver;
 
33
using ICSharpCode.NRefactory.Semantics;
 
34
using ICSharpCode.NRefactory.TypeSystem;
 
35
 
 
36
namespace ICSharpCode.NRefactory.Demo
 
37
{
 
38
        /// <summary>
 
39
        /// Description of CSDemo.
 
40
        /// </summary>
 
41
        public partial class CSDemo : UserControl
 
42
        {
 
43
                public CSDemo()
 
44
                {
 
45
                        //
 
46
                        // The InitializeComponent() call is required for Windows Forms designer support.
 
47
                        //
 
48
                        InitializeComponent();
 
49
                        
 
50
                        if (LicenseManager.UsageMode != LicenseUsageMode.Designtime) {
 
51
                                csharpCodeTextBox.SelectAll();
 
52
                                CSharpParseButtonClick(null, null);
 
53
                                resolveButton.UseWaitCursor = true;
 
54
                                ThreadPool.QueueUserWorkItem(
 
55
                                        delegate {
 
56
                                                builtInLibs.Value.ToString();
 
57
                                                BeginInvoke(new Action(delegate { resolveButton.UseWaitCursor = false; }));
 
58
                                        });
 
59
                        }
 
60
                }
 
61
                
 
62
                SyntaxTree syntaxTree;
 
63
                
 
64
                void CSharpParseButtonClick(object sender, EventArgs e)
 
65
                {
 
66
                        var parser = new CSharpParser();
 
67
                        syntaxTree = parser.Parse(csharpCodeTextBox.Text, "demo.cs");
 
68
                        if (parser.HasErrors) {
 
69
                                MessageBox.Show(string.Join(Environment.NewLine, parser.Errors.Select(err => err.Message)));
 
70
                        }
 
71
                        csharpTreeView.Nodes.Clear();
 
72
                        foreach (var element in syntaxTree.Children) {
 
73
                                csharpTreeView.Nodes.Add(MakeTreeNode(element));
 
74
                        }
 
75
                        SelectCurrentNode(csharpTreeView.Nodes);
 
76
                        resolveButton.Enabled = true;
 
77
                        findReferencesButton.Enabled = true;
 
78
                }
 
79
                
 
80
                TreeNode MakeTreeNode(AstNode node)
 
81
                {
 
82
                        TreeNode t = new TreeNode(GetNodeTitle(node));
 
83
                        t.Tag = node;
 
84
                        foreach (AstNode child in node.Children) {
 
85
                                t.Nodes.Add(MakeTreeNode(child));
 
86
                        }
 
87
                        return t;
 
88
                }
 
89
                
 
90
                string GetNodeTitle(AstNode node)
 
91
                {
 
92
                        StringBuilder b = new StringBuilder();
 
93
                        b.Append(node.Role.ToString());
 
94
                        b.Append(": ");
 
95
                        b.Append(node.GetType().Name);
 
96
                        bool hasProperties = false;
 
97
                        foreach (PropertyInfo p in node.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance)) {
 
98
                                if (p.Name == "NodeType" || p.Name == "IsNull" || p.Name == "IsFrozen" || p.Name == "HasChildren")
 
99
                                        continue;
 
100
                                if (p.PropertyType == typeof(string) || p.PropertyType.IsEnum || p.PropertyType == typeof(bool)) {
 
101
                                        if (!hasProperties) {
 
102
                                                hasProperties = true;
 
103
                                                b.Append(" (");
 
104
                                        } else {
 
105
                                                b.Append(", ");
 
106
                                        }
 
107
                                        b.Append(p.Name);
 
108
                                        b.Append(" = ");
 
109
                                        try {
 
110
                                                object val = p.GetValue(node, null);
 
111
                                                b.Append(val != null ? val.ToString() : "**null**");
 
112
                                        } catch (TargetInvocationException ex) {
 
113
                                                b.Append("**" + ex.InnerException.GetType().Name + "**");
 
114
                                        }
 
115
                                }
 
116
                        }
 
117
                        if (hasProperties)
 
118
                                b.Append(")");
 
119
                        return b.ToString();
 
120
                }
 
121
                
 
122
                bool SelectCurrentNode(TreeNodeCollection c)
 
123
                {
 
124
                        int selectionStart = csharpCodeTextBox.SelectionStart;
 
125
                        int selectionEnd = selectionStart + csharpCodeTextBox.SelectionLength;
 
126
                        foreach (TreeNode t in c) {
 
127
                                AstNode node = t.Tag as AstNode;
 
128
                                if (node != null && !node.StartLocation.IsEmpty && !node.EndLocation.IsEmpty
 
129
                                    && selectionStart >= GetOffset(csharpCodeTextBox, node.StartLocation)
 
130
                                    && selectionEnd <= GetOffset(csharpCodeTextBox, node.EndLocation))
 
131
                                {
 
132
                                        if (selectionStart == selectionEnd
 
133
                                            && (selectionStart == GetOffset(csharpCodeTextBox, node.StartLocation)
 
134
                                                || selectionStart == GetOffset(csharpCodeTextBox, node.EndLocation)))
 
135
                                        {
 
136
                                                // caret is on border of this node; don't expand
 
137
                                                csharpTreeView.SelectedNode = t;
 
138
                                        } else {
 
139
                                                t.Expand();
 
140
                                                if (!SelectCurrentNode(t.Nodes))
 
141
                                                        csharpTreeView.SelectedNode = t;
 
142
                                        }
 
143
                                        return true;
 
144
                                }
 
145
                        }
 
146
                        return false;
 
147
                }
 
148
                
 
149
                void CSharpGenerateCodeButtonClick(object sender, EventArgs e)
 
150
                {
 
151
                        csharpCodeTextBox.Text = syntaxTree.GetText();
 
152
                }
 
153
                
 
154
                int GetOffset(TextBox textBox, TextLocation location)
 
155
                {
 
156
                        // TextBox uses 0-based coordinates, TextLocation is 1-based
 
157
                        return textBox.GetFirstCharIndexFromLine(location.Line - 1) + location.Column - 1;
 
158
                }
 
159
                
 
160
                TextLocation GetTextLocation(TextBox textBox, int offset)
 
161
                {
 
162
                        int line = textBox.GetLineFromCharIndex(offset);
 
163
                        int col = offset - textBox.GetFirstCharIndexFromLine(line);
 
164
                        return new TextLocation(line + 1, col + 1);
 
165
                }
 
166
                
 
167
                void CSharpTreeViewAfterSelect(object sender, TreeViewEventArgs e)
 
168
                {
 
169
                        AstNode node = e.Node.Tag as AstNode;
 
170
                        if (node != null) {
 
171
                                if (node.StartLocation.IsEmpty || node.EndLocation.IsEmpty) {
 
172
                                        csharpCodeTextBox.DeselectAll();
 
173
                                } else {
 
174
                                        int startOffset = GetOffset(csharpCodeTextBox, node.StartLocation);
 
175
                                        int endOffset = GetOffset(csharpCodeTextBox, node.EndLocation);
 
176
                                        csharpCodeTextBox.Select(startOffset, endOffset - startOffset);
 
177
                                }
 
178
                        }
 
179
                }
 
180
                
 
181
                Lazy<IList<IUnresolvedAssembly>> builtInLibs = new Lazy<IList<IUnresolvedAssembly>>(
 
182
                        delegate {
 
183
                                Assembly[] assemblies = {
 
184
                                        typeof(object).Assembly, // mscorlib
 
185
                                        typeof(Uri).Assembly, // System.dll
 
186
                                        typeof(System.Linq.Enumerable).Assembly, // System.Core.dll
 
187
//                                      typeof(System.Xml.XmlDocument).Assembly, // System.Xml.dll
 
188
//                                      typeof(System.Drawing.Bitmap).Assembly, // System.Drawing.dll
 
189
//                                      typeof(Form).Assembly, // System.Windows.Forms.dll
 
190
                                        typeof(ICSharpCode.NRefactory.TypeSystem.IProjectContent).Assembly,
 
191
                                };
 
192
                                IUnresolvedAssembly[] projectContents = new IUnresolvedAssembly[assemblies.Length];
 
193
                                Stopwatch total = Stopwatch.StartNew();
 
194
                                Parallel.For(
 
195
                                        0, assemblies.Length,
 
196
                                        delegate (int i) {
 
197
                                                Stopwatch w = Stopwatch.StartNew();
 
198
                                                CecilLoader loader = new CecilLoader();
 
199
                                                projectContents[i] = loader.LoadAssemblyFile(assemblies[i].Location);
 
200
                                                Debug.WriteLine(Path.GetFileName(assemblies[i].Location) + ": " + w.Elapsed);
 
201
                                        });
 
202
                                Debug.WriteLine("Total: " + total.Elapsed);
 
203
                                return projectContents;
 
204
                        });
 
205
                
 
206
                void ResolveButtonClick(object sender, EventArgs e)
 
207
                {
 
208
                        IProjectContent project = new CSharpProjectContent();
 
209
                        var unresolvedFile = syntaxTree.ToTypeSystem();
 
210
                        project = project.AddOrUpdateFiles(unresolvedFile);
 
211
                        project = project.AddAssemblyReferences(builtInLibs.Value);
 
212
                        
 
213
                        ICompilation compilation = project.CreateCompilation();
 
214
                        
 
215
                        ResolveResult result;
 
216
                        if (csharpTreeView.SelectedNode != null) {
 
217
                                var selectedNode = (AstNode)csharpTreeView.SelectedNode.Tag;
 
218
                                CSharpAstResolver resolver = new CSharpAstResolver(compilation, syntaxTree, unresolvedFile);
 
219
                                result = resolver.Resolve(selectedNode);
 
220
                                // CSharpAstResolver.Resolve() never returns null
 
221
                        } else {
 
222
                                TextLocation location = GetTextLocation(csharpCodeTextBox, csharpCodeTextBox.SelectionStart);
 
223
                                result = ResolveAtLocation.Resolve(compilation, unresolvedFile, syntaxTree, location);
 
224
                                if (result == null) {
 
225
                                        MessageBox.Show("Could not find a resolvable node at the caret location.");
 
226
                                        return;
 
227
                                }
 
228
                        }
 
229
                        using (var dlg = new SemanticTreeDialog(result))
 
230
                                dlg.ShowDialog();
 
231
                }
 
232
                
 
233
                void CSharpCodeTextBoxKeyDown(object sender, KeyEventArgs e)
 
234
                {
 
235
                        if (e.Control && e.KeyCode == Keys.A) {
 
236
                                e.Handled = true;
 
237
                                csharpCodeTextBox.SelectAll();
 
238
                        }
 
239
                }
 
240
                
 
241
                void CsharpCodeTextBoxTextChanged(object sender, EventArgs e)
 
242
                {
 
243
                        resolveButton.Enabled = false;
 
244
                        findReferencesButton.Enabled = false;
 
245
                }
 
246
                
 
247
                void FindReferencesButtonClick(object sender, EventArgs e)
 
248
                {
 
249
                        if (csharpTreeView.SelectedNode == null)
 
250
                                return;
 
251
                        
 
252
                        IProjectContent project = new CSharpProjectContent();
 
253
                        var unresolvedFile = syntaxTree.ToTypeSystem();
 
254
                        project = project.AddOrUpdateFiles(unresolvedFile);
 
255
                        project = project.AddAssemblyReferences(builtInLibs.Value);
 
256
                        
 
257
                        ICompilation compilation = project.CreateCompilation();
 
258
                        CSharpAstResolver resolver = new CSharpAstResolver(compilation, syntaxTree, unresolvedFile);
 
259
                        
 
260
                        AstNode node = (AstNode)csharpTreeView.SelectedNode.Tag;
 
261
                        IEntity entity;
 
262
                        MemberResolveResult mrr = resolver.Resolve(node) as MemberResolveResult;
 
263
                        TypeResolveResult trr = resolver.Resolve(node) as TypeResolveResult;
 
264
                        if (mrr != null) {
 
265
                                entity = mrr.Member;
 
266
                        } else if (trr != null) {
 
267
                                entity = trr.Type.GetDefinition();
 
268
                        } else {
 
269
                                return;
 
270
                        }
 
271
                        
 
272
                        FindReferences fr = new FindReferences();
 
273
                        int referenceCount = 0;
 
274
                        FoundReferenceCallback callback = delegate(AstNode matchNode, ResolveResult result) {
 
275
                                Debug.WriteLine(matchNode.StartLocation + " - " + matchNode + " - " + result);
 
276
                                referenceCount++;
 
277
                        };
 
278
                        
 
279
                        var searchScopes = fr.GetSearchScopes(entity);
 
280
                        Debug.WriteLine("Find references to " + entity.ReflectionName);
 
281
                        fr.FindReferencesInFile(searchScopes, unresolvedFile, syntaxTree, compilation, callback, CancellationToken.None);
 
282
                        
 
283
                        MessageBox.Show("Found " + referenceCount + " references to " + entity.FullName);
 
284
                }
 
285
        }
 
286
}