Skip to content
This repository was archived by the owner on Jan 14, 2021. It is now read-only.
48 changes: 44 additions & 4 deletions Forms/MainForm.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ public partial class MainForm : Form

private FileDefinition async_definitions;
private ListViewItem[] async_assemblies;

public MainForm ()
{
InitializeComponent ();
Expand Down Expand Up @@ -82,6 +82,9 @@ public string SubmitFileName {
}
set { submit_filename = value; }
}
public string AssembliesToIgnore{
get; set;
}
#endregion

#region Public Methods
Expand All @@ -90,22 +93,36 @@ public void AddAssembly (string path)
if (!ListContainsAssembly (Path.GetFileName (path))) {
ListViewItem lvi = new ListViewItem (Path.GetFileName (path));
lvi.Tag = path;

Console.WriteLine(path + " added to assembly list.");
AssemblyListView.Items.Add (lvi);
}
}

public void AnalyzeNoGui ()
public int AnalyzeNoGui ()
{
RemoveIgnoredAssemblies();
string msg = VerifyValidAssemblies ();

if (!string.IsNullOrEmpty (msg))
Console.WriteLine (msg);

async_definitions = (FileDefinition)MonoVersionCombo.SelectedItem;
if (async_definitions == null){
Console.WriteLine("No language definition file found! Please run the GUI-version "+
"to download the latest definition files.");
return 1;
}
async_assemblies = (ListViewItem[])new ArrayList (AssemblyListView.Items).ToArray (typeof (ListViewItem));

ScanningCompletedEventArgs e = AnalyzeAssemblies ();
int totalIssues = e.MissingMethodTotal + e.MonoTodoTotal + e.NotImplementedExceptionTotal + e.PInvokeTotal;
if (totalIssues > 0){
Console.WriteLine(e.MissingMethodTotal+" Missing, "+ e.MonoTodoTotal+" ToDo, " + e.NotImplementedExceptionTotal+" NotImplemented, "+e.PInvokeTotal+" PInvoke ");
return 1;
}
else{
return 0;
}
}
#endregion

Expand Down Expand Up @@ -474,7 +491,7 @@ private void DirectoryAddButton_Click (object sender, EventArgs e)
AssemblyListView.EndUpdate ();
}

private void ScanForAssemblies (string path)
internal void ScanForAssemblies (string path)
{
foreach (string file in Directory.GetFiles (path, "*.dll"))
AddAssembly (file);
Expand All @@ -499,6 +516,29 @@ private void GettingStartedButton_Click (object sender, EventArgs e)
{
System.Diagnostics.Process.Start ("http://www.mono-project.com/Start");
}
private void RemoveIgnoredAssemblies()
{

String[] ignored = AssembliesToIgnore.Split(',');
List<ListViewItem> toRemove = new List<ListViewItem>();

foreach (ListViewItem item in AssemblyListView.Items)
{
foreach (string str in ignored)
{
if (Path.GetFileName((string)item.Tag) == str.Trim())
{
toRemove.Add(item);
}
}
}
foreach (ListViewItem lvr in toRemove)
{
Console.WriteLine(lvr.Tag + " will not be scanned for Mono compatibility.");
AssemblyListView.Items.Remove(lvr);
}

}
#endregion

#region Static Methods
Expand Down
2 changes: 1 addition & 1 deletion MoMA.Analyzer/Analysis/CheckPInvokes.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ public CheckPInvokes ()

public void FindPInvokesInAssembly (string assembly)
{
AssemblyDefinition ad = AssemblyFactory.GetAssembly (assembly);
AssemblyDefinition ad =AssemblyDefinition.ReadAssembly (assembly);

//Gets all types of the MainModule of the assembly
foreach (TypeDefinition type in ad.MainModule.Types) {
Expand Down
45 changes: 5 additions & 40 deletions MoMA.Analyzer/AssemblyAnalyzer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -122,20 +122,8 @@ public string AssemblyName {
public string AssemblyRuntime {
get { return assembly_runtime; }
set {
switch (value) {
case "NET_1_0":
assembly_runtime = "1.0";
break;
case "NET_1_1":
assembly_runtime = "1.1";
break;
case "NET_2_0":
assembly_runtime = "2.0";
break;
default:
assembly_runtime = value;
break;
}
//Net_4_0 -> 4.0
assembly_runtime = value.ToLower().Replace("net_", "").Replace("_",".");
}
}

Expand Down Expand Up @@ -215,7 +203,7 @@ public ScanningCompletedEventArgs Analyze ()
public static bool IsValidAssembly (string assembly)
{
try {
AssemblyFactory.GetAssembly (assembly);
AssemblyDefinition.ReadAssembly(assembly);
return true;
} catch {
return false;
Expand Down Expand Up @@ -254,10 +242,10 @@ private void AddAssemblyToReport (AssemblyScannedEventArgs e)

private void AnalyzeAssembly (string assembly)
{
AssemblyDefinition ad = AssemblyFactory.GetAssembly (assembly);
AssemblyDefinition ad = AssemblyDefinition.ReadAssembly(assembly);

assembly_version = ad.Name.Version;
AssemblyRuntime = ad.Runtime.ToString ();
AssemblyRuntime = ad.MainModule.Runtime.ToString ();
assembly_name = Path.GetFileName (assembly);

foreach (TypeDefinition type in ad.MainModule.Types) {
Expand All @@ -284,29 +272,6 @@ private void AnalyzeAssembly (string assembly)
}
}
}

// Check every constructor for calls that match our issues lists
foreach (MethodDefinition method in type.Constructors) {
if (method.Body != null) {
foreach (Instruction i in method.Body.Instructions) {
if (i.OpCode == OpCodes.Call || i.OpCode == OpCodes.Callvirt || i.OpCode == OpCodes.Calli || i.OpCode == OpCodes.Ldftn || i.OpCode == OpCodes.Ldvirtftn || i.OpCode == OpCodes.Newobj || i.OpCode == OpCodes.Initobj) {
Method match;

if (mono_todo != null && mono_todo.Matches (i.Operand.ToString (), out match))
mono_todo_results.Add (new MomaError (new Method (method.ToString ()), match));

if (not_implemented != null && not_implemented.Matches (i.Operand.ToString (), out match))
not_implemented_results.Add (new MomaError (new Method (method.ToString ()), match));

if (pinvoke.Matches (i.Operand.ToString (), out match))
pinvoke_results.Add (new MomaError (new Method (method.ToString ()), match));

if (missing.Matches (i.Operand.ToString (), out match))
missing_results.Add (new MomaError (new Method (method.ToString ()), match));
}
}
}
}
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion MoMA.Analyzer/Methods/Method.cs
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ private void ParseMethod (MethodDefinition md)
final_parameters += (ConvertType (p.ParameterType.ToString ()) + ", ");

function_name = md.Name;
return_type = ConvertType (md.ReturnType.ReturnType.FullName);
return_type = ConvertType (md.MethodReturnType.ReturnType.FullName);

if (final_parameters.Length > 0)
final_parameters = final_parameters.Substring (0, final_parameters.Length - 2);
Expand Down
31 changes: 5 additions & 26 deletions MoMA.Analyzer/Methods/MethodExtractor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public class MethodExtractor
// Leave any of the SortedList parameters null that you aren't interested in
public static void ExtractFromAssembly (string assembly, SortedList<string, Method> allMethods, SortedList<string, Method> throwsNotImplementedMethods, SortedList<string, Method> monoTodoMethods)
{
AssemblyDefinition ad = AssemblyFactory.GetAssembly (assembly);
AssemblyDefinition ad = AssemblyDefinition.ReadAssembly(assembly);

//Gets all types of the MainModule of the assembly
foreach (TypeDefinition type in ad.MainModule.Types) {
Expand All @@ -51,9 +51,9 @@ public static void ExtractFromAssembly (string assembly, SortedList<string, Meth
foreach (CustomAttribute ca in property.CustomAttributes) {
if (IsReportableMonoTODO (ca.Constructor.DeclaringType.ToString ())) {
if (property.GetMethod != null && IsMethodVisible (property.GetMethod))
monoTodoMethods[property.GetMethod.ToString ()] = new Method (property.GetMethod.ToString (), ca.ConstructorParameters.Count > 0 ? ca.ConstructorParameters[0].ToString ().Replace ('\n', ' ') : string.Empty);
monoTodoMethods[property.GetMethod.ToString ()] = new Method (property.GetMethod.ToString (), ca.ConstructorArguments.Count > 0 ? ca.ConstructorArguments[0].Value.ToString ().Replace ('\n', ' ') : string.Empty);
if (property.SetMethod != null && IsMethodVisible (property.SetMethod))
monoTodoMethods[property.SetMethod.ToString ()] = new Method (property.SetMethod.ToString (), ca.ConstructorParameters.Count > 0 ? ca.ConstructorParameters[0].ToString ().Replace ('\n', ' ') : string.Empty);
monoTodoMethods[property.SetMethod.ToString ()] = new Method (property.SetMethod.ToString (), ca.ConstructorArguments.Count > 0 ? ca.ConstructorArguments[0].Value.ToString ().Replace ('\n', ' ') : string.Empty);
}
}
}
Expand All @@ -72,28 +72,7 @@ public static void ExtractFromAssembly (string assembly, SortedList<string, Meth
if (monoTodoMethods != null)
foreach (CustomAttribute ca in method.CustomAttributes)
if (IsReportableMonoTODO (ca.Constructor.DeclaringType.ToString ()))
monoTodoMethods[method.ToString ()] = new Method (method.ToString (), ca.ConstructorParameters.Count > 0 ? ca.ConstructorParameters[0].ToString ().Replace ('\n', ' ') : string.Empty);

// If adding methods that throw NotImplementedException, look for those
if (throwsNotImplementedMethods != null && ThrowsNotImplementedException (method))
throwsNotImplementedMethods[method.ToString ()] = new Method (method.ToString ());
}

//Gets all constructors of the current type
foreach (MethodDefinition method in type.Constructors) {
// We only want Public and Protected methods
if (!IsMethodVisible (method))
continue;

// If adding all methods, add this method
if (allMethods != null)
allMethods[method.ToString ()] = new Method (method.ToString ());

// If adding MonoTODO methods, check this method
if (monoTodoMethods != null)
foreach (CustomAttribute ca in method.CustomAttributes)
if (IsReportableMonoTODO (ca.Constructor.DeclaringType.ToString ()))
monoTodoMethods[method.ToString ()] = new Method (method.ToString (), ca.ConstructorParameters.Count > 0 ? ca.ConstructorParameters[0].ToString ().Replace ('\n', ' ') : string.Empty);
monoTodoMethods[method.ToString ()] = new Method (method.ToString (), ca.ConstructorArguments.Count > 0 ? ca.ConstructorArguments[0].Value.ToString ().Replace ('\n', ' ') : string.Empty);

// If adding methods that throw NotImplementedException, look for those
if (throwsNotImplementedMethods != null && ThrowsNotImplementedException (method))
Expand Down Expand Up @@ -135,7 +114,7 @@ private static bool IsTypeVisible (TypeDefinition type)

private static TypeDefinition TypeReferenceToDefinition (TypeReference type)
{
return type.Module.Types[type.FullName];
return type.Module.GetType(type.FullName);
}

// Is this attribute a MonoTODO that we want to report in MoMA?
Expand Down
2 changes: 1 addition & 1 deletion MoMAExtractor/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ class Program
private static bool use_30 = false; // Include the 3.0 framework
private static bool use_35 = false; // Include the 3.5 framework
private static bool use_40 = true; // Include the 4.0 framework
private static bool use_mobile = false;
private static bool use_mobile = true;

private static bool use_design = false; // Include *Design namespaces
private static bool mwf_only = false; // Only do System.Windows.Forms (overrides others)
Expand Down
9 changes: 6 additions & 3 deletions MoMAExtractor/Summary.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,13 @@ class Program2
private static bool use_20 = true;
private static bool use_30 = true;
private static bool use_35 = true;
private static bool use_40 = true;

private static bool use_design = true;
private static bool mwf_only = false;
private static bool use_mobile = false;

private static bool mwf_only = false;

// True: Output the count of methods in each MS assembly
// False: Output MoMA stats for each assembly
private static bool count_only = false;
Expand All @@ -25,8 +28,8 @@ static void Main0 (string[] args)
string output_path = Path.GetDirectoryName (Application.ExecutablePath);

// Get the assemblies we want to examine
List<string> mono_assemblies = AssemblyManager.GetAssemblies (true, use_20, use_30, use_35, use_design, mwf_only);
List<string> ms_assemblies = AssemblyManager.GetAssemblies (false, use_20, use_30, use_35, use_design, mwf_only);
List<string> mono_assemblies = AssemblyManager.GetAssemblies (true, use_20, use_30, use_35,use_40, use_mobile, use_design, mwf_only);
List<string> ms_assemblies = AssemblyManager.GetAssemblies (false, use_20, use_30, use_35,use_40, use_mobile, use_design, mwf_only);

StreamWriter sw = new StreamWriter (Path.Combine (output_path, "summary.txt"));

Expand Down
82 changes: 74 additions & 8 deletions Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
//

using System;
using System.IO;
using System.Windows.Forms;

namespace MoMA
Expand All @@ -47,33 +48,98 @@ static int Main (string[] args)
string nextArg = (i + 1 < args.Length) ? args[i + 1] : null;

switch (arg.ToLower ()) {
case "--help":
case "-help":
ShowHelp ();
return 0;
case "--nogui":
case "-nogui":
nogui = true;
break;
case "--ignore":
case "-ignore":
form.AssembliesToIgnore = nextArg;
i++;
break;
case "--out":
case "-out":
// if !full path, use report dir
form.ReportFileName = nextArg;
if (CheckPath (nextArg)) {
form.ReportFileName = nextArg;
}
else {
Console.WriteLine ("Need path definition for '-out', try '-out .\\" + nextArg + "' to use current directory.");
}
i++;
break;
case "--xml":
case "-xml":
if (CheckPath (nextArg)) {
form.SubmitFileName = nextArg;
}
else {
Console.WriteLine ("Need path definition for '-xml', try '-xml .\\" + nextArg + "' to use current directory.");
}
i++;
break;
default:
if (arg.StartsWith ("-")) {
Console.WriteLine ("Unknown argument: {0}", arg);
return 1;
}

form.AddAssembly (arg);
AddAssemblies (form, arg);
break;
}
}

if (!nogui)
if (!nogui){
Application.Run (form);
else
form.AnalyzeNoGui ();

return 0;
return 0;
}
else{
return form.AnalyzeNoGui ();
}
}

private static void AddAssemblies (MainForm form, string arg)
{
try {
FileAttributes att = File.GetAttributes (arg);
if ((att & FileAttributes.Directory) == FileAttributes.Directory) {
Console.WriteLine ("Searching for assemblies in: " + arg);
form.ScanForAssemblies (arg);
}
else {
form.AddAssembly (arg);
}
}
catch (Exception ex) {
Console.WriteLine (ex.ToString ());
}
}
private static bool CheckPath (string nextArg)
{
string path = Path.GetDirectoryName (nextArg);
return (path != "");
}
private static void ShowHelp ()
{
Console.WriteLine (
"MoMA.exe [options] [inputfiles|inputFilePath]" + Environment.NewLine + Environment.NewLine +
"Options:" + Environment.NewLine + Environment.NewLine +
" --help:" + Environment.NewLine +
" -help: Show this help message." + Environment.NewLine + Environment.NewLine +
" --nogui:" + Environment.NewLine +
" -nogui: Run application without GUI." + Environment.NewLine + Environment.NewLine +
"--ignore:" + Environment.NewLine +
" -ignore: Comma separated list of Assemblies to ignore" + Environment.NewLine + Environment.NewLine +
" --out:" + Environment.NewLine +
" -out: HTML report filename" + Environment.NewLine + Environment.NewLine +
" --xml:" + Environment.NewLine +
" -xml: XML report filename" + Environment.NewLine + Environment.NewLine +
"Sample:" + Environment.NewLine +
"\tMoMA.exe " + @"-nogui -xml ./foobar.xml -out ./boing/out.html C:\MyApplication\bin\Debug -ignore WPF-tainted.dll"
);
}
}
}