Skip to content
This repository has been archived by the owner on Oct 16, 2020. It is now read-only.

Commit

Permalink
implement method usage in method bodies
Browse files Browse the repository at this point in the history
  • Loading branch information
siegfriedpammer committed Jan 28, 2012
1 parent 16279c1 commit 13965a7
Show file tree
Hide file tree
Showing 19 changed files with 325 additions and 100 deletions.
9 changes: 2 additions & 7 deletions SharpDevelop.sln
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

Microsoft Visual Studio Solution File, Format Version 11.00
# Visual Studio 2010
# SharpDevelop 4.2.0.8363-alpha
# SharpDevelop 4.2.0.8380-alpha
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Main", "Main", "{256F5C28-532C-44C0-8AB8-D8EC5E492E01}"
ProjectSection(SolutionItems) = postProject
EndProjectSection
Expand Down Expand Up @@ -505,10 +505,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SourceAnalysis", "src\AddIn
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MachineSpecifications", "src\AddIns\Analysis\MachineSpecifications\MachineSpecifications\MachineSpecifications.csproj", "{D1DA3B8F-7313-4BDA-8880-461C5F007751}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "CodeQuality", "CodeQuality", "{558479FB-A397-4EE9-A1AD-879F80D1FCD0}"
ProjectSection(SolutionItems) = postProject
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CodeQuality", "src\AddIns\Analysis\CodeQuality\CodeQuality.csproj", "{3C532D80-32B4-40E5-B5FE-BC6BAE1A00E7}"
EndProject
Project("{00000000-0000-0000-0000-000000000000}") = "Tools", "src\Tools\Tools.build", "{3DF4060F-5EE0-41CF-8096-F27355FD5511}"
Expand Down Expand Up @@ -1266,7 +1262,6 @@ Global
{08CE9972-283B-44F4-82FA-966F7DFA6B7A} = {F355E45F-F54F-4B42-8916-9A633A392789}
{CE498514-D12D-4B6E-AE0E-FEC29BD43748} = {F355E45F-F54F-4B42-8916-9A633A392789}
{D1DA3B8F-7313-4BDA-8880-461C5F007751} = {F355E45F-F54F-4B42-8916-9A633A392789}
{558479FB-A397-4EE9-A1AD-879F80D1FCD0} = {F355E45F-F54F-4B42-8916-9A633A392789}
{3C532D80-32B4-40E5-B5FE-BC6BAE1A00E7} = {558479FB-A397-4EE9-A1AD-879F80D1FCD0}
{3C532D80-32B4-40E5-B5FE-BC6BAE1A00E7} = {F355E45F-F54F-4B42-8916-9A633A392789}
EndGlobalSection
EndGlobal
4 changes: 4 additions & 0 deletions src/AddIns/Analysis/CodeQuality/CodeQuality.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,10 @@
<Name>Mono.Cecil</Name>
<Private>False</Private>
</ProjectReference>
<ProjectReference Include="..\..\..\Libraries\NewNRefactory\ICSharpCode.NRefactory.CSharp\ICSharpCode.NRefactory.CSharp.csproj">
<Project>{53DCA265-3C3C-42F9-B647-F72BA678122B}</Project>
<Name>ICSharpCode.NRefactory.CSharp</Name>
</ProjectReference>
<ProjectReference Include="..\..\..\Libraries\NewNRefactory\ICSharpCode.NRefactory\ICSharpCode.NRefactory.csproj">
<Project>{3B2A5653-EC97-4001-BB9B-D90F1AF2C371}</Project>
<Name>ICSharpCode.NRefactory</Name>
Expand Down
87 changes: 67 additions & 20 deletions src/AddIns/Analysis/CodeQuality/Engine/AssemblyAnalyzer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Reflection;
using ICSharpCode.CodeQuality.Engine.Dom;
using ICSharpCode.NRefactory.TypeSystem;
using ICSharpCode.NRefactory.TypeSystem.Implementation;
Expand All @@ -18,13 +17,14 @@ namespace ICSharpCode.CodeQuality.Engine
/// </summary>
public class AssemblyAnalyzer
{
CecilLoader loader = new CecilLoader(true);
CecilLoader loader = new CecilLoader(true) { IncludeInternalMembers = true };
ICompilation compilation;
Dictionary<IAssembly, AssemblyNode> assemblyMappings;
Dictionary<string, NamespaceNode> namespaceMappings;
Dictionary<ITypeDefinition, TypeNode> typeMappings;
Dictionary<IMethod, MethodNode> methodMappings;
Dictionary<IField, FieldNode> fieldMappings;
internal Dictionary<IAssembly, AssemblyNode> assemblyMappings;
internal Dictionary<string, NamespaceNode> namespaceMappings;
internal Dictionary<ITypeDefinition, TypeNode> typeMappings;
internal Dictionary<IMethod, MethodNode> methodMappings;
internal Dictionary<IField, FieldNode> fieldMappings;
internal Dictionary<MemberReference, IEntity> cecilMappings;
List<string> fileNames;

public AssemblyAnalyzer()
Expand All @@ -45,25 +45,54 @@ public ReadOnlyCollection<AssemblyNode> Analyze()
assemblyMappings = new Dictionary<IAssembly, AssemblyNode>();
namespaceMappings = new Dictionary<string, NamespaceNode>();
typeMappings = new Dictionary<ITypeDefinition, TypeNode>();
fieldMappings = new Dictionary<IField, FieldNode>();
methodMappings = new Dictionary<IMethod, MethodNode>();
cecilMappings = new Dictionary<MemberReference, IEntity>();

foreach (var type in compilation.GetAllTypeDefinitions()) {
AnalyzeType(type);
ReadType(type);
}
foreach (TypeNode type in typeMappings.Values) {
foreach (var field in type.TypeDefinition.Fields) {
var node = new FieldNode(field);
fieldMappings.Add(field, node);
try {
var cecilObj = loader.GetCecilObject((IUnresolvedField)field.UnresolvedMember);
cecilMappings[cecilObj] = field;
} catch (InvalidOperationException) {}
type.Children.Add(node);
}

foreach (var method in type.TypeDefinition.Methods) {
var node = new MethodNode(method);
methodMappings.Add(method, node);
try {
var cecilObj = loader.GetCecilObject((IUnresolvedMethod)method.UnresolvedMember);
cecilMappings[cecilObj] = method;
} catch (InvalidOperationException) {}
type.Children.Add(node);
}
}
ILAnalyzer analyzer = new ILAnalyzer(loadedAssemblies.Select(asm => loader.GetCecilObject(asm)).ToArray(), this);
foreach (var element in methodMappings) {
int cc;
try {
var cecilObj = loader.GetCecilObject((IUnresolvedMethod)element.Key.UnresolvedMember);
analyzer.Analyze(cecilObj.Body, element.Value, out cc);
} catch (InvalidOperationException) {}
}
return new ReadOnlyCollection<AssemblyNode>(assemblyMappings.Values.ToList());
}

