From 76fc9dc3bfb4549813d3f5294597ee42e06aa17e Mon Sep 17 00:00:00 2001 From: Rolf Bjarne Kvinge Date: Thu, 14 May 2020 16:45:05 +0200 Subject: [PATCH] Improve our error handling code. (#8591) * Move much of ErrorHandler.cs into a partial class in ErrorHandler.tools.cs, which is referenced by mtouch and mmp (but not our runtime). * Add ErrorHandler.runtime.cs for runtime-specific bits, including a simpler version of ErrorHandler.Show. In particular this gets rid of the call to Environment.Exit, which should never happen at runtime. * Rename MonoTouchException and MonoMacException to ProductException, which allows us to remove a lot of ifdefs. * This required moving Application.LoadSymbols and Target.LoadSymbols to shared mtouch/mmp code. --- src/ObjCRuntime/DynamicRegistrar.cs | 2 +- src/ObjCRuntime/ErrorHelper.cs | 399 +------------------------ src/ObjCRuntime/ErrorHelper.runtime.cs | 44 +++ src/ObjCRuntime/Registrar.cs | 20 +- src/ObjCRuntime/RuntimeException.cs | 5 - src/frameworks.sources | 1 + tests/mmp-aot-tests/aot.cs | 8 +- tests/mtouch/Compat.cs | 12 + tests/mtouch/ErrorTest.cs | 6 - tests/mtouch/Setup.cs | 14 + tests/mtouch/mtouch.csproj | 8 + tools/common/Application.cs | 17 +- tools/common/Assembly.cs | 7 - tools/common/CoreResolver.cs | 6 - tools/common/Driver.cs | 15 +- tools/common/ErrorHelper.tools.cs | 348 +++++++++++++++++++++ tools/common/StaticRegistrar.cs | 8 +- tools/common/Target.cs | 9 + tools/common/Tuning.cs | 12 +- tools/common/error.cs | 53 +--- tools/linker/ScanTypeReferenceStep.cs | 6 - tools/mmp/Assembly.mmp.cs | 2 +- tools/mmp/Tuning.mmp.cs | 6 +- tools/mmp/aot.cs | 10 +- tools/mmp/driver.cs | 44 +-- tools/mmp/mmp.csproj | 3 + tools/mtouch/Application.mtouch.cs | 34 +-- tools/mtouch/Assembly.mtouch.cs | 8 +- tools/mtouch/BuildTasks.mtouch.cs | 6 +- tools/mtouch/Stripper.cs | 8 +- tools/mtouch/Target.mtouch.cs | 22 +- tools/mtouch/Tuning.mtouch.cs | 6 +- tools/mtouch/mtouch.cs | 40 +-- tools/mtouch/mtouch.csproj | 3 + 34 files changed, 575 insertions(+), 617 deletions(-) create mode 100644 src/ObjCRuntime/ErrorHelper.runtime.cs create mode 100644 tests/mtouch/Compat.cs create mode 100644 tests/mtouch/Setup.cs create mode 100644 tools/common/ErrorHelper.tools.cs diff --git a/src/ObjCRuntime/DynamicRegistrar.cs b/src/ObjCRuntime/DynamicRegistrar.cs index 4776138857..d469d16550 100644 --- a/src/ObjCRuntime/DynamicRegistrar.cs +++ b/src/ObjCRuntime/DynamicRegistrar.cs @@ -733,7 +733,7 @@ namespace Registrar { #else const string msg = "Detected a protocol ({0}) inheriting from the JSExport protocol while using the dynamic registrar. It is not possible to export protocols to JavaScriptCore dynamically; the static registrar must be used (add '--registrar:static' to the additional mtouch arguments in the project's iOS Build options to select the static registrar)."; #endif - ErrorHelper.Warning (4147, msg, GetTypeFullName (type.Type)); + ErrorHelper.Show (ErrorHelper.CreateWarning (4147, msg, GetTypeFullName (type.Type))); } Protocol.protocol_addProtocol (protocol, proto.Handle); } diff --git a/src/ObjCRuntime/ErrorHelper.cs b/src/ObjCRuntime/ErrorHelper.cs index 2b73157abf..c9b385b52d 100644 --- a/src/ObjCRuntime/ErrorHelper.cs +++ b/src/ObjCRuntime/ErrorHelper.cs @@ -1,279 +1,33 @@ // Copyright 2014, Xamarin Inc. All rights reserved, +#if MTOUCH || MMP || MMP_TEST || MTOUCH_TESTS +#define BUNDLER +#endif + using System; using System.Collections.Generic; -#if MONOTOUCH -#if MTOUCH -using ProductException=Xamarin.Bundler.MonoTouchException; -#else -#if XAMCORE_2_0 +#if !BUNDLER using ProductException=ObjCRuntime.RuntimeException; -#else -using ProductException=MonoTouch.RuntimeException; -#endif -#endif -#elif MONOMAC -#if MMP -using ProductException=Xamarin.Bundler.MonoMacException; -#else -#if XAMCORE_2_0 -using ProductException=ObjCRuntime.RuntimeException; -#else -using ProductException=MonoMac.RuntimeException; -#endif -#endif -#else -#error Only supports XI or XM #endif -#if !MTOUCH && !MMP -#if XAMCORE_2_0 -using ObjCRuntime; -#endif -#else -using System.Linq; -using Mono.Cecil.Cil; -#endif - -#if MMP || MMP_TEST || MTOUCH || MTOUCH_TESTS +#if BUNDLER namespace Xamarin.Bundler { #else namespace ObjCRuntime { #endif - static class ErrorHelper { - public enum WarningLevel - { - Error = -1, - Warning = 0, - Disable = 1, - } -#if MONOTOUCH - const string Prefix = "MT"; -#else - const string Prefix = "MM"; -#endif - static Dictionary warning_levels; - public static int Verbosity { get; set; } - -#if MTOUCH || MMP -#pragma warning disable 649 - public static Func IsExpectedException; - public static Action ExitCallback; -#pragma warning restore 649 -#endif - - public static WarningLevel GetWarningLevel (int code) - { - WarningLevel level; - - if (warning_levels == null) - return WarningLevel.Warning; - - // code -1: all codes - if (warning_levels.TryGetValue (-1, out level)) - return level; - - if (warning_levels.TryGetValue (code, out level)) - return level; - - return WarningLevel.Warning;; - } - - public static void SetWarningLevel (WarningLevel level, int? code = null /* if null, apply to all warnings */) - { - if (warning_levels == null) - warning_levels = new Dictionary (); - if (code.HasValue) { - warning_levels [code.Value] = level; - } else { - warning_levels [-1] = level; // code -1: all codes. - } - } - - public static ProductException CreateError (int code, string message, params object[] args) + static partial class ErrorHelper { + public static ProductException CreateError (int code, string message, params object [] args) { return new ProductException (code, true, message, args); } -#if (MTOUCH || MMP) && !MMP_TEST && !WIN32 - public static void SetLocation (Application app, ProductException ex, Mono.Cecil.MethodDefinition method, Instruction instruction = null) - { - if (!method.HasBody) - return; - - if (instruction == null && method.Body.Instructions.Count == 0) - return; - - if (instruction == null) - instruction = method.Body.Instructions [0]; -#if MTOUCH - app.LoadSymbols (); -#endif - - if (!method.DebugInformation.HasSequencePoints) - return; - - // Find the sequence point with the highest offset that is less than or equal to the instruction's offset - SequencePoint seq = null; - foreach (var pnt in method.DebugInformation.SequencePoints) { - if (pnt.Offset > instruction.Offset) - continue; - - if (seq != null && seq.Offset >= pnt.Offset) - continue; - - seq = pnt; - } - if (seq == null) - return; - - ex.FileName = seq.Document.Url; - ex.LineNumber = seq.StartLine; - } - - public static ProductException CreateError (Application app, int code, Mono.Cecil.MemberReference member, string message, params object[] args) - { - return Create (app, code, true, null, member, null, message, args); - } - - public static ProductException CreateError (Application app, int code, Mono.Cecil.MethodDefinition location, string message, params object[] args) - { - return Create (app, code, true, null, location, null, message, args); - } - - public static ProductException CreateError (Application app, int code, Mono.Cecil.MethodDefinition location, Instruction instruction, string message, params object [] args) - { - return Create (app, code, true, null, location, instruction, message, args); - } - - public static ProductException CreateError (Application app, int code, Mono.Cecil.ICustomAttributeProvider provider, string message, params object [] args) - { - return Create (app, code, true, null, provider, null, message, args); - } - - public static ProductException CreateError (Application app, int code, Exception innerException, Mono.Cecil.MethodDefinition location, string message, params object[] args) - { - return Create (app, code, true, innerException, location, message, args); - } - - public static ProductException CreateError (Application app, int code, Exception innerException, Mono.Cecil.TypeReference location, string message, params object[] args) - { - return Create (app, code, true, innerException, location, message, args); - } - - public static ProductException CreateError (Application app, int code, Exception innerException, Mono.Cecil.ICustomAttributeProvider provider, string message, params object [] args) - { - return Create (app, code, true, innerException, provider, message, args); - } - - public static ProductException CreateWarning (Application app, int code, Mono.Cecil.MemberReference member, string message, params object [] args) - { - return Create (app, code, false, null, member, null, message, args); - } - - public static ProductException CreateWarning (Application app, int code, Mono.Cecil.MemberReference member, Instruction instruction, string message, params object [] args) - { - return Create (app, code, false, null, member, instruction, message, args); - } - - public static ProductException CreateWarning (Application app, int code, Mono.Cecil.MethodDefinition location, string message, params object[] args) - { - return Create (app, code, false, null, location, message, args); - } - - public static ProductException CreateWarning (Application app, int code, Mono.Cecil.ICustomAttributeProvider provider, string message, params object [] args) - { - return Create (app, code, false, null, provider, message, args); - } - - public static ProductException CreateWarning (Application app, int code, Exception innerException, Mono.Cecil.MethodDefinition location, string message, params object[] args) - { - return Create (app, code, false, innerException, location, message, args); - } - - public static ProductException CreateWarning (Application app, int code, Exception innerException, Mono.Cecil.MethodDefinition location, Instruction instruction, string message, params object [] args) - { - return Create (app, code, false, innerException, location, instruction, message, args); - } - - public static ProductException CreateWarning (Application app, int code, Exception innerException, Mono.Cecil.TypeReference location, string message, params object[] args) - { - return Create (app, code, false, innerException, location, message, args); - } - - public static ProductException CreateWarning (Application app, int code, Exception innerException, Mono.Cecil.ICustomAttributeProvider provider, string message, params object [] args) - { - return Create (app, code, false, innerException, provider, message, args); - } - - public static ProductException Create (Application app, int code, bool error, Exception innerException, Mono.Cecil.ICustomAttributeProvider provider, string message, params object [] args) - { - return Create (app, code, error, innerException, provider, null, message, args); - } - - public static ProductException Create (Application app, int code, bool error, Exception innerException, Mono.Cecil.ICustomAttributeProvider provider, Instruction instruction, string message, params object [] args) - { - if (provider is Mono.Cecil.MemberReference member) { - if (instruction != null) - return Create (app, code, error, innerException, member, instruction, message, args); - return Create (app, code, error, innerException, member, null, message, args); - } - - if (provider is Mono.Cecil.TypeReference type) - return Create (app, code, error, innerException, type, message, args); - - return new ProductException (code, error, innerException, message, args); - } - - public static ProductException Create (Application app, int code, bool error, Exception innerException, Mono.Cecil.MemberReference member, Instruction instruction, string message, params object [] args) - { - Mono.Cecil.MethodReference method = member as Mono.Cecil.MethodReference; - if (method == null) { - var property = member as Mono.Cecil.PropertyDefinition; - if (property != null) { - method = property.GetMethod; - if (method == null) - method = property.SetMethod; - } - } - return Create (app, code, error, innerException, method == null ? null : method.Resolve (), instruction, message, args); - } - - public static ProductException Create (Application app, int code, bool error, Exception innerException, Mono.Cecil.MethodDefinition location, Instruction instruction, string message, params object [] args) - { - var e = new ProductException (code, error, innerException, message, args); - if (location != null) - SetLocation (app, e, location, instruction); - return e; - } - - public static ProductException Create (Application app, int code, bool error, Exception innerException, Mono.Cecil.TypeReference location, string message, params object [] args) - { - var e = new ProductException (code, error, innerException, message, args); - if (location != null) { - var td = location.Resolve (); - - if (td.HasMethods) { - foreach (var method in td.Methods) { - if (!method.IsConstructor) - continue; - SetLocation (app, e, method); - if (e.FileName != null) - break; - } - } - } - return e; - } -#endif - - public static ProductException CreateError (int code, Exception innerException, string message, params object[] args) + public static ProductException CreateError (int code, Exception innerException, string message, params object [] args) { return new ProductException (code, true, innerException, message, args); } - public static ProductException CreateWarning (int code, string message, params object[] args) + public static ProductException CreateWarning (int code, string message, params object [] args) { return new ProductException (code, false, message, args); } @@ -283,84 +37,6 @@ namespace ObjCRuntime { return new ProductException (code, false, innerException, message, args); } - public static void Error (int code, Exception innerException, string message, params object[] args) - { - throw new ProductException (code, true, innerException, message, args); - } - - public static void Error (int code, string message, params object[] args) - { - throw new ProductException (code, true, message, args); - } - - public static void Warning (int code, string message, params object[] args) - { - Show (new ProductException (code, false, message, args)); - } - - public static void Warning (int code, Exception innerException, string message, params object[] args) - { - Show (new ProductException (code, false, innerException, message, args)); - } - -#if MMP || MTOUCH - // Shows any warnings, and if there are any errors, throws an AggregateException. - public static void ThrowIfErrors (IList exceptions) - { - if (exceptions?.Any () != true) - return; - - // Separate warnings from errors - var grouped = exceptions.GroupBy ((v) => (v as ProductException)?.Error == false); - - var warnings = grouped.SingleOrDefault ((v) => v.Key); - if (warnings?.Any () == true) - Show (warnings); - - var errors = grouped.SingleOrDefault ((v) => !v.Key); - if (errors?.Any () == true) - throw new AggregateException (errors); - } -#endif - - public static void Show (IEnumerable list) - { - List exceptions = new List (); - bool error = false; - - foreach (var e in list) - CollectExceptions (e, exceptions); - - foreach (var ex in exceptions) - error |= ShowInternal (ex); - - if (error) - Exit (1); - } - - static public void Show (Exception e) - { - List exceptions = new List (); - bool error = false; - - CollectExceptions (e, exceptions); - - foreach (var ex in exceptions) - error |= ShowInternal (ex); - - if (error) - Exit (1); - } - - static void Exit (int exitCode) - { -#if MTOUCH - if (ExitCallback != null) - ExitCallback (exitCode); -#endif - Environment.Exit (exitCode); - } - static void CollectExceptions (Exception ex, List exceptions) { AggregateException ae = ex as AggregateException; @@ -372,60 +48,5 @@ namespace ObjCRuntime { exceptions.Add (ex); } } - - static bool ShowInternal (Exception e) - { - ProductException mte = (e as ProductException); - bool error = true; - - if (mte != null) { - error = mte.Error; - - if (!error && GetWarningLevel (mte.Code) == WarningLevel.Disable) - return false; // This is an ignored warning. - - Console.Error.WriteLine (mte.ToString ()); - - // Errors with code >= 9000 are activation/licensing errors. - // PROTIP: do not show a stack trace that points the exact method where the license checks are done - if (mte.Code > 8999) - return error; - - if (Verbosity > 1) - ShowInner (e); - - if (Verbosity > 2 && !string.IsNullOrEmpty (e.StackTrace)) - Console.Error.WriteLine (e.StackTrace); -#if MTOUCH || MMP - } else if (IsExpectedException == null || !IsExpectedException (e)) { - Console.Error.WriteLine ("error " + Prefix + "0000: Unexpected error - Please file a bug report at https://github.com/xamarin/xamarin-macios/issues/new"); - Console.Error.WriteLine (e.ToString ()); -#endif - } else { - Console.Error.WriteLine (e.ToString ()); - if (Verbosity > 1) - ShowInner (e); - if (Verbosity > 2 && !string.IsNullOrEmpty (e.StackTrace)) - Console.Error.WriteLine (e.StackTrace); - } - - return error; - } - - static void ShowInner (Exception e) - { - Exception ie = e.InnerException; - if (ie == null) - return; - - if (Verbosity > 3) { - Console.Error.WriteLine ("--- inner exception"); - Console.Error.WriteLine (ie); - Console.Error.WriteLine ("---"); - } else { - Console.Error.WriteLine ("\t{0}", ie.Message); - } - ShowInner (ie); - } } } diff --git a/src/ObjCRuntime/ErrorHelper.runtime.cs b/src/ObjCRuntime/ErrorHelper.runtime.cs new file mode 100644 index 0000000000..9628a08a48 --- /dev/null +++ b/src/ObjCRuntime/ErrorHelper.runtime.cs @@ -0,0 +1,44 @@ +// Copyright 2020, Microsoft Corp. All rights reserved, + +using System; +using System.Collections.Generic; + +using ProductException = ObjCRuntime.RuntimeException; + +namespace ObjCRuntime { + static partial class ErrorHelper { + public static void Show (Exception e) + { + var list = new List (); + var errors = new List (); + + // Unwrap AggregateExceptions. + CollectExceptions (e, list); + + foreach (var ex in list) { + var pe = ex as ProductException; + + // Show the exception + Console.Error.WriteLine (ex); + + // Add to list of errors if it's an error + if (pe?.Error == false) { + // This is a warning, we don't need to do anything + } else { + errors.Add (ex); + } + } + + // No actual errors, we're done + if (errors.Count == 0) + return; + + // Errors were found, we need to throw + if (errors.Count == 1) + throw errors [0]; + + // Use an AggregateException for multiple errors. + throw new AggregateException (errors); + } + } +} diff --git a/src/ObjCRuntime/Registrar.cs b/src/ObjCRuntime/Registrar.cs index 4cf43da482..1ba877a35e 100644 --- a/src/ObjCRuntime/Registrar.cs +++ b/src/ObjCRuntime/Registrar.cs @@ -41,26 +41,8 @@ using TField=System.Reflection.FieldInfo; using R=ObjCRuntime.Runtime; #endif -#if MONOTOUCH -#if MTOUCH -using ProductException=Xamarin.Bundler.MonoTouchException; -#else -#if XAMCORE_2_0 +#if !(MTOUCH || MMP) using ProductException=ObjCRuntime.RuntimeException; -#else -using ProductException=MonoTouch.RuntimeException; -#endif -#endif -#elif MONOMAC -#if MMP -using ProductException=Xamarin.Bundler.MonoMacException; -#elif XAMCORE_2_0 -using ProductException=ObjCRuntime.RuntimeException; -#else -using ProductException=MonoMac.RuntimeException; -#endif -#else -#error Only XI and XM #endif // diff --git a/src/ObjCRuntime/RuntimeException.cs b/src/ObjCRuntime/RuntimeException.cs index 783f53ace0..35c14427be 100644 --- a/src/ObjCRuntime/RuntimeException.cs +++ b/src/ObjCRuntime/RuntimeException.cs @@ -3,10 +3,7 @@ using System; using System.Collections.Generic; -#if XAMCORE_2_0 namespace ObjCRuntime { -#endif - public class RuntimeException : Exception { public RuntimeException (string message, params object[] args) : base (string.Format (message, args)) @@ -43,6 +40,4 @@ namespace ObjCRuntime { } */ } -#if XAMCORE_2_0 } -#endif diff --git a/src/frameworks.sources b/src/frameworks.sources index 2fea7dff23..3387d1f370 100644 --- a/src/frameworks.sources +++ b/src/frameworks.sources @@ -1773,6 +1773,7 @@ SHARED_SOURCES = \ ObjCRuntime/Dlfcn.cs \ ObjCRuntime/DynamicRegistrar.cs \ ObjCRuntime/ErrorHelper.cs \ + ObjCRuntime/ErrorHelper.runtime.cs \ ObjCRuntime/Exceptions.cs \ ObjCRuntime/ExceptionMode.cs \ ObjCRuntime/Method.cs \ diff --git a/tests/mmp-aot-tests/aot.cs b/tests/mmp-aot-tests/aot.cs index 0c3b434ea5..eb5f5e63d0 100644 --- a/tests/mmp-aot-tests/aot.cs +++ b/tests/mmp-aot-tests/aot.cs @@ -164,18 +164,18 @@ namespace Xamarin.MMP.Tests.Unit try { action (); } - catch (MonoMacException e) { + catch (ProductException e) { Assert.AreEqual (e.Code, code, $"Got code {e.Code} but expected {code}"); return; } catch (AggregateException e) { Assert.AreEqual (e.InnerExceptions.Count, 1, "Got AggregateException but more than one exception"); - MonoMacException innerException = e.InnerExceptions[0] as MonoMacException; - Assert.IsNotNull (innerException, "Got AggregateException but inner not MonoMacException"); + ProductException innerException = e.InnerExceptions[0] as ProductException; + Assert.IsNotNull (innerException, "Got AggregateException but inner not ProductException"); Assert.AreEqual (innerException.Code, code, $"Got code {innerException.Code} but expected {code}"); return; } - Assert.Fail ($"We should have thrown MonoMacException with code: {code}"); + Assert.Fail ($"We should have thrown ProductException with code: {code}"); } readonly string [] FullAppFileList = { diff --git a/tests/mtouch/Compat.cs b/tests/mtouch/Compat.cs new file mode 100644 index 0000000000..1be6d747db --- /dev/null +++ b/tests/mtouch/Compat.cs @@ -0,0 +1,12 @@ +using System; + +namespace Xamarin.Bundler { + // Compat class to make ErrorHelper.tools.cs compile without ugly ifdefs. + public class Application { + public void LoadSymbols () + { + + } + } +} + diff --git a/tests/mtouch/ErrorTest.cs b/tests/mtouch/ErrorTest.cs index d48fd4cfea..b65c2749e0 100644 --- a/tests/mtouch/ErrorTest.cs +++ b/tests/mtouch/ErrorTest.cs @@ -4,12 +4,6 @@ using NUnit.Framework; using Xamarin.Bundler; -#if MONOTOUCH -using ProductException = Xamarin.Bundler.MonoTouchException; -#else -using ProductException = Xamarin.Bundler.MonoMacException; -#endif - namespace Xamarin.Test.Bundler { [TestFixture] diff --git a/tests/mtouch/Setup.cs b/tests/mtouch/Setup.cs new file mode 100644 index 0000000000..88d5526309 --- /dev/null +++ b/tests/mtouch/Setup.cs @@ -0,0 +1,14 @@ +using NUnit.Framework; + +using Xamarin.Bundler; +using Xamarin.Utils; + +[SetUpFixture] +public class AssemblyInitialization { + [OneTimeSetUp] + public void Setup () + { + ErrorHelper.Platform = ApplePlatform.iOS; + } +} + diff --git a/tests/mtouch/mtouch.csproj b/tests/mtouch/mtouch.csproj index 8b996d4886..69d8d567f2 100644 --- a/tests/mtouch/mtouch.csproj +++ b/tests/mtouch/mtouch.csproj @@ -89,6 +89,9 @@ ErrorHelper.cs + + tools\common\ErrorHelper.tools.cs + SdkVersions.cs @@ -100,6 +103,11 @@ error.cs + + tools\common\ApplePlatform.cs + + + diff --git a/tools/common/Application.cs b/tools/common/Application.cs index c5888b7e04..012a4b0b23 100644 --- a/tools/common/Application.cs +++ b/tools/common/Application.cs @@ -13,10 +13,8 @@ using Xamarin.Utils; using ObjCRuntime; #if MONOTOUCH -using PlatformException = Xamarin.Bundler.MonoTouchException; using PlatformResolver = MonoTouch.Tuner.MonoTouchResolver; #else -using PlatformException = Xamarin.Bundler.MonoMacException; using PlatformResolver = Xamarin.Bundler.MonoMacResolver; #endif @@ -244,7 +242,7 @@ namespace Xamarin.Bundler { string max_s = null; if (sources.Count () == 0 || targets.Count () == 0) - ErrorHelper.Error (1013, Errors.MT1013); + throw ErrorHelper.CreateError (1013, Errors.MT1013); foreach (var s in sources) { var sfi = new FileInfo (s); @@ -342,9 +340,9 @@ namespace Xamarin.Bundler { if (DeploymentTarget != null) { if (DeploymentTarget < Xamarin.SdkVersions.GetMinVersion (Platform)) - throw new PlatformException (73, true, Errors.MT0073, Constants.Version, DeploymentTarget, Xamarin.SdkVersions.GetMinVersion (Platform), PlatformName, ProductName); + throw new ProductException (73, true, Errors.MT0073, Constants.Version, DeploymentTarget, Xamarin.SdkVersions.GetMinVersion (Platform), PlatformName, ProductName); if (DeploymentTarget > Xamarin.SdkVersions.GetVersion (Platform)) - throw new PlatformException (74, true, Errors.MX0074, Constants.Version, DeploymentTarget, Xamarin.SdkVersions.GetVersion (Platform), PlatformName, ProductName); + throw new ProductException (74, true, Errors.MX0074, Constants.Version, DeploymentTarget, Xamarin.SdkVersions.GetVersion (Platform), PlatformName, ProductName); } if (Platform == ApplePlatform.WatchOS && EnableCoopGC.HasValue && !EnableCoopGC.Value) @@ -463,7 +461,7 @@ namespace Xamarin.Bundler { { // The static registrar. if (Registrar != RegistrarMode.Static) - throw new PlatformException (67, Errors.MT0067, Registrar); // this is only called during our own build + throw new ProductException (67, Errors.MT0067, Registrar); // this is only called during our own build if (RootAssemblies.Count < 1) throw ErrorHelper.CreateError (130, Errors.MX0130); @@ -767,5 +765,12 @@ namespace Xamarin.Bundler { } } + // This is to load the symbols for all assemblies, so that we can give better error messages + // (with file name / line number information). + public void LoadSymbols () + { + foreach (var t in Targets) + t.LoadSymbols (); + } } } diff --git a/tools/common/Assembly.cs b/tools/common/Assembly.cs index 7cff102b96..83b23be4f4 100644 --- a/tools/common/Assembly.cs +++ b/tools/common/Assembly.cs @@ -11,13 +11,6 @@ using ObjCRuntime; using Xamarin; using Xamarin.Utils; -#if MONOTOUCH -using PlatformException = Xamarin.Bundler.MonoTouchException; -#else -using PlatformException = Xamarin.Bundler.MonoMacException; -#endif - - namespace Xamarin.Bundler { struct NativeReferenceMetadata diff --git a/tools/common/CoreResolver.cs b/tools/common/CoreResolver.cs index 970b9b5807..443924c818 100644 --- a/tools/common/CoreResolver.cs +++ b/tools/common/CoreResolver.cs @@ -6,12 +6,6 @@ using System.IO; using Mono.Cecil; using Mono.Cecil.Cil; -#if MTOUCH -using ProductException=Xamarin.Bundler.MonoTouchException; -#else -using ProductException=Xamarin.Bundler.MonoMacException; -#endif - namespace Xamarin.Bundler { public abstract class CoreResolver : IAssemblyResolver { diff --git a/tools/common/Driver.cs b/tools/common/Driver.cs index e9c2d16db0..909a9fe4b4 100644 --- a/tools/common/Driver.cs +++ b/tools/common/Driver.cs @@ -19,17 +19,16 @@ using Xamarin.MacDev; using Xamarin.Utils; using ObjCRuntime; -#if MTOUCH -using ProductException = Xamarin.Bundler.MonoTouchException; -#else -using ProductException=Xamarin.Bundler.MonoMacException; -#endif - namespace Xamarin.Bundler { public partial class Driver { public static int Main (string [] args) { try { +#if MMP + ErrorHelper.Platform = ApplePlatform.MacOSX; +#else + ErrorHelper.Platform = ApplePlatform.iOS; +#endif Console.OutputEncoding = new UTF8Encoding (false, false); SetCurrentLanguage (); return Main2 (args); @@ -68,7 +67,7 @@ namespace Xamarin.Bundler { ErrorHelper.SetWarningLevel (ErrorHelper.WarningLevel.Error); } } catch (Exception ex) { - ErrorHelper.Error (26, ex, Errors.MX0026, "--warnaserror", ex.Message); + throw ErrorHelper.CreateError (26, ex, Errors.MX0026, "--warnaserror", ex.Message); } }); options.Add ("nowarn:", "An optional comma-separated list of warning codes to ignore (if no warnings are specified all warnings are ignored).", v => @@ -81,7 +80,7 @@ namespace Xamarin.Bundler { ErrorHelper.SetWarningLevel (ErrorHelper.WarningLevel.Disable); } } catch (Exception ex) { - ErrorHelper.Error (26, ex, Errors.MX0026, "--nowarn", ex.Message); + throw ErrorHelper.CreateError (26, ex, Errors.MX0026, "--nowarn", ex.Message); } }); options.Add ("coop:", "If the GC should run in cooperative mode.", v => { app.EnableCoopGC = ParseBool (v, "coop"); }, hidden: true); diff --git a/tools/common/ErrorHelper.tools.cs b/tools/common/ErrorHelper.tools.cs new file mode 100644 index 0000000000..68be0fc88e --- /dev/null +++ b/tools/common/ErrorHelper.tools.cs @@ -0,0 +1,348 @@ +// Copyright 2020, Microsoft Corp. All rights reserved, + +using System; +using System.Collections.Generic; +using System.Linq; + +using Mono.Cecil; +using Mono.Cecil.Cil; + +using Xamarin.Utils; + +namespace Xamarin.Bundler { + static partial class ErrorHelper { + public static ApplePlatform Platform; + + internal static string Prefix { + get { + switch (Platform) { + case ApplePlatform.iOS: + case ApplePlatform.TVOS: + case ApplePlatform.WatchOS: + return "MT"; + case ApplePlatform.MacOSX: + return "MM"; + case ApplePlatform.None: + throw new InvalidOperationException ($"ErrorHelper.Platform has not been set."); + default: + // Do not use the ErrorHandler machinery, because it will probably end up recursing and eventually throwing a StackOverflowException. + throw new InvalidOperationException ($"Unknown platform: {Platform}"); + } + } + } + + public enum WarningLevel { + Error = -1, + Warning = 0, + Disable = 1, + } + + static Dictionary warning_levels; + public static int Verbosity { get; set; } + +#pragma warning disable 649 + public static Func IsExpectedException; + public static Action ExitCallback; +#pragma warning restore 649 + + public static WarningLevel GetWarningLevel (int code) + { + WarningLevel level; + + if (warning_levels == null) + return WarningLevel.Warning; + + // code -1: all codes + if (warning_levels.TryGetValue (-1, out level)) + return level; + + if (warning_levels.TryGetValue (code, out level)) + return level; + + return WarningLevel.Warning; + } + + public static void SetWarningLevel (WarningLevel level, int? code = null /* if null, apply to all warnings */) + { + if (warning_levels == null) + warning_levels = new Dictionary (); + if (code.HasValue) { + warning_levels [code.Value] = level; + } else { + warning_levels [-1] = level; // code -1: all codes. + } + } + + public static void SetLocation (Application app, ProductException ex, MethodDefinition method, Instruction instruction = null) + { + if (!method.HasBody) + return; + + if (instruction == null && method.Body.Instructions.Count == 0) + return; + + if (instruction == null) + instruction = method.Body.Instructions [0]; + + app.LoadSymbols (); + + if (!method.DebugInformation.HasSequencePoints) + return; + + // Find the sequence point with the highest offset that is less than or equal to the instruction's offset + SequencePoint seq = null; + foreach (var pnt in method.DebugInformation.SequencePoints) { + if (pnt.Offset > instruction.Offset) + continue; + + if (seq != null && seq.Offset >= pnt.Offset) + continue; + + seq = pnt; + } + if (seq == null) + return; + + ex.FileName = seq.Document.Url; + ex.LineNumber = seq.StartLine; + } + + public static ProductException CreateError (Application app, int code, MemberReference member, string message, params object [] args) + { + return Create (app, code, true, null, member, null, message, args); + } + + public static ProductException CreateError (Application app, int code, MethodDefinition location, string message, params object [] args) + { + return Create (app, code, true, null, location, null, message, args); + } + + public static ProductException CreateError (Application app, int code, MethodDefinition location, Instruction instruction, string message, params object [] args) + { + return Create (app, code, true, null, location, instruction, message, args); + } + + public static ProductException CreateError (Application app, int code, ICustomAttributeProvider provider, string message, params object [] args) + { + return Create (app, code, true, null, provider, null, message, args); + } + + public static ProductException CreateError (Application app, int code, Exception innerException, MethodDefinition location, string message, params object [] args) + { + return Create (app, code, true, innerException, location, message, args); + } + + public static ProductException CreateError (Application app, int code, Exception innerException, TypeReference location, string message, params object [] args) + { + return Create (app, code, true, innerException, location, message, args); + } + + public static ProductException CreateError (Application app, int code, Exception innerException, ICustomAttributeProvider provider, string message, params object [] args) + { + return Create (app, code, true, innerException, provider, message, args); + } + + public static ProductException CreateWarning (Application app, int code, MemberReference member, string message, params object [] args) + { + return Create (app, code, false, null, member, null, message, args); + } + + public static ProductException CreateWarning (Application app, int code, MemberReference member, Instruction instruction, string message, params object [] args) + { + return Create (app, code, false, null, member, instruction, message, args); + } + + public static ProductException CreateWarning (Application app, int code, MethodDefinition location, string message, params object [] args) + { + return Create (app, code, false, null, location, message, args); + } + + public static ProductException CreateWarning (Application app, int code, ICustomAttributeProvider provider, string message, params object [] args) + { + return Create (app, code, false, null, provider, message, args); + } + + public static ProductException CreateWarning (Application app, int code, Exception innerException, MethodDefinition location, string message, params object [] args) + { + return Create (app, code, false, innerException, location, message, args); + } + + public static ProductException CreateWarning (Application app, int code, Exception innerException, MethodDefinition location, Instruction instruction, string message, params object [] args) + { + return Create (app, code, false, innerException, location, instruction, message, args); + } + + public static ProductException CreateWarning (Application app, int code, Exception innerException, TypeReference location, string message, params object [] args) + { + return Create (app, code, false, innerException, location, message, args); + } + + public static ProductException CreateWarning (Application app, int code, Exception innerException, ICustomAttributeProvider provider, string message, params object [] args) + { + return Create (app, code, false, innerException, provider, message, args); + } + + public static ProductException Create (Application app, int code, bool error, Exception innerException, ICustomAttributeProvider provider, string message, params object [] args) + { + return Create (app, code, error, innerException, provider, null, message, args); + } + + public static ProductException Create (Application app, int code, bool error, Exception innerException, ICustomAttributeProvider provider, Instruction instruction, string message, params object [] args) + { + if (provider is MemberReference member) { + if (instruction != null) + return Create (app, code, error, innerException, member, instruction, message, args); + return Create (app, code, error, innerException, member, null, message, args); + } + + if (provider is TypeReference type) + return Create (app, code, error, innerException, type, message, args); + + return new ProductException (code, error, innerException, message, args); + } + + public static ProductException Create (Application app, int code, bool error, Exception innerException, MemberReference member, Instruction instruction, string message, params object [] args) + { + var method = member as MethodReference; + if (method == null) { + var property = member as PropertyDefinition; + if (property != null) { + method = property.GetMethod; + if (method == null) + method = property.SetMethod; + } + } + return Create (app, code, error, innerException, method == null ? null : method.Resolve (), instruction, message, args); + } + + public static ProductException Create (Application app, int code, bool error, Exception innerException, MethodDefinition location, Instruction instruction, string message, params object [] args) + { + var e = new ProductException (code, error, innerException, message, args); + if (location != null) + SetLocation (app, e, location, instruction); + return e; + } + + public static ProductException Create (Application app, int code, bool error, Exception innerException, TypeReference location, string message, params object [] args) + { + var e = new ProductException (code, error, innerException, message, args); + if (location != null) { + var td = location.Resolve (); + + if (td.HasMethods) { + foreach (var method in td.Methods) { + if (!method.IsConstructor) + continue; + SetLocation (app, e, method); + if (e.FileName != null) + break; + } + } + } + return e; + } + + public static void Warning (int code, string message, params object [] args) + { + Show (new ProductException (code, false, message, args)); + } + + public static void Warning (int code, Exception innerException, string message, params object [] args) + { + Show (new ProductException (code, false, innerException, message, args)); + } + + // Shows any warnings, and if there are any errors, throws an AggregateException. + public static void ThrowIfErrors (IList exceptions) + { + if (exceptions?.Any () != true) + return; + + // Separate warnings from errors + var grouped = exceptions.GroupBy ((v) => (v as ProductException)?.Error == false); + + var warnings = grouped.SingleOrDefault ((v) => v.Key); + if (warnings?.Any () == true) + Show (warnings); + + var errors = grouped.SingleOrDefault ((v) => !v.Key); + if (errors?.Any () == true) + throw new AggregateException (errors); + } + + public static void Show (IEnumerable list) + { + List exceptions = new List (); + bool error = false; + + foreach (var e in list) + CollectExceptions (e, exceptions); + + foreach (var ex in exceptions) + error |= ShowInternal (ex); + + if (error) + Exit (1); + } + + public static void Show (Exception e) + { + Show (new Exception [] { e }); + } + + static void Exit (int exitCode) + { + if (ExitCallback != null) + ExitCallback (exitCode); + Environment.Exit (exitCode); + } + + static bool ShowInternal (Exception e) + { + ProductException mte = (e as ProductException); + bool error = true; + + if (mte != null) { + error = mte.Error; + + if (!error && GetWarningLevel (mte.Code) == WarningLevel.Disable) + return false; // This is an ignored warning. + + Console.Error.WriteLine (mte.ToString ()); + + if (Verbosity > 1) + ShowInner (e); + + if (Verbosity > 2 && !string.IsNullOrEmpty (e.StackTrace)) + Console.Error.WriteLine (e.StackTrace); + } else if (IsExpectedException == null || !IsExpectedException (e)) { + Console.Error.WriteLine ("error " + Prefix + "0000: Unexpected error - Please file a bug report at https://github.com/xamarin/xamarin-macios/issues/new"); + Console.Error.WriteLine (e.ToString ()); + } else { + Console.Error.WriteLine (e.ToString ()); + if (Verbosity > 1) + ShowInner (e); + if (Verbosity > 2 && !string.IsNullOrEmpty (e.StackTrace)) + Console.Error.WriteLine (e.StackTrace); + } + + return error; + } + + static void ShowInner (Exception e) + { + Exception ie = e.InnerException; + if (ie == null) + return; + + if (Verbosity > 3) { + Console.Error.WriteLine ("--- inner exception"); + Console.Error.WriteLine (ie); + Console.Error.WriteLine ("---"); + } else { + Console.Error.WriteLine ("\t{0}", ie.Message); + } + ShowInner (ie); + } + } +} diff --git a/tools/common/StaticRegistrar.cs b/tools/common/StaticRegistrar.cs index 57b1dbc874..86b657eef0 100644 --- a/tools/common/StaticRegistrar.cs +++ b/tools/common/StaticRegistrar.cs @@ -16,12 +16,6 @@ using System.Text; using Xamarin.Bundler; using Xamarin.Linker; -#if MTOUCH -using ProductException=Xamarin.Bundler.MonoTouchException; -#else -using ProductException=Xamarin.Bundler.MonoMacException; -#endif - using Registrar; using Foundation; using ObjCRuntime; @@ -2177,7 +2171,7 @@ namespace Registrar { case "Accounts": var compiler = Path.GetFileName (App.CompilerPath); if (compiler == "gcc" || compiler == "g++") { - exceptions.Add (new MonoTouchException (4121, true, "Cannot use GCC/G++ to compile the generated code from the static registrar when using the Accounts framework (the header files provided by Apple used during the compilation require Clang). Either use Clang (--compiler:clang) or the dynamic registrar (--registrar:dynamic).")); + exceptions.Add (new ProductException (4121, true, "Cannot use GCC/G++ to compile the generated code from the static registrar when using the Accounts framework (the header files provided by Apple used during the compilation require Clang). Either use Clang (--compiler:clang) or the dynamic registrar (--registrar:dynamic).")); return; } goto default; diff --git a/tools/common/Target.cs b/tools/common/Target.cs index a4248bb205..e21b27c203 100644 --- a/tools/common/Target.cs +++ b/tools/common/Target.cs @@ -450,5 +450,14 @@ namespace Xamarin.Bundler { return reference_m; #endif } + + // This is to load the symbols for all assemblies, so that we can give better error messages + // (with file name / line number information). + public void LoadSymbols () + { + foreach (var a in Assemblies) + a.LoadSymbols (); + } + } } diff --git a/tools/common/Tuning.cs b/tools/common/Tuning.cs index ddf91105bc..73878e1f45 100644 --- a/tools/common/Tuning.cs +++ b/tools/common/Tuning.cs @@ -11,10 +11,8 @@ using Mono.Cecil.Cil; using Xamarin.Bundler; #if MONOTOUCH -using PlatformException = Xamarin.Bundler.MonoTouchException; using PlatformLinkContext = MonoTouch.Tuner.MonoTouchLinkContext; #else -using PlatformException = Xamarin.Bundler.MonoMacException; using PlatformLinkContext = MonoMac.Tuner.MonoMacLinkContext; #endif @@ -48,10 +46,10 @@ namespace MonoMac.Tuner { { switch (e) { case AssemblyResolutionException are: - return new PlatformException (2002, true, are, are.Message); + return new ProductException (2002, true, are, are.Message); case AggregateException ae: return ae; - case PlatformException pe: + case ProductException pe: return pe; case MarkException me: { @@ -72,10 +70,10 @@ namespace MonoMac.Tuner { { TypeReference tr = (re.Member as TypeReference); IMetadataScope scope = tr == null ? re.Member.DeclaringType.Scope : tr.Scope; - return new PlatformException (2002, true, re, "Failed to resolve \"{0}\" reference from \"{1}\"", re.Member, scope); + return new ProductException (2002, true, re, "Failed to resolve \"{0}\" reference from \"{1}\"", re.Member, scope); } case XmlResolutionException ex: - return new PlatformException (2017, true, ex, Errors.MX2017, ex?.InnerException?.Message ?? ex.Message); + return new ProductException (2017, true, ex, Errors.MX2017, ex?.InnerException?.Message ?? ex.Message); default: if (e.InnerException != null) return HandlePipelineProcessException (e.InnerException); @@ -94,7 +92,7 @@ namespace MonoMac.Tuner { message.AppendLine ($"\tAssembly: `{a}`"); } message.Append ($"Reason: {e.Message}"); - return new PlatformException (2001, true, e, Errors.MX2001, message); + return new ProductException (2001, true, e, Errors.MX2001, message); } } } diff --git a/tools/common/error.cs b/tools/common/error.cs index d3b7de72ec..07e161c9dc 100644 --- a/tools/common/error.cs +++ b/tools/common/error.cs @@ -6,77 +6,40 @@ using System.Text; namespace Xamarin.Bundler { -#if MTOUCH || MONOTOUCH - public class MonoTouchException : Exception { - public const string Prefix = "MT"; + public class ProductException : Exception { + public static string Prefix => ErrorHelper.Prefix; - public MonoTouchException (int code, string message) : + public ProductException (int code, string message) : this (code, false, message) { } - public MonoTouchException (int code, string message, params object[] args) : + public ProductException (int code, string message, params object[] args) : this (code, false, message, args) { } - public MonoTouchException (int code, bool error, string message) : + public ProductException (int code, bool error, string message) : this (code, error, null, message) { } - public MonoTouchException (int code, bool error, string message, params object[] args) : + public ProductException (int code, bool error, string message, params object[] args) : this (code, error, null, message, args) { } - public MonoTouchException (int code, bool error, Exception innerException, string message) : + public ProductException (int code, bool error, Exception innerException, string message) : base (message, innerException) { SetValues (code, error); } - public MonoTouchException (int code, bool error, Exception innerException, string message, params object[] args) : + public ProductException (int code, bool error, Exception innerException, string message, params object[] args) : base (Format (message, args), innerException) { SetValues (code, error); } -#else - public class MonoMacException : Exception { - public const string Prefix = "MM"; - - public MonoMacException (int code, string message) : - this (code, false, message) - { - } - - public MonoMacException (int code, string message, params object[] args) : - this (code, false, message, args) - { - } - - public MonoMacException (int code, bool error, string message) : - this (code, error, null, message) - { - } - - public MonoMacException (int code, bool error, string message, params object[] args) : - this (code, error, null, message, args) - { - } - - public MonoMacException (int code, bool error, Exception innerException, string message) : - base (message, innerException) - { - SetValues (code, error); - } - - public MonoMacException (int code, bool error, Exception innerException, string message, params object[] args) : - base (Format (message, args), innerException) - { - SetValues (code, error); - } -#endif public string FileName { get; set; } diff --git a/tools/linker/ScanTypeReferenceStep.cs b/tools/linker/ScanTypeReferenceStep.cs index ea249435b4..073f476f60 100644 --- a/tools/linker/ScanTypeReferenceStep.cs +++ b/tools/linker/ScanTypeReferenceStep.cs @@ -4,12 +4,6 @@ using Mono.Cecil; using Mono.Linker.Steps; using Xamarin.Bundler; -#if MTOUCH -using ProductException = Xamarin.Bundler.MonoTouchException; -#else -using ProductException = Xamarin.Bundler.MonoMacException; -#endif - namespace Xamarin.Linker.Steps { abstract public class ScanTypeReferenceStep : BaseStep { diff --git a/tools/mmp/Assembly.mmp.cs b/tools/mmp/Assembly.mmp.cs index 3c3454c08b..944663ce0c 100644 --- a/tools/mmp/Assembly.mmp.cs +++ b/tools/mmp/Assembly.mmp.cs @@ -16,7 +16,7 @@ namespace Xamarin.Bundler { Application.CopyFile (source, target); } } catch (Exception e) { - throw new MonoMacException (1009, true, e, Errors.MX1009, source, target, e.Message); + throw new ProductException (1009, true, e, Errors.MX1009, source, target, e.Message); } return copied; diff --git a/tools/mmp/Tuning.mmp.cs b/tools/mmp/Tuning.mmp.cs index 5abe86b20c..e0bb28cb12 100644 --- a/tools/mmp/Tuning.mmp.cs +++ b/tools/mmp/Tuning.mmp.cs @@ -206,7 +206,7 @@ namespace MonoMac.Tuner { filename = Path.GetFullPath (filename); if (!File.Exists (filename)) - throw new MonoMacException (2004, true, Errors.MX2004, filename); + throw new ProductException (2004, true, Errors.MX2004, filename); try { using (StreamReader sr = new StreamReader (filename)) { @@ -214,7 +214,7 @@ namespace MonoMac.Tuner { } } catch (Exception e) { - throw new MonoMacException (2005, true, e, Errors.MX2005, filename); + throw new ProductException (2005, true, e, Errors.MX2005, filename); } } } @@ -257,7 +257,7 @@ namespace MonoMac.Tuner { base.ProcessAssembly (assembly); } catch (Exception e) { - throw new MonoMacException (2103, true, e, Errors.MX2103, assembly.FullName, e); + throw new ProductException (2103, true, e, Errors.MX2103, assembly.FullName, e); } } } diff --git a/tools/mmp/aot.cs b/tools/mmp/aot.cs index dab544fe9c..905ebbc6d9 100644 --- a/tools/mmp/aot.cs +++ b/tools/mmp/aot.cs @@ -103,7 +103,7 @@ namespace Xamarin.Bundler { if (option.Contains ("|")) { string [] optionTypeParts = option.Split ('|'); if (optionTypeParts.Length != 2) - throw new MonoMacException (20, true, Errors.MX0020, "--aot", "{none, all, core, sdk}{|hybrid}, then an optional explicit list of assemblies."); + throw new ProductException (20, true, Errors.MX0020, "--aot", "{none, all, core, sdk}{|hybrid}, then an optional explicit list of assemblies."); switch (optionTypeParts [0]) { case "none": case "core": @@ -113,14 +113,14 @@ namespace Xamarin.Bundler { switch (optionTypeParts [1]) { case "hybrid": if (option != "all") - throw new MonoMacException (114, true, Errors.MM0114); + throw new ProductException (114, true, Errors.MM0114); kind = AOTKind.Hybrid; break; case "standard": kind = AOTKind.Standard; break; default: - throw new MonoMacException (20, true, Errors.MX0020, "--aot", "{none, all, core, sdk}{|hybrid}, then an optional explicit list of assemblies."); + throw new ProductException (20, true, Errors.MX0020, "--aot", "{none, all, core, sdk}{|hybrid}, then an optional explicit list of assemblies."); } break; } @@ -164,10 +164,10 @@ namespace Xamarin.Bundler { ExcludedAssemblies.Add (option.Substring (1)); continue; } - throw new MonoMacException (20, true, Errors.MX0020, "--aot", "{none, all, core, sdk}{|hybrid}, then an optional explicit list of assemblies."); + throw new ProductException (20, true, Errors.MX0020, "--aot", "{none, all, core, sdk}{|hybrid}, then an optional explicit list of assemblies."); } if (CompilationType == AOTCompilationType.Default) - throw new MonoMacException (20, true, Errors.MX0020, "--aot", "{none, all, core, sdk}{|hybrid}, then an optional explicit list of assemblies."); + throw new ProductException (20, true, Errors.MX0020, "--aot", "{none, all, core, sdk}{|hybrid}, then an optional explicit list of assemblies."); } } diff --git a/tools/mmp/driver.cs b/tools/mmp/driver.cs index bf98bddb21..19f254bd23 100644 --- a/tools/mmp/driver.cs +++ b/tools/mmp/driver.cs @@ -188,13 +188,13 @@ namespace Xamarin.Bundler { true // do not show this option anymore }, { "nolink", "Do not link the assemblies", v => App.LinkMode = LinkMode.None }, - { "mapinject", "Inject a fast method map [deprecated]", v => { ErrorHelper.Show (new MonoMacException (16, false, Errors.MX0016, "--mapinject")); } }, + { "mapinject", "Inject a fast method map [deprecated]", v => { ErrorHelper.Show (new ProductException (16, false, Errors.MX0016, "--mapinject")); } }, { "minos=", "Minimum supported version of Mac OS X", v => { try { App.DeploymentTarget = StringUtils.ParseVersion (v); } catch (Exception ex) { - ErrorHelper.Error (26, ex, Errors.MX0026, $"minos:{v}", ex.Message); + throw ErrorHelper.CreateError (26, ex, Errors.MX0026, $"minos:{v}", ex.Message); } } }, @@ -230,7 +230,7 @@ namespace Xamarin.Bundler { App.Registrar = RegistrarMode.Default; break; default: - throw new MonoMacException (20, true, Errors.MX0020, "--registrar", "dynamic, static, partial, or default"); + throw new ProductException (20, true, Errors.MX0020, "--registrar", "dynamic, static, partial, or default"); } } }, @@ -239,7 +239,7 @@ namespace Xamarin.Bundler { try { App.SdkVersion = StringUtils.ParseVersion (v); } catch (Exception ex) { - ErrorHelper.Error (26, ex, Errors.MX0026, $"sdk:{v}", ex.Message); + throw ErrorHelper.CreateError (26, ex, Errors.MX0026, $"sdk:{v}", ex.Message); } } }, @@ -329,7 +329,7 @@ namespace Xamarin.Bundler { } if (App.Registrar == RegistrarMode.PartialStatic && App.LinkMode != LinkMode.None) - throw new MonoMacException (2110, true, Errors.MM2110); + throw new ProductException (2110, true, Errors.MM2110); // sanity check as this should never happen: we start out by not setting any // Unified/Classic properties, and only IsUnifiedMobile if we are are on the @@ -353,7 +353,7 @@ namespace Xamarin.Bundler { case LinkMode.Platform: break; default: - throw new MonoMacException (2007, true, Errors.MM2007); + throw new ProductException (2007, true, Errors.MM2007); } } @@ -525,13 +525,13 @@ namespace Xamarin.Bundler { CheckForUnknownCommandLineArguments (exceptions, unprocessed); - exceptions.Add (new MonoMacException (50, true, Errors.MM0050, unprocessed.Count, string.Join ("', '", unprocessed.ToArray ()))); + exceptions.Add (new ProductException (50, true, Errors.MM0050, unprocessed.Count, string.Join ("', '", unprocessed.ToArray ()))); throw new AggregateException (exceptions); } if (string.IsNullOrEmpty (output_dir)) - throw new MonoMacException (51, true, Errors.MM0051); + throw new ProductException (51, true, Errors.MM0051); if (string.IsNullOrEmpty (app_name)) app_name = Path.GetFileNameWithoutExtension (output_dir); @@ -552,14 +552,14 @@ namespace Xamarin.Bundler { root_assembly = unprocessed [0]; if (!File.Exists (root_assembly)) - throw new MonoMacException (7, true, Errors.MX0007, root_assembly); + throw new ProductException (7, true, Errors.MX0007, root_assembly); string root_wo_ext = Path.GetFileNameWithoutExtension (root_assembly); if (Profile.IsSdkAssembly (root_wo_ext) || Profile.IsProductAssembly (root_wo_ext)) - throw new MonoMacException (3, true, Errors.MX0003, root_wo_ext); + throw new ProductException (3, true, Errors.MX0003, root_wo_ext); if (App.References.Exists (a => Path.GetFileNameWithoutExtension (a).Equals (root_wo_ext))) - throw new MonoMacException (23, true, Errors.MM0023, root_wo_ext); + throw new ProductException (23, true, Errors.MM0023, root_wo_ext); string monoFrameworkDirectory; @@ -572,7 +572,7 @@ namespace Xamarin.Bundler { fx_dir = Path.Combine (MonoDirectory, "lib", "mono", monoFrameworkDirectory); if (!Directory.Exists (fx_dir)) - throw new MonoMacException (1403, true, Errors.MM1403, "Directory", fx_dir, TargetFramework); + throw new ProductException (1403, true, Errors.MM1403, "Directory", fx_dir, TargetFramework); App.References.Add (root_assembly); BuildTarget.Resolver.CommandLineAssemblies = App.References; @@ -613,7 +613,7 @@ namespace Xamarin.Bundler { CheckReferences (); if (!is_extension && !resolved_assemblies.Exists (f => Path.GetExtension (f).ToLower () == ".exe") && !App.Embeddinator) - throw new MonoMacException (79, true, Errors.MM0079, ""); + throw new ProductException (79, true, Errors.MM0079, ""); // i18n must be dealed outside linking too (e.g. bug 11448) if (App.LinkMode == LinkMode.None) @@ -951,7 +951,7 @@ namespace Xamarin.Bundler { var libxammac = Path.Combine (GetXamarinLibraryDirectory (App), libmain + (App.EnableDebug ? "-debug" : "") + ".a"); if (!File.Exists (libxammac)) - throw new MonoMacException (5203, true, Errors.MM5203, libxammac); + throw new ProductException (5203, true, Errors.MM5203, libxammac); try { var args = new List (); @@ -1082,7 +1082,7 @@ namespace Xamarin.Bundler { string libmono = Path.Combine (libdir, "libmonosgen-2.0.a"); if (!File.Exists (libmono)) - throw new MonoMacException (5202, true, Errors.MM5202); + throw new ProductException (5202, true, Errors.MM5202); args.Add (libmono); @@ -1148,7 +1148,7 @@ namespace Xamarin.Bundler { RunClang (args); } catch (Win32Exception e) { - throw new MonoMacException (5103, true, e, Errors.MM5103, "driver"); + throw new ProductException (5103, true, e, Errors.MM5103, "driver"); } } @@ -1195,10 +1195,10 @@ namespace Xamarin.Bundler { } if (!haveValidReference) - exceptions.Add (new MonoMacException (1401, true, Errors.MM1401)); + exceptions.Add (new ProductException (1401, true, Errors.MM1401)); foreach (var refName in incompatibleReferences) - exceptions.Add (new MonoMacException (1402, true, Errors.MM1402, refName + ".dll")); + exceptions.Add (new ProductException (1402, true, Errors.MM1402, refName + ".dll")); if (exceptions.Count > 0) throw new AggregateException (exceptions); @@ -1435,7 +1435,7 @@ namespace Xamarin.Bundler { // If we can't find it at this point, scream if (src == null) { - ErrorHelper.Show (new MonoMacException (2006, false, Errors.MM2006, name)); + ErrorHelper.Show (new ProductException (2006, false, Errors.MM2006, name)); if (used_by_methods != null && used_by_methods.Count > 0) { const int referencedByLimit = 25; bool limitReferencedByWarnings = used_by_methods.Count > referencedByLimit && Verbosity < 4; @@ -1577,7 +1577,7 @@ namespace Xamarin.Bundler { string machine_config = Path.Combine (MonoDirectory, "etc", "mono", "4.5", "machine.config"); if (!File.Exists (machine_config)) - throw new MonoMacException (1403, true, Errors.MM1403, "File", machine_config, TargetFramework); + throw new ProductException (1403, true, Errors.MM1403, "File", machine_config, TargetFramework); File.Copy (machine_config, Path.Combine (mmp_dir, "machine.config"), true); } @@ -1595,7 +1595,7 @@ namespace Xamarin.Bundler { } else { if (!File.Exists (machine_config_path)) - throw new MonoMacException (97, true, Errors.MM0097, machine_config_path); + throw new ProductException (97, true, Errors.MM0097, machine_config_path); File.Copy (machine_config_path, machineConfigDestFile); } } @@ -1753,7 +1753,7 @@ namespace Xamarin.Bundler { case Abi.x86_64: return Path.Combine (Driver.FrameworkLibDirectory, arch, flavor, name + ".dll"); default: - throw new MonoMacException (5205, true, Errors.MM5205, arch); + throw new ProductException (5205, true, Errors.MM5205, arch); } } } diff --git a/tools/mmp/mmp.csproj b/tools/mmp/mmp.csproj index f90063d73c..96ba9684f8 100644 --- a/tools/mmp/mmp.csproj +++ b/tools/mmp/mmp.csproj @@ -446,6 +446,9 @@ tools\linker\ScanTypeReferenceStep.cs + + tools\common\ErrorHelper.tools.cs + diff --git a/tools/mtouch/Application.mtouch.cs b/tools/mtouch/Application.mtouch.cs index 07c11a8465..7e80048434 100644 --- a/tools/mtouch/Application.mtouch.cs +++ b/tools/mtouch/Application.mtouch.cs @@ -597,14 +597,6 @@ namespace Xamarin.Bundler { return plist.GetString (key); } - // This is to load the symbols for all assemblies, so that we can give better error messages - // (with file name / line number information). - public void LoadSymbols () - { - foreach (var t in Targets) - t.LoadSymbols (); - } - public void BuildAll () { var allapps = new List (); @@ -1020,7 +1012,7 @@ namespace Xamarin.Bundler { foreach (var root in RootAssemblies) { string root_wo_ext = Path.GetFileNameWithoutExtension (root); if (Profile.IsSdkAssembly (root_wo_ext) || Profile.IsProductAssembly (root_wo_ext)) - throw new MonoTouchException (3, true, Errors.MX0003, root_wo_ext); + throw new ProductException (3, true, Errors.MX0003, root_wo_ext); } if (IsDualBuild) { @@ -1088,13 +1080,13 @@ namespace Xamarin.Bundler { ExecutableName, Path.GetFileName (AppDirectory)); if (IsExtension && Platform == ApplePlatform.iOS && SdkVersion < new Version (8, 0)) - throw new MonoTouchException (45, true, Errors.MT0045); + throw new ProductException (45, true, Errors.MT0045); if (IsExtension && Platform != ApplePlatform.iOS && Platform != ApplePlatform.WatchOS && Platform != ApplePlatform.TVOS) - throw new MonoTouchException (72, true, Errors.MT0072, Platform); + throw new ProductException (72, true, Errors.MT0072, Platform); if (!IsExtension && Platform == ApplePlatform.WatchOS) - throw new MonoTouchException (77, true, Errors.MT0077); + throw new ProductException (77, true, Errors.MT0077); #if ENABLE_BITCODE_ON_IOS if (Platform == ApplePlatform.iOS) @@ -1332,7 +1324,7 @@ namespace Xamarin.Bundler { { var path = Path.Combine (directory, "NOTICE"); if (Directory.Exists (path)) - throw new MonoTouchException (1016, true, Errors.MT1016); + throw new ProductException (1016, true, Errors.MT1016); try { // write license information inside the .app @@ -1342,7 +1334,7 @@ namespace Xamarin.Bundler { sb.AppendLine ().AppendLine ().Append ("http://xamarin.com/mobile-licensing").AppendLine (); Driver.WriteIfDifferent (path, sb.ToString ()); } catch (Exception ex) { - throw new MonoTouchException (1017, true, ex, Errors.MT1017, ex.Message); + throw new ProductException (1017, true, ex, Errors.MT1017, ex.Message); } } @@ -1698,16 +1690,16 @@ namespace Xamarin.Bundler { var symbol = line.Replace (", referenced from:", "").Trim ('\"', ' '); if (symbol.StartsWith ("_OBJC_CLASS_$_", StringComparison.Ordinal)) { - errors.Add (new MonoTouchException (5211, error, Errors.MT5211, symbol.Replace ("_OBJC_CLASS_$_", ""), symbol)); + errors.Add (new ProductException (5211, error, Errors.MT5211, symbol.Replace ("_OBJC_CLASS_$_", ""), symbol)); } else { var members = target.GetAllSymbols ().Find (symbol.Substring (1))?.Members; if (members != null && members.Any ()) { var member = members.First (); // Just report the first one. // Neither P/Invokes nor fields have IL, so we can't find the source code location. - errors.Add (new MonoTouchException (5214, error, Errors.MT5214, + errors.Add (new ProductException (5214, error, Errors.MT5214, symbol, member.DeclaringType.FullName, member.Name)); } else { - errors.Add (new MonoTouchException (5210, error, Errors.MT5210, symbol)); + errors.Add (new ProductException (5210, error, Errors.MT5210, symbol)); } } @@ -1723,7 +1715,7 @@ namespace Xamarin.Bundler { } } else if (line.StartsWith ("duplicate symbol", StringComparison.Ordinal) && line.EndsWith (" in:", StringComparison.Ordinal)) { var symbol = line.Replace ("duplicate symbol ", "").Replace (" in:", "").Trim (); - errors.Add (new MonoTouchException (5212, error, Errors.MT5212, symbol)); + errors.Add (new ProductException (5212, error, Errors.MT5212, symbol)); var indent = GetIndentation (line); while (i + 1 < lines.Count) { @@ -1731,7 +1723,7 @@ namespace Xamarin.Bundler { if (GetIndentation (lines [i + 1]) <= indent) break; i++; - errors.Add (new MonoTouchException (5213, error, Errors.MT5213, line.Trim ())); + errors.Add (new ProductException (5213, error, Errors.MT5213, line.Trim ())); } } else { if (line.StartsWith ("ld: ", StringComparison.Ordinal)) @@ -1740,9 +1732,9 @@ namespace Xamarin.Bundler { line = line.Trim (); if (error) { - errors.Add (new MonoTouchException (5209, error, Errors.MT5209, line)); + errors.Add (new ProductException (5209, error, Errors.MT5209, line)); } else { - errors.Add (new MonoTouchException (5203, error, Errors.MT5203, line)); + errors.Add (new ProductException (5203, error, Errors.MT5203, line)); } } } diff --git a/tools/mtouch/Assembly.mtouch.cs b/tools/mtouch/Assembly.mtouch.cs index 0a724b7ee2..1145727b30 100644 --- a/tools/mtouch/Assembly.mtouch.cs +++ b/tools/mtouch/Assembly.mtouch.cs @@ -90,7 +90,7 @@ namespace Xamarin.Bundler { } if (!found) { - warnings.Add (new MonoTouchException (3005, false, Errors.MT3005, ar.FullName, AssemblyDefinition.FullName)); + warnings.Add (new ProductException (3005, false, Errors.MT3005, ar.FullName, AssemblyDefinition.FullName)); has_dependency_map = false; } } @@ -137,7 +137,7 @@ namespace Xamarin.Bundler { CopyConfigToDirectory (Path.GetDirectoryName (target)); } catch (Exception e) { - throw new MonoTouchException (1009, true, e, Errors.MX1009, source, target, e.Message); + throw new ProductException (1009, true, e, Errors.MX1009, source, target, e.Message); } return copied; @@ -253,7 +253,7 @@ namespace Xamarin.Bundler { Directory.CreateDirectory (asm_dir); if (!File.Exists (assembly_path)) - throw new MonoTouchException (3004, true, Errors.MT3004, assembly_path); + throw new ProductException (3004, true, Errors.MT3004, assembly_path); var aotInfo = new AotInfo (); AotInfos.Add (abi, aotInfo); @@ -353,7 +353,7 @@ namespace Xamarin.Bundler { Driver.Log (3, "Loaded '{0}'", FullPath); } catch (Exception e) { // cecil might not be able to load the assembly, e.g. bug #758 - throw new MonoTouchException (1010, true, e, Errors.MT1010, FullPath, e.Message); + throw new ProductException (1010, true, e, Errors.MT1010, FullPath, e.Message); } } } diff --git a/tools/mtouch/BuildTasks.mtouch.cs b/tools/mtouch/BuildTasks.mtouch.cs index c5823622ec..44bf06d6bb 100644 --- a/tools/mtouch/BuildTasks.mtouch.cs +++ b/tools/mtouch/BuildTasks.mtouch.cs @@ -324,14 +324,14 @@ namespace Xamarin.Bundler foreach (var mr in assembly.UnresolvedModuleReferences) { // TODO: add more diagnose information on the warnings var name = Path.GetFileNameWithoutExtension (mr.Name); - linker_errors.Add (new MonoTouchException (5215, false, Errors.MT5215, name)); + linker_errors.Add (new ProductException (5215, false, Errors.MT5215, name)); } } // mtouch does not validate extra parameters given to GCC when linking (--gcc_flags) if (Target.App.UserGccFlags?.Count > 0) - linker_errors.Add (new MonoTouchException (5201, true, Errors.MT5201, StringUtils.FormatArguments (Target.App.UserGccFlags))); + linker_errors.Add (new ProductException (5201, true, Errors.MT5201, StringUtils.FormatArguments (Target.App.UserGccFlags))); else - linker_errors.Add (new MonoTouchException (5202, true, Errors.MT5202)); + linker_errors.Add (new ProductException (5202, true, Errors.MT5202)); if (code == 255) { // check command length diff --git a/tools/mtouch/Stripper.cs b/tools/mtouch/Stripper.cs index 13264b0243..27e2f436dc 100644 --- a/tools/mtouch/Stripper.cs +++ b/tools/mtouch/Stripper.cs @@ -25,14 +25,14 @@ namespace MonoTouch.Tuner { string tool = "/Library/Frameworks/Mono.framework/Versions/Current/lib/mono/4.5/mono-cil-strip.exe"; if (Driver.RunCommand ("/Library/Frameworks/Mono.framework/Versions/Current/bin/mono", tool, assembly_file, output_file) != 0) - throw new MonoTouchException (6002, true, "Could not strip assembly `{0}`.", assembly_file); + throw new ProductException (6002, true, "Could not strip assembly `{0}`.", assembly_file); } catch (NotSupportedException e) { - throw new MonoTouchException (6001, true, e.Message); + throw new ProductException (6001, true, e.Message); } catch (UnauthorizedAccessException e) { // access denied, e.g. non-writable (by SCM) assembly - see assistly #10923 - throw new MonoTouchException (6003, true, e.Message); + throw new ProductException (6003, true, e.Message); } catch (Exception e) { - throw new MonoTouchException (6002, true, e, "Could not strip assembly `{0}`.", assembly_file); + throw new ProductException (6002, true, e, "Could not strip assembly `{0}`.", assembly_file); } } } diff --git a/tools/mtouch/Target.mtouch.cs b/tools/mtouch/Target.mtouch.cs index 3d79728cc6..0c136746e2 100644 --- a/tools/mtouch/Target.mtouch.cs +++ b/tools/mtouch/Target.mtouch.cs @@ -240,7 +240,7 @@ namespace Xamarin.Bundler var corlib_path = Path.Combine (Resolver.FrameworkDirectory, "mscorlib.dll"); var corlib = ManifestResolver.Load (corlib_path); if (corlib == null) - throw new MonoTouchException (2006, true, Errors.MT2006, corlib_path); + throw new ProductException (2006, true, Errors.MT2006, corlib_path); var roots = new List (); foreach (var root_assembly in App.RootAssemblies) { @@ -255,7 +255,7 @@ namespace Xamarin.Bundler foreach (var reference in App.References) { var ad = ManifestResolver.Load (reference); if (ad == null) - throw new MonoTouchException (2002, true, Errors.MT2002, reference); + throw new ProductException (2002, true, Errors.MT2002, reference); var root_assembly = roots.FirstOrDefault ((v) => v.MainModule.FileName == ad.MainModule.FileName); if (root_assembly != null) { @@ -264,7 +264,7 @@ namespace Xamarin.Bundler } if (ad.MainModule.Runtime > TargetRuntime.Net_4_0) - ErrorHelper.Show (new MonoTouchException (11, false, Errors.MT0011, Path.GetFileName (reference), ad.MainModule.Runtime)); + ErrorHelper.Show (new ProductException (11, false, Errors.MT0011, Path.GetFileName (reference), ad.MainModule.Runtime)); // Figure out if we're referencing Xamarin.iOS or monotouch.dll var filename = ad.MainModule.FileName; @@ -319,14 +319,6 @@ namespace Xamarin.Bundler } } - // This is to load the symbols for all assemblies, so that we can give better error messages - // (with file name / line number information). - public void LoadSymbols () - { - foreach (var a in Assemblies) - a.LoadSymbols (); - } - IEnumerable GetAssemblies () { if (App.LinkMode == LinkMode.None) @@ -380,10 +372,10 @@ namespace Xamarin.Bundler var assembly = ManifestResolver.Load (root); ComputeListOfAssemblies (assemblies, assembly, exceptions); } - } catch (MonoTouchException mte) { + } catch (ProductException mte) { exceptions.Add (mte); } catch (Exception e) { - exceptions.Add (new MonoTouchException (9, true, e, Errors.MX0009, e.Message)); + exceptions.Add (new ProductException (9, true, e, Errors.MX0009, e.Message)); } if (App.LinkMode == LinkMode.None) @@ -1723,10 +1715,10 @@ namespace Xamarin.Bundler throw new ArgumentException ($"{targetExecutable} is a directory."); File.Copy (launcher.ToString (), targetExecutable); File.SetLastWriteTime (targetExecutable, DateTime.Now); - } catch (MonoTouchException) { + } catch (ProductException) { throw; } catch (Exception ex) { - throw new MonoTouchException (1015, true, ex, Errors.MT1015, targetExecutable, ex.Message); + throw new ProductException (1015, true, ex, Errors.MT1015, targetExecutable, ex.Message); } Symlinked = true; diff --git a/tools/mtouch/Tuning.mtouch.cs b/tools/mtouch/Tuning.mtouch.cs index 18593d35e1..b88c890767 100644 --- a/tools/mtouch/Tuning.mtouch.cs +++ b/tools/mtouch/Tuning.mtouch.cs @@ -224,7 +224,7 @@ namespace MonoTouch.Tuner { filename = Path.GetFullPath (filename); if (!File.Exists (filename)) - throw new MonoTouchException (2004, true, Errors.MX2004, filename); + throw new ProductException (2004, true, Errors.MX2004, filename); try { using (StreamReader sr = new StreamReader (filename)) { @@ -232,7 +232,7 @@ namespace MonoTouch.Tuner { } } catch (Exception e) { - throw new MonoTouchException (2005, true, e, Errors.MX2005, filename); + throw new ProductException (2005, true, e, Errors.MX2005, filename); } } } @@ -273,7 +273,7 @@ namespace MonoTouch.Tuner { base.ProcessAssembly (assembly); } catch (Exception e) { - throw new MonoTouchException (2103, true, e, Errors.MX2103, assembly.FullName, e); + throw new ProductException (2103, true, e, Errors.MX2103, assembly.FullName, e); } } } diff --git a/tools/mtouch/mtouch.cs b/tools/mtouch/mtouch.cs index ed15cfe5db..8487f32496 100644 --- a/tools/mtouch/mtouch.cs +++ b/tools/mtouch/mtouch.cs @@ -536,10 +536,10 @@ namespace Xamarin.Bundler } } WriteIfDifferent (main_source, sb.ToString (), true); - } catch (MonoTouchException) { + } catch (ProductException) { throw; } catch (Exception e) { - throw new MonoTouchException (4001, true, e, Errors.MT4001, main_source); + throw new ProductException (4001, true, e, Errors.MT4001, main_source); } return main_source; @@ -735,7 +735,7 @@ namespace Xamarin.Bundler } goto default; default: - throw new MonoTouchException (19, true, Errors.MT0019); + throw new ProductException (19, true, Errors.MT0019); } }; @@ -815,7 +815,7 @@ namespace Xamarin.Bundler try { app.SdkVersion = StringUtils.ParseVersion (v); } catch (Exception ex) { - ErrorHelper.Error (26, ex, Errors.MX0026, "sdk:" + v, ex.Message); + throw ErrorHelper.CreateError (26, ex, Errors.MX0026, "sdk:" + v, ex.Message); } } }, @@ -824,7 +824,7 @@ namespace Xamarin.Bundler try { app.DeploymentTarget = StringUtils.ParseVersion (v); } catch (Exception ex) { - throw new MonoTouchException (26, true, ex, Errors.MX0026, "targetver:" + v, ex.Message); + throw new ProductException (26, true, ex, Errors.MX0026, "targetver:" + v, ex.Message); } } }, @@ -920,7 +920,7 @@ namespace Xamarin.Bundler app.Registrar = RegistrarMode.Default; break; default: - throw new MonoTouchException (20, true, Errors.MX0020, "--registrar", "static, dynamic or default"); + throw new ProductException (20, true, Errors.MX0020, "--registrar", "static, dynamic or default"); } switch (value) { @@ -932,7 +932,7 @@ namespace Xamarin.Bundler app.RegistrarOptions = RegistrarOptions.Default; break; default: - throw new MonoTouchException (20, true, Errors.MX0020, "--registrar", "static, dynamic or default"); + throw new ProductException (20, true, Errors.MX0020, "--registrar", "static, dynamic or default"); } } }, @@ -963,7 +963,7 @@ namespace Xamarin.Bundler app.PackageMonoFramework = false; break; default: - throw new MonoTouchException (20, true, Errors.MX0020, "--mono", "static, framework or [no-]package-framework"); + throw new ProductException (20, true, Errors.MX0020, "--mono", "static, framework or [no-]package-framework"); } } } @@ -981,7 +981,7 @@ namespace Xamarin.Bundler app.BitCodeMode = BitCodeMode.MarkerOnly; break; default: - throw new MonoTouchException (20, true, Errors.MX0020, "--bitcode", "asmonly, full or marker"); + throw new ProductException (20, true, Errors.MX0020, "--bitcode", "asmonly, full or marker"); } } }, @@ -1035,7 +1035,7 @@ namespace Xamarin.Bundler if (action == Action.Build || action == Action.RunRegistrar) { if (app.RootAssemblies.Count == 0) - throw new MonoTouchException (17, true, Errors.MX0017); + throw new ProductException (17, true, Errors.MX0017); } return app; @@ -1077,22 +1077,22 @@ namespace Xamarin.Bundler } if (app.SdkVersion == null) - throw new MonoTouchException (25, true, Errors.MT0025, app.PlatformName); + throw new ProductException (25, true, Errors.MT0025, app.PlatformName); var framework_dir = GetFrameworkDirectory (app); Driver.Log ("Xamarin.iOS {0}.{1} using framework: {2}", Constants.Version, Constants.Revision, framework_dir); if (action == Action.None) - throw new MonoTouchException (52, true, Errors.MT0052); + throw new ProductException (52, true, Errors.MT0052); if (app.SdkVersion < new Version (6, 0) && app.IsArchEnabled (Abi.ARMv7s)) - throw new MonoTouchException (14, true, Errors.MT0014, app.SdkVersion, "ARMv7s"); + throw new ProductException (14, true, Errors.MT0014, app.SdkVersion, "ARMv7s"); if (app.SdkVersion < new Version (7, 0) && app.IsArchEnabled (Abi.ARM64)) - throw new MonoTouchException (14, true, Errors.MT0014, app.SdkVersion, "ARM64"); + throw new ProductException (14, true, Errors.MT0014, app.SdkVersion, "ARM64"); if (app.SdkVersion < new Version (7, 0) && app.IsArchEnabled (Abi.x86_64)) - throw new MonoTouchException (14, true, Errors.MT0014, app.SdkVersion, "x86_64"); + throw new ProductException (14, true, Errors.MT0014, app.SdkVersion, "x86_64"); if (!Directory.Exists (framework_dir)) { Console.WriteLine ("Framework does not exist {0}", framework_dir); @@ -1102,16 +1102,16 @@ namespace Xamarin.Bundler } if (!Directory.Exists (GetPlatformDirectory (app))) - throw new MonoTouchException (6, true, Errors.MT0006, GetPlatformDirectory (app)); + throw new ProductException (6, true, Errors.MT0006, GetPlatformDirectory (app)); if (!Directory.Exists (app.AppDirectory)) Directory.CreateDirectory (app.AppDirectory); if (app.EnableRepl && app.BuildTarget != BuildTarget.Simulator) - throw new MonoTouchException (29, true, Errors.MT0029); + throw new ProductException (29, true, Errors.MT0029); if (app.EnableRepl && app.LinkMode != LinkMode.None) - throw new MonoTouchException (82, true, Errors.MT0082); + throw new ProductException (82, true, Errors.MT0082); if (cross_prefix == null) cross_prefix = FrameworkDirectory; @@ -1269,9 +1269,9 @@ namespace Xamarin.Bundler goto tryagain; } if (string.IsNullOrEmpty (original_compiler)) { - throw new MonoTouchException (5101, true, Errors.MT5101, app.Compiler); + throw new ProductException (5101, true, Errors.MT5101, app.Compiler); } else { - throw new MonoTouchException (5103, true, Errors.MT5103, app.Compiler, original_compiler); + throw new ProductException (5103, true, Errors.MT5103, app.Compiler, original_compiler); } } } diff --git a/tools/mtouch/mtouch.csproj b/tools/mtouch/mtouch.csproj index 05aac1337e..a04cd1c232 100644 --- a/tools/mtouch/mtouch.csproj +++ b/tools/mtouch/mtouch.csproj @@ -463,6 +463,9 @@ tools\linker\MonoTouch.Tuner\RemoveCodeBase.cs + + tools\common\ErrorHelper.tools.cs +