summaryrefslogtreecommitdiff
path: root/Xamarin.Forms.Build.Tasks/DebugXamlCTask.cs
diff options
context:
space:
mode:
authorStephane Delcroix <stephane@delcroix.org>2017-03-01 19:45:03 +0100
committerJason Smith <jason.smith@xamarin.com>2017-03-01 10:45:03 -0800
commitc57f859745aeef7965e03639fc016ee0c7a8a218 (patch)
treea9629670f09032d2d352dcd8c368a0661c901392 /Xamarin.Forms.Build.Tasks/DebugXamlCTask.cs
parent9b18ab9fb438a88c2be8a54aa3f567a9b1c398da (diff)
downloadxamarin-forms-c57f859745aeef7965e03639fc016ee0c7a8a218.tar.gz
xamarin-forms-c57f859745aeef7965e03639fc016ee0c7a8a218.tar.bz2
xamarin-forms-c57f859745aeef7965e03639fc016ee0c7a8a218.zip
Xamlc ppdb backport (#792)
* [XamlC] Produce correct mdb files (#699) * [XamlC] change MockCompile (internal) API * [XamlC] fix debugging in unit test project * f * [XamlC] update cecil to 0.10.0-beta1-v2 * beta2 * avoid method duplication * [XamlC] force loading MdbReader and Writer * [XamlC] force use the writer in the other task too * [XamlC] fix test and test code generator * try building this * [XamlC] Ensure InitializeComponent is correctly routed * fix * [XamlC] support portable pdb (#726) * [XamlC] update to cecil 0.10.0-b4 to better symbol detection (#791)
Diffstat (limited to 'Xamarin.Forms.Build.Tasks/DebugXamlCTask.cs')
-rw-r--r--Xamarin.Forms.Build.Tasks/DebugXamlCTask.cs187
1 files changed, 99 insertions, 88 deletions
diff --git a/Xamarin.Forms.Build.Tasks/DebugXamlCTask.cs b/Xamarin.Forms.Build.Tasks/DebugXamlCTask.cs
index a8ef874a..1e441c97 100644
--- a/Xamarin.Forms.Build.Tasks/DebugXamlCTask.cs
+++ b/Xamarin.Forms.Build.Tasks/DebugXamlCTask.cs
@@ -2,16 +2,22 @@ using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
+
using Mono.Cecil;
using Mono.Cecil.Cil;
+using Mono.Cecil.Mdb;
+using Mono.Cecil.Pdb;
using Mono.Cecil.Rocks;
+using Xamarin.Forms.Xaml;
+
namespace Xamarin.Forms.Build.Tasks
{
public class DebugXamlCTask : XamlTask
{
- public override bool Execute(IList<Exception> thrownExceptions)
+ public override bool Execute(out IList<Exception> thrownExceptions)
{
+ thrownExceptions = null;
Logger = Logger ?? new Logger(null, Verbosity);
Logger.LogLine(1, "Preparing debug code for xamlc");
Logger.LogLine(1, "\nAssembly: {0}", Assembly);
@@ -37,109 +43,114 @@ namespace Xamarin.Forms.Build.Tasks
// resolver.AddAssembly (p);
}
}
- var assemblyDefinition = AssemblyDefinition.ReadAssembly(Assembly, new ReaderParameters
- {
- //ReadSymbols = DebugSymbols,
+ using (var assemblyDefinition = AssemblyDefinition.ReadAssembly(Assembly, new ReaderParameters {
+ ReadWrite = true,
+ ReadSymbols = DebugSymbols,
AssemblyResolver = resolver
- });
+ })) {
+ foreach (var module in assemblyDefinition.Modules) {
+ Logger.LogLine(2, " Module: {0}", module.Name);
+ foreach (var resource in module.Resources.OfType<EmbeddedResource>()) {
+ Logger.LogString(2, " Resource: {0}... ", resource.Name);
+ string classname;
+ if (!resource.IsXaml(out classname)) {
+ Logger.LogLine(2, "skipped.");
+ continue;
+ } else
+ Logger.LogLine(2, "");
+ TypeDefinition typeDef = module.GetType(classname);
+ if (typeDef == null) {
+ Logger.LogLine(2, "no type found... skipped.");
+ continue;
+ }
- foreach (var module in assemblyDefinition.Modules)
- {
- Logger.LogLine(2, " Module: {0}", module.Name);
- foreach (var resource in module.Resources.OfType<EmbeddedResource>())
- {
- Logger.LogString(2, " Resource: {0}... ", resource.Name);
- string classname;
- if (!resource.IsXaml(out classname))
- {
- Logger.LogLine(2, "skipped.");
- continue;
- }
- TypeDefinition typeDef = module.GetType(classname);
- if (typeDef == null)
- {
- Logger.LogLine(2, "no type found... skipped.");
- continue;
- }
- var initComp = typeDef.Methods.FirstOrDefault(md => md.Name == "InitializeComponent");
- if (initComp == null)
- {
- Logger.LogLine(2, "no InitializeComponent found... skipped.");
- continue;
- }
- var initCompRuntime = typeDef.Methods.FirstOrDefault(md => md.Name == "__InitComponentRuntime");
- if (initCompRuntime == null) {
- Logger.LogLine(2, "no __InitComponentRuntime found... duplicating.");
- initCompRuntime = DuplicateMethodDef(typeDef, initComp, "__InitComponentRuntime");
- }
+ var initComp = typeDef.Methods.FirstOrDefault(md => md.Name == "InitializeComponent");
+ if (initComp == null) {
+ Logger.LogLine(2, "no InitializeComponent found... skipped.");
+ continue;
+ }
+ var initCompRuntime = typeDef.Methods.FirstOrDefault(md => md.Name == "__InitComponentRuntime");
+ if (initCompRuntime == null) {
+ Logger.LogString(2, " Creating empty {0}.__InitComponentRuntime ...", typeDef.Name);
+ initCompRuntime = new MethodDefinition("__InitComponentRuntime", initComp.Attributes, initComp.ReturnType);
+ Logger.LogLine(2, "done.");
+ Logger.LogString(2, " Copying body of InitializeComponent to __InitComponentRuntime ...", typeDef.Name);
+ initCompRuntime.Body = new MethodBody(initCompRuntime);
+ var iCRIl = initCompRuntime.Body.GetILProcessor();
+ foreach (var instr in initComp.Body.Instructions)
+ iCRIl.Append(instr);
+ initComp.Body.Instructions.Clear();
+ initComp.Body.GetILProcessor().Emit(OpCodes.Ret);
+ typeDef.Methods.Add(initCompRuntime);
+ Logger.LogLine(2, "done.");
+ }
-// IL_0000: ldarg.0
-// IL_0001: callvirt instance void class [Xamarin.Forms.Core]Xamarin.Forms.ContentPage::'.ctor'()
+// IL_0000: ldarg.0
+// IL_0001: callvirt instance void class [Xamarin.Forms.Core]Xamarin.Forms.ContentPage::'.ctor'()
//
-// IL_0006: nop
-// IL_0007: ldarg.1
-// IL_0008: brfalse IL_0018
+// IL_0006: nop
+// IL_0007: ldarg.1
+// IL_0008: brfalse IL_0018
//
-// IL_000d: ldarg.0
-// IL_000e: callvirt instance void class Xamarin.Forms.Xaml.XamlcTests.MyPage::InitializeComponent()
-// IL_0013: br IL_001e
+// IL_000d: ldarg.0
+// IL_000e: callvirt instance void class Xamarin.Forms.Xaml.XamlcTests.MyPage::InitializeComponent()
+// IL_0013: br IL_001e
//
-// IL_0018: ldarg.0
-// IL_0019: callvirt instance void class Xamarin.Forms.Xaml.XamlcTests.MyPage::__InitComponentRuntime()
-// IL_001e: ret
+// IL_0018: ldarg.0
+// IL_0019: callvirt instance void class Xamarin.Forms.Xaml.XamlcTests.MyPage::__InitComponentRuntime()
+// IL_001e: ret
- var altCtor =
- typeDef.Methods.Where(
- md => md.IsConstructor && md.Parameters.Count == 1 && md.Parameters[0].ParameterType == module.TypeSystem.Boolean)
- .FirstOrDefault();
- if (altCtor != null)
- Logger.LogString(2, " Replacing body of {0}.{0} (bool {1}) ... ", typeDef.Name, altCtor.Parameters[0].Name);
- else
- {
- Logger.LogString(2, " Adding {0}.{0} (bool useCompiledXaml) ... ", typeDef.Name);
- altCtor = new MethodDefinition(".ctor",
- MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.SpecialName |
- MethodAttributes.RTSpecialName, module.TypeSystem.Void);
- altCtor.Parameters.Add(new ParameterDefinition("useCompiledXaml", ParameterAttributes.None,
- module.TypeSystem.Boolean));
- }
+ var altCtor =
+ typeDef.Methods.Where(
+ md => md.IsConstructor && md.Parameters.Count == 1 && md.Parameters[0].ParameterType == module.TypeSystem.Boolean)
+ .FirstOrDefault();
+ if (altCtor != null)
+ Logger.LogString(2, " Replacing body of {0}.{0} (bool {1}) ... ", typeDef.Name, altCtor.Parameters[0].Name);
+ else {
+ Logger.LogString(2, " Adding {0}.{0} (bool useCompiledXaml) ... ", typeDef.Name);
+ altCtor = new MethodDefinition(".ctor",
+ MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.SpecialName |
+ MethodAttributes.RTSpecialName, module.TypeSystem.Void);
+ altCtor.Parameters.Add(new ParameterDefinition("useCompiledXaml", ParameterAttributes.None,
+ module.TypeSystem.Boolean));
+ }
- var body = new MethodBody(altCtor);
- var il = body.GetILProcessor();
- var br2 = Instruction.Create(OpCodes.Ldarg_0);
- var ret = Instruction.Create(OpCodes.Ret);
- il.Emit(OpCodes.Ldarg_0);
- il.Emit(OpCodes.Callvirt,
- module.Import(typeDef.BaseType.Resolve().GetConstructors().First(c => c.HasParameters == false)));
+ var body = new MethodBody(altCtor);
+ var il = body.GetILProcessor();
+ var br2 = Instruction.Create(OpCodes.Ldarg_0);
+ var ret = Instruction.Create(OpCodes.Ret);
+ il.Emit(OpCodes.Ldarg_0);
+ il.Emit(OpCodes.Callvirt,
+ module.ImportReference(typeDef.BaseType.Resolve().GetConstructors().First(c => c.HasParameters == false)));
- il.Emit(OpCodes.Nop);
- il.Emit(OpCodes.Ldarg_1);
- il.Emit(OpCodes.Brfalse, br2);
+ il.Emit(OpCodes.Nop);
+ il.Emit(OpCodes.Ldarg_1);
+ il.Emit(OpCodes.Brfalse, br2);
- il.Emit(OpCodes.Ldarg_0);
- il.Emit(OpCodes.Callvirt, initComp);
- il.Emit(OpCodes.Br, ret);
+ il.Emit(OpCodes.Ldarg_0);
+ il.Emit(OpCodes.Callvirt, initComp);
+ il.Emit(OpCodes.Br, ret);
- il.Append(br2);
- il.Emit(OpCodes.Callvirt, initCompRuntime);
- il.Append(ret);
+ il.Append(br2);
+ il.Emit(OpCodes.Callvirt, initCompRuntime);
+ il.Append(ret);
- altCtor.Body = body;
- if (!typeDef.Methods.Contains(altCtor))
- typeDef.Methods.Add(altCtor);
- Logger.LogLine(2, "done.");
- }
+ altCtor.Body = body;
+ if (!typeDef.Methods.Contains(altCtor))
+ typeDef.Methods.Add(altCtor);
+ Logger.LogLine(2, "done.");
+ }
- Logger.LogLine(2, "");
+ Logger.LogLine(2, "");
+ }
+ Logger.LogString(1, "Writing the assembly... ");
+ assemblyDefinition.Write(new WriterParameters {
+ WriteSymbols = DebugSymbols
+ });
}
- Logger.LogString(1, "Writing the assembly... ");
- assemblyDefinition.Write(Assembly, new WriterParameters
- {
- WriteSymbols = DebugSymbols
- });
Logger.LogLine(1, "done.");
return true;
}
}
-} \ No newline at end of file
+}