1
ļ»æ// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team
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:
9
// The above copyright notice and this permission notice shall be included in all copies or
10
// substantial portions of the Software.
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.
20
using System.Collections.Generic;
21
using System.ComponentModel;
22
using System.Diagnostics;
25
using System.Reflection;
27
using System.Threading;
28
using System.Threading.Tasks;
29
using System.Windows.Forms;
31
using ICSharpCode.NRefactory.CSharp;
32
using ICSharpCode.NRefactory.CSharp.Resolver;
33
using ICSharpCode.NRefactory.Semantics;
34
using ICSharpCode.NRefactory.TypeSystem;
36
namespace ICSharpCode.NRefactory.Demo
39
/// Description of CSDemo.
41
public partial class CSDemo : UserControl
46
// The InitializeComponent() call is required for Windows Forms designer support.
48
InitializeComponent();
50
if (LicenseManager.UsageMode != LicenseUsageMode.Designtime) {
51
csharpCodeTextBox.SelectAll();
52
CSharpParseButtonClick(null, null);
53
resolveButton.UseWaitCursor = true;
54
ThreadPool.QueueUserWorkItem(
56
builtInLibs.Value.ToString();
57
BeginInvoke(new Action(delegate { resolveButton.UseWaitCursor = false; }));
62
SyntaxTree syntaxTree;
64
void CSharpParseButtonClick(object sender, EventArgs e)
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)));
71
csharpTreeView.Nodes.Clear();
72
foreach (var element in syntaxTree.Children) {
73
csharpTreeView.Nodes.Add(MakeTreeNode(element));
75
SelectCurrentNode(csharpTreeView.Nodes);
76
resolveButton.Enabled = true;
77
findReferencesButton.Enabled = true;
80
TreeNode MakeTreeNode(AstNode node)
82
TreeNode t = new TreeNode(GetNodeTitle(node));
84
foreach (AstNode child in node.Children) {
85
t.Nodes.Add(MakeTreeNode(child));
90
string GetNodeTitle(AstNode node)
92
StringBuilder b = new StringBuilder();
93
b.Append(node.Role.ToString());
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")
100
if (p.PropertyType == typeof(string) || p.PropertyType.IsEnum || p.PropertyType == typeof(bool)) {
101
if (!hasProperties) {
102
hasProperties = true;
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 + "**");
122
bool SelectCurrentNode(TreeNodeCollection c)
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))
132
if (selectionStart == selectionEnd
133
&& (selectionStart == GetOffset(csharpCodeTextBox, node.StartLocation)
134
|| selectionStart == GetOffset(csharpCodeTextBox, node.EndLocation)))
136
// caret is on border of this node; don't expand
137
csharpTreeView.SelectedNode = t;
140
if (!SelectCurrentNode(t.Nodes))
141
csharpTreeView.SelectedNode = t;
149
void CSharpGenerateCodeButtonClick(object sender, EventArgs e)
151
csharpCodeTextBox.Text = syntaxTree.GetText();
154
int GetOffset(TextBox textBox, TextLocation location)
156
// TextBox uses 0-based coordinates, TextLocation is 1-based
157
return textBox.GetFirstCharIndexFromLine(location.Line - 1) + location.Column - 1;
160
TextLocation GetTextLocation(TextBox textBox, int offset)
162
int line = textBox.GetLineFromCharIndex(offset);
163
int col = offset - textBox.GetFirstCharIndexFromLine(line);
164
return new TextLocation(line + 1, col + 1);
167
void CSharpTreeViewAfterSelect(object sender, TreeViewEventArgs e)
169
AstNode node = e.Node.Tag as AstNode;
171
if (node.StartLocation.IsEmpty || node.EndLocation.IsEmpty) {
172
csharpCodeTextBox.DeselectAll();
174
int startOffset = GetOffset(csharpCodeTextBox, node.StartLocation);
175
int endOffset = GetOffset(csharpCodeTextBox, node.EndLocation);
176
csharpCodeTextBox.Select(startOffset, endOffset - startOffset);
181
Lazy<IList<IUnresolvedAssembly>> builtInLibs = new Lazy<IList<IUnresolvedAssembly>>(
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,
192
IUnresolvedAssembly[] projectContents = new IUnresolvedAssembly[assemblies.Length];
193
Stopwatch total = Stopwatch.StartNew();
195
0, assemblies.Length,
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);
202
Debug.WriteLine("Total: " + total.Elapsed);
203
return projectContents;
206
void ResolveButtonClick(object sender, EventArgs e)
208
IProjectContent project = new CSharpProjectContent();
209
var unresolvedFile = syntaxTree.ToTypeSystem();
210
project = project.AddOrUpdateFiles(unresolvedFile);
211
project = project.AddAssemblyReferences(builtInLibs.Value);
213
ICompilation compilation = project.CreateCompilation();
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
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.");
229
using (var dlg = new SemanticTreeDialog(result))
233
void CSharpCodeTextBoxKeyDown(object sender, KeyEventArgs e)
235
if (e.Control && e.KeyCode == Keys.A) {
237
csharpCodeTextBox.SelectAll();
241
void CsharpCodeTextBoxTextChanged(object sender, EventArgs e)
243
resolveButton.Enabled = false;
244
findReferencesButton.Enabled = false;
247
void FindReferencesButtonClick(object sender, EventArgs e)
249
if (csharpTreeView.SelectedNode == null)
252
IProjectContent project = new CSharpProjectContent();
253
var unresolvedFile = syntaxTree.ToTypeSystem();
254
project = project.AddOrUpdateFiles(unresolvedFile);
255
project = project.AddAssemblyReferences(builtInLibs.Value);
257
ICompilation compilation = project.CreateCompilation();
258
CSharpAstResolver resolver = new CSharpAstResolver(compilation, syntaxTree, unresolvedFile);
260
AstNode node = (AstNode)csharpTreeView.SelectedNode.Tag;
262
MemberResolveResult mrr = resolver.Resolve(node) as MemberResolveResult;
263
TypeResolveResult trr = resolver.Resolve(node) as TypeResolveResult;
266
} else if (trr != null) {
267
entity = trr.Type.GetDefinition();
272
FindReferences fr = new FindReferences();
273
int referenceCount = 0;
274
FoundReferenceCallback callback = delegate(AstNode matchNode, ResolveResult result) {
275
Debug.WriteLine(matchNode.StartLocation + " - " + matchNode + " - " + result);
279
var searchScopes = fr.GetSearchScopes(entity);
280
Debug.WriteLine("Find references to " + entity.ReflectionName);
281
fr.FindReferencesInFile(searchScopes, unresolvedFile, syntaxTree, compilation, callback, CancellationToken.None);
283
MessageBox.Show("Found " + referenceCount + " references to " + entity.FullName);