IEnumerable<IUnresolvedAssembly> LoadAssemblies()
{
var resolver = new DefaultAssemblyResolver();
foreach (var file in fileNames) {
var mainAsm = loader.LoadAssemblyFile(file);
yield return mainAsm;
var referencedAssemblies = loader.GetCecilObject(mainAsm).Modules
.SelectMany(m => m.AssemblyReferences)
.Select(r => resolver.Resolve(r));
foreach (var asm in referencedAssemblies)
yield return loader.LoadAssembly(asm);
}
var resolver = new AssemblyResolver();
List<AssemblyDefinition> assemblies = new List<AssemblyDefinition>();
foreach (var file in fileNames.Distinct(StringComparer.OrdinalIgnoreCase))
assemblies.Add(resolver.LoadAssemblyFile(file));
foreach (var asm in assemblies.ToArray())
assemblies.AddRange(asm.Modules.SelectMany(m => m.AssemblyReferences).Select(r => resolver.Resolve(r)));
return assemblies.Distinct().Select(asm => loader.LoadAssembly(asm));
}

NamespaceNode GetOrCreateNamespace(AssemblyNode assembly, string namespaceName)
Expand All @@ -88,13 +117,31 @@ AssemblyNode GetOrCreateAssembly(IAssembly asm)
return result;
}

void AnalyzeType(ITypeDefinition type)
void ReadType(ITypeDefinition type)
{
var asm = GetOrCreateAssembly(type.ParentAssembly);
var ns = GetOrCreateNamespace(asm, type.Namespace);
TypeNode parent;
var node = new TypeNode(type);
if (type.DeclaringTypeDefinition != null) {
if (typeMappings.TryGetValue(type.DeclaringTypeDefinition, out parent))
parent.Children.Add(node);
else
throw new Exception("TypeNode not found: " + type.DeclaringTypeDefinition.FullName);
} else
ns.Children.Add(node);
cecilMappings[loader.GetCecilObject(type.Parts.First())] = type;
typeMappings.Add(type, node);
ns.Children.Add(node);
}

class AssemblyResolver : DefaultAssemblyResolver
{
public AssemblyDefinition LoadAssemblyFile(string fileName)
{
var assembly = AssemblyDefinition.ReadAssembly(fileName, new ReaderParameters { AssemblyResolver = this });
RegisterAssembly(assembly);
return assembly;
}
}
}
}
25 changes: 14 additions & 11 deletions src/AddIns/Analysis/CodeQuality/Engine/Dom/AssemblyNode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@

using System;
using System.Collections.Generic;
using System.Linq;
using ICSharpCode.NRefactory.TypeSystem;
using ICSharpCode.NRefactory.Utils;

