PageRenderTime 23ms CodeModel.GetById 15ms app.highlight 5ms RepoModel.GetById 2ms app.codeStats 0ms

/ILSpy/TreeNodes/Analyzer/AnalyzedTypeInstantiationsTreeNode.cs

http://github.com/icsharpcode/ILSpy
C# | 93 lines | 61 code | 13 blank | 19 comment | 18 complexity | d374213dc45f8b6db6d8d828cd94a220 MD5 | raw file
 1// Copyright (c) 2011 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
19using System;
20using System.Collections.Generic;
21using System.Linq;
22using System.Threading;
23using ICSharpCode.Decompiler.Ast;
24using Mono.Cecil;
25using Mono.Cecil.Cil;
26
27namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
28{
29	internal sealed class AnalyzedTypeInstantiationsTreeNode : AnalyzerSearchTreeNode
30	{
31		private readonly TypeDefinition analyzedType;
32		private readonly bool isSystemObject;
33
34		public AnalyzedTypeInstantiationsTreeNode(TypeDefinition analyzedType)
35		{
36			if (analyzedType == null)
37				throw new ArgumentNullException("analyzedType");
38
39			this.analyzedType = analyzedType;
40
41			this.isSystemObject = (analyzedType.FullName == "System.Object");
42		}
43
44		public override object Text
45		{
46			get { return "Instantiated By"; }
47		}
48
49		protected override IEnumerable<AnalyzerTreeNode> FetchChildren(CancellationToken ct)
50		{
51			var analyzer = new ScopedWhereUsedAnalyzer<AnalyzerTreeNode>(analyzedType, FindReferencesInType);
52			return analyzer.PerformAnalysis(ct).OrderBy(n => n.Text);
53		}
54
55		private IEnumerable<AnalyzerTreeNode> FindReferencesInType(TypeDefinition type)
56		{
57			foreach (MethodDefinition method in type.Methods) {
58				bool found = false;
59				if (!method.HasBody)
60					continue;
61
62				// ignore chained constructors
63				// (since object is the root of everything, we can short circuit the test in this case)
64				if (method.Name == ".ctor" &&
65					(isSystemObject || analyzedType == type || TypesHierarchyHelpers.IsBaseType(analyzedType, type, false)))
66					continue;
67
68				foreach (Instruction instr in method.Body.Instructions) {
69					MethodReference mr = instr.Operand as MethodReference;
70					if (mr != null && mr.Name == ".ctor") {
71						if (Helpers.IsReferencedBy(analyzedType, mr.DeclaringType)) {
72							found = true;
73							break;
74						}
75					}
76				}
77
78				method.Body = null;
79
80				if (found) {
81					var node = new AnalyzedMethodTreeNode(method);
82					node.Language = this.Language;
83					yield return node;
84				}
85			}
86		}
87
88		public static bool CanShow(TypeDefinition type)
89		{
90			return (type.IsClass && !(type.IsAbstract && type.IsSealed) && !type.IsEnum);
91		}
92	}
93}