114 строки
3.1 KiB
C#
114 строки
3.1 KiB
C#
using System;
|
|
using System.IO;
|
|
using System.Text;
|
|
|
|
using Mono.Linker;
|
|
using Mono.Linker.Steps;
|
|
|
|
using Mono.Cecil;
|
|
using Mono.Cecil.Cil;
|
|
|
|
using Xamarin.Bundler;
|
|
|
|
#if MONOTOUCH
|
|
using PlatformLinkContext = MonoTouch.Tuner.MonoTouchLinkContext;
|
|
#else
|
|
using PlatformLinkContext = MonoMac.Tuner.MonoMacLinkContext;
|
|
#endif
|
|
|
|
#if MONOTOUCH
|
|
namespace MonoTouch.Tuner {
|
|
#else
|
|
namespace MonoMac.Tuner {
|
|
#endif
|
|
static partial class Linker {
|
|
|
|
static void Process (Pipeline pipeline, PlatformLinkContext context)
|
|
{
|
|
try {
|
|
pipeline.Process (context);
|
|
} catch (Exception e) {
|
|
var pe = HandlePipelineProcessException (e);
|
|
if (pe == e) // Throw original if possible to preserve stack trace
|
|
throw;
|
|
throw pe;
|
|
}
|
|
}
|
|
|
|
static void Append (this Pipeline self, IStep step)
|
|
{
|
|
self.AppendStep (step);
|
|
if (Driver.WatchLevel > 0)
|
|
self.AppendStep (new TimeStampStep (step));
|
|
}
|
|
|
|
static Exception HandlePipelineProcessException (Exception e)
|
|
{
|
|
switch (e) {
|
|
case AssemblyResolutionException are:
|
|
return new ProductException (2002, true, are, are.Message);
|
|
case AggregateException ae:
|
|
return ae;
|
|
case ProductException pe:
|
|
return pe;
|
|
case MarkException me:
|
|
{
|
|
var re = me.InnerException as ResolutionException;
|
|
if (re == null) {
|
|
if (me.InnerException != null) {
|
|
return ErrorHelper.CreateError (2102, me, Errors.MT2102, me.Method.FullName, me.Method.Module, me.InnerException.Message);
|
|
} else {
|
|
return ErrorHelper.CreateError (2102, me, Errors.MT2102_A, me.Method.FullName, me.Method.Module);
|
|
}
|
|
} else {
|
|
TypeReference tr = (re.Member as TypeReference);
|
|
IMetadataScope scope = tr == null ? re.Member.DeclaringType.Scope : tr.Scope;
|
|
return ErrorHelper.CreateError (2101, me, Errors.MT2101, re.Member, me.Method.FullName, scope);
|
|
}
|
|
}
|
|
case ResolutionException re:
|
|
{
|
|
TypeReference tr = (re.Member as TypeReference);
|
|
IMetadataScope scope = tr == null ? re.Member.DeclaringType.Scope : tr.Scope;
|
|
return new ProductException (2002, true, re, "Failed to resolve \"{0}\" reference from \"{1}\"", re.Member, scope);
|
|
}
|
|
case XmlResolutionException ex:
|
|
return new ProductException (2017, true, ex, Errors.MX2017, ex?.InnerException?.Message ?? ex.Message);
|
|
default:
|
|
if (e.InnerException != null)
|
|
return HandlePipelineProcessException (e.InnerException);
|
|
|
|
var message = new StringBuilder ();
|
|
if (e.Data.Count > 0) {
|
|
message.AppendLine ();
|
|
var m = e.Data ["MethodDefinition"] as string;
|
|
if (m != null)
|
|
message.AppendLine ($"\tMethod: `{m}`");
|
|
var t = e.Data ["TypeReference"] as string;
|
|
if (t != null)
|
|
message.AppendLine ($"\tType: `{t}`");
|
|
var a = e.Data ["AssemblyDefinition"] as string;
|
|
if (a != null)
|
|
message.AppendLine ($"\tAssembly: `{a}`");
|
|
}
|
|
message.Append ($"Reason: {e.Message}");
|
|
return new ProductException (2001, true, e, Errors.MX2001, message);
|
|
}
|
|
}
|
|
}
|
|
|
|
public class TimeStampStep : IStep {
|
|
string message;
|
|
|
|
public TimeStampStep (IStep step)
|
|
{
|
|
message = step.ToString ();
|
|
}
|
|
|
|
public void Process (LinkContext context)
|
|
{
|
|
Driver.Watch (message, 2);
|
|
}
|
|
}
|
|
}
|