namespace ICSharpCode.CodeQuality.Engine.Dom
{
Expand All @@ -27,28 +29,29 @@ public IList<INode> Children {
get { return namespaces; }
}

public IEnumerable<INode> Uses {
get {
throw new NotImplementedException();
}
public IEnumerable<INode> Descendants {
get { return TreeTraversal.PreOrder(Children, node => node.Children); }
}

public IEnumerable<INode> UsedBy {
get {
throw new NotImplementedException();
}
public IEnumerable<INode> Uses {
get { return Descendants.SelectMany(node => node.Uses); }
}

public void CalculateMetricsAndFreeze(IEnumerable<AssemblyNode> assemblies)
{

public IEnumerable<INode> UsedBy {
get { return Descendants.SelectMany(node => node.UsedBy); }
}

public Relationship GetRelationship(INode value)
{
Relationship r = new Relationship();
if (value == this)
r.AddRelationship(RelationshipType.Same);
if (Uses.Contains(value))
r.AddRelationship(RelationshipType.Uses);
if (UsedBy.Contains(value))
r.AddRelationship(RelationshipType.UsedBy);
if (Descendants.Contains(value))
r.AddRelationship(RelationshipType.Contains);
return r;
}
}
Expand Down
10 changes: 7 additions & 3 deletions src/AddIns/Analysis/CodeQuality/Engine/Dom/EventNode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@

using System;
using System.Collections.Generic;
using System.Linq;

using ICSharpCode.NRefactory.TypeSystem;

namespace ICSharpCode.CodeQuality.Engine.Dom
Expand All @@ -16,9 +18,7 @@ public string Name {
}

public IList<INode> Children {
get {
throw new NotImplementedException();
}
get { return null; }
}

public IEnumerable<INode> Uses {
Expand All @@ -38,6 +38,10 @@ public Relationship GetRelationship(INode value)
Relationship r = new Relationship();
if (value == this)
r.AddRelationship(RelationshipType.Same);
if (Uses.Contains(value))
r.AddRelationship(RelationshipType.Uses);
if (UsedBy.Contains(value))
r.AddRelationship(RelationshipType.UsedBy);
return r;
}
}
Expand Down
24 changes: 12 additions & 12 deletions src/AddIns/Analysis/CodeQuality/Engine/Dom/FieldNode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,34 +3,34 @@

using System;
using System.Collections.Generic;
using System.Linq;
using ICSharpCode.NRefactory.TypeSystem;

namespace ICSharpCode.CodeQuality.Engine.Dom
{
public class FieldNode : INode
{
public IField FieldDefinition { get; private set; }

public FieldNode(IField fieldDefinition)
{
this.FieldDefinition = fieldDefinition;
}

public string Name {
get {
throw new NotImplementedException();
}
get { return FieldDefinition.PrintFullName(); }
}

public IList<INode> Children {
get {
throw new NotImplementedException();
}
get { return null; }
}

public IEnumerable<INode> Uses {
get {
throw new NotImplementedException();
}
get { return Enumerable.Empty<INode>(); }
}

public IEnumerable<INode> UsedBy {
get {
throw new NotImplementedException();
}
get { return Enumerable.Empty<INode>(); }
}

public Relationship GetRelationship(INode value)
Expand Down
33 changes: 21 additions & 12 deletions src/AddIns/Analysis/CodeQuality/Engine/Dom/MethodNode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,41 +3,50 @@

using System;
using System.Collections.Generic;
using System.Linq;

using ICSharpCode.NRefactory.TypeSystem;

namespace ICSharpCode.CodeQuality.Engine.Dom
{
public class MethodNode : INode
{
public IMethod MethodDefinition { get; private set; }

public MethodNode(IMethod methodDefinition)
{
this.MethodDefinition = methodDefinition;
uses = new List<INode>();
usedBy = new List<INode>();
}

public string Name {
get {
throw new NotImplementedException();
}
get { return MethodDefinition.PrintFullName(); }
}

public IList<INode> Children {
get {
throw new NotImplementedException();
}
get { return null; }
}

internal IList<INode> uses, usedBy;

public IEnumerable<INode> Uses {
get {
throw new NotImplementedException();
}
get { return uses; }
}

public IEnumerable<INode> UsedBy {
get {
throw new NotImplementedException();
}
get { return usedBy; }
}

public Relationship GetRelationship(INode value)
{
Relationship r = new Relationship();
if (value == this)
r.AddRelationship(RelationshipType.Same);
if (Uses.Contains(value))
r.AddRelationship(RelationshipType.Uses);
if (UsedBy.Contains(value))
r.AddRelationship(RelationshipType.UsedBy);
return r;
}
}
Expand Down
Loading

0 comments on commit 13965a7

Please sign in to comment.