Permalink
Browse files

Fri Nov 24 16:25:51 CET 2006 Paolo Molaro <lupus@ximian.com>

	* CoverageModel.cs: updated to use Cecil to load assemblies
	so the tool can be used with both 1.0 and 2.0 runtimes.
	Made it handle the conversion between the different name
	conventions for nested types.
	* coverage.c: include the assembly filename in the output so
	we don't have to try and emulate the runtime assembly load
	process and we can find the used assembly right away.


svn path=/trunk/monocov/; revision=68432
  • Loading branch information...
1 parent cbf89b1 commit 700a3591bb5982481b1949b86261663fd914bb2d @illupus illupus committed Nov 24, 2006
Showing with 170 additions and 36 deletions.
  1. +16 −0 ChangeLog
  2. +5 −0 ClassCoverageItem.cs
  3. +129 −3 CoverageModel.cs
  4. +2 −1 Makefile
  5. +13 −30 README
  6. +5 −2 coverage.c
View
@@ -1,3 +1,19 @@
+
+Fri Nov 24 16:25:51 CET 2006 Paolo Molaro <lupus@ximian.com>
+
+ * CoverageModel.cs: updated to use Cecil to load assemblies
+ so the tool can be used with both 1.0 and 2.0 runtimes.
+ Made it handle the conversion between the different name
+ conventions for nested types.
+ * coverage.c: include the assembly filename in the output so
+ we don't have to try and emulate the runtime assembly load
+ process and we can find the used assembly right away.
+
+Fri Nov 24 16:23:38 CET 2006 Paolo Molaro <lupus@ximian.com>
+
+ * gui/gtk/*.cs: usability improvements and changes to make
+ it run with more recent versions of glade-sharp.
+
2006-04-04 Jacob Ilsø Christensen <jacobilsoe@gmail.com>
* CoverageModel.cs: Removed redundant for loops
View
@@ -1,6 +1,7 @@
using System;
using System.Collections;
+using Mono.Cecil;
namespace MonoCov {
@@ -15,7 +16,11 @@ public class ClassCoverageItem : CoverageItem {
public SourceFileCoverageData sourceFile;
// The type object representing this class
+#if USE_REFLECTION
public Type type;
+#else
+ public TypeDefinition type;
+#endif
// Contains MethodBase -> MethodCoverageData mappings
public Hashtable methodsByMethod;
View
@@ -2,9 +2,12 @@
using System.Collections;
using System.Xml;
using System.IO;
+using System.Text;
using System.Reflection;
using System.Text.RegularExpressions;
using Mono.CompilerServices.SymbolWriter;
+using Mono.Cecil;
+using Mono.Cecil.Metadata;
namespace MonoCov
{
@@ -83,7 +86,10 @@ private void LoadAssemblies (XmlDocument dom)
foreach (XmlNode n in dom.GetElementsByTagName ("assembly")) {
string assemblyName = n.Attributes ["name"].Value;
string guid = n.Attributes ["guid"].Value;
+ string filename = n.Attributes ["filename"].Value;
+ MonoSymbolFile symbolFile;
+#if USE_REFLECTION
Assembly assembly = Assembly.Load (assemblyName);
MethodInfo getguid = typeof (Module).GetMethod (
@@ -96,10 +102,10 @@ private void LoadAssemblies (XmlDocument dom)
if (assembly_guid != new Guid (guid)) {
Console.WriteLine ("WARNING: Loaded version of assembly " + assembly + " is different from the version used to collect coverage data.");
}
+ } else {
+ Console.WriteLine ("WARNING: Can't verify the guid of " + assembly);
}
- MonoSymbolFile symbolFile;
-
loadedAssemblies [assemblyName] = assembly;
Console.Write ("Reading symbols for " + assembly + " ...");
@@ -110,6 +116,23 @@ private void LoadAssemblies (XmlDocument dom)
symbolFiles [assembly] = symbolFile;
Console.WriteLine (" (" + symbolFile.SourceCount + " files, " + symbolFile.MethodCount + " methods)");
}
+#else
+ AssemblyDefinition assembly = AssemblyFactory.GetAssembly (filename);
+ ModuleDefinition module = assembly.MainModule;
+ if (module.Mvid != new Guid (guid)) {
+ Console.WriteLine ("WARNING: Loaded version of assembly " + assembly + " is different from the version used to collect coverage data.");
+ }
+ loadedAssemblies [assemblyName] = assembly;
+
+ Console.Write ("Reading symbols for " + assemblyName + " ...");
+ symbolFile = MonoSymbolFile.ReadSymbolFile (filename + ".mdb");
+ if (symbolFile == null)
+ Console.WriteLine (" (No symbols found)");
+ else {
+ symbolFiles [assembly] = symbolFile;
+ Console.WriteLine (" (" + symbolFile.SourceCount + " files, " + symbolFile.MethodCount + " methods)");
+ }
+#endif
}
}
@@ -120,6 +143,46 @@ private void LoadFilters (XmlDocument dom)
}
}
+#if USE_REFLECTION
+ static Type LoadType (Assembly assembly, string name) {
+ Type type = assembly.GetType (name);
+ if (type != null)
+ return type;
+ int last_dot = name.LastIndexOf ('.');
+ // covert names from IL to reflection naming
+ // needed to deal with nested types
+ while (last_dot >= 0) {
+ StringBuilder sb = new StringBuilder (name);
+ sb [last_dot] = '/';
+ name = sb.ToString ();
+ type = assembly.GetType (name);
+ if (type != null)
+ return type;
+ last_dot = name.LastIndexOf ('.');
+ }
+ return null;
+ }
+#else
+ static TypeDefinition LoadType (AssemblyDefinition assembly, string name) {
+ TypeDefinition type = assembly.MainModule.Types [name];
+ if (type != null)
+ return type;
+ int last_dot = name.LastIndexOf ('.');
+ // covert names from IL to reflection naming
+ // needed to deal with nested types
+ while (last_dot >= 0) {
+ StringBuilder sb = new StringBuilder (name);
+ sb [last_dot] = '/';
+ name = sb.ToString ();
+ type = assembly.MainModule.Types [name];
+ if (type != null)
+ return type;
+ last_dot = name.LastIndexOf ('.');
+ }
+ return null;
+ }
+#endif
+
public void ReadFromFile (string fileName)
{
namespaces = new Hashtable ();
@@ -155,14 +218,16 @@ public void ReadFromFile (string fileName)
string methodName = n.Attributes ["name"].Value;
string token = n.Attributes ["token"].Value;
string cov_info = n.FirstChild.Value;
+ int itok = int.Parse (token);
+#if USE_REFLECTION
Assembly assembly = (Assembly)loadedAssemblies [assemblyName];
MonoSymbolFile symbolFile = (MonoSymbolFile)symbolFiles [assembly];
if (symbolFile == null)
continue;
- Type t = assembly.GetType (className);
+ Type t = LoadType (assembly, className);
if (t == null) {
Console.WriteLine ("ERROR: Unable to resolve type " + className + " in " + assembly);
continue;
@@ -182,6 +247,29 @@ public void ReadFromFile (string fileName)
MethodBase monoMethod = module.ResolveMethod(Int32.Parse(token));
ProcessMethod (monoMethod, entry, klass, methodName, cov_info);
+#else
+ AssemblyDefinition assembly = (AssemblyDefinition)loadedAssemblies [assemblyName];
+ MonoSymbolFile symbolFile = (MonoSymbolFile)symbolFiles [assembly];
+
+ if (symbolFile == null)
+ continue;
+
+ TypeDefinition t = LoadType (assembly, className);
+ if (t == null) {
+ Console.WriteLine ("ERROR: Unable to resolve type " + className + " in " + assembly);
+ continue;
+ }
+
+ ClassCoverageItem klass = ProcessClass (t);
+
+ MethodEntry entry = symbolFile.GetMethodByToken (itok);
+
+ MethodDefinition monoMethod = assembly.MainModule.LookupByToken (
+ new MetadataToken ((TokenType)(itok & 0xff000000), (uint)(itok & 0xffffff)))
+ as MethodDefinition;
+ //Console.WriteLine (monoMethod);
+ ProcessMethod (monoMethod, entry, klass, methodName, cov_info);
+#endif
}
msec2 = DateTime.Now.Ticks / 10000;
@@ -190,6 +278,7 @@ public void ReadFromFile (string fileName)
// Add info for klasses for which we have no coverage
+#if USE_REFLECTION
foreach (Assembly assembly in loadedAssemblies.Values) {
foreach (Type t in assembly.GetTypes ()) {
ProcessClass (t);
@@ -210,6 +299,27 @@ public void ReadFromFile (string fileName)
}
}
}
+#else
+ foreach (AssemblyDefinition assembly in loadedAssemblies.Values) {
+ foreach (TypeDefinition t in assembly.MainModule.Types) {
+ ProcessClass (t);
+ }
+ }
+
+ // Add info for methods for which we have no coverage
+ foreach (ClassCoverageItem klass in classes.Values) {
+ foreach (MethodDefinition mb in klass.type.Methods) {
+ MonoSymbolFile symbolFile = (MonoSymbolFile)symbolFiles [klass.type.Module.Assembly];
+ if (symbolFile == null)
+ continue;
+
+ if (! klass.methodsByMethod.ContainsKey (mb)) {
+ MethodEntry entry = symbolFile.GetMethodByToken ((int)mb.MetadataToken.ToUInt());
+ ProcessMethod (mb, entry, klass, mb.Name, null);
+ }
+ }
+ }
+#endif
msec2 = DateTime.Now.Ticks / 10000;
Console.WriteLine ("Additional classes: " + (msec2 - msec) + " msec");
@@ -356,7 +466,11 @@ private void computeMethodCoverage (MethodCoverageItem method, LineNumberEntry[]
}
}
+#if USE_REFLECTION
private ClassCoverageItem ProcessClass (Type t)
+#else
+ private ClassCoverageItem ProcessClass (TypeDefinition t)
+#endif
{
string className = t.FullName;
int nsindex = className.LastIndexOf (".");
@@ -403,14 +517,22 @@ private ClassCoverageItem ProcessClass (Type t)
klass.type = t;
klass.parent = ns;
+#if USE_REFLECTION
klass.filtered = IsFiltered ("[" + t.Assembly + "]" + className);
+#else
+ klass.filtered = IsFiltered ("[" + t.Module.Name + "]" + className);
+#endif
classes [className] = klass;
}
return klass;
}
+#if USE_REFLECTION
private void ProcessMethod (MethodBase monoMethod, MethodEntry entry, ClassCoverageItem klass, string methodName, string cov_info)
+#else
+ private void ProcessMethod (MethodDefinition monoMethod, MethodEntry entry, ClassCoverageItem klass, string methodName, string cov_info)
+#endif
{
if (entry == null)
// Compiler generated, abstract method etc.
@@ -429,7 +551,11 @@ MethodCoverageItem method
method.startLine = start_line;
method.endLine = end_line;
+#if USE_REFLECTION
method.filtered = IsFiltered ("[" + monoMethod.DeclaringType.Assembly + "]" + monoMethod.DeclaringType + "::" + monoMethod.Name);
+#else
+ method.filtered = IsFiltered ("[" + monoMethod.DeclaringType.Module.Name + "]" + monoMethod.DeclaringType + "::" + monoMethod.Name);
+#endif
klass.methodsByMethod [monoMethod] = method;
View
@@ -2,6 +2,7 @@
PROJECTNAME = monocov
GUI = gtk
MONO_ROOT = ../mono
+LIBS=-r:Mono.Cecil
all: monocov.exe libmono-profiler-monocov.so symbols.exe
@@ -33,7 +34,7 @@ SRCS = \
$(GUI_SRCS)
monocov.exe: $(SRCS) style.xsl .gui-$(GUI)
- gmcs -debug /target:exe /out:$@ -define:GUI_$(GUI) -r:Mono.CompilerServices.SymbolWriter -r:Mono.GetOptions $(GUI_LIBS) $(SRCS) -resource:style.xsl,style.xsl -resource:trans.gif,trans.gif
+ gmcs -debug /target:exe /out:$@ -define:GUI_$(GUI) $(LIBS) -r:Mono.CompilerServices.SymbolWriter -r:Mono.GetOptions $(GUI_LIBS) $(SRCS) -resource:style.xsl,style.xsl -resource:trans.gif,trans.gif
.gui-gtk:
@rm -f .gui-*
Oops, something went wrong.

0 comments on commit 700a359

Please sign in to comment.