diff options
author | Stephane Delcroix <stephane@delcroix.org> | 2017-03-01 19:45:03 +0100 |
---|---|---|
committer | Jason Smith <jason.smith@xamarin.com> | 2017-03-01 10:45:03 -0800 |
commit | c57f859745aeef7965e03639fc016ee0c7a8a218 (patch) | |
tree | a9629670f09032d2d352dcd8c368a0661c901392 /Xamarin.Forms.Build.Tasks/DebugXamlCTask.cs | |
parent | 9b18ab9fb438a88c2be8a54aa3f567a9b1c398da (diff) | |
download | xamarin-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.cs | 187 |
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 +} |