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.
This commit is contained in:
Rolf Bjarne Kvinge 2020-05-14 16:45:05 +02:00 коммит произвёл GitHub
Родитель 7ea03b8dd8
Коммит 76fc9dc3bf
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
34 изменённых файлов: 575 добавлений и 617 удалений

Просмотреть файл

@ -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);
}

Просмотреть файл

@ -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<int, WarningLevel> warning_levels;
public static int Verbosity { get; set; }
#if MTOUCH || MMP
#pragma warning disable 649
public static Func<Exception, bool> IsExpectedException;
public static Action<int> 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<int, WarningLevel> ();
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<Exception> 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<Exception> list)
{
List<Exception> exceptions = new List<Exception> ();
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<Exception> exceptions = new List<Exception> ();
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<Exception> 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);
}
}
}

Просмотреть файл

@ -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<Exception> ();
var errors = new List<Exception> ();
// 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);
}
}
}

Просмотреть файл

@ -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
//

Просмотреть файл

@ -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

Просмотреть файл

@ -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 \

Просмотреть файл

@ -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 = {

12
tests/mtouch/Compat.cs Normal file
Просмотреть файл

@ -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 ()
{
}
}
}

Просмотреть файл

@ -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]

14
tests/mtouch/Setup.cs Normal file
Просмотреть файл

@ -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;
}
}

Просмотреть файл

@ -89,6 +89,9 @@
<Compile Include="..\..\src\ObjCRuntime\ErrorHelper.cs">
<Link>ErrorHelper.cs</Link>
</Compile>
<Compile Include="..\..\tools\common\ErrorHelper.tools.cs">
<Link>tools\common\ErrorHelper.tools.cs</Link>
</Compile>
<Compile Include="RuntimeException.cs" />
<Compile Include="..\..\tools\common\SdkVersions.cs">
<Link>SdkVersions.cs</Link>
@ -100,6 +103,11 @@
<Link>error.cs</Link>
</Compile>
<Compile Include="ErrorTest.cs" />
<Compile Include="..\..\tools\common\ApplePlatform.cs">
<Link>tools\common\ApplePlatform.cs</Link>
</Compile>
<Compile Include="Setup.cs" />
<Compile Include="Compat.cs" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />

Просмотреть файл

@ -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 ();
}
}
}

Просмотреть файл

@ -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

Просмотреть файл

@ -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 {

Просмотреть файл

@ -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);

Просмотреть файл

@ -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<int, WarningLevel> warning_levels;
public static int Verbosity { get; set; }
#pragma warning disable 649
public static Func<Exception, bool> IsExpectedException;
public static Action<int> 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<int, WarningLevel> ();
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<Exception> 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<Exception> list)
{
List<Exception> exceptions = new List<Exception> ();
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);
}
}
}

Просмотреть файл

@ -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;

Просмотреть файл

@ -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 ();
}
}
}

Просмотреть файл

@ -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);
}
}
}

Просмотреть файл

@ -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; }

Просмотреть файл

@ -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 {

Просмотреть файл

@ -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;

Просмотреть файл

@ -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);
}
}
}

Просмотреть файл

@ -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.");
}
}

Просмотреть файл

@ -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<string> ();
@ -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);
}
}
}

Просмотреть файл

@ -446,6 +446,9 @@
<Compile Include="..\linker\ScanTypeReferenceStep.cs">
<Link>tools\linker\ScanTypeReferenceStep.cs</Link>
</Compile>
<Compile Include="..\common\ErrorHelper.tools.cs">
<Link>tools\common\ErrorHelper.tools.cs</Link>
</Compile>
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<ItemGroup>

Просмотреть файл

@ -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<Application> ();
@ -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));
}
}
}

Просмотреть файл

@ -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);
}
}
}

Просмотреть файл

@ -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

Просмотреть файл

@ -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);
}
}
}

Просмотреть файл

@ -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<AssemblyDefinition> ();
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<AssemblyDefinition> 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;

Просмотреть файл

@ -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);
}
}
}

Просмотреть файл

@ -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);
}
}
}

Просмотреть файл

@ -463,6 +463,9 @@
<Compile Include="..\linker\MonoTouch.Tuner\RemoveCodeBase.cs">
<Link>tools\linker\MonoTouch.Tuner\RemoveCodeBase.cs</Link>
</Compile>
<Compile Include="..\common\ErrorHelper.tools.cs">
<Link>tools\common\ErrorHelper.tools.cs</Link>
</Compile>
</ItemGroup>
<ItemGroup>
<Reference Include="System.Core" />