From 978a3ede6577fabf060cb0fb86a9d7de8ffb2146 Mon Sep 17 00:00:00 2001 From: Tomas Matousek Date: Thu, 15 Jun 2017 17:06:57 -0700 Subject: [PATCH 1/4] Include Mono.Cecil.Tests.csproj in netstandard build --- Mono.Cecil.Tests.props | 8 ++- Mono.Cecil.props | 7 +-- Mono.Cecil.sln | 1 + Mono.Cecil/BaseAssemblyResolver.cs | 10 ++-- Mono.Cecil/DefaultAssemblyResolver.cs | 4 -- NetStandard.props | 2 +- Test/Mono.Cecil.Tests.csproj | 21 +++++++- Test/Mono.Cecil.Tests/BaseTestFixture.cs | 16 +++--- .../CallerMemberNameAttribute.cs | 10 ++++ Test/Mono.Cecil.Tests/CompilationService.cs | 9 +++- .../Mono.Cecil.Tests/CustomAttributesTests.cs | 17 +++--- Test/Mono.Cecil.Tests/Extensions.cs | 53 ++++++++++++++++-- Test/Mono.Cecil.Tests/ImageReadTests.cs | 3 +- Test/Mono.Cecil.Tests/ImportCecilTests.cs | 34 +++++------- .../Mono.Cecil.Tests/ImportReflectionTests.cs | 54 ++++++++----------- Test/Mono.Cecil.Tests/ModuleTests.cs | 8 +-- Test/Mono.Cecil.Tests/ResolveTests.cs | 9 ++-- .../SecurityDeclarationTests.cs | 15 +++--- Test/Mono.Cecil.Tests/TypeParserTests.cs | 8 +-- Test/Mono.Cecil.Tests/TypeTests.cs | 4 +- .../WindowsRuntimeAssemblyResolver.cs | 5 +- .../WindowsRuntimeProjectionsTests.cs | 5 +- 22 files changed, 183 insertions(+), 120 deletions(-) create mode 100644 Test/Mono.Cecil.Tests/CallerMemberNameAttribute.cs diff --git a/Mono.Cecil.Tests.props b/Mono.Cecil.Tests.props index e1290901b..a94b8aa2c 100644 --- a/Mono.Cecil.Tests.props +++ b/Mono.Cecil.Tests.props @@ -2,9 +2,15 @@ $(MSBuildProjectDirectory) + true - + + + 3.7.1 + + + False $(MSBuildThisFileDirectory)\Test\libs\nunit-2.6.2\nunit.core.dll diff --git a/Mono.Cecil.props b/Mono.Cecil.props index da63a2ffe..c04324c70 100644 --- a/Mono.Cecil.props +++ b/Mono.Cecil.props @@ -36,14 +36,15 @@ v3.5 - $(DefineConstants); + $(DefineConstants);NET_3_5; v4.0 $(DefineConstants);NET_4_0; - - netstandard1.3 + + netstandard1.5 + netstandard1.3 diff --git a/Mono.Cecil.sln b/Mono.Cecil.sln index f7ce9efa6..beaa28cbf 100644 --- a/Mono.Cecil.sln +++ b/Mono.Cecil.sln @@ -81,6 +81,7 @@ Global {A47B1F49-A81A-43E8-BE6B-DD28AF2C4055}.netstandard_Debug_ReadOnly|Any CPU.ActiveCfg = netstandard_Debug_ReadOnly|Any CPU {A47B1F49-A81A-43E8-BE6B-DD28AF2C4055}.netstandard_Debug_ReadOnly|Any CPU.Build.0 = netstandard_Debug_ReadOnly|Any CPU {A47B1F49-A81A-43E8-BE6B-DD28AF2C4055}.netstandard_Debug|Any CPU.ActiveCfg = netstandard_Debug|Any CPU + {A47B1F49-A81A-43E8-BE6B-DD28AF2C4055}.netstandard_Debug|Any CPU.Build.0 = netstandard_Debug|Any CPU {A47B1F49-A81A-43E8-BE6B-DD28AF2C4055}.netstandard_Release_ReadOnly|Any CPU.ActiveCfg = netstandard_Release_ReadOnly|Any CPU {A47B1F49-A81A-43E8-BE6B-DD28AF2C4055}.netstandard_Release_ReadOnly|Any CPU.Build.0 = netstandard_Release_ReadOnly|Any CPU {A47B1F49-A81A-43E8-BE6B-DD28AF2C4055}.netstandard_Release|Any CPU.ActiveCfg = netstandard_Release|Any CPU diff --git a/Mono.Cecil/BaseAssemblyResolver.cs b/Mono.Cecil/BaseAssemblyResolver.cs index ade0102e5..27d6fe8e6 100644 --- a/Mono.Cecil/BaseAssemblyResolver.cs +++ b/Mono.Cecil/BaseAssemblyResolver.cs @@ -65,15 +65,15 @@ public AssemblyResolutionException (AssemblyNameReference reference, Exception i #endif } -#if !NET_CORE public abstract class BaseAssemblyResolver : IAssemblyResolver { static readonly bool on_mono = Type.GetType ("Mono.Runtime") != null; readonly Collection directories; +#if !NET_CORE Collection gac_paths; - +#endif public void AddSearchDirectory (string directory) { directories.Add (directory); @@ -120,6 +120,7 @@ public virtual AssemblyDefinition Resolve (AssemblyNameReference name, ReaderPar if (assembly != null) return assembly; +#if !NET_CORE if (name.IsRetargetable) { // if the reference is retargetable, zero it name = new AssemblyNameReference (name.Name, Mixin.ZeroVersion) { @@ -151,6 +152,7 @@ public virtual AssemblyDefinition Resolve (AssemblyNameReference name, ReaderPar assembly = SearchDirectory (name, framework_dirs, parameters); if (assembly != null) return assembly; +#endif if (ResolveFailure != null) { assembly = ResolveFailure (this, name); @@ -185,6 +187,7 @@ static bool IsZero (Version version) return version.Major == 0 && version.Minor == 0 && version.Build == 0 && version.Revision == 0; } +#if !NET_CORE AssemblyDefinition GetCorlib (AssemblyNameReference reference, ReaderParameters parameters) { var version = reference.Version; @@ -325,7 +328,7 @@ AssemblyDefinition GetAssemblyInNetGac (AssemblyNameReference reference, ReaderP return null; } - +#endif static string GetAssemblyFile (AssemblyNameReference reference, string prefix, string gac) { var gac_folder = new StringBuilder () @@ -352,5 +355,4 @@ protected virtual void Dispose (bool disposing) { } } -#endif } diff --git a/Mono.Cecil/DefaultAssemblyResolver.cs b/Mono.Cecil/DefaultAssemblyResolver.cs index 197aaa0e6..755071ea4 100644 --- a/Mono.Cecil/DefaultAssemblyResolver.cs +++ b/Mono.Cecil/DefaultAssemblyResolver.cs @@ -8,8 +8,6 @@ // Licensed under the MIT/X11 license. // -#if !NET_CORE - using System; using System.Collections.Generic; @@ -61,5 +59,3 @@ protected override void Dispose (bool disposing) } } } - -#endif diff --git a/NetStandard.props b/NetStandard.props index d5f4196ef..bc0bacc6e 100644 --- a/NetStandard.props +++ b/NetStandard.props @@ -1,7 +1,7 @@ - $(DefineConstants);NET_4_0;NET_CORE; + $(DefineConstants);NET_CORE; false false true diff --git a/Test/Mono.Cecil.Tests.csproj b/Test/Mono.Cecil.Tests.csproj index 9277d6a3a..19d0e5707 100644 --- a/Test/Mono.Cecil.Tests.csproj +++ b/Test/Mono.Cecil.Tests.csproj @@ -1,10 +1,28 @@  + {A47B1F49-A81A-43E8-BE6B-DD28AF2C4055} Mono.Cecil.Tests Mono.Cecil.Tests + + + 4.3.0 + + + 4.3.0 + + + 4.3.0 + + + 4.3.0 + + + 4.3.0 + + {D68133BD-1E63-496E-9EDE-4FBDBF77B486} @@ -26,6 +44,5 @@ - - + \ No newline at end of file diff --git a/Test/Mono.Cecil.Tests/BaseTestFixture.cs b/Test/Mono.Cecil.Tests/BaseTestFixture.cs index c49880eda..9ec583345 100644 --- a/Test/Mono.Cecil.Tests/BaseTestFixture.cs +++ b/Test/Mono.Cecil.Tests/BaseTestFixture.cs @@ -38,38 +38,38 @@ public static string GetILResourcePath (string name, Assembly assembly) public ModuleDefinition GetResourceModule (string name) { - return ModuleDefinition.ReadModule (GetAssemblyResourcePath (name, GetType ().Assembly)); + return ModuleDefinition.ReadModule (GetAssemblyResourcePath (name, GetType ().GetTypeInfo().Assembly)); } public ModuleDefinition GetResourceModule (string name, ReaderParameters parameters) { - return ModuleDefinition.ReadModule (GetAssemblyResourcePath (name, GetType ().Assembly), parameters); + return ModuleDefinition.ReadModule (GetAssemblyResourcePath (name, GetType ().GetTypeInfo ().Assembly), parameters); } public ModuleDefinition GetResourceModule (string name, ReadingMode mode) { - return ModuleDefinition.ReadModule (GetAssemblyResourcePath (name, GetType ().Assembly), new ReaderParameters (mode)); + return ModuleDefinition.ReadModule (GetAssemblyResourcePath (name, GetType ().GetTypeInfo ().Assembly), new ReaderParameters (mode)); } internal Image GetResourceImage (string name) { - var file = new FileStream (GetAssemblyResourcePath (name, GetType ().Assembly), FileMode.Open, FileAccess.Read); + var file = new FileStream (GetAssemblyResourcePath (name, GetType ().GetTypeInfo ().Assembly), FileMode.Open, FileAccess.Read); return ImageReader.ReadImage (Disposable.Owned (file as Stream), file.Name); } public ModuleDefinition GetCurrentModule () { - return ModuleDefinition.ReadModule (GetType ().Module.FullyQualifiedName); + return ModuleDefinition.ReadModule (GetType ().GetTypeInfo ().Module.FullyQualifiedName); } public ModuleDefinition GetCurrentModule (ReaderParameters parameters) { - return ModuleDefinition.ReadModule (GetType ().Module.FullyQualifiedName, parameters); + return ModuleDefinition.ReadModule (GetType ().GetTypeInfo().Module.FullyQualifiedName, parameters); } public static string FindResourcesDirectory (Assembly assembly) { - var path = Path.GetDirectoryName (new Uri (assembly.CodeBase).LocalPath); + var path = Path.GetDirectoryName (assembly.ManifestModule.FullyQualifiedName); while (!Directory.Exists (Path.Combine (path, "Resources"))) { var old = path; path = Path.GetDirectoryName (path); @@ -140,7 +140,7 @@ abstract class TestCase { public abstract string ModuleLocation { get; } - protected Assembly Assembly { get { return Test.Method.Module.Assembly; } } + protected Assembly Assembly { get { return Test.GetMethodInfo().Module.Assembly; } } protected TestCase (Action test, bool verify, bool readOnly, Type symbolReaderProvider, Type symbolWriterProvider, IAssemblyResolver assemblyResolver, bool applyWindowsRuntimeProjections) { diff --git a/Test/Mono.Cecil.Tests/CallerMemberNameAttribute.cs b/Test/Mono.Cecil.Tests/CallerMemberNameAttribute.cs new file mode 100644 index 000000000..63bd9b8ac --- /dev/null +++ b/Test/Mono.Cecil.Tests/CallerMemberNameAttribute.cs @@ -0,0 +1,10 @@ +#if NET_3_5 || NET_4_0 +namespace System.Runtime.CompilerServices { + [AttributeUsage (AttributeTargets.Parameter, Inherited = false)] + public sealed class CallerMemberNameAttribute : Attribute { + public CallerMemberNameAttribute () + { + } + } +} +#endif \ No newline at end of file diff --git a/Test/Mono.Cecil.Tests/CompilationService.cs b/Test/Mono.Cecil.Tests/CompilationService.cs index 877ed24d3..9dccb0d15 100644 --- a/Test/Mono.Cecil.Tests/CompilationService.cs +++ b/Test/Mono.Cecil.Tests/CompilationService.cs @@ -22,7 +22,7 @@ public CompilationResult (DateTime write_time, string result_file) public static class Platform { - public static bool OnMono { get { return typeof (object).Assembly.GetType ("Mono.Runtime") != null; } } + public static bool OnMono { get { return typeof (object).GetTypeInfo().Assembly.GetType ("Mono.Runtime") != null; } } } abstract class CompilationService { @@ -64,12 +64,13 @@ void RegisterFile (string name, string result_file) public static string CompileResource (string name) { var extension = Path.GetExtension (name); +#if !NET_CORE if (extension == ".il") return IlasmCompilationService.Instance.Compile (name); if (extension == ".cs" || extension == ".vb") return CodeDomCompilationService.Instance.Compile (name); - +#endif throw new NotSupportedException (extension); } @@ -84,12 +85,15 @@ protected static string GetCompiledFilePath (string file_name) public static void Verify (string name) { +#if !NET_CORE var output = Platform.OnMono ? ShellService.PEDump (name) : ShellService.PEVerify (name); if (output.ExitCode != 0) Assert.Fail (output.ToString ()); +#endif } } +#if !NET_CORE class IlasmCompilationService : CompilationService { public static readonly IlasmCompilationService Instance = new IlasmCompilationService (); @@ -276,4 +280,5 @@ static string WinSdkTool (string tool) return tool; } } +#endif } diff --git a/Test/Mono.Cecil.Tests/CustomAttributesTests.cs b/Test/Mono.Cecil.Tests/CustomAttributesTests.cs index a89fcfdfc..e3b86fd02 100644 --- a/Test/Mono.Cecil.Tests/CustomAttributesTests.cs +++ b/Test/Mono.Cecil.Tests/CustomAttributesTests.cs @@ -456,7 +456,7 @@ public void DefineCustomAttributeFromBlob () var file = Path.Combine (Path.GetTempPath (), "CaBlob.dll"); var module = ModuleDefinition.CreateModule ("CaBlob.dll", new ModuleParameters { Kind = ModuleKind.Dll, Runtime = TargetRuntime.Net_2_0 }); - var assembly_title_ctor = module.ImportReference (typeof (System.Reflection.AssemblyTitleAttribute).GetConstructor (new [] {typeof (string)})); + var assembly_title_ctor = module.ImportReference (typeof (System.Reflection.AssemblyTitleAttribute).GetTypeInfo().GetConstructor (new [] {typeof (string)})); Assert.IsNotNull (assembly_title_ctor); @@ -558,14 +558,12 @@ static void PrettyPrintValue (object value, StringBuilder signature) return; } - switch (Type.GetTypeCode (value.GetType ())) { - case TypeCode.String: - signature.AppendFormat ("\"{0}\"", value); - break; - case TypeCode.Char: - signature.AppendFormat ("'{0}'", (char) value); - break; - default: + string str; + if ((str = value as string) != null) { + signature.AppendFormat("\"{0}\"", str); + } else if (value is char) { + signature.AppendFormat ("'{0}'", (char)value); + } else { var formattable = value as IFormattable; if (formattable != null) { signature.Append (formattable.ToString (null, CultureInfo.InvariantCulture)); @@ -576,7 +574,6 @@ static void PrettyPrintValue (object value, StringBuilder signature) PrettyPrint ((CustomAttributeArgument) value, signature); return; } - break; } } diff --git a/Test/Mono.Cecil.Tests/Extensions.cs b/Test/Mono.Cecil.Tests/Extensions.cs index ab27e9b02..c5be9afd8 100644 --- a/Test/Mono.Cecil.Tests/Extensions.cs +++ b/Test/Mono.Cecil.Tests/Extensions.cs @@ -3,12 +3,57 @@ using System.Linq; using SR = System.Reflection; -using Mono.Cecil; - namespace Mono.Cecil.Tests { public static class Extensions { +#if NET_CORE + public static SR.Assembly LoadAssembly (MemoryStream stream) + { + return System.Runtime.Loader.AssemblyLoadContext.Default.LoadFromStream (stream); + } + + public static SR.TypeInfo GetTypeInfo (this Type self) + { + return SR.IntrospectionExtensions.GetTypeInfo(self); + } + + public static SR.MethodInfo GetMethodInfo (this Delegate self) + { + return SR.RuntimeReflectionExtensions.GetMethodInfo (self); + } + + public static string GetCultureName(this SR.AssemblyName self) + { + return self.CultureName; + } +#else + public static SR.Assembly LoadAssembly (MemoryStream stream) + { + return SR.Assembly.Load(stream.ToArray ()); + } + + public static Type GetTypeInfo (this Type self) + { + return self; + } + + public static SR.MethodInfo GetMethodInfo (this Delegate self) + { + return self.Method; + } + + public static Delegate CreateDelegate (this SR.MethodInfo self, Type type) + { + return Delegate.CreateDelegate (type, self); + } + + public static string GetCultureName(this SR.AssemblyName self) + { + return self.CultureInfo.Name; + } +#endif + public static MethodDefinition GetMethod (this TypeDefinition self, string name) { return self.Methods.Where (m => m.Name == name).First (); @@ -21,8 +66,8 @@ public static FieldDefinition GetField (this TypeDefinition self, string name) public static TypeDefinition ToDefinition (this Type self) { - var module = ModuleDefinition.ReadModule (new MemoryStream (File.ReadAllBytes (self.Module.FullyQualifiedName))); - return (TypeDefinition) module.LookupToken (self.MetadataToken); + var module = ModuleDefinition.ReadModule (new MemoryStream (File.ReadAllBytes (self.GetTypeInfo().Module.FullyQualifiedName))); + return (TypeDefinition) module.LookupToken (self.GetTypeInfo().MetadataToken); } public static MethodDefinition ToDefinition (this SR.MethodBase method) diff --git a/Test/Mono.Cecil.Tests/ImageReadTests.cs b/Test/Mono.Cecil.Tests/ImageReadTests.cs index 16f89d295..16b8a7b3f 100644 --- a/Test/Mono.Cecil.Tests/ImageReadTests.cs +++ b/Test/Mono.Cecil.Tests/ImageReadTests.cs @@ -170,6 +170,7 @@ public void MetroAssembly () }, verify: false); } +#if !NET_CORE [Test] public void WindowsRuntimeComponentAssembly () { @@ -181,7 +182,7 @@ public void WindowsRuntimeComponentAssembly () Assert.IsTrue (module.Assembly.Name.IsWindowsRuntime); }, verify: false, assemblyResolver: resolver); } - +#endif [Test] public void DeterministicAssembly () { diff --git a/Test/Mono.Cecil.Tests/ImportCecilTests.cs b/Test/Mono.Cecil.Tests/ImportCecilTests.cs index a28b0935e..1d450dbd9 100644 --- a/Test/Mono.Cecil.Tests/ImportCecilTests.cs +++ b/Test/Mono.Cecil.Tests/ImportCecilTests.cs @@ -76,7 +76,7 @@ public void ImportFieldStringEmpty () { var get_empty = Compile> ((module, body) => { var il = body.GetILProcessor (); - il.Emit (OpCodes.Ldsfld, module.ImportReference (typeof (string).GetField ("Empty").ToDefinition ())); + il.Emit (OpCodes.Ldsfld, module.ImportReference (typeof (string).GetTypeInfo().GetField ("Empty").ToDefinition ())); il.Emit (OpCodes.Ret); }); @@ -90,7 +90,7 @@ public void ImportStringConcat () var il = body.GetILProcessor (); il.Emit (OpCodes.Ldarg_0); il.Emit (OpCodes.Ldarg_1); - il.Emit (OpCodes.Call, module.ImportReference (typeof (string).GetMethod ("Concat", new [] { typeof (string), typeof (string) }).ToDefinition ())); + il.Emit (OpCodes.Call, module.ImportReference (typeof (string).GetTypeInfo ().GetMethod ("Concat", new [] { typeof (string), typeof (string) }).ToDefinition ())); il.Emit (OpCodes.Ret); }); @@ -255,31 +255,31 @@ public A GenericMethod (B b, C c) [Test] public void ContextGenericTest () { - var module = ModuleDefinition.ReadModule (typeof (ContextGeneric1Method2<>).Module.FullyQualifiedName); + var module = ModuleDefinition.ReadModule (typeof (ContextGeneric1Method2<>).GetTypeInfo ().Module.FullyQualifiedName); // by mixing open generics with 2 & 1 parameters, we make sure the right context is used (because otherwise, an exception will be thrown) var type = typeof (ContextGeneric1Method2<>).MakeGenericType (typeof (ContextGeneric2Method1<,>)); - var meth = type.GetMethod ("GenericMethod"); + var meth = type.GetTypeInfo ().GetMethod ("GenericMethod"); var imported_type = module.ImportReference (type); var method = module.ImportReference (meth, imported_type); Assert.AreEqual ("G1 Mono.Cecil.Tests.ImportCecilTests/ContextGeneric1Method2`1>::GenericMethod(R1,S1)", method.FullName); // and the other way around type = typeof (ContextGeneric2Method1<,>).MakeGenericType (typeof (ContextGeneric1Method2<>), typeof (IList<>)); - meth = type.GetMethod ("GenericMethod"); + meth = type.GetTypeInfo ().GetMethod ("GenericMethod"); imported_type = module.ImportReference (type); method = module.ImportReference (meth, imported_type); Assert.AreEqual ("R2 Mono.Cecil.Tests.ImportCecilTests/ContextGeneric2Method1`2,System.Collections.Generic.IList`1>::GenericMethod(G2,H2)", method.FullName); // not sure about this one type = typeof (NestedGenericsA.NestedGenericsB.NestedGenericsC); - meth = type.GetMethod ("GenericMethod"); + meth = type.GetTypeInfo().GetMethod ("GenericMethod"); imported_type = module.ImportReference (type); method = module.ImportReference (meth, imported_type); Assert.AreEqual ("A Mono.Cecil.Tests.ImportCecilTests/NestedGenericsA`1/NestedGenericsB`1/NestedGenericsC`1::GenericMethod(B,C)", method.FullName); // We need both the method & type ! type = typeof (Generic<>).MakeGenericType (typeof (string)); - meth = type.GetMethod ("ComplexGenericMethod"); + meth = type.GetTypeInfo ().GetMethod ("ComplexGenericMethod"); imported_type = module.ImportReference (type); method = module.ImportReference (meth, imported_type); Assert.AreEqual ("Mono.Cecil.Tests.ImportCecilTests/Generic`1 Mono.Cecil.Tests.ImportCecilTests/Generic`1::ComplexGenericMethod(T,TS)", method.FullName); @@ -287,11 +287,10 @@ public void ContextGenericTest () delegate void Emitter (ModuleDefinition module, MethodBody body); - [MethodImpl (MethodImplOptions.NoInlining)] - static TDelegate Compile (Emitter emitter) + static TDelegate Compile (Emitter emitter, [CallerMemberName]string testMethodName = null) where TDelegate : class { - var name = GetTestCaseName (); + var name = "ImportCecil_" + testMethodName; var module = CreateTestModule (name, emitter); var assembly = LoadTestModule (module); @@ -302,7 +301,7 @@ static TDelegate Compile (Emitter emitter) static TDelegate CreateRunDelegate (Type type) where TDelegate : class { - return (TDelegate) (object) Delegate.CreateDelegate (typeof (TDelegate), type.GetMethod ("Run")); + return (TDelegate) (object)type.GetTypeInfo ().GetMethod ("Run").CreateDelegate (typeof (TDelegate)); } static Type GetTestCase (string name, SR.Assembly assembly) @@ -315,7 +314,7 @@ static SR.Assembly LoadTestModule (ModuleDefinition module) using (var stream = new MemoryStream ()) { module.Write (stream); File.WriteAllBytes (Path.Combine (Path.Combine (Path.GetTempPath (), "cecil"), module.Name + ".dll"), stream.ToArray ()); - return SR.Assembly.Load (stream.ToArray ()); + return Extensions.LoadAssembly (stream); } } @@ -331,7 +330,7 @@ static ModuleDefinition CreateTestModule (string name, Emitter emitte module.Types.Add (type); - var method = CreateMethod (type, typeof (TDelegate).GetMethod ("Invoke")); + var method = CreateMethod (type, typeof (TDelegate).GetTypeInfo ().GetMethod ("Invoke")); emitter (module, method.Body); @@ -362,15 +361,6 @@ static ModuleDefinition CreateModule (string name) { return ModuleDefinition.CreateModule (name, ModuleKind.Dll); } - - [MethodImpl (MethodImplOptions.NoInlining)] - static string GetTestCaseName () - { - var stack_trace = new StackTrace (); - var stack_frame = stack_trace.GetFrame (2); - - return "ImportCecil_" + stack_frame.GetMethod ().Name; - } } } #endif \ No newline at end of file diff --git a/Test/Mono.Cecil.Tests/ImportReflectionTests.cs b/Test/Mono.Cecil.Tests/ImportReflectionTests.cs index 04768615f..523550c98 100644 --- a/Test/Mono.Cecil.Tests/ImportReflectionTests.cs +++ b/Test/Mono.Cecil.Tests/ImportReflectionTests.cs @@ -101,7 +101,7 @@ public void ImportFieldStringEmpty () { var get_empty = Compile> ((module, body) => { var il = body.GetILProcessor (); - il.Emit (OpCodes.Ldsfld, module.ImportReference (typeof (string).GetField ("Empty"))); + il.Emit (OpCodes.Ldsfld, module.ImportReference (typeof (string).GetTypeInfo ().GetField ("Empty"))); il.Emit (OpCodes.Ret); }); @@ -115,7 +115,7 @@ public void ImportStringConcat () var il = body.GetILProcessor (); il.Emit (OpCodes.Ldarg_0); il.Emit (OpCodes.Ldarg_1); - il.Emit (OpCodes.Call, module.ImportReference (typeof (string).GetMethod ("Concat", new [] { typeof (string), typeof (string) }))); + il.Emit (OpCodes.Call, module.ImportReference (typeof (string).GetTypeInfo ().GetMethod ("Concat", new [] { typeof (string), typeof (string) }))); il.Emit (OpCodes.Ret); }); @@ -131,7 +131,7 @@ public void GeneratedAssemblyCulture () il.Emit (OpCodes.Ret); }); - Assert.AreEqual ("", id.Method.DeclaringType.Assembly.GetName ().CultureInfo.Name); + Assert.AreEqual ("", id.GetMethodInfo().DeclaringType.GetTypeInfo().Assembly.GetName ().GetCultureName()); } public class Generic { @@ -159,7 +159,7 @@ public void ImportGenericField () var get_field = Compile, string>> ((module, body) => { var il = body.GetILProcessor (); il.Emit (OpCodes.Ldarg_0); - il.Emit (OpCodes.Ldfld, module.ImportReference (typeof (Generic).GetField ("Field"))); + il.Emit (OpCodes.Ldfld, module.ImportReference (typeof (Generic).GetTypeInfo ().GetField ("Field"))); il.Emit (OpCodes.Ret); }); @@ -177,7 +177,7 @@ public void ImportGenericMethod () var il = body.GetILProcessor (); il.Emit (OpCodes.Ldarg_0); il.Emit (OpCodes.Ldarg_1); - il.Emit (OpCodes.Callvirt, module.ImportReference (typeof (Generic).GetMethod ("Method"))); + il.Emit (OpCodes.Callvirt, module.ImportReference (typeof (Generic).GetTypeInfo ().GetMethod ("Method"))); il.Emit (OpCodes.Ret); }); @@ -192,7 +192,7 @@ public void ImportGenericMethodSpec () il.Emit (OpCodes.Ldarg_0); il.Emit (OpCodes.Ldnull); il.Emit (OpCodes.Ldarg_1); - il.Emit (OpCodes.Callvirt, module.ImportReference (typeof (Generic).GetMethod ("GenericMethod").MakeGenericMethod (typeof (int)))); + il.Emit (OpCodes.Callvirt, module.ImportReference (typeof (Generic).GetTypeInfo ().GetMethod ("GenericMethod").MakeGenericMethod (typeof (int)))); il.Emit (OpCodes.Ret); }); @@ -207,8 +207,8 @@ public void ImportComplexGenericMethodSpec () il.Emit (OpCodes.Ldarg_0); il.Emit (OpCodes.Ldnull); il.Emit (OpCodes.Ldarg_1); - il.Emit (OpCodes.Callvirt, module.ImportReference (typeof (Generic).GetMethod ("ComplexGenericMethod").MakeGenericMethod (typeof (int)))); - il.Emit (OpCodes.Ldfld, module.ImportReference (typeof (Generic).GetField ("Field"))); + il.Emit (OpCodes.Callvirt, module.ImportReference (typeof (Generic).GetTypeInfo ().GetMethod ("ComplexGenericMethod").MakeGenericMethod (typeof (int)))); + il.Emit (OpCodes.Ldfld, module.ImportReference (typeof (Generic).GetTypeInfo ().GetField ("Field"))); il.Emit (OpCodes.Ret); }); @@ -234,7 +234,7 @@ public void ImportGenericTypeDefOrOpen () [Test] public void ImportGenericTypeFromContext () { - var list_foo = typeof (Foo<>).GetField ("list").FieldType; + var list_foo = typeof (Foo<>).GetTypeInfo ().GetField ("list").FieldType; var generic_list_foo_open = typeof (Generic<>).MakeGenericType (list_foo); var foo_def = typeof (Foo<>).ToDefinition (); @@ -279,9 +279,9 @@ public void ImportArrayTypeDefFromContext () [Test] public void ImportGenericFieldFromContext () { - var list_foo = typeof (Foo<>).GetField ("list").FieldType; + var list_foo = typeof (Foo<>).GetTypeInfo ().GetField ("list").FieldType; var generic_list_foo_open = typeof (Generic<>).MakeGenericType (list_foo); - var generic_list_foo_open_field = generic_list_foo_open.GetField ("Field"); + var generic_list_foo_open_field = generic_list_foo_open.GetTypeInfo ().GetField ("Field"); var foo_def = typeof (Foo<>).ToDefinition (); using (var module = foo_def.Module) { @@ -295,9 +295,9 @@ public void ImportGenericFieldFromContext () [Test] public void ImportGenericMethodFromContext () { - var list_foo = typeof (Foo<>).GetField ("list").FieldType; + var list_foo = typeof (Foo<>).GetTypeInfo ().GetField ("list").FieldType; var generic_list_foo_open = typeof (Generic<>).MakeGenericType (list_foo); - var generic_list_foo_open_method = generic_list_foo_open.GetMethod ("Method"); + var generic_list_foo_open_method = generic_list_foo_open.GetTypeInfo ().GetMethod ("Method"); var foo_def = typeof (Foo<>).ToDefinition (); using (var module = foo_def.Module) { @@ -312,7 +312,7 @@ public void ImportGenericMethodFromContext () public void ImportMethodOnOpenGenericType () { using (var module = typeof (Generic<>).ToDefinition ().Module) { - var method = module.ImportReference (typeof (Generic<>).GetMethod ("Method")); + var method = module.ImportReference (typeof (Generic<>).GetTypeInfo ().GetMethod ("Method")); Assert.AreEqual ("T Mono.Cecil.Tests.ImportReflectionTests/Generic`1::Method(T)", method.FullName); } @@ -322,11 +322,11 @@ public void ImportMethodOnOpenGenericType () public void ImportGenericMethodOnOpenGenericType () { using (var module = typeof (Generic<>).ToDefinition ().Module) { - var generic_method = module.ImportReference (typeof (Generic<>).GetMethod ("GenericMethod")); + var generic_method = module.ImportReference (typeof (Generic<>).GetTypeInfo ().GetMethod ("GenericMethod")); Assert.AreEqual ("TS Mono.Cecil.Tests.ImportReflectionTests/Generic`1::GenericMethod(T,TS)", generic_method.FullName); - generic_method = module.ImportReference (typeof (Generic<>).GetMethod ("GenericMethod"), generic_method); + generic_method = module.ImportReference (typeof (Generic<>).GetTypeInfo ().GetMethod ("GenericMethod"), generic_method); Assert.AreEqual ("TS Mono.Cecil.Tests.ImportReflectionTests/Generic`1::GenericMethod(T,TS)", generic_method.FullName); } @@ -334,11 +334,10 @@ public void ImportGenericMethodOnOpenGenericType () delegate void Emitter (ModuleDefinition module, MethodBody body); - [MethodImpl (MethodImplOptions.NoInlining)] - static TDelegate Compile (Emitter emitter) + static TDelegate Compile (Emitter emitter, [CallerMemberName] string testMethodName = null) where TDelegate : class { - var name = GetTestCaseName (); + var name = "ImportReflection_" + testMethodName; var module = CreateTestModule (name, emitter); var assembly = LoadTestModule (module); @@ -349,7 +348,7 @@ static TDelegate Compile (Emitter emitter) static TDelegate CreateRunDelegate (Type type) where TDelegate : class { - return (TDelegate) (object) Delegate.CreateDelegate (typeof (TDelegate), type.GetMethod ("Run")); + return (TDelegate) (object) type.GetTypeInfo().GetMethod ("Run").CreateDelegate(typeof (TDelegate)); } static Type GetTestCase (string name, SR.Assembly assembly) @@ -362,7 +361,7 @@ static SR.Assembly LoadTestModule (ModuleDefinition module) using (var stream = new MemoryStream ()) { module.Write (stream); File.WriteAllBytes (Path.Combine (Path.Combine (Path.GetTempPath (), "cecil"), module.Name + ".dll"), stream.ToArray ()); - return SR.Assembly.Load (stream.ToArray ()); + return Extensions.LoadAssembly (stream); } } @@ -378,7 +377,7 @@ static ModuleDefinition CreateTestModule (string name, Emitter emitte module.Types.Add (type); - var method = CreateMethod (type, typeof (TDelegate).GetMethod ("Invoke")); + var method = CreateMethod (type, typeof (TDelegate).GetTypeInfo ().GetMethod ("Invoke")); emitter (module, method.Body); @@ -409,15 +408,6 @@ static ModuleDefinition CreateModule (string name) { return ModuleDefinition.CreateModule (name, ModuleKind.Dll); } - - [MethodImpl (MethodImplOptions.NoInlining)] - static string GetTestCaseName () - { - var stack_trace = new StackTrace (); - var stack_frame = stack_trace.GetFrame (2); - - return "ImportReflection_" + stack_frame.GetMethod ().Name; - } } } -#endif \ No newline at end of file +#endif diff --git a/Test/Mono.Cecil.Tests/ModuleTests.cs b/Test/Mono.Cecil.Tests/ModuleTests.cs index 476b8ffbe..54613b6f4 100644 --- a/Test/Mono.Cecil.Tests/ModuleTests.cs +++ b/Test/Mono.Cecil.Tests/ModuleTests.cs @@ -234,10 +234,9 @@ public void MixedModeModule () } [Test] - [ExpectedException (typeof (BadImageFormatException))] public void OpenIrrelevantFile () { - GetResourceModule ("text_file.txt"); + Assert.Throws (() => GetResourceModule ("text_file.txt")); } [Test] @@ -268,12 +267,13 @@ public void OpenModuleDeferred () [Test] public void OwnedStreamModuleFileName () { - var path = GetAssemblyResourcePath ("hello.exe", GetType ().Assembly); + var path = GetAssemblyResourcePath ("hello.exe", GetType ().GetTypeInfo().Assembly); using (var file = File.Open (path, FileMode.Open)) { using (var module = ModuleDefinition.ReadModule (file)) { - Assert.IsNotNullOrEmpty (module.FileName); + Assert.IsNotNull (module.FileName); + Assert.IsNotEmpty (module.FileName); Assert.AreEqual (path, module.FileName); } } diff --git a/Test/Mono.Cecil.Tests/ResolveTests.cs b/Test/Mono.Cecil.Tests/ResolveTests.cs index aab7d0cf5..b4ea57f9d 100644 --- a/Test/Mono.Cecil.Tests/ResolveTests.cs +++ b/Test/Mono.Cecil.Tests/ResolveTests.cs @@ -2,7 +2,6 @@ using System.Collections.Generic; using System.IO; using System.Linq; - using Mono.Cecil; using Mono.Cecil.Cil; @@ -129,7 +128,7 @@ public void TypeForwarder () var parameters = new ReaderParameters { AssemblyResolver = resolver }; var types = ModuleDefinition.ReadModule ( - CompilationService.CompileResource (GetCSharpResourcePath ("CustomAttributes.cs", typeof (ResolveTests).Assembly)), + CompilationService.CompileResource (GetCSharpResourcePath ("CustomAttributes.cs", typeof (ResolveTests).GetTypeInfo ().Assembly)), parameters); resolver.Register (types.Assembly); @@ -150,7 +149,7 @@ public void NestedTypeForwarder () var parameters = new ReaderParameters { AssemblyResolver = resolver }; var types = ModuleDefinition.ReadModule ( - CompilationService.CompileResource (GetCSharpResourcePath ("CustomAttributes.cs", typeof (ResolveTests).Assembly)), + CompilationService.CompileResource (GetCSharpResourcePath ("CustomAttributes.cs", typeof (ResolveTests).GetTypeInfo ().Assembly)), parameters); resolver.Register (types.Assembly); @@ -223,7 +222,7 @@ public void ResolvePortableClassLibraryReference () Assert.IsTrue (reference.IsRetargetable); var assembly = resolver.Resolve (reference); Assert.IsNotNull (assembly); - Assert.AreEqual (typeof (object).Assembly.GetName ().Version, assembly.Name.Version); + Assert.AreEqual (typeof (object).GetTypeInfo ().Assembly.GetName ().Version, assembly.Name.Version); } } @@ -267,7 +266,7 @@ static object GetReturnee (MethodDefinition method) MethodDefinition GetMethodFromDelegate (Delegate @delegate) { - var method = @delegate.Method; + var method = @delegate.GetMethodInfo(); var type = (TypeDefinition) TypeParser.ParseType (GetCurrentModule (), method.DeclaringType.FullName); Assert.IsNotNull (type); diff --git a/Test/Mono.Cecil.Tests/SecurityDeclarationTests.cs b/Test/Mono.Cecil.Tests/SecurityDeclarationTests.cs index 3b59e6f78..5c13ccd9c 100644 --- a/Test/Mono.Cecil.Tests/SecurityDeclarationTests.cs +++ b/Test/Mono.Cecil.Tests/SecurityDeclarationTests.cs @@ -248,14 +248,12 @@ static void PrettyPrintValue (object value, StringBuilder signature) return; } - switch (Type.GetTypeCode (value.GetType ())) { - case TypeCode.String: - signature.AppendFormat ("\"{0}\"", value); - break; - case TypeCode.Char: - signature.AppendFormat ("'{0}'", (char) value); - break; - default: + string str; + if ((str = value as string) != null) { + signature.AppendFormat("\"{0}\"", str); + } else if (value is char) { + signature.AppendFormat ("'{0}'", (char)value); + } else { var formattable = value as IFormattable; if (formattable != null) { signature.Append (formattable.ToString (null, CultureInfo.InvariantCulture)); @@ -266,7 +264,6 @@ static void PrettyPrintValue (object value, StringBuilder signature) PrettyPrint ((CustomAttributeArgument) value, signature); return; } - break; } } diff --git a/Test/Mono.Cecil.Tests/TypeParserTests.cs b/Test/Mono.Cecil.Tests/TypeParserTests.cs index 603b7f4d5..51ea6215e 100644 --- a/Test/Mono.Cecil.Tests/TypeParserTests.cs +++ b/Test/Mono.Cecil.Tests/TypeParserTests.cs @@ -236,7 +236,7 @@ public void GenericInstanceExternArguments () var module = GetCurrentModule (); var fullname = string.Format ("System.Collections.Generic.Dictionary`2[[System.Int32, {0}],[System.String, {0}]]", - typeof (object).Assembly.FullName); + typeof (object).GetTypeInfo ().Assembly.FullName); var type = TypeParser.ParseType (module, fullname); @@ -273,7 +273,7 @@ public void GenericInstanceMixedArguments () var module = GetCurrentModule (); var fullname = string.Format ("System.Collections.Generic.Dictionary`2[Mono.Cecil.Tests.TypeParserTests,[System.String, {0}]]", - typeof (object).Assembly.FullName); + typeof (object).GetTypeInfo ().Assembly.FullName); var type = TypeParser.ParseType (module, fullname); @@ -312,7 +312,7 @@ public void GenericInstanceTwoNonFqArguments () { var module = GetCurrentModule (); - var fullname = string.Format ("System.Collections.Generic.Dictionary`2[Mono.Cecil.Tests.TypeParserTests+Bar,Mono.Cecil.Tests.TypeParserTests+Bar], {0}", typeof (object).Assembly.FullName); + var fullname = string.Format ("System.Collections.Generic.Dictionary`2[Mono.Cecil.Tests.TypeParserTests+Bar,Mono.Cecil.Tests.TypeParserTests+Bar], {0}", typeof (object).GetTypeInfo ().Assembly.FullName); var type = TypeParser.ParseType (module, fullname); @@ -347,7 +347,7 @@ public void ComplexGenericInstanceMixedArguments () var module = GetCurrentModule (); var fullname = string.Format ("System.Collections.Generic.Dictionary`2[[System.String, {0}],Mono.Cecil.Tests.TypeParserTests+Foo`2[Mono.Cecil.Tests.TypeParserTests,[System.Int32, {0}]]]", - typeof (object).Assembly.FullName); + typeof (object).GetTypeInfo ().Assembly.FullName); var type = TypeParser.ParseType (module, fullname); diff --git a/Test/Mono.Cecil.Tests/TypeTests.cs b/Test/Mono.Cecil.Tests/TypeTests.cs index d37804209..9ac4ba135 100644 --- a/Test/Mono.Cecil.Tests/TypeTests.cs +++ b/Test/Mono.Cecil.Tests/TypeTests.cs @@ -255,7 +255,7 @@ public void ExplicitThis () [Test] public void DeferredCorlibTypeDef () { - using (var module = ModuleDefinition.ReadModule (typeof (object).Assembly.Location, new ReaderParameters (ReadingMode.Deferred))) { + using (var module = ModuleDefinition.ReadModule (typeof (object).GetTypeInfo ().Assembly.Location, new ReaderParameters (ReadingMode.Deferred))) { var object_type = module.TypeSystem.Object; Assert.IsInstanceOf (object_type); } @@ -264,7 +264,7 @@ public void DeferredCorlibTypeDef () [Test] public void CorlibTypesMetadataType () { - using (var module = ModuleDefinition.ReadModule (typeof (object).Assembly.Location)) { + using (var module = ModuleDefinition.ReadModule (typeof (object).GetTypeInfo ().Assembly.Location)) { var type = module.GetType ("System.String"); Assert.IsNotNull (type); Assert.IsNotNull (type.BaseType); diff --git a/Test/Mono.Cecil.Tests/WindowsRuntimeAssemblyResolver.cs b/Test/Mono.Cecil.Tests/WindowsRuntimeAssemblyResolver.cs index 1e3a90bb7..fb39e3342 100644 --- a/Test/Mono.Cecil.Tests/WindowsRuntimeAssemblyResolver.cs +++ b/Test/Mono.Cecil.Tests/WindowsRuntimeAssemblyResolver.cs @@ -1,4 +1,6 @@ -using System; +#if !NET_CORE + +using System; using System.Collections.Generic; using System.IO; using Microsoft.Win32; @@ -91,3 +93,4 @@ void LoadWindowsSdk (string registryVersion, string windowsKitsVersion, Action Date: Thu, 15 Jun 2017 15:09:53 -0700 Subject: [PATCH 2/4] Add Mono.Cecil.WindowsPdb --- .gitignore | 1 + Mono.Cecil.Cil/PortablePdb.cs | 13 +- Mono.Cecil.Cil/Symbols.cs | 22 + Mono.Cecil.Windows.nuspec | 37 ++ Mono.Cecil.props | 4 +- Mono.Cecil.sln | 53 +- Mono.Cecil/AssemblyInfo.cs | 1 + NuGet.Config | 10 + symbols/pdb.windows/AssemblyInfo.cs | 8 + symbols/pdb.windows/ModuleMetadata.cs | 101 ++++ .../pdb.windows/Mono.Cecil.WindowsPdb.csproj | 26 + symbols/pdb.windows/NativePdbReader.cs | 41 ++ symbols/pdb.windows/NativePdbWriter.cs | 403 ++++++++++++++++ symbols/pdb.windows/PdbHelper.cs | 114 +++++ symbols/pdb.windows/ProjectInfo.cs | 13 + .../Test/Mono.Cecil.Tests/WindowsPdbTests.cs | 456 ++++++++++++++++++ .../Test/Mono.Cecil.WindowsPdb.Tests.csproj | 22 + 17 files changed, 1301 insertions(+), 24 deletions(-) create mode 100644 Mono.Cecil.Windows.nuspec create mode 100644 NuGet.Config create mode 100644 symbols/pdb.windows/AssemblyInfo.cs create mode 100644 symbols/pdb.windows/ModuleMetadata.cs create mode 100644 symbols/pdb.windows/Mono.Cecil.WindowsPdb.csproj create mode 100644 symbols/pdb.windows/NativePdbReader.cs create mode 100644 symbols/pdb.windows/NativePdbWriter.cs create mode 100644 symbols/pdb.windows/PdbHelper.cs create mode 100644 symbols/pdb.windows/ProjectInfo.cs create mode 100644 symbols/pdb.windows/Test/Mono.Cecil.Tests/WindowsPdbTests.cs create mode 100644 symbols/pdb.windows/Test/Mono.Cecil.WindowsPdb.Tests.csproj diff --git a/.gitignore b/.gitignore index 08c8509f5..187dfc831 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ bin obj +packages *.suo *.iml *.user diff --git a/Mono.Cecil.Cil/PortablePdb.cs b/Mono.Cecil.Cil/PortablePdb.cs index 717249e90..c9ff26ad9 100644 --- a/Mono.Cecil.Cil/PortablePdb.cs +++ b/Mono.Cecil.Cil/PortablePdb.cs @@ -311,23 +311,12 @@ public ImageDebugHeader GetDebugHeader () TimeDateStamp = (int) module.timestamp, }; - var buffer = new ByteBuffer (); - // RSDS - buffer.WriteUInt32 (0x53445352); - // Module ID - buffer.WriteBytes (module.Mvid.ToByteArray ()); - // PDB Age - buffer.WriteUInt32 (1); - // PDB Path var filename = writer.BaseStream.GetFileName (); if (!string.IsNullOrEmpty (filename)) filename = Path.GetFileName (filename); - buffer.WriteBytes (System.Text.Encoding.UTF8.GetBytes (filename)); - buffer.WriteByte (0); + var data = Mixin.GetCodeViewData (module.Mvid, filename, age: 1); - var data = new byte [buffer.length]; - Buffer.BlockCopy (buffer.buffer, 0, data, 0, buffer.length); directory.SizeOfData = data.Length; return new ImageDebugHeader (new ImageDebugHeaderEntry (directory, data)); diff --git a/Mono.Cecil.Cil/Symbols.cs b/Mono.Cecil.Cil/Symbols.cs index 6ef5ad2a6..df315042c 100644 --- a/Mono.Cecil.Cil/Symbols.cs +++ b/Mono.Cecil.Cil/Symbols.cs @@ -16,6 +16,7 @@ using Mono.Collections.Generic; using Mono.Cecil.Cil; +using Mono.Cecil.PE; namespace Mono.Cecil.Cil { @@ -939,6 +940,27 @@ public static ImageDebugHeaderEntry GetCodeViewEntry (this ImageDebugHeader head return GetEntry (header, ImageDebugType.CodeView); } +#if !READ_ONLY + + public static byte[] GetCodeViewData (Guid pdb_id, string pdb_path, int age) + { + var buffer = new ByteBuffer (); + // RSDS + buffer.WriteUInt32 (0x53445352); + // Module ID + buffer.WriteBytes (pdb_id.ToByteArray ()); + // PDB Age + buffer.WriteInt32 (age); + // PDB Path + buffer.WriteBytes (System.Text.Encoding.UTF8.GetBytes (pdb_path)); + buffer.WriteByte (0); + + var data = new byte[buffer.length]; + Buffer.BlockCopy (buffer.buffer, 0, data, 0, buffer.length); + return data; + } +#endif + public static ImageDebugHeaderEntry GetDeterministicEntry (this ImageDebugHeader header) { return GetEntry (header, ImageDebugType.Deterministic); diff --git a/Mono.Cecil.Windows.nuspec b/Mono.Cecil.Windows.nuspec new file mode 100644 index 000000000..a7bf482d4 --- /dev/null +++ b/Mono.Cecil.Windows.nuspec @@ -0,0 +1,37 @@ + + + + Mono.Cecil.Windows + 0.10.0.0-beta6 + Mono.Cecil.Windows + Jb Evain, Microsoft + Jb Evain + http://opensource.org/licenses/mit-license.php + false + http://github.com/jbevain/cecil/ + Adds full Windows PDB support to Mono.Cecil + Cecil is a library written by Jb Evain to generate and inspect programs and libraries in the ECMA CIL format. It has full support for generics, and support some debugging symbol format. In simple English, with Cecil, you can load existing managed assemblies, browse all the contained types, modify them on the fly and save back to the disk the modified assembly. + en-US + assembly assemblies module modules il cil msil bytecode reflection injection cecil mono aop + + + + + + + + + + + + + + + + + + + + + + diff --git a/Mono.Cecil.props b/Mono.Cecil.props index c04324c70..91399b993 100644 --- a/Mono.Cecil.props +++ b/Mono.Cecil.props @@ -46,9 +46,9 @@ netstandard1.5 netstandard1.3 - + - + diff --git a/Mono.Cecil.sln b/Mono.Cecil.sln index beaa28cbf..7e159a782 100644 --- a/Mono.Cecil.sln +++ b/Mono.Cecil.sln @@ -1,6 +1,6 @@ Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 14 -VisualStudioVersion = 14.0.25420.1 +# Visual Studio 15 +VisualStudioVersion = 15.0.26612.0 MinimumVisualStudioVersion = 10.0.40219.1 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{74E5ECE0-06B4-401C-AEBA-E8DD53E17943}" EndProject @@ -22,6 +22,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Mono.Cecil.Rocks.Tests", "r EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Mono.Cecil.Rocks", "rocks\Mono.Cecil.Rocks.csproj", "{FBC6DD59-D09D-499C-B03C-99C1C78FF2AC}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Mono.Cecil.WindowsPdb", "symbols\pdb.windows\Mono.Cecil.WindowsPdb.csproj", "{1A7F5B01-F15F-4943-8AF5-CB736C60B1BE}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Mono.Cecil.WindowsPdb.Tests", "symbols\pdb.windows\Test\Mono.Cecil.WindowsPdb.Tests.csproj", "{77E8A7D2-4DC4-43E1-94FF-002B33FF2397}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution net_3_5_Debug_ReadOnly|Any CPU = net_3_5_Debug_ReadOnly|Any CPU @@ -79,11 +83,9 @@ Global {A47B1F49-A81A-43E8-BE6B-DD28AF2C4055}.net_4_0_Release|Any CPU.ActiveCfg = net_4_0_Release|Any CPU {A47B1F49-A81A-43E8-BE6B-DD28AF2C4055}.net_4_0_Release|Any CPU.Build.0 = net_4_0_Release|Any CPU {A47B1F49-A81A-43E8-BE6B-DD28AF2C4055}.netstandard_Debug_ReadOnly|Any CPU.ActiveCfg = netstandard_Debug_ReadOnly|Any CPU - {A47B1F49-A81A-43E8-BE6B-DD28AF2C4055}.netstandard_Debug_ReadOnly|Any CPU.Build.0 = netstandard_Debug_ReadOnly|Any CPU {A47B1F49-A81A-43E8-BE6B-DD28AF2C4055}.netstandard_Debug|Any CPU.ActiveCfg = netstandard_Debug|Any CPU {A47B1F49-A81A-43E8-BE6B-DD28AF2C4055}.netstandard_Debug|Any CPU.Build.0 = netstandard_Debug|Any CPU {A47B1F49-A81A-43E8-BE6B-DD28AF2C4055}.netstandard_Release_ReadOnly|Any CPU.ActiveCfg = netstandard_Release_ReadOnly|Any CPU - {A47B1F49-A81A-43E8-BE6B-DD28AF2C4055}.netstandard_Release_ReadOnly|Any CPU.Build.0 = netstandard_Release_ReadOnly|Any CPU {A47B1F49-A81A-43E8-BE6B-DD28AF2C4055}.netstandard_Release|Any CPU.ActiveCfg = netstandard_Release|Any CPU {8559DD7F-A16F-46D0-A05A-9139FAEBA8FD}.net_3_5_Debug_ReadOnly|Any CPU.ActiveCfg = net_3_5_Debug_ReadOnly|Any CPU {8559DD7F-A16F-46D0-A05A-9139FAEBA8FD}.net_3_5_Debug_ReadOnly|Any CPU.Build.0 = net_3_5_Debug_ReadOnly|Any CPU @@ -126,10 +128,8 @@ Global {AC71DF9C-99FA-4A63-990A-66C8010355A6}.net_4_0_Release|Any CPU.ActiveCfg = net_4_0_Release|Any CPU {AC71DF9C-99FA-4A63-990A-66C8010355A6}.net_4_0_Release|Any CPU.Build.0 = net_4_0_Release|Any CPU {AC71DF9C-99FA-4A63-990A-66C8010355A6}.netstandard_Debug_ReadOnly|Any CPU.ActiveCfg = netstandard_Debug_ReadOnly|Any CPU - {AC71DF9C-99FA-4A63-990A-66C8010355A6}.netstandard_Debug_ReadOnly|Any CPU.Build.0 = netstandard_Debug_ReadOnly|Any CPU {AC71DF9C-99FA-4A63-990A-66C8010355A6}.netstandard_Debug|Any CPU.ActiveCfg = netstandard_Debug|Any CPU {AC71DF9C-99FA-4A63-990A-66C8010355A6}.netstandard_Release_ReadOnly|Any CPU.ActiveCfg = netstandard_Release_ReadOnly|Any CPU - {AC71DF9C-99FA-4A63-990A-66C8010355A6}.netstandard_Release_ReadOnly|Any CPU.Build.0 = netstandard_Release_ReadOnly|Any CPU {AC71DF9C-99FA-4A63-990A-66C8010355A6}.netstandard_Release|Any CPU.ActiveCfg = netstandard_Release|Any CPU {63E6915C-7EA4-4D76-AB28-0D7191EEA626}.net_3_5_Debug_ReadOnly|Any CPU.ActiveCfg = net_3_5_Debug_ReadOnly|Any CPU {63E6915C-7EA4-4D76-AB28-0D7191EEA626}.net_3_5_Debug_ReadOnly|Any CPU.Build.0 = net_3_5_Debug_ReadOnly|Any CPU @@ -172,10 +172,8 @@ Global {29300103-CB76-4A1D-B6FD-FFD91C1EC8AA}.net_4_0_Release|Any CPU.ActiveCfg = net_4_0_Release|Any CPU {29300103-CB76-4A1D-B6FD-FFD91C1EC8AA}.net_4_0_Release|Any CPU.Build.0 = net_4_0_Release|Any CPU {29300103-CB76-4A1D-B6FD-FFD91C1EC8AA}.netstandard_Debug_ReadOnly|Any CPU.ActiveCfg = netstandard_Debug_ReadOnly|Any CPU - {29300103-CB76-4A1D-B6FD-FFD91C1EC8AA}.netstandard_Debug_ReadOnly|Any CPU.Build.0 = netstandard_Debug_ReadOnly|Any CPU {29300103-CB76-4A1D-B6FD-FFD91C1EC8AA}.netstandard_Debug|Any CPU.ActiveCfg = netstandard_Debug|Any CPU {29300103-CB76-4A1D-B6FD-FFD91C1EC8AA}.netstandard_Release_ReadOnly|Any CPU.ActiveCfg = netstandard_Release_ReadOnly|Any CPU - {29300103-CB76-4A1D-B6FD-FFD91C1EC8AA}.netstandard_Release_ReadOnly|Any CPU.Build.0 = netstandard_Release_ReadOnly|Any CPU {29300103-CB76-4A1D-B6FD-FFD91C1EC8AA}.netstandard_Release|Any CPU.ActiveCfg = netstandard_Release|Any CPU {C6CFD7E1-B855-44DC-B4CE-9CD72984AF52}.net_3_5_Debug_ReadOnly|Any CPU.ActiveCfg = net_3_5_Debug_ReadOnly|Any CPU {C6CFD7E1-B855-44DC-B4CE-9CD72984AF52}.net_3_5_Debug_ReadOnly|Any CPU.Build.0 = net_3_5_Debug_ReadOnly|Any CPU @@ -194,10 +192,8 @@ Global {C6CFD7E1-B855-44DC-B4CE-9CD72984AF52}.net_4_0_Release|Any CPU.ActiveCfg = net_4_0_Release|Any CPU {C6CFD7E1-B855-44DC-B4CE-9CD72984AF52}.net_4_0_Release|Any CPU.Build.0 = net_4_0_Release|Any CPU {C6CFD7E1-B855-44DC-B4CE-9CD72984AF52}.netstandard_Debug_ReadOnly|Any CPU.ActiveCfg = netstandard_Debug_ReadOnly|Any CPU - {C6CFD7E1-B855-44DC-B4CE-9CD72984AF52}.netstandard_Debug_ReadOnly|Any CPU.Build.0 = netstandard_Debug_ReadOnly|Any CPU {C6CFD7E1-B855-44DC-B4CE-9CD72984AF52}.netstandard_Debug|Any CPU.ActiveCfg = netstandard_Debug|Any CPU {C6CFD7E1-B855-44DC-B4CE-9CD72984AF52}.netstandard_Release_ReadOnly|Any CPU.ActiveCfg = netstandard_Release_ReadOnly|Any CPU - {C6CFD7E1-B855-44DC-B4CE-9CD72984AF52}.netstandard_Release_ReadOnly|Any CPU.Build.0 = netstandard_Release_ReadOnly|Any CPU {C6CFD7E1-B855-44DC-B4CE-9CD72984AF52}.netstandard_Release|Any CPU.ActiveCfg = netstandard_Release|Any CPU {FBC6DD59-D09D-499C-B03C-99C1C78FF2AC}.net_3_5_Debug_ReadOnly|Any CPU.ActiveCfg = net_3_5_Debug_ReadOnly|Any CPU {FBC6DD59-D09D-499C-B03C-99C1C78FF2AC}.net_3_5_Debug_ReadOnly|Any CPU.Build.0 = net_3_5_Debug_ReadOnly|Any CPU @@ -223,6 +219,38 @@ Global {FBC6DD59-D09D-499C-B03C-99C1C78FF2AC}.netstandard_Release_ReadOnly|Any CPU.Build.0 = netstandard_Release_ReadOnly|Any CPU {FBC6DD59-D09D-499C-B03C-99C1C78FF2AC}.netstandard_Release|Any CPU.ActiveCfg = netstandard_Release|Any CPU {FBC6DD59-D09D-499C-B03C-99C1C78FF2AC}.netstandard_Release|Any CPU.Build.0 = netstandard_Release|Any CPU + {1A7F5B01-F15F-4943-8AF5-CB736C60B1BE}.net_3_5_Debug_ReadOnly|Any CPU.ActiveCfg = net_3_5_Debug_ReadOnly|Any CPU + {1A7F5B01-F15F-4943-8AF5-CB736C60B1BE}.net_3_5_Debug|Any CPU.ActiveCfg = net_3_5_Debug|Any CPU + {1A7F5B01-F15F-4943-8AF5-CB736C60B1BE}.net_3_5_Release_ReadOnly|Any CPU.ActiveCfg = net_3_5_Release_ReadOnly|Any CPU + {1A7F5B01-F15F-4943-8AF5-CB736C60B1BE}.net_3_5_Release|Any CPU.ActiveCfg = net_3_5_Release|Any CPU + {1A7F5B01-F15F-4943-8AF5-CB736C60B1BE}.net_4_0_Debug_ReadOnly|Any CPU.ActiveCfg = net_4_0_Debug_ReadOnly|Any CPU + {1A7F5B01-F15F-4943-8AF5-CB736C60B1BE}.net_4_0_Debug|Any CPU.ActiveCfg = net_4_0_Debug|Any CPU + {1A7F5B01-F15F-4943-8AF5-CB736C60B1BE}.net_4_0_Release_ReadOnly|Any CPU.ActiveCfg = net_4_0_Release_ReadOnly|Any CPU + {1A7F5B01-F15F-4943-8AF5-CB736C60B1BE}.net_4_0_Release|Any CPU.ActiveCfg = net_4_0_Release|Any CPU + {1A7F5B01-F15F-4943-8AF5-CB736C60B1BE}.netstandard_Debug_ReadOnly|Any CPU.ActiveCfg = netstandard_Debug_ReadOnly|Any CPU + {1A7F5B01-F15F-4943-8AF5-CB736C60B1BE}.netstandard_Debug_ReadOnly|Any CPU.Build.0 = netstandard_Debug_ReadOnly|Any CPU + {1A7F5B01-F15F-4943-8AF5-CB736C60B1BE}.netstandard_Debug|Any CPU.ActiveCfg = netstandard_Debug|Any CPU + {1A7F5B01-F15F-4943-8AF5-CB736C60B1BE}.netstandard_Debug|Any CPU.Build.0 = netstandard_Debug|Any CPU + {1A7F5B01-F15F-4943-8AF5-CB736C60B1BE}.netstandard_Release_ReadOnly|Any CPU.ActiveCfg = netstandard_Release_ReadOnly|Any CPU + {1A7F5B01-F15F-4943-8AF5-CB736C60B1BE}.netstandard_Release_ReadOnly|Any CPU.Build.0 = netstandard_Release_ReadOnly|Any CPU + {1A7F5B01-F15F-4943-8AF5-CB736C60B1BE}.netstandard_Release|Any CPU.ActiveCfg = netstandard_Release|Any CPU + {1A7F5B01-F15F-4943-8AF5-CB736C60B1BE}.netstandard_Release|Any CPU.Build.0 = netstandard_Release|Any CPU + {77E8A7D2-4DC4-43E1-94FF-002B33FF2397}.net_3_5_Debug_ReadOnly|Any CPU.ActiveCfg = net_3_5_Debug_ReadOnly|Any CPU + {77E8A7D2-4DC4-43E1-94FF-002B33FF2397}.net_3_5_Debug|Any CPU.ActiveCfg = net_3_5_Debug|Any CPU + {77E8A7D2-4DC4-43E1-94FF-002B33FF2397}.net_3_5_Release_ReadOnly|Any CPU.ActiveCfg = net_3_5_Release_ReadOnly|Any CPU + {77E8A7D2-4DC4-43E1-94FF-002B33FF2397}.net_3_5_Release|Any CPU.ActiveCfg = net_3_5_Release|Any CPU + {77E8A7D2-4DC4-43E1-94FF-002B33FF2397}.net_4_0_Debug_ReadOnly|Any CPU.ActiveCfg = net_4_0_Debug_ReadOnly|Any CPU + {77E8A7D2-4DC4-43E1-94FF-002B33FF2397}.net_4_0_Debug|Any CPU.ActiveCfg = net_4_0_Debug|Any CPU + {77E8A7D2-4DC4-43E1-94FF-002B33FF2397}.net_4_0_Release_ReadOnly|Any CPU.ActiveCfg = net_4_0_Release_ReadOnly|Any CPU + {77E8A7D2-4DC4-43E1-94FF-002B33FF2397}.net_4_0_Release|Any CPU.ActiveCfg = net_4_0_Release|Any CPU + {77E8A7D2-4DC4-43E1-94FF-002B33FF2397}.netstandard_Debug_ReadOnly|Any CPU.ActiveCfg = netstandard_Debug_ReadOnly|Any CPU + {77E8A7D2-4DC4-43E1-94FF-002B33FF2397}.netstandard_Debug_ReadOnly|Any CPU.Build.0 = netstandard_Debug_ReadOnly|Any CPU + {77E8A7D2-4DC4-43E1-94FF-002B33FF2397}.netstandard_Debug|Any CPU.ActiveCfg = netstandard_Debug|Any CPU + {77E8A7D2-4DC4-43E1-94FF-002B33FF2397}.netstandard_Debug|Any CPU.Build.0 = netstandard_Debug|Any CPU + {77E8A7D2-4DC4-43E1-94FF-002B33FF2397}.netstandard_Release_ReadOnly|Any CPU.ActiveCfg = netstandard_Release_ReadOnly|Any CPU + {77E8A7D2-4DC4-43E1-94FF-002B33FF2397}.netstandard_Release_ReadOnly|Any CPU.Build.0 = netstandard_Release_ReadOnly|Any CPU + {77E8A7D2-4DC4-43E1-94FF-002B33FF2397}.netstandard_Release|Any CPU.ActiveCfg = netstandard_Release|Any CPU + {77E8A7D2-4DC4-43E1-94FF-002B33FF2397}.netstandard_Release|Any CPU.Build.0 = netstandard_Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -234,5 +262,10 @@ Global {63E6915C-7EA4-4D76-AB28-0D7191EEA626} = {929D5B3B-E29A-40CC-93D8-0FF43A6F9FA1} {29300103-CB76-4A1D-B6FD-FFD91C1EC8AA} = {74E5ECE0-06B4-401C-AEBA-E8DD53E17943} {C6CFD7E1-B855-44DC-B4CE-9CD72984AF52} = {74E5ECE0-06B4-401C-AEBA-E8DD53E17943} + {1A7F5B01-F15F-4943-8AF5-CB736C60B1BE} = {929D5B3B-E29A-40CC-93D8-0FF43A6F9FA1} + {77E8A7D2-4DC4-43E1-94FF-002B33FF2397} = {74E5ECE0-06B4-401C-AEBA-E8DD53E17943} + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {9F99F5B5-3BEF-4AC3-8E6A-94BA9CFA9381} EndGlobalSection EndGlobal diff --git a/Mono.Cecil/AssemblyInfo.cs b/Mono.Cecil/AssemblyInfo.cs index 5571093b6..5cc8fa682 100644 --- a/Mono.Cecil/AssemblyInfo.cs +++ b/Mono.Cecil/AssemblyInfo.cs @@ -18,6 +18,7 @@ [assembly: Guid ("fd225bb4-fa53-44b2-a6db-85f5e48dcb54")] #endif +[assembly: InternalsVisibleTo ("Mono.Cecil.WindowsPdb, PublicKey=" + Consts.PublicKey)] [assembly: InternalsVisibleTo ("Mono.Cecil.Pdb, PublicKey=" + Consts.PublicKey)] [assembly: InternalsVisibleTo ("Mono.Cecil.Mdb, PublicKey=" + Consts.PublicKey)] [assembly: InternalsVisibleTo ("Mono.Cecil.Rocks, PublicKey=" + Consts.PublicKey)] diff --git a/NuGet.Config b/NuGet.Config new file mode 100644 index 000000000..369acdc0c --- /dev/null +++ b/NuGet.Config @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/symbols/pdb.windows/AssemblyInfo.cs b/symbols/pdb.windows/AssemblyInfo.cs new file mode 100644 index 000000000..d3a01b08f --- /dev/null +++ b/symbols/pdb.windows/AssemblyInfo.cs @@ -0,0 +1,8 @@ +// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Reflection; + +[assembly: AssemblyTitle ("Mono.Cecil.WindowsPdb")] + +[assembly: CLSCompliant (false)] diff --git a/symbols/pdb.windows/ModuleMetadata.cs b/symbols/pdb.windows/ModuleMetadata.cs new file mode 100644 index 000000000..671b9a47e --- /dev/null +++ b/symbols/pdb.windows/ModuleMetadata.cs @@ -0,0 +1,101 @@ +// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +#if !READ_ONLY + +using System.Collections.Generic; +using Microsoft.DiaSymReader; + +namespace Mono.Cecil.WindowsPdb { + + class ModuleMetadata : ISymWriterMetadataProvider { + + readonly ModuleDefinition module; + + Dictionary types; + Dictionary methods; + + public ModuleMetadata (ModuleDefinition module) + { + this.module = module; + } + + bool TryGetType (uint token, out TypeDefinition type) + { + if (types == null) + InitializeMetadata (module); + + return types.TryGetValue (token, out type); + } + + bool TryGetMethod (uint token, out MethodDefinition method) + { + if (methods == null) + InitializeMetadata (module); + + return methods.TryGetValue (token, out method); + } + + void InitializeMetadata (ModuleDefinition module) + { + types = new Dictionary (); + methods = new Dictionary (); + + foreach (var type in module.GetTypes ()) { + types.Add (type.MetadataToken.ToUInt32 (), type); + InitializeMethods (type); + } + } + + void InitializeMethods (TypeDefinition type) + { + foreach (var method in type.Methods) + methods.Add (method.MetadataToken.ToUInt32 (), method); + } + + bool ISymWriterMetadataProvider.TryGetTypeDefinitionInfo (int typeDefinitionToken, out string namespaceName, out string typeName, out System.Reflection.TypeAttributes attributes, out int baseTypeToken) + { + TypeDefinition type; + if (!TryGetType ((uint)typeDefinitionToken, out type)) { + namespaceName = null; + typeName = null; + attributes = 0; + baseTypeToken = 0; + return false; + } + + typeName = type.IsNested ? type.Name : type.FullName; + namespaceName = type.Namespace; + attributes = (System.Reflection.TypeAttributes)type.Attributes; + baseTypeToken = type.BaseType.MetadataToken.ToInt32 (); + return true; + } + + bool ISymWriterMetadataProvider.TryGetEnclosingType (int nestedTypeToken, out int enclosingTypeToken) + { + TypeDefinition type; + if (!TryGetType ((uint)nestedTypeToken, out type) || !type.IsNested) { + enclosingTypeToken = 0; + return false; + } + + enclosingTypeToken = type.DeclaringType.MetadataToken.ToInt32 (); + return true; + } + + bool ISymWriterMetadataProvider.TryGetMethodInfo (int methodDefinitionToken, out string methodName, out int declaringTypeToken) + { + MethodDefinition method; + if (!TryGetMethod ((uint)methodDefinitionToken, out method)) { + methodName = null; + declaringTypeToken = 0; + return false; + } + + declaringTypeToken = method.DeclaringType.MetadataToken.ToInt32 (); + methodName = method.Name; + return true; + } + } +} + +#endif diff --git a/symbols/pdb.windows/Mono.Cecil.WindowsPdb.csproj b/symbols/pdb.windows/Mono.Cecil.WindowsPdb.csproj new file mode 100644 index 000000000..1d3c19a67 --- /dev/null +++ b/symbols/pdb.windows/Mono.Cecil.WindowsPdb.csproj @@ -0,0 +1,26 @@ + + + + + {1A7F5B01-F15F-4943-8AF5-CB736C60B1BE} + Mono.Cecil.WindowsPdb + Mono.Cecil.WindowsPdb + true + + + + {D68133BD-1E63-496E-9EDE-4FBDBF77B486} + Mono.Cecil + + + + + + + + + + + + + \ No newline at end of file diff --git a/symbols/pdb.windows/NativePdbReader.cs b/symbols/pdb.windows/NativePdbReader.cs new file mode 100644 index 000000000..c430338e3 --- /dev/null +++ b/symbols/pdb.windows/NativePdbReader.cs @@ -0,0 +1,41 @@ +// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Collections.Generic; +using System.IO; + +using Mono.Collections.Generic; + +using Mono.Cecil.Cil; + +namespace Mono.Cecil.WindowsPdb { + + public class NativePdbReader : ISymbolReader { + + internal NativePdbReader (Disposable file) + { + } + +#if !READ_ONLY + public ISymbolWriterProvider GetWriterProvider () + { + return new NativePdbWriterProvider (); + } +#endif + + public bool ProcessDebugHeader (ImageDebugHeader header) + { + throw null; + } + + public MethodDebugInformation Read (MethodDefinition method) + { + throw null; + } + + public void Dispose () + { + throw null; + } + } +} diff --git a/symbols/pdb.windows/NativePdbWriter.cs b/symbols/pdb.windows/NativePdbWriter.cs new file mode 100644 index 000000000..56dc1fd69 --- /dev/null +++ b/symbols/pdb.windows/NativePdbWriter.cs @@ -0,0 +1,403 @@ +// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +#if !READ_ONLY + +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; + +using Mono.Cecil.Cil; +using Mono.Cecil.PE; +using Mono.Collections.Generic; + +using Microsoft.DiaSymReader; + +namespace Mono.Cecil.WindowsPdb { + + public class NativePdbWriter : ISymbolWriter, IMetadataSymbolWriter { + const int Age = 1; + + readonly ModuleDefinition module; + readonly SymUnmanagedWriter writer; + readonly SymUnmanagedSequencePointsWriter sequence_point_writer; + readonly string pdb_path; + readonly Dictionary documents; + readonly Dictionary import_info_to_parent; + readonly Guid id; + readonly uint timestamp; + + MetadataBuilder metadata; + + internal NativePdbWriter (ModuleDefinition module, SymUnmanagedWriter writer, string pdb_path) + { + this.module = module; + this.writer = writer; + this.sequence_point_writer = new SymUnmanagedSequencePointsWriter (writer, capacity: 64); + this.pdb_path = pdb_path; + this.documents = new Dictionary (); + this.import_info_to_parent = new Dictionary (); + + // TODO: calculate id based on the content to produce deterministic output + this.id = Guid.NewGuid (); + this.timestamp = module.timestamp; + } + + public ISymbolReaderProvider GetReaderProvider () + { + return new NativePdbReaderProvider (); + } + + public ImageDebugHeader GetDebugHeader () + { + var data = Mixin.GetCodeViewData (id, pdb_path, Age); + + var directory = new ImageDebugDirectory () { + MajorVersion = 0, + MinorVersion = 0, + Type = ImageDebugType.CodeView, + TimeDateStamp = (int)timestamp, + SizeOfData = data.Length, + }; + + return new ImageDebugHeader (new ImageDebugHeaderEntry (directory, data)); + } + + public void Write (MethodDebugInformation info) + { + var method_token = info.method.MetadataToken; + var sym_token = method_token.ToInt32 (); + + if (!info.HasSequencePoints && info.scope == null && !info.HasCustomDebugInformations && info.StateMachineKickOffMethod == null) + return; + + writer.OpenMethod (sym_token); + + if (!info.sequence_points.IsNullOrEmpty ()) + DefineSequencePoints (info.sequence_points); + + var import_parent = new MetadataToken (); + + if (info.scope != null) + DefineScope (info.scope, info, out import_parent); + + DefineCustomMetadata (info, import_parent); + + writer.CloseMethod (); + } + + void IMetadataSymbolWriter.SetMetadata (MetadataBuilder metadata) + { + this.metadata = metadata; + } + + void IMetadataSymbolWriter.WriteModule () + { + } + + void DefineCustomMetadata (MethodDebugInformation info, MetadataToken import_parent) + { + var metadata = new CustomMetadataWriter (this.writer); + + if (import_parent.RID != 0) { + metadata.WriteForwardInfo (import_parent); + } else if (info.scope != null && info.scope.Import != null && info.scope.Import.HasTargets) { + metadata.WriteUsingInfo (info.scope.Import); + } + + if (info.Method.HasCustomAttributes) { + foreach (var attribute in info.Method.CustomAttributes) { + const string compiler_services = "System.Runtime.CompilerServices"; + var attribute_type = attribute.AttributeType; + + if (!attribute_type.IsTypeOf (compiler_services, "IteratorStateMachineAttribute") && !attribute_type.IsTypeOf (compiler_services, "AsyncStateMachineAttribute")) + continue; + + var type = attribute.ConstructorArguments [0].Value as TypeReference; + if (type == null) + continue; + + metadata.WriteForwardIterator (type); + } + } + + if (info.HasCustomDebugInformations) { + var scopes = info.CustomDebugInformations.OfType ().ToArray (); + + if (scopes.Length > 0) + metadata.WriteIteratorScopes (scopes, info); + } + + metadata.WriteCustomMetadata (); + + DefineAsyncCustomMetadata (info); + } + + void DefineAsyncCustomMetadata (MethodDebugInformation info) + { + if (!info.HasCustomDebugInformations) + return; + + foreach (var custom_info in info.CustomDebugInformations) { + var async_debug_info = custom_info as AsyncMethodBodyDebugInformation; + if (async_debug_info == null) + continue; + + int offsetCount = async_debug_info.Resumes.Count; + + int[] yieldOffsets = new int[offsetCount]; + int[] resumeOffsets = new int[offsetCount]; + for (int i = 0; i < offsetCount; i++) { + yieldOffsets[i] = async_debug_info.Yields[i].Offset; + resumeOffsets[i] = async_debug_info.Resumes[i].Offset; + } + + writer.SetAsyncInfo ( + moveNextMethodToken: async_debug_info.MoveNextMethod.MetadataToken.ToInt32 (), + kickoffMethodToken: info.StateMachineKickOffMethod.MetadataToken.ToInt32 (), + catchHandlerOffset: async_debug_info.CatchHandler.Offset, + yieldOffsets: yieldOffsets, + resumeOffsets: resumeOffsets); + } + } + + void DefineScope (ScopeDebugInformation scope, MethodDebugInformation info, out MetadataToken import_parent) + { + var start_offset = scope.Start.Offset; + var end_offset = scope.End.IsEndOfMethod + ? info.code_size + : scope.End.Offset; + + import_parent = new MetadataToken (0u); + + writer.OpenScope (start_offset); + + if (scope.Import != null && scope.Import.HasTargets && !import_info_to_parent.TryGetValue (info.scope.Import, out import_parent)) { + foreach (var target in scope.Import.Targets) { + switch (target.Kind) { + case ImportTargetKind.ImportNamespace: + writer.UsingNamespace ("U" + target.@namespace); + break; + case ImportTargetKind.ImportType: + writer.UsingNamespace ("T" + TypeParser.ToParseable (target.type)); + break; + case ImportTargetKind.DefineNamespaceAlias: + writer.UsingNamespace ("A" + target.Alias + " U" + target.@namespace); + break; + case ImportTargetKind.DefineTypeAlias: + writer.UsingNamespace ("A" + target.Alias + " T" + TypeParser.ToParseable (target.type)); + break; + } + } + + import_info_to_parent.Add (info.scope.Import, info.method.MetadataToken); + } + + var sym_token = info.local_var_token.ToInt32 (); + + if (!scope.variables.IsNullOrEmpty ()) { + for (int i = 0; i < scope.variables.Count; i++) { + var variable = scope.variables [i]; + DefineLocalVariable (variable, sym_token); + } + } + + if (!scope.constants.IsNullOrEmpty ()) { + for (int i = 0; i < scope.constants.Count; i++) { + var constant = scope.constants [i]; + DefineConstant (constant); + } + } + + if (!scope.scopes.IsNullOrEmpty ()) { + for (int i = 0; i < scope.scopes.Count; i++) { + MetadataToken _; + DefineScope (scope.scopes [i], info, out _); + } + } + + writer.CloseScope (end_offset); + } + + void DefineSequencePoints (Collection sequence_points) + { + int current_doc_index = -1; + Document current_doc = null; + + for (int i = 0; i < sequence_points.Count; i++) { + var sequence_point = sequence_points[i]; + + if (!ReferenceEquals(current_doc, sequence_point.Document)) { + current_doc_index = GetDocumentIndex (sequence_point.Document); + current_doc = sequence_point.Document; + } + + sequence_point_writer.Add ( + current_doc_index, + sequence_point.Offset, + sequence_point.StartLine, + sequence_point.StartColumn, + sequence_point.EndLine, + sequence_point.EndColumn); + } + + sequence_point_writer.Flush (); + } + + void DefineLocalVariable (VariableDebugInformation variable, int local_var_token) + { + writer.DefineLocalVariable ( + variable.Index, + variable.Name, + (int)variable.Attributes, + local_var_token); + } + + void DefineConstant (ConstantDebugInformation constant) + { + var row = metadata.AddStandAloneSignature (metadata.GetConstantTypeBlobIndex (constant.ConstantType)); + var token = new MetadataToken (TokenType.Signature, row); + + writer.DefineLocalConstant (constant.Name, constant.Value, token.ToInt32 ()); + } + + int GetDocumentIndex (Document document) + { + if (document == null) + return -1; + + int doc_index; + if (documents.TryGetValue (document.Url, out doc_index)) + return doc_index; + + doc_index = writer.DefineDocument ( + document.Url, + document.Language.ToGuid (), + document.LanguageVendor.ToGuid (), + document.Type.ToGuid (), + document.HashAlgorithm.ToGuid (), + document.Hash, + source: null); // TODO: implement support for embedded source + + documents [document.Url] = doc_index; + return doc_index; + } + + public void Dispose () + { + var entry_point = module.EntryPoint; + if (entry_point != null) + writer.SetEntryPoint (entry_point.MetadataToken.ToInt32 ()); + + writer.UpdateSignature (id, timestamp, Age); + + using (var stream = new FileStream (pdb_path, FileMode.Create, FileAccess.Write, FileShare.None)) { + writer.WriteTo (stream); + } + + writer.Dispose (); + } + } + + enum CustomMetadataType : byte { + UsingInfo = 0, + ForwardInfo = 1, + IteratorScopes = 3, + ForwardIterator = 4, + } + + class CustomMetadataWriter : IDisposable { + + readonly SymUnmanagedWriter sym_writer; + readonly MemoryStream stream; + readonly BinaryStreamWriter writer; + + int count; + + const byte version = 4; + + public CustomMetadataWriter (SymUnmanagedWriter sym_writer) + { + this.sym_writer = sym_writer; + this.stream = new MemoryStream (); + this.writer = new BinaryStreamWriter (stream); + + writer.WriteByte (version); + writer.WriteByte (0); // count + writer.Align (4); + } + + public void WriteUsingInfo (ImportDebugInformation import_info) + { + Write (CustomMetadataType.UsingInfo, () => { + writer.WriteUInt16 ((ushort) 1); + writer.WriteUInt16 ((ushort) import_info.Targets.Count); + }); + } + + public void WriteForwardInfo (MetadataToken import_parent) + { + Write (CustomMetadataType.ForwardInfo, () => writer.WriteUInt32 (import_parent.ToUInt32 ())); + } + + public void WriteIteratorScopes (StateMachineScopeDebugInformation [] scopes, MethodDebugInformation debug_info) + { + Write (CustomMetadataType.IteratorScopes, () => { + writer.WriteInt32 (scopes.Length); + foreach (var scope in scopes) { + var start = scope.Start.Offset; + var end = scope.End.IsEndOfMethod ? debug_info.code_size : scope.End.Offset; + writer.WriteInt32 (start); + writer.WriteInt32 (end - 1); + } + }); + } + + public void WriteForwardIterator (TypeReference type) + { + Write (CustomMetadataType.ForwardIterator, () => writer.WriteBytes(Encoding.Unicode.GetBytes(type.Name))); + } + + void Write (CustomMetadataType type, Action write) + { + count++; + writer.WriteByte (version); + writer.WriteByte ((byte) type); + writer.Align (4); + + var length_position = writer.Position; + writer.WriteUInt32 (0); + + write (); + writer.Align (4); + + var end = writer.Position; + var length = end - length_position + 4; // header is 4 bytes long + + writer.Position = length_position; + writer.WriteInt32 (length); + + writer.Position = end; + } + + public void WriteCustomMetadata () + { + if (count == 0) + return; + + writer.BaseStream.Position = 1; + writer.WriteByte ((byte) count); + writer.Flush (); + + sym_writer.DefineCustomMetadata (stream.ToArray ()); + } + + public void Dispose () + { + stream.Dispose (); + } + } +} + +#endif diff --git a/symbols/pdb.windows/PdbHelper.cs b/symbols/pdb.windows/PdbHelper.cs new file mode 100644 index 000000000..421db5427 --- /dev/null +++ b/symbols/pdb.windows/PdbHelper.cs @@ -0,0 +1,114 @@ +// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.IO; + +using Mono.Cecil.Cil; + +#if !READ_ONLY +using Microsoft.DiaSymReader; +#endif + +namespace Mono.Cecil.WindowsPdb { + + public sealed class NativePdbReaderProvider : ISymbolReaderProvider { + + public ISymbolReader GetSymbolReader (ModuleDefinition module, string fileName) + { + Mixin.CheckModule (module); + Mixin.CheckFileName (fileName); + + return new NativePdbReader (Disposable.Owned (File.OpenRead (Mixin.GetPdbFileName (fileName)) as Stream)); + } + + public ISymbolReader GetSymbolReader (ModuleDefinition module, Stream symbolStream) + { + Mixin.CheckModule (module); + Mixin.CheckStream (symbolStream); + + return new NativePdbReader (Disposable.NotOwned (symbolStream)); + } + } + + public sealed class PdbReaderProvider : ISymbolReaderProvider { + + public ISymbolReader GetSymbolReader (ModuleDefinition module, string fileName) + { + Mixin.CheckModule (module); + Mixin.CheckFileName (fileName); + + if (module.HasDebugHeader) { + var header = module.GetDebugHeader (); + var entry = header.GetEmbeddedPortablePdbEntry (); + if (entry != null) + return new EmbeddedPortablePdbReaderProvider ().GetSymbolReader (module, fileName); + } + + return Mixin.IsPortablePdb (Mixin.GetPdbFileName (fileName)) + ? new PortablePdbReaderProvider ().GetSymbolReader (module, fileName) + : new NativePdbReaderProvider ().GetSymbolReader (module, fileName); + } + + public ISymbolReader GetSymbolReader (ModuleDefinition module, Stream symbolStream) + { + Mixin.CheckModule (module); + Mixin.CheckStream (symbolStream); + Mixin.CheckReadSeek (symbolStream); + + return Mixin.IsPortablePdb (symbolStream) + ? new PortablePdbReaderProvider ().GetSymbolReader (module, symbolStream) + : new NativePdbReaderProvider ().GetSymbolReader (module, symbolStream); + } + } + +#if !READ_ONLY + + public sealed class NativePdbWriterProvider : ISymbolWriterProvider { + + public ISymbolWriter GetSymbolWriter (ModuleDefinition module, string fileName) + { + Mixin.CheckModule (module); + Mixin.CheckFileName (fileName); + + return new NativePdbWriter (module, SymUnmanagedWriterFactory.CreateWriter (new ModuleMetadata (module)), Mixin.GetPdbFileName (fileName)); + } + + public ISymbolWriter GetSymbolWriter (ModuleDefinition module, Stream symbolStream) + { + throw new NotImplementedException (); + } + } + + public sealed class PdbWriterProvider : ISymbolWriterProvider { + + public ISymbolWriter GetSymbolWriter (ModuleDefinition module, string fileName) + { + Mixin.CheckModule (module); + Mixin.CheckFileName (fileName); + + if (HasPortablePdbSymbols (module)) + return new PortablePdbWriterProvider ().GetSymbolWriter (module, fileName); + + return new NativePdbWriterProvider ().GetSymbolWriter (module, fileName); + } + + static bool HasPortablePdbSymbols (ModuleDefinition module) + { + return module.symbol_reader != null && module.symbol_reader is PortablePdbReader; + } + + public ISymbolWriter GetSymbolWriter (ModuleDefinition module, Stream symbolStream) + { + Mixin.CheckModule (module); + Mixin.CheckStream (symbolStream); + Mixin.CheckReadSeek (symbolStream); + + if (HasPortablePdbSymbols (module)) + return new PortablePdbWriterProvider ().GetSymbolWriter (module, symbolStream); + + return new NativePdbWriterProvider ().GetSymbolWriter (module, symbolStream); + } + } + +#endif +} diff --git a/symbols/pdb.windows/ProjectInfo.cs b/symbols/pdb.windows/ProjectInfo.cs new file mode 100644 index 000000000..d51e57e25 --- /dev/null +++ b/symbols/pdb.windows/ProjectInfo.cs @@ -0,0 +1,13 @@ +// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System.Reflection; +using System.Runtime.InteropServices; + +[assembly: AssemblyProduct (Consts.AssemblyName)] +[assembly: AssemblyCopyright ("Copyright © Microsoft")] + +[assembly: ComVisible (false)] + +[assembly: AssemblyVersion ("0.10.0.0")] +[assembly: AssemblyFileVersion ("0.10.0.0")] +[assembly: AssemblyInformationalVersion ("0.10.0.0-beta6")] diff --git a/symbols/pdb.windows/Test/Mono.Cecil.Tests/WindowsPdbTests.cs b/symbols/pdb.windows/Test/Mono.Cecil.Tests/WindowsPdbTests.cs new file mode 100644 index 000000000..bb809a010 --- /dev/null +++ b/symbols/pdb.windows/Test/Mono.Cecil.Tests/WindowsPdbTests.cs @@ -0,0 +1,456 @@ +using System.IO; +using System.Linq; + +using Mono.Cecil.Cil; + +using NUnit.Framework; + +namespace Mono.Cecil.Tests { + + [TestFixture] + public class PdbTests { +#if TODO + [Test] + public void Main () + { + TestModule ("test.exe", module => { + var type = module.GetType ("Program"); + var main = type.GetMethod ("Main"); + + AssertCode (@" + .locals init (System.Int32 i, System.Int32 CS$1$0000, System.Boolean CS$4$0001) + .line 6,6:2,3 'c:\sources\cecil\symbols\Mono.Cecil.Pdb\Test\Resources\assemblies\test.cs' + IL_0000: nop + .line 7,7:8,18 'c:\sources\cecil\symbols\Mono.Cecil.Pdb\Test\Resources\assemblies\test.cs' + IL_0001: ldc.i4.0 + IL_0002: stloc.0 + .line hidden 'c:\sources\cecil\symbols\Mono.Cecil.Pdb\Test\Resources\assemblies\test.cs' + IL_0003: br.s IL_0012 + .line 8,8:4,21 'c:\sources\cecil\symbols\Mono.Cecil.Pdb\Test\Resources\assemblies\test.cs' + IL_0005: ldarg.0 + IL_0006: ldloc.0 + IL_0007: ldelem.ref + IL_0008: call System.Void Program::Print(System.String) + IL_000d: nop + .line 7,7:36,39 'c:\sources\cecil\symbols\Mono.Cecil.Pdb\Test\Resources\assemblies\test.cs' + IL_000e: ldloc.0 + IL_000f: ldc.i4.1 + IL_0010: add + IL_0011: stloc.0 + .line 7,7:19,34 'c:\sources\cecil\symbols\Mono.Cecil.Pdb\Test\Resources\assemblies\test.cs' + IL_0012: ldloc.0 + IL_0013: ldarg.0 + IL_0014: ldlen + IL_0015: conv.i4 + IL_0016: clt + IL_0018: stloc.2 + .line hidden 'c:\sources\cecil\symbols\Mono.Cecil.Pdb\Test\Resources\assemblies\test.cs' + IL_0019: ldloc.2 + IL_001a: brtrue.s IL_0005 + .line 10,10:3,12 'c:\sources\cecil\symbols\Mono.Cecil.Pdb\Test\Resources\assemblies\test.cs' + IL_001c: ldc.i4.0 + IL_001d: stloc.1 + IL_001e: br.s IL_0020 + .line 11,11:2,3 'c:\sources\cecil\symbols\Mono.Cecil.Pdb\Test\Resources\assemblies\test.cs' + IL_0020: ldloc.1 + IL_0021: ret +", main); + }, readOnly: Platform.OnMono, symbolReaderProvider: typeof(PdbReaderProvider), symbolWriterProvider: typeof(PdbWriterProvider)); + } + + [Test] + public void DebuggerHiddenVariable () + { + TestModule ("test.exe", module => { + var type = module.GetType ("Program"); + var method = type.GetMethod ("Main"); + + var scope = method.DebugInformation.Scope; + + Assert.IsTrue (scope.HasVariables); + var variables = scope.Variables; + + Assert.AreEqual ("CS$1$0000", variables [0].Name); + Assert.IsTrue (variables [0].IsDebuggerHidden); + Assert.AreEqual ("CS$4$0001", variables [1].Name); + Assert.IsTrue (variables [1].IsDebuggerHidden); + + Assert.AreEqual (1, scope.Scopes.Count); + scope = scope.Scopes [0]; + variables = scope.Variables; + + Assert.AreEqual ("i", variables [0].Name); + Assert.IsFalse (variables [0].IsDebuggerHidden); + }, readOnly: Platform.OnMono, symbolReaderProvider: typeof(PdbReaderProvider), symbolWriterProvider: typeof(PdbWriterProvider)); + } + + [Test] + public void Document () + { + TestModule ("test.exe", module => { + var type = module.GetType ("Program"); + var method = type.GetMethod ("Main"); + + var sequence_point = method.DebugInformation.SequencePoints.First (sp => sp != null); + var document = sequence_point.Document; + + Assert.IsNotNull (document); + + Assert.AreEqual (@"c:\sources\cecil\symbols\Mono.Cecil.Pdb\Test\Resources\assemblies\test.cs", document.Url); + Assert.AreEqual (DocumentType.Text, document.Type); + Assert.AreEqual (DocumentHashAlgorithm.None, document.HashAlgorithm); + Assert.AreEqual (DocumentLanguage.CSharp, document.Language); + Assert.AreEqual (DocumentLanguageVendor.Microsoft, document.LanguageVendor); + }, readOnly: Platform.OnMono, symbolReaderProvider: typeof(PdbReaderProvider), symbolWriterProvider: typeof(PdbWriterProvider)); + } + + [Test] + public void BasicDocument () + { + TestModule ("VBConsApp.exe", module => { + var type = module.GetType ("VBConsApp.Program"); + var method = type.GetMethod ("Main"); + + var sequence_point = method.DebugInformation.SequencePoints.First (sp => sp != null); + var document = sequence_point.Document; + + Assert.IsNotNull (document); + + Assert.AreEqual (@"c:\tmp\VBConsApp\Program.vb", document.Url); + Assert.AreEqual (DocumentType.Text, document.Type); + Assert.AreEqual (DocumentHashAlgorithm.None, document.HashAlgorithm); + Assert.AreEqual (DocumentLanguage.Basic, document.Language); + Assert.AreEqual (DocumentLanguageVendor.Microsoft, document.LanguageVendor); + }, readOnly: Platform.OnMono, symbolReaderProvider: typeof(PdbReaderProvider), symbolWriterProvider: typeof(PdbWriterProvider)); + } + + [Test] + public void FSharpDocument () + { + TestModule ("fsapp.exe", module => { + var type = module.GetType ("Program"); + var method = type.GetMethod ("fact"); + + var sequence_point = method.DebugInformation.SequencePoints.First (sp => sp != null); + var document = sequence_point.Document; + + Assert.IsNotNull (document); + + Assert.AreEqual (@"c:\tmp\fsapp\Program.fs", document.Url); + Assert.AreEqual (DocumentType.Text, document.Type); + Assert.AreEqual (DocumentHashAlgorithm.None, document.HashAlgorithm); + Assert.AreEqual (DocumentLanguage.FSharp, document.Language); + Assert.AreEqual (DocumentLanguageVendor.Microsoft, document.LanguageVendor); + }, readOnly: Platform.OnMono, symbolReaderProvider: typeof(PdbReaderProvider), symbolWriterProvider: typeof(PdbWriterProvider)); + } + + [Test] + public void EmptyEnumerable () + { + TestModule ("empty-iterator.dll", module => { + }, readOnly: Platform.OnMono, symbolReaderProvider: typeof (PdbReaderProvider), symbolWriterProvider: typeof (PdbWriterProvider)); + } + + [Test] + public void EmptyRootNamespace () + { + TestModule ("EmptyRootNamespace.dll", module => { + }, readOnly: Platform.OnMono, symbolReaderProvider: typeof(PdbReaderProvider), symbolWriterProvider: typeof(PdbWriterProvider)); + } + + [Test] + public void LocalVariables () + { + TestModule ("ComplexPdb.dll", module => { + var type = module.GetType ("ComplexPdb.Program"); + var method = type.GetMethod ("Bar"); + var debug_info = method.DebugInformation; + + Assert.IsNotNull (debug_info.Scope); + Assert.IsTrue (debug_info.Scope.HasScopes); + Assert.AreEqual (2, debug_info.Scope.Scopes.Count); + + var scope = debug_info.Scope.Scopes [0]; + + Assert.IsNotNull (scope); + Assert.IsTrue (scope.HasVariables); + Assert.AreEqual (1, scope.Variables.Count); + + var variable = scope.Variables [0]; + + Assert.AreEqual ("s", variable.Name); + Assert.IsFalse (variable.IsDebuggerHidden); + Assert.AreEqual (2, variable.Index); + + scope = debug_info.Scope.Scopes [1]; + + Assert.IsNotNull (scope); + Assert.IsTrue (scope.HasVariables); + Assert.AreEqual (1, scope.Variables.Count); + + variable = scope.Variables [0]; + + Assert.AreEqual ("s", variable.Name); + Assert.IsFalse (variable.IsDebuggerHidden); + Assert.AreEqual (3, variable.Index); + + Assert.IsTrue (scope.HasScopes); + Assert.AreEqual (1, scope.Scopes.Count); + + scope = scope.Scopes [0]; + + Assert.IsNotNull (scope); + Assert.IsTrue (scope.HasVariables); + Assert.AreEqual (1, scope.Variables.Count); + + variable = scope.Variables [0]; + + Assert.AreEqual ("u", variable.Name); + Assert.IsFalse (variable.IsDebuggerHidden); + Assert.AreEqual (5, variable.Index); + }, readOnly: Platform.OnMono, symbolReaderProvider: typeof (PdbReaderProvider), symbolWriterProvider: typeof (PdbWriterProvider)); + } + + [Test] + public void LocalConstants () + { + TestModule ("ComplexPdb.dll", module => { + var type = module.GetType ("ComplexPdb.Program"); + var method = type.GetMethod ("Bar"); + var debug_info = method.DebugInformation; + + Assert.IsNotNull (debug_info.Scope); + Assert.IsTrue (debug_info.Scope.HasScopes); + Assert.AreEqual (2, debug_info.Scope.Scopes.Count); + + var scope = debug_info.Scope.Scopes [1]; + + Assert.IsNotNull (scope); + Assert.IsTrue (scope.HasConstants); + Assert.AreEqual (2, scope.Constants.Count); + + var constant = scope.Constants [0]; + + Assert.AreEqual ("b", constant.Name); + Assert.AreEqual (12, constant.Value); + Assert.AreEqual (MetadataType.Int32, constant.ConstantType.MetadataType); + + constant = scope.Constants [1]; + Assert.AreEqual ("c", constant.Name); + Assert.AreEqual ((decimal) 74, constant.Value); + Assert.AreEqual (MetadataType.ValueType, constant.ConstantType.MetadataType); + + method = type.GetMethod ("Foo"); + debug_info = method.DebugInformation; + + Assert.IsNotNull (debug_info.Scope); + Assert.IsTrue (debug_info.Scope.HasConstants); + Assert.AreEqual (4, debug_info.Scope.Constants.Count); + + constant = debug_info.Scope.Constants [0]; + Assert.AreEqual ("s", constant.Name); + Assert.AreEqual ("const string", constant.Value); + Assert.AreEqual (MetadataType.String, constant.ConstantType.MetadataType); + + constant = debug_info.Scope.Constants [1]; + Assert.AreEqual ("f", constant.Name); + Assert.AreEqual (1, constant.Value); + Assert.AreEqual (MetadataType.Int32, constant.ConstantType.MetadataType); + + constant = debug_info.Scope.Constants [2]; + Assert.AreEqual ("o", constant.Name); + Assert.AreEqual (null, constant.Value); + Assert.AreEqual (MetadataType.Object, constant.ConstantType.MetadataType); + + constant = debug_info.Scope.Constants [3]; + Assert.AreEqual ("u", constant.Name); + Assert.AreEqual (null, constant.Value); + Assert.AreEqual (MetadataType.String, constant.ConstantType.MetadataType); + }, readOnly: Platform.OnMono, symbolReaderProvider: typeof (PdbReaderProvider), symbolWriterProvider: typeof (PdbWriterProvider)); + } + + [Test] + public void ImportScope () + { + TestModule ("ComplexPdb.dll", module => { + var type = module.GetType ("ComplexPdb.Program"); + var method = type.GetMethod ("Bar"); + var debug_info = method.DebugInformation; + + Assert.IsNotNull (debug_info.Scope); + + var import = debug_info.Scope.Import; + Assert.IsNotNull (import); + + Assert.IsTrue (import.HasTargets); + Assert.AreEqual (6, import.Targets.Count); + var target = import.Targets [0]; + + Assert.AreEqual (ImportTargetKind.ImportNamespace, target.Kind); + Assert.AreEqual ("System", target.Namespace); + + target = import.Targets [1]; + + Assert.AreEqual (ImportTargetKind.ImportNamespace, target.Kind); + Assert.AreEqual ("System.Collections.Generic", target.Namespace); + + target = import.Targets [2]; + + Assert.AreEqual (ImportTargetKind.ImportNamespace, target.Kind); + Assert.AreEqual ("System.Threading.Tasks", target.Namespace); + + target = import.Targets [3]; + + Assert.AreEqual (ImportTargetKind.ImportType, target.Kind); + Assert.AreEqual ("System.Console", target.Type.FullName); + + target = import.Targets [4]; + + Assert.AreEqual (ImportTargetKind.DefineTypeAlias, target.Kind); + Assert.AreEqual ("Foo1", target.Alias); + Assert.AreEqual ("System.Console", target.Type.FullName); + + target = import.Targets [5]; + + Assert.AreEqual (ImportTargetKind.DefineNamespaceAlias, target.Kind); + Assert.AreEqual ("Foo2", target.Alias); + Assert.AreEqual ("System.Reflection", target.Namespace); + }, readOnly: Platform.OnMono, symbolReaderProvider: typeof (PdbReaderProvider), symbolWriterProvider: typeof (PdbWriterProvider)); + } + + [Test] + public void StateMachineKickOff () + { + TestModule ("ComplexPdb.dll", module => { + var state_machine = module.GetType ("ComplexPdb.Program/d__2"); + var move_next = state_machine.GetMethod ("MoveNext"); + var symbol = move_next.DebugInformation; + + Assert.IsNotNull (symbol); + Assert.IsNotNull (symbol.StateMachineKickOffMethod); + Assert.AreEqual ("System.Threading.Tasks.Task ComplexPdb.Program::TestAsync()", symbol.StateMachineKickOffMethod.FullName); + }, readOnly: Platform.OnMono, symbolReaderProvider: typeof (PdbReaderProvider), symbolWriterProvider: typeof (PdbWriterProvider)); + } + + [Test] + public void Iterators () + { + TestModule ("ComplexPdb.dll", module => { + var state_machine = module.GetType ("ComplexPdb.Program/d__2"); + var move_next = state_machine.GetMethod ("MoveNext"); + + Assert.IsTrue (move_next.DebugInformation.HasCustomDebugInformations); + Assert.AreEqual (2, move_next.DebugInformation.CustomDebugInformations.Count); + + var state_machine_scope = move_next.DebugInformation.CustomDebugInformations [0] as StateMachineScopeDebugInformation; + Assert.IsNotNull (state_machine_scope); + Assert.AreEqual (142, state_machine_scope.Start.Offset); + Assert.AreEqual (319, state_machine_scope.End.Offset); + + var async_body = move_next.DebugInformation.CustomDebugInformations [1] as AsyncMethodBodyDebugInformation; + Assert.IsNotNull (async_body); + Assert.AreEqual (-1, async_body.CatchHandler.Offset); + + Assert.AreEqual (2, async_body.Yields.Count); + Assert.AreEqual (68, async_body.Yields [0].Offset); + Assert.AreEqual (197, async_body.Yields [1].Offset); + + Assert.AreEqual (2, async_body.Resumes.Count); + Assert.AreEqual (98, async_body.Resumes [0].Offset); + Assert.AreEqual (227, async_body.Resumes [1].Offset); + + Assert.AreEqual (move_next, async_body.MoveNextMethod); + }, readOnly: Platform.OnMono, symbolReaderProvider: typeof (PdbReaderProvider), symbolWriterProvider: typeof (PdbWriterProvider)); + } + + [Test] + public void ImportsForFirstMethod () + { + TestModule ("CecilTest.exe", module => { + var type = module.GetType ("CecilTest.Program"); + var method = type.GetMethod ("Main"); + + var debug = method.DebugInformation; + var scope = debug.Scope; + + Assert.IsTrue (scope.End.IsEndOfMethod); + + var import = scope.Import; + + Assert.IsNotNull (import); + Assert.AreEqual (5, import.Targets.Count); + + var ns = new [] { + "System", + "System.Collections.Generic", + "System.Linq", + "System.Text", + "System.Threading.Tasks", + }; + + for (int i = 0; i < import.Targets.Count; i++) { + var target = import.Targets [i]; + + Assert.AreEqual (ImportTargetKind.ImportNamespace, target.Kind); + Assert.AreEqual (ns [i], target.Namespace); + } + + Assert.AreEqual ("System", import.Targets [0].Namespace); + }, readOnly: Platform.OnMono, symbolReaderProvider: typeof (PdbReaderProvider), symbolWriterProvider: typeof (PdbWriterProvider)); + } + + [Test] + public void CreateMethodFromScratch () + { + IgnoreOnMono (); + + var module = ModuleDefinition.CreateModule ("Pan", ModuleKind.Dll); + var type = new TypeDefinition ("Pin", "Pon", TypeAttributes.Public | TypeAttributes.Abstract | TypeAttributes.Sealed, module.ImportReference (typeof (object))); + module.Types.Add (type); + + var method = new MethodDefinition ("Pang", MethodAttributes.Public | MethodAttributes.Static, module.ImportReference (typeof (string))); + type.Methods.Add (method); + + var body = method.Body; + + body.InitLocals = true; + + var il = body.GetILProcessor (); + var temp = new VariableDefinition (module.ImportReference (typeof (string))); + body.Variables.Add (temp); + + il.Emit (OpCodes.Nop); + il.Emit (OpCodes.Ldstr, "hello"); + il.Emit (OpCodes.Stloc, temp); + il.Emit (OpCodes.Ldloc, temp); + il.Emit (OpCodes.Ret); + + var sequence_point = new SequencePoint (body.Instructions [0], new Document (@"C:\test.cs")) { + StartLine = 0, + StartColumn = 0, + EndLine = 0, + EndColumn = 4, + }; + + method.DebugInformation.SequencePoints.Add (sequence_point); + + method.DebugInformation.Scope = new ScopeDebugInformation (body.Instructions [0], null) { + Variables = { new VariableDebugInformation (temp, "temp") } + }; + + var file = Path.Combine (Path.GetTempPath (), "Pan.dll"); + module.Write (file, new WriterParameters { + SymbolWriterProvider = new PdbWriterProvider (), + }); + + module = ModuleDefinition.ReadModule (file, new ReaderParameters { + SymbolReaderProvider = new PdbReaderProvider (), + }); + + method = module.GetType ("Pin.Pon").GetMethod ("Pang"); + + Assert.AreEqual ("temp", method.DebugInformation.Scope.Variables [0].Name); + } +#endif + } +} diff --git a/symbols/pdb.windows/Test/Mono.Cecil.WindowsPdb.Tests.csproj b/symbols/pdb.windows/Test/Mono.Cecil.WindowsPdb.Tests.csproj new file mode 100644 index 000000000..9eeb1059f --- /dev/null +++ b/symbols/pdb.windows/Test/Mono.Cecil.WindowsPdb.Tests.csproj @@ -0,0 +1,22 @@ + + + + + {77E8A7D2-4DC4-43E1-94FF-002B33FF2397} + Mono.Cecil.WindowsPdb.Tests + Mono.Cecil.WindowsPdb.Tests + + + + {D68133BD-1E63-496E-9EDE-4FBDBF77B486} + Mono.Cecil + + + {1a7f5b01-f15f-4943-8af5-cb736c60b1be} + Mono.Cecil.WindowsPdb + + + + + + \ No newline at end of file From 6b903aca0795e5da66d0792f4e3aa8a4d04200bc Mon Sep 17 00:00:00 2001 From: Tomas Matousek Date: Thu, 15 Jun 2017 17:48:47 -0700 Subject: [PATCH 3/4] Multitarget tests --- Mono.Cecil.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mono.Cecil.props b/Mono.Cecil.props index 91399b993..7b21ef4f2 100644 --- a/Mono.Cecil.props +++ b/Mono.Cecil.props @@ -43,7 +43,7 @@ $(DefineConstants);NET_4_0; - netstandard1.5 + net462;netcoreapp1.1 netstandard1.3 From 02559ed4975142bef1cf98804b85b22c17a96c26 Mon Sep 17 00:00:00 2001 From: Tomas Matousek Date: Thu, 15 Jun 2017 18:05:20 -0700 Subject: [PATCH 4/4] Add packaging info --- Mono.Cecil.props | 8 +++++++- symbols/pdb.windows/Mono.Cecil.WindowsPdb.csproj | 8 ++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/Mono.Cecil.props b/Mono.Cecil.props index 7b21ef4f2..2d7a589bb 100644 --- a/Mono.Cecil.props +++ b/Mono.Cecil.props @@ -13,7 +13,7 @@ $(BuildDirectory)\bin\$(Configuration)\ $(MSBuildToolsPath)\Microsoft.CSharp.targets true - false + false true @@ -45,6 +45,12 @@ net462;netcoreapp1.1 netstandard1.3 + + 0.10.0.0-beta6 + en-US + http://opensource.org/licenses/mit-license.php + false + http://github.com/jbevain/cecil/ diff --git a/symbols/pdb.windows/Mono.Cecil.WindowsPdb.csproj b/symbols/pdb.windows/Mono.Cecil.WindowsPdb.csproj index 1d3c19a67..e5aaf32cd 100644 --- a/symbols/pdb.windows/Mono.Cecil.WindowsPdb.csproj +++ b/symbols/pdb.windows/Mono.Cecil.WindowsPdb.csproj @@ -7,6 +7,14 @@ Mono.Cecil.WindowsPdb true + + true + Microsoft + Microsoft + Mono.Cecil symbol provider for Windows PDBs + Mono.Cecil symbol provider for Windows PDBs + Mono.Cecil symbol provider Windows PDBs + {D68133BD-1E63-496E-9EDE-4FBDBF77B486}