public bool CheckILSize (PositiveTestCase test, PositiveChecker checker, string file) { Assembly assembly = Assembly.LoadFile (file); bool success = true; Type[] types = assembly.GetTypes (); foreach (Type t in types) { // Skip interfaces if (!t.IsClass && !t.IsValueType) continue; if (test.VerificationProvider == null) { if (!checker.UpdateVerificationDataFile) checker.LogFileLine (test.FileName, "Missing IL verification data"); test.CreateNewTest (); } foreach (MemberInfo m in t.GetMembers (BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance | BindingFlags.DeclaredOnly)) { MethodBase mi = m as MethodBase; if (mi == null) continue; if ((mi.Attributes & (MethodAttributes.PinvokeImpl)) != 0) continue; success &= CompareIL (mi, test, checker); } } return success; }
bool CompareIL (MethodBase mi, PositiveTestCase test, PositiveChecker checker) { string m_name = mi.ToString (); string decl_type = mi.DeclaringType.ToString (); PositiveTestCase.VerificationData data_provider = test.VerificationProvider; PositiveTestCase.VerificationData.MethodData md = data_provider.FindMethodData (m_name, decl_type); if (md == null) { data_provider.AddNewMethod (mi, GetILSize (mi)); if (!data_provider.IsNewSet) { checker.HandleFailure (test.FileName, PositiveChecker.TestResult.ILError, decl_type + ": " + m_name + " (new method?)"); return false; } return true; } if (md.Checked) { checker.HandleFailure (test.FileName, PositiveChecker.TestResult.ILError, decl_type + ": " + m_name + " has a duplicate"); return false; } md.Checked = true; if (md.MethodAttributes != (int) mi.Attributes) { checker.HandleFailure (test.FileName, PositiveChecker.TestResult.MethodAttributesError, string.Format ("{0} ({1} -> {2})", decl_type + ": " + m_name, md.MethodAttributes, mi.Attributes)); } md.MethodAttributes = (int) mi.Attributes; int il_size = GetILSize (mi); if (md.ILSize == il_size) return true; if (md.ILSize > il_size) { checker.LogFileLine (test.FileName, "{0} (code size reduction {1} -> {2})", decl_type + ": " + m_name, md.ILSize, il_size); md.ILSize = il_size; return true; } checker.HandleFailure (test.FileName, PositiveChecker.TestResult.ILError, string.Format ("{0} (code size {1} -> {2})", decl_type + ": " + m_name, md.ILSize, il_size)); md.ILSize = il_size; return false; }
static int Main(string[] args) { string temp; if (GetOption ("help", args, false, out temp)) { Usage (); return 0; } string compiler; if (!GetOption ("compiler", args, true, out compiler)) { Usage (); return 1; } ITester tester; try { Console.WriteLine ("Loading " + compiler + " ..."); tester = new ReflectionTester (Assembly.LoadFile (compiler)); } catch (Exception) { Console.Error.WriteLine ("Switching to command line mode (compiler entry point was not found)"); if (!File.Exists (compiler)) { Console.Error.WriteLine ("ERROR: Tested compiler was not found"); return 1; } tester = new ProcessTester (compiler); } string mode; if (!GetOption ("mode", args, true, out mode)) { Usage (); return 1; } Checker checker; bool positive; switch (mode) { case "neg": checker = new NegativeChecker (tester, true); positive = false; break; case "pos": string iltest; GetOption ("il", args, false, out iltest); checker = new PositiveChecker (tester, iltest); positive = true; if (iltest != null && GetOption ("update-il", args, false, out temp)) { ((PositiveChecker) checker).UpdateVerificationDataFile = true; } break; case "nunit": positive = true; checker = new NUnitChecker (tester); break; default: Console.Error.WriteLine ("Invalid -mode argument"); return 1; } if (GetOption ("issues", args, true, out temp)) checker.IssueFile = temp; if (GetOption ("log", args, true, out temp)) checker.LogFile = temp; if (GetOption ("verbose", args, false, out temp)) checker.Verbose = true; if (GetOption ("safe-execution", args, false, out temp)) checker.SafeExecution = true; if (GetOption ("compiler-options", args, true, out temp)) { string[] extra = temp.Split (' '); checker.ExtraCompilerOptions = extra; } string test_pattern; if (!GetOption ("files", args, true, out test_pattern)) { Usage (); return 1; } var files = new List<string> (); switch (test_pattern) { case "v1": files.AddRange (Directory.GetFiles (".", positive ? "test*.cs" : "cs*.cs")); break; case "v2": files.AddRange (Directory.GetFiles (".", positive ? "gtest*.cs" : "gcs*.cs")); goto case "v1"; case "v4": files.AddRange (Directory.GetFiles (".", positive ? "dtest*.cs" : "dcs*.cs")); goto case "v2"; default: files.AddRange (Directory.GetFiles (".", test_pattern)); break; } if (files.Count == 0) { Console.Error.WriteLine ("No files matching `{0}' found", test_pattern); return 2; } checker.Initialize (); /* files.Sort ((a, b) => { if (a.EndsWith ("-lib.cs", StringComparison.Ordinal)) { if (!b.EndsWith ("-lib.cs", StringComparison.Ordinal)) return -1; } else if (b.EndsWith ("-lib.cs", StringComparison.Ordinal)) { if (!a.EndsWith ("-lib.cs", StringComparison.Ordinal)) return 1; } return a.CompareTo (b); }); */ foreach (string s in files) { string filename = Path.GetFileName (s); if (Char.IsUpper (filename, 0)) { // Windows hack continue; } if (filename.EndsWith ("-p2.cs")) continue; checker.Do (filename); } checker.CleanUp (); checker.Dispose (); return checker.ResultCode; }