Imported Upstream version 4.8.0.309

Former-commit-id: 5f9c6ae75f295e057a7d2971f3a6df4656fa8850
This commit is contained in:
Xamarin Public Jenkins (auto-signing)
2016-11-10 13:04:39 +00:00
parent ee1447783b
commit 94b2861243
4912 changed files with 390737 additions and 49310 deletions

7
external/cecil-legacy/Test/.gitignore vendored Normal file
View File

@@ -0,0 +1,7 @@
bin
obj
*.suo
*.user
*.xml
*.pidb
*.userprefs

View File

@@ -0,0 +1,179 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">net_4_0_Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>9.0.30729</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{A47B1F49-A81A-43E8-BE6B-DD28AF2C4055}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Mono.Cecil.Tests</RootNamespace>
<AssemblyName>Mono.Cecil.Tests</AssemblyName>
<FileAlignment>512</FileAlignment>
<SignAssembly>true</SignAssembly>
<AssemblyOriginatorKeyFile>..\mono.snk</AssemblyOriginatorKeyFile>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'net_2_0_Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\net_2_0_Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<TargetFrameworkVersion>v2.0</TargetFrameworkVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'net_2_0_Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\net_2_0_Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<TargetFrameworkVersion>v2.0</TargetFrameworkVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'net_3_5_Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\net_3_5_Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE;NET_3_5</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'net_3_5_Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\net_3_5_Release\</OutputPath>
<DefineConstants>TRACE;NET_3_5</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'net_4_0_Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\net_4_0_Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE;NET_3_5;NET_4_0</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'net_4_0_Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\net_4_0_Release\</OutputPath>
<DefineConstants>TRACE;NET_3_5;NET_4_0</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
</PropertyGroup>
<ItemGroup Condition=" '$(TargetFrameworkVersion)' != 'v2.0' ">
<Reference Include="System.Core" />
</ItemGroup>
<ItemGroup>
<Reference Include="nunit.core">
<SpecificVersion>False</SpecificVersion>
<HintPath>libs\nunit-2.6.2\nunit.core.dll</HintPath>
</Reference>
<Reference Include="nunit.core.interfaces">
<SpecificVersion>False</SpecificVersion>
<HintPath>libs\nunit-2.6.2\nunit.core.interfaces.dll</HintPath>
</Reference>
<Reference Include="nunit.framework">
<SpecificVersion>False</SpecificVersion>
<HintPath>libs\nunit-2.6.2\nunit.framework.dll</HintPath>
</Reference>
<Reference Include="System" />
</ItemGroup>
<ItemGroup>
<Compile Include="Mono.Cecil.Tests\Addin.cs" />
<Compile Include="Mono.Cecil.Tests\AssemblyTests.cs" />
<Compile Include="Mono.Cecil.Tests\AssemblyInfo.cs" />
<Compile Include="Mono.Cecil.Tests\BaseTestFixture.cs" />
<Compile Include="Mono.Cecil.Tests\CompilationService.cs" />
<Compile Include="Mono.Cecil.Tests\VariableTests.cs" />
<Compile Include="Mono.Cecil.Tests\TypeParserTests.cs" />
<Compile Include="Mono.Cecil.Tests\ImportCecilTests.cs" />
<Compile Include="Mono.Cecil.Tests\ImportReflectionTests.cs" />
<Compile Include="Mono.Cecil.Tests\ILProcessorTests.cs" />
<Compile Include="Mono.Cecil.Tests\SecurityDeclarationTests.cs" />
<Compile Include="Mono.Cecil.Tests\ParameterTests.cs" />
<Compile Include="Mono.Cecil.Tests\Extensions.cs" />
<Compile Include="Mono.Cecil.Tests\Linq.cs" />
<Compile Include="Mono.Cecil.Tests\ResolveTests.cs" />
<Compile Include="Mono.Cecil.Tests\CustomAttributesTests.cs" />
<Compile Include="Mono.Cecil.Tests\Formatter.cs" />
<Compile Include="Mono.Cecil.Tests\MethodBodyTests.cs" />
<Compile Include="Mono.Cecil.Tests\TypeTests.cs" />
<Compile Include="Mono.Cecil.Tests\PropertyTests.cs" />
<Compile Include="Mono.Cecil.Tests\EventTests.cs" />
<Compile Include="Mono.Cecil.Tests\MethodTests.cs" />
<Compile Include="Mono.Cecil.Tests\FieldTests.cs" />
<Compile Include="Mono.Cecil.Tests\ImageReadTests.cs" />
<Compile Include="Mono.Cecil.Tests\ModuleTests.cs" />
<Compile Include="Mono.Cecil.Tests\NestedTypesTests.cs" />
<None Include="Resources\il\explicitthis.il" />
<None Include="Resources\cs\CustomAttributes.cs" />
<None Include="Resources\cs\Generics.cs" />
<None Include="Resources\cs\Interfaces.cs" />
<None Include="Resources\cs\Layouts.cs" />
<None Include="Resources\cs\Properties.cs" />
<None Include="Resources\cs\Events.cs" />
<None Include="Resources\cs\Methods.cs" />
<None Include="Resources\assemblies\moda.netmodule" />
<None Include="Resources\assemblies\modb.netmodule" />
<None Include="Resources\cs\Fields.cs" />
<None Include="Resources\cs\NestedTypes.cs" />
<None Include="Resources\il\hello.il" />
<None Include="Resources\il\methodspecs.il" />
<None Include="Resources\il\others.il" />
<None Include="Resources\il\types.il" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Mono.Cecil.csproj">
<Project>{D68133BD-1E63-496E-9EDE-4FBDBF77B486}</Project>
<Name>Mono.Cecil</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<Content Include="Resources\assemblies\boxedoptarg.dll" />
<Content Include="Resources\assemblies\catch.exe" />
<Content Include="Resources\assemblies\cppcli.dll" />
<Content Include="Resources\assemblies\cscgpbug.dll" />
<Content Include="Resources\assemblies\decsec-att.dll" />
<Content Include="Resources\assemblies\decsec-xml.dll" />
<Content Include="Resources\assemblies\decsec1-xml.dll" />
<Content Include="Resources\assemblies\empty-decsec-att.dll" />
<Content Include="Resources\assemblies\fptr.exe" />
<Content Include="Resources\assemblies\gifaceref.exe" />
<Content Include="Resources\assemblies\hello.anycpu.exe" />
<Content Include="Resources\assemblies\hello.exe" />
<Content Include="Resources\assemblies\hello.ia64.exe" />
<Content Include="Resources\assemblies\hello.x64.exe" />
<Content Include="Resources\assemblies\hello.x86.exe" />
<Content Include="Resources\assemblies\hello1.exe" />
<Content Include="Resources\assemblies\hellow.exe" />
<Content Include="Resources\assemblies\iterator.exe" />
<Content Include="Resources\assemblies\libhello.dll" />
<Content Include="Resources\assemblies\libres.dll" />
<Content Include="Resources\assemblies\marshal.dll" />
<Content Include="Resources\assemblies\mma.exe" />
<Content Include="Resources\assemblies\noblob.dll" />
<Content Include="Resources\assemblies\pinvoke.exe" />
<Content Include="Resources\assemblies\switch.exe" />
<Content Include="Resources\assemblies\text_file.txt" />
<Content Include="Resources\assemblies\varargs.exe" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

View File

@@ -0,0 +1,305 @@
using System;
using System.IO;
using System.Reflection;
using NUnit.Core;
using NUnit.Core.Extensibility;
using Mono.Cecil.Cil;
namespace Mono.Cecil.Tests {
public abstract class TestCecilAttribute : Attribute {
bool verify = true;
Type symbol_reader_provider;
Type symbol_writer_provider;
public bool Verify {
get { return verify; }
set { verify = value; }
}
public Type SymbolReaderProvider {
get { return symbol_reader_provider; }
set { symbol_reader_provider = value; }
}
public Type SymbolWriterProvider {
get { return symbol_writer_provider; }
set { symbol_writer_provider = value; }
}
public abstract string GetModuleLocation (Assembly assembly);
}
[AttributeUsage (AttributeTargets.Method, AllowMultiple = false)]
public sealed class TestModuleAttribute : TestCecilAttribute {
readonly string module;
public string Module {
get { return module; }
}
public TestModuleAttribute (string assembly)
{
this.module = assembly;
}
public override string GetModuleLocation (Assembly assembly)
{
return BaseTestFixture.GetAssemblyResourcePath (module, assembly);
}
}
[AttributeUsage (AttributeTargets.Method, AllowMultiple = false)]
public sealed class TestCSharpAttribute : TestCecilAttribute {
readonly string file;
public string File {
get { return file; }
}
public TestCSharpAttribute (string file)
{
this.file = file;
}
public override string GetModuleLocation (Assembly assembly)
{
return CompilationService.CompileResource (
BaseTestFixture.GetCSharpResourcePath (file, assembly));
}
}
[AttributeUsage (AttributeTargets.Method, AllowMultiple = false)]
public sealed class TestILAttribute : TestCecilAttribute {
readonly string file;
public string File {
get { return file; }
}
public TestILAttribute (string file)
{
this.file = file;
}
public override string GetModuleLocation (Assembly assembly)
{
return CompilationService.CompileResource (
BaseTestFixture.GetILResourcePath (file, assembly));
}
}
class CecilTestCase : NUnitTestMethod {
readonly TestCecilAttribute attribute;
readonly TestCaseType type;
public CecilTestCase (MethodInfo method, TestCecilAttribute attribute, TestCaseType type)
: base (method)
{
this.TestName.Name = type.ToString ();
this.TestName.FullName = method.DeclaringType.FullName + "." + method.Name + "." + type;
this.attribute = attribute;
this.type = type;
}
ModuleDefinition GetModule ()
{
var location = attribute.GetModuleLocation (this.Method.DeclaringType.Assembly);
var parameters = new ReaderParameters {
SymbolReaderProvider = GetSymbolReaderProvider (attribute),
};
switch (type) {
case TestCaseType.ReadImmediate:
parameters.ReadingMode = ReadingMode.Immediate;
return ModuleDefinition.ReadModule (location, parameters);
case TestCaseType.ReadDeferred:
parameters.ReadingMode = ReadingMode.Deferred;
return ModuleDefinition.ReadModule (location, parameters);
case TestCaseType.WriteFromImmediate:
parameters.ReadingMode = ReadingMode.Immediate;
return RoundTrip (location, parameters, "cecil-irt");
case TestCaseType.WriteFromDeferred:
parameters.ReadingMode = ReadingMode.Deferred;
return RoundTrip (location, parameters, "cecil-drt");
default:
return null;
}
}
static ISymbolReaderProvider GetSymbolReaderProvider (TestCecilAttribute attribute)
{
if (attribute.SymbolReaderProvider == null)
return null;
return (ISymbolReaderProvider) Activator.CreateInstance (attribute.SymbolReaderProvider);
}
static ISymbolWriterProvider GetSymbolWriterProvider (TestCecilAttribute attribute)
{
if (attribute.SymbolReaderProvider == null)
return null;
return (ISymbolWriterProvider) Activator.CreateInstance (attribute.SymbolWriterProvider);
}
ModuleDefinition RoundTrip (string location, ReaderParameters reader_parameters, string folder)
{
var module = ModuleDefinition.ReadModule (location, reader_parameters);
var rt_folder = Path.Combine (Path.GetTempPath (), folder);
if (!Directory.Exists (rt_folder))
Directory.CreateDirectory (rt_folder);
var rt_module = Path.Combine (rt_folder, Path.GetFileName (location));
var writer_parameters = new WriterParameters {
SymbolWriterProvider = GetSymbolWriterProvider (attribute),
};
Reflect.InvokeMethod (Method, Fixture, new object [] { module });
module.Write (rt_module, writer_parameters);
if (attribute.Verify)
CompilationService.Verify (rt_module);
return ModuleDefinition.ReadModule (rt_module, reader_parameters);
}
public override TestResult RunTest ()
{
var result = new TestResult (TestName);
var module = GetModule ();
if (module == null)
return result;
Reflect.InvokeMethod (Method, Fixture, new object [] { module });
result.Success ();
return result;
}
}
class CecilTestSuite : TestSuite {
public CecilTestSuite (MethodInfo method)
: base (method.DeclaringType.FullName, method.Name)
{
}
public override TestResult Run (EventListener listener, ITestFilter filter)
{
if (this.Parent != null)
this.Fixture = this.Parent.Fixture;
return base.Run (listener, filter);
}
protected override void DoOneTimeSetUp (TestResult suiteResult)
{
}
protected override void DoOneTimeTearDown (TestResult suiteResult)
{
}
}
enum TestCaseType {
ReadImmediate,
ReadDeferred,
WriteFromImmediate,
WriteFromDeferred,
}
static class CecilTestFactory {
public static CecilTestSuite CreateTestSuite (MethodInfo method)
{
if (method == null)
throw new ArgumentNullException ("method");
var suite = new CecilTestSuite (method);
NUnitFramework.ApplyCommonAttributes (method, suite);
PopulateTestSuite (method, suite);
return suite;
}
static void PopulateTestSuite (MethodInfo method, CecilTestSuite suite)
{
var attribute = GetTestCecilAttribute (method);
if (attribute == null)
throw new ArgumentException ();
foreach (var value in Enum.GetValues (typeof (TestCaseType))) {
var test = CreateTestCase (method, attribute, (TestCaseType) value);
if (test != null)
suite.Add (test);
}
}
static CecilTestCase CreateTestCase (MethodInfo method, TestCecilAttribute attribute, TestCaseType type)
{
return new CecilTestCase (method, attribute, type);
}
static TestCecilAttribute GetTestCecilAttribute (MethodInfo method)
{
foreach (var attribute in method.GetCustomAttributes (false)) {
var test = attribute as TestCecilAttribute;
if (test != null)
return test;
}
return null;
}
}
[NUnitAddin]
public class CecilTestAddin : IAddin, ITestCaseBuilder {
public bool Install (IExtensionHost host)
{
if (host == null)
throw new ArgumentNullException ("host");
var builders = host.GetExtensionPoint ("TestCaseBuilders");
if (builders == null)
return false;
builders.Install (this);
return true;
}
public Test BuildFrom (MethodInfo method)
{
if (method == null)
throw new ArgumentNullException ("method");
return CecilTestFactory.CreateTestSuite (method);
}
public bool CanBuildFrom (MethodInfo method)
{
if (method == null)
return false;
return IsCecilTestMethod (method);
}
static bool IsCecilTestMethod (MethodInfo method)
{
return Reflect.HasAttribute (method, typeof (TestModuleAttribute).FullName, false)
|| Reflect.HasAttribute (method, typeof (TestILAttribute).FullName, false)
|| Reflect.HasAttribute (method, typeof (TestCSharpAttribute).FullName, false);
}
}
}

View File

@@ -0,0 +1,14 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
[assembly: AssemblyTitle ("Mono.Cecil.Tests")]
[assembly: AssemblyProduct ("Mono.Cecil")]
[assembly: AssemblyCopyright ("Copyright © 2008 - 2011 Jb Evain")]
[assembly: ComVisible (false)]
[assembly: Guid ("da96c202-696a-457e-89af-5fa74e6bda0d")]
[assembly: AssemblyVersion ("1.0.0.0")]
[assembly: AssemblyFileVersion ("1.0.0.0")]

View File

@@ -0,0 +1,35 @@
using System;
using Mono.Cecil;
using NUnit.Framework;
namespace Mono.Cecil.Tests {
[TestFixture]
public class AssemblyTests : BaseTestFixture {
[TestModule ("hello.exe")]
public void Name (ModuleDefinition module)
{
var name = module.Assembly.Name;
Assert.IsNotNull (name);
Assert.AreEqual ("hello", name.Name);
Assert.AreEqual (string.Empty, name.Culture);
Assert.AreEqual (new Version (0, 0, 0, 0), name.Version);
Assert.AreEqual (AssemblyHashAlgorithm.SHA1, name.HashAlgorithm);
}
[Test]
public void ParseLowerCaseNameParts()
{
var name = AssemblyNameReference.Parse ("Foo, version=2.0.0.0, culture=fr-FR");
Assert.AreEqual ("Foo", name.Name);
Assert.AreEqual (2, name.Version.Major);
Assert.AreEqual (0, name.Version.Minor);
Assert.AreEqual ("fr-FR", name.Culture);
}
}
}

View File

@@ -0,0 +1,76 @@
using System;
using System.IO;
using System.Reflection;
using NUnit.Framework;
using Mono.Cecil.PE;
namespace Mono.Cecil.Tests {
public abstract class BaseTestFixture {
public static string GetResourcePath (string name, Assembly assembly)
{
return Path.Combine (FindResourcesDirectory (assembly), name);
}
public static string GetAssemblyResourcePath (string name, Assembly assembly)
{
return GetResourcePath (Path.Combine ("assemblies", name), assembly);
}
public static string GetCSharpResourcePath (string name, Assembly assembly)
{
return GetResourcePath (Path.Combine ("cs", name), assembly);
}
public static string GetILResourcePath (string name, Assembly assembly)
{
return GetResourcePath (Path.Combine ("il", name), assembly);
}
public static ModuleDefinition GetResourceModule (string name)
{
return ModuleDefinition.ReadModule (GetAssemblyResourcePath (name, typeof (BaseTestFixture).Assembly));
}
public static ModuleDefinition GetResourceModule (string name, ReaderParameters parameters)
{
return ModuleDefinition.ReadModule (GetAssemblyResourcePath (name, typeof (BaseTestFixture).Assembly), parameters);
}
public static ModuleDefinition GetResourceModule (string name, ReadingMode mode)
{
return ModuleDefinition.ReadModule (GetAssemblyResourcePath (name, typeof (BaseTestFixture).Assembly), new ReaderParameters (mode));
}
internal static Image GetResourceImage (string name)
{
using (var fs = new FileStream (GetAssemblyResourcePath (name, typeof (BaseTestFixture).Assembly), FileMode.Open, FileAccess.Read))
return ImageReader.ReadImageFrom (fs);
}
public static ModuleDefinition GetCurrentModule ()
{
return ModuleDefinition.ReadModule (typeof (BaseTestFixture).Module.FullyQualifiedName);
}
public static ModuleDefinition GetCurrentModule (ReaderParameters parameters)
{
return ModuleDefinition.ReadModule (typeof (BaseTestFixture).Module.FullyQualifiedName, parameters);
}
public static string FindResourcesDirectory (Assembly assembly)
{
var path = Path.GetDirectoryName (new Uri (assembly.CodeBase).LocalPath);
while (!Directory.Exists (Path.Combine (path, "Resources"))) {
var old = path;
path = Path.GetDirectoryName (path);
Assert.AreNotEqual (old, path);
}
return Path.Combine (path, "Resources");
}
}
}

View File

@@ -0,0 +1,237 @@
using System;
using System.CodeDom.Compiler;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Text;
using NUnit.Framework;
namespace Mono.Cecil.Tests {
struct CompilationResult {
internal DateTime source_write_time;
internal string result_file;
public CompilationResult (DateTime write_time, string result_file)
{
this.source_write_time = write_time;
this.result_file = result_file;
}
}
abstract class CompilationService {
Dictionary<string, CompilationResult> files = new Dictionary<string, CompilationResult> ();
bool TryGetResult (string name, out string file_result)
{
file_result = null;
CompilationResult result;
if (!files.TryGetValue (name, out result))
return false;
if (result.source_write_time != File.GetLastWriteTime (name))
return false;
file_result = result.result_file;
return true;
}
public string Compile (string name)
{
string result_file;
if (TryGetResult (name, out result_file))
return result_file;
result_file = CompileFile (name);
RegisterFile (name, result_file);
return result_file;
}
void RegisterFile (string name, string result_file)
{
files [name] = new CompilationResult (File.GetLastWriteTime (name), result_file);
}
protected abstract string CompileFile (string name);
public static string CompileResource (string name)
{
var extension = Path.GetExtension (name);
if (extension == ".il")
return IlasmCompilationService.Instance.Compile (name);
if (extension == ".cs" || extension == ".vb")
return CodeDomCompilationService.Instance.Compile (name);
throw new NotSupportedException (extension);
}
protected static string GetCompiledFilePath (string file_name)
{
var tmp_cecil = Path.Combine (Path.GetTempPath (), "cecil");
if (!Directory.Exists (tmp_cecil))
Directory.CreateDirectory (tmp_cecil);
return Path.Combine (tmp_cecil, Path.GetFileName (file_name) + ".dll");
}
static bool OnMono { get { return typeof (object).Assembly.GetType ("Mono.Runtime") != null; } }
public static void Verify (string name)
{
var output = OnMono ? ShellService.PEDump (name) : ShellService.PEVerify (name);
if (output.ExitCode != 0)
Assert.Fail (output.ToString ());
}
}
class IlasmCompilationService : CompilationService {
public static readonly IlasmCompilationService Instance = new IlasmCompilationService ();
protected override string CompileFile (string name)
{
string file = GetCompiledFilePath (name);
var output = ShellService.ILAsm (name, file);
AssertAssemblerResult (output);
return file;
}
static void AssertAssemblerResult (ShellService.ProcessOutput output)
{
if (output.ExitCode != 0)
Assert.Fail (output.ToString ());
}
}
class CodeDomCompilationService : CompilationService {
public static readonly CodeDomCompilationService Instance = new CodeDomCompilationService ();
protected override string CompileFile (string name)
{
string file = GetCompiledFilePath (name);
using (var provider = GetProvider (name)) {
var parameters = GetDefaultParameters (name);
parameters.IncludeDebugInformation = false;
parameters.GenerateExecutable = false;
parameters.OutputAssembly = file;
var results = provider.CompileAssemblyFromFile (parameters, name);
AssertCompilerResults (results);
}
return file;
}
static void AssertCompilerResults (CompilerResults results)
{
Assert.IsFalse (results.Errors.HasErrors, GetErrorMessage (results));
}
static string GetErrorMessage (CompilerResults results)
{
if (!results.Errors.HasErrors)
return string.Empty;
var builder = new StringBuilder ();
foreach (CompilerError error in results.Errors)
builder.AppendLine (error.ToString ());
return builder.ToString ();
}
static CompilerParameters GetDefaultParameters (string name)
{
return GetCompilerInfo (name).CreateDefaultCompilerParameters ();
}
static CodeDomProvider GetProvider (string name)
{
return GetCompilerInfo (name).CreateProvider ();
}
static CompilerInfo GetCompilerInfo (string name)
{
return CodeDomProvider.GetCompilerInfo (
CodeDomProvider.GetLanguageFromExtension (Path.GetExtension (name)));
}
}
class ShellService {
public class ProcessOutput {
public int ExitCode;
public string StdOut;
public string StdErr;
public ProcessOutput (int exitCode, string stdout, string stderr)
{
ExitCode = exitCode;
StdOut = stdout;
StdErr = stderr;
}
public override string ToString ()
{
return StdOut + StdErr;
}
}
static ProcessOutput RunProcess (string target, params string [] arguments)
{
var stdout = new StringWriter ();
var stderr = new StringWriter ();
var process = new Process {
StartInfo = new ProcessStartInfo {
FileName = target,
Arguments = string.Join (" ", arguments),
CreateNoWindow = true,
UseShellExecute = false,
RedirectStandardError = true,
RedirectStandardInput = true,
RedirectStandardOutput = true,
},
};
process.Start ();
process.OutputDataReceived += (_, args) => stdout.Write (args.Data);
process.ErrorDataReceived += (_, args) => stderr.Write (args.Data);
process.BeginOutputReadLine ();
process.BeginErrorReadLine ();
process.WaitForExit ();
return new ProcessOutput (process.ExitCode, stdout.ToString (), stderr.ToString ());
}
public static ProcessOutput ILAsm (string source, string output)
{
return RunProcess ("ilasm", "/nologo", "/dll", "/out:" + Quote (output), Quote (source));
}
static string Quote (string file)
{
return "\"" + file + "\"";
}
public static ProcessOutput PEVerify (string source)
{
return RunProcess ("peverify", "/nologo", Quote (source));
}
public static ProcessOutput PEDump (string source)
{
return RunProcess ("pedump", "--verify code,metadata", Quote (source));
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,66 @@
using System;
using Mono.Cecil;
using Mono.Cecil.Metadata;
using NUnit.Framework;
namespace Mono.Cecil.Tests {
[TestFixture]
public class EventTests : BaseTestFixture {
[TestCSharp ("Events.cs")]
public void AbstractMethod (ModuleDefinition module)
{
var type = module.GetType ("Foo");
Assert.IsTrue (type.HasEvents);
var events = type.Events;
Assert.AreEqual (1, events.Count);
var @event = events [0];
Assert.IsNotNull (@event);
Assert.AreEqual ("Bar", @event.Name);
Assert.IsNotNull (@event.EventType);
Assert.AreEqual ("Pan", @event.EventType.FullName);
Assert.IsNotNull (@event.AddMethod);
Assert.AreEqual (MethodSemanticsAttributes.AddOn, @event.AddMethod.SemanticsAttributes);
Assert.IsNotNull (@event.RemoveMethod);
Assert.AreEqual (MethodSemanticsAttributes.RemoveOn, @event.RemoveMethod.SemanticsAttributes);
}
[TestIL ("others.il")]
public void OtherMethod (ModuleDefinition module)
{
var type = module.GetType ("Others");
Assert.IsTrue (type.HasEvents);
var events = type.Events;
Assert.AreEqual (1, events.Count);
var @event = events [0];
Assert.IsNotNull (@event);
Assert.AreEqual ("Handler", @event.Name);
Assert.IsNotNull (@event.EventType);
Assert.AreEqual ("System.EventHandler", @event.EventType.FullName);
Assert.IsTrue (@event.HasOtherMethods);
Assert.AreEqual (2, @event.OtherMethods.Count);
var other = @event.OtherMethods [0];
Assert.AreEqual ("dang_Handler", other.Name);
other = @event.OtherMethods [1];
Assert.AreEqual ("fang_Handler", other.Name);
}
}
}

View File

@@ -0,0 +1,92 @@
using System;
using System.Linq;
using SR = System.Reflection;
using Mono.Cecil;
namespace Mono.Cecil.Tests {
public static class Extensions {
public static MethodDefinition GetMethod (this TypeDefinition self, string name)
{
return self.Methods.Where (m => m.Name == name).First ();
}
public static FieldDefinition GetField (this TypeDefinition self, string name)
{
return self.Fields.Where (f => f.Name == name).First ();
}
public static TypeDefinition ToDefinition (this Type self)
{
var module = ModuleDefinition.ReadModule (self.Module.FullyQualifiedName);
return (TypeDefinition) module.LookupToken (self.MetadataToken);
}
public static MethodDefinition ToDefinition (this SR.MethodBase method)
{
var declaring_type = method.DeclaringType.ToDefinition ();
return (MethodDefinition) declaring_type.Module.LookupToken (method.MetadataToken);
}
public static FieldDefinition ToDefinition (this SR.FieldInfo field)
{
var declaring_type = field.DeclaringType.ToDefinition ();
return (FieldDefinition) declaring_type.Module.LookupToken (field.MetadataToken);
}
public static TypeReference MakeGenericType (this TypeReference self, params TypeReference [] arguments)
{
if (self.GenericParameters.Count != arguments.Length)
throw new ArgumentException ();
var instance = new GenericInstanceType (self);
foreach (var argument in arguments)
instance.GenericArguments.Add (argument);
return instance;
}
public static MethodReference MakeGenericMethod (this MethodReference self, params TypeReference [] arguments)
{
if (self.GenericParameters.Count != arguments.Length)
throw new ArgumentException ();
var instance = new GenericInstanceMethod (self);
foreach (var argument in arguments)
instance.GenericArguments.Add (argument);
return instance;
}
public static MethodReference MakeGeneric (this MethodReference self, params TypeReference [] arguments)
{
var reference = new MethodReference {
Name = self.Name,
DeclaringType = self.DeclaringType.MakeGenericType (arguments),
HasThis = self.HasThis,
ExplicitThis = self.ExplicitThis,
ReturnType = self.ReturnType,
CallingConvention = self.CallingConvention,
};
foreach (var parameter in self.Parameters)
reference.Parameters.Add (new ParameterDefinition (parameter.ParameterType));
foreach (var generic_parameter in self.GenericParameters)
reference.GenericParameters.Add (new GenericParameter (generic_parameter.Name, reference));
return reference;
}
public static FieldReference MakeGeneric (this FieldReference self, params TypeReference [] arguments)
{
return new FieldReference {
Name = self.Name,
DeclaringType = self.DeclaringType.MakeGenericType (arguments),
FieldType = self.FieldType,
};
}
}
}

View File

@@ -0,0 +1,333 @@
using System;
using Mono.Cecil;
using Mono.Cecil.Metadata;
using Mono.Cecil.PE;
using NUnit.Framework;
namespace Mono.Cecil.Tests {
[TestFixture]
public class FieldTests : BaseTestFixture {
[TestCSharp ("Fields.cs")]
public void TypeDefField (ModuleDefinition module)
{
var type = module.Types [1];
Assert.AreEqual ("Foo", type.Name);
Assert.AreEqual (1, type.Fields.Count);
var field = type.Fields [0];
Assert.AreEqual ("bar", field.Name);
Assert.AreEqual (1, field.MetadataToken.RID);
Assert.IsNotNull (field.FieldType);
Assert.AreEqual ("Bar", field.FieldType.FullName);
Assert.AreEqual (TokenType.Field, field.MetadataToken.TokenType);
Assert.IsFalse (field.HasConstant);
Assert.IsNull (field.Constant);
}
[TestCSharp ("Fields.cs")]
public void PrimitiveTypes (ModuleDefinition module)
{
var type = module.GetType ("Baz");
AssertField (type, "char", typeof (char));
AssertField (type, "bool", typeof (bool));
AssertField (type, "sbyte", typeof (sbyte));
AssertField (type, "byte", typeof (byte));
AssertField (type, "int16", typeof (short));
AssertField (type, "uint16", typeof (ushort));
AssertField (type, "int32", typeof (int));
AssertField (type, "uint32", typeof (uint));
AssertField (type, "int64", typeof (long));
AssertField (type, "uint64", typeof (ulong));
AssertField (type, "single", typeof (float));
AssertField (type, "double", typeof (double));
AssertField (type, "string", typeof (string));
AssertField (type, "object", typeof (object));
}
[TestCSharp ("Fields.cs")]
public void VolatileField (ModuleDefinition module)
{
var type = module.GetType ("Bar");
Assert.IsTrue (type.HasFields);
Assert.AreEqual (1, type.Fields.Count);
var field = type.Fields [0];
Assert.AreEqual ("oiseau", field.Name);
Assert.AreEqual ("System.Int32 modreq(System.Runtime.CompilerServices.IsVolatile)", field.FieldType.FullName);
Assert.IsFalse (field.HasConstant);
}
[TestCSharp ("Layouts.cs")]
public void FieldLayout (ModuleDefinition module)
{
var foo = module.GetType ("Foo");
Assert.IsNotNull (foo);
Assert.IsTrue (foo.HasFields);
var fields = foo.Fields;
var field = fields [0];
Assert.AreEqual ("Bar", field.Name);
Assert.IsTrue (field.HasLayoutInfo);
Assert.AreEqual (0, field.Offset);
field = fields [1];
Assert.AreEqual ("Baz", field.Name);
Assert.IsTrue (field.HasLayoutInfo);
Assert.AreEqual (2, field.Offset);
field = fields [2];
Assert.AreEqual ("Gazonk", field.Name);
Assert.IsTrue (field.HasLayoutInfo);
Assert.AreEqual (4, field.Offset);
}
[TestCSharp ("Layouts.cs")]
public void FieldRVA (ModuleDefinition module)
{
var priv_impl = GetPrivateImplementationType (module);
Assert.IsNotNull (priv_impl);
Assert.AreEqual (1, priv_impl.Fields.Count);
var field = priv_impl.Fields [0];
Assert.IsNotNull (field);
Assert.AreNotEqual (0, field.RVA);
Assert.IsNotNull (field.InitialValue);
Assert.AreEqual (16, field.InitialValue.Length);
var buffer = new ByteBuffer (field.InitialValue);
Assert.AreEqual (1, buffer.ReadUInt32 ());
Assert.AreEqual (2, buffer.ReadUInt32 ());
Assert.AreEqual (3, buffer.ReadUInt32 ());
Assert.AreEqual (4, buffer.ReadUInt32 ());
}
[TestCSharp ("Generics.cs")]
public void GenericFieldDefinition (ModuleDefinition module)
{
var bar = module.GetType ("Bar`1");
Assert.IsNotNull (bar);
Assert.IsTrue (bar.HasGenericParameters);
var t = bar.GenericParameters [0];
Assert.AreEqual ("T", t.Name);
Assert.AreEqual (t.Owner, bar);
var bang = bar.GetField ("bang");
Assert.IsNotNull (bang);
Assert.AreEqual (t, bang.FieldType);
}
[TestIL ("types.il")]
public void ArrayFields (ModuleDefinition module)
{
var types = module.GetType ("Types");
Assert.IsNotNull (types);
var rank_two = types.GetField ("rank_two");
var array = rank_two.FieldType as ArrayType;
Assert.IsNotNull (array);
Assert.AreEqual (2, array.Rank);
Assert.IsFalse (array.Dimensions [0].IsSized);
Assert.IsFalse (array.Dimensions [1].IsSized);
var rank_two_low_bound_zero = types.GetField ("rank_two_low_bound_zero");
array = rank_two_low_bound_zero.FieldType as ArrayType;
Assert.IsNotNull (array);
Assert.AreEqual (2, array.Rank);
Assert.IsTrue (array.Dimensions [0].IsSized);
Assert.AreEqual (0, array.Dimensions [0].LowerBound);
Assert.AreEqual (null, array.Dimensions [0].UpperBound);
Assert.IsTrue (array.Dimensions [1].IsSized);
Assert.AreEqual (0, array.Dimensions [1].LowerBound);
Assert.AreEqual (null, array.Dimensions [1].UpperBound);
var rank_one_low_bound_m1 = types.GetField ("rank_one_low_bound_m1");
array = rank_one_low_bound_m1.FieldType as ArrayType;
Assert.IsNotNull (array);
Assert.AreEqual (1, array.Rank);
Assert.IsTrue (array.Dimensions [0].IsSized);
Assert.AreEqual (-1, array.Dimensions [0].LowerBound);
Assert.AreEqual (4, array.Dimensions [0].UpperBound);
}
[TestCSharp ("Fields.cs")]
public void EnumFieldsConstant (ModuleDefinition module)
{
var pim = module.GetType ("Pim");
Assert.IsNotNull (pim);
var field = pim.GetField ("Pam");
Assert.IsTrue (field.HasConstant);
Assert.AreEqual (1, (int) field.Constant);
field = pim.GetField ("Poum");
Assert.AreEqual (2, (int) field.Constant);
}
[TestCSharp ("Fields.cs")]
public void StringAndClassConstant (ModuleDefinition module)
{
var panpan = module.GetType ("PanPan");
Assert.IsNotNull (panpan);
var field = panpan.GetField ("Peter");
Assert.IsTrue (field.HasConstant);
Assert.IsNull (field.Constant);
field = panpan.GetField ("QQ");
Assert.AreEqual ("qq", (string) field.Constant);
field = panpan.GetField ("nil");
Assert.AreEqual (null, (string) field.Constant);
}
[TestCSharp ("Fields.cs")]
public void ObjectConstant (ModuleDefinition module)
{
var panpan = module.GetType ("PanPan");
Assert.IsNotNull (panpan);
var field = panpan.GetField ("obj");
Assert.IsTrue (field.HasConstant);
Assert.IsNull (field.Constant);
}
[TestIL ("types.il")]
public void NullPrimitiveConstant (ModuleDefinition module)
{
var fields = module.GetType ("Fields");
var field = fields.GetField ("int32_nullref");
Assert.IsTrue (field.HasConstant);
Assert.AreEqual (null, field.Constant);
}
[TestCSharp ("Fields.cs")]
public void ArrayConstant (ModuleDefinition module)
{
var panpan = module.GetType ("PanPan");
Assert.IsNotNull (panpan);
var field = panpan.GetField ("ints");
Assert.IsTrue (field.HasConstant);
Assert.IsNull (field.Constant);
}
[TestIL ("types.il")]
public void ConstantCoalescing (ModuleDefinition module)
{
var fields = module.GetType ("Fields");
var field = fields.GetField ("int32_int16");
Assert.AreEqual ("System.Int32", field.FieldType.FullName);
Assert.IsTrue (field.HasConstant);
Assert.IsInstanceOf (typeof (short), field.Constant);
Assert.AreEqual ((short) 1, field.Constant);
field = fields.GetField ("int16_int32");
Assert.AreEqual ("System.Int16", field.FieldType.FullName);
Assert.IsTrue (field.HasConstant);
Assert.IsInstanceOf (typeof (int), field.Constant);
Assert.AreEqual (1, field.Constant);
field = fields.GetField ("char_int16");
Assert.AreEqual ("System.Char", field.FieldType.FullName);
Assert.IsTrue (field.HasConstant);
Assert.IsInstanceOf (typeof (short), field.Constant);
Assert.AreEqual ((short) 1, field.Constant);
field = fields.GetField ("int16_char");
Assert.AreEqual ("System.Int16", field.FieldType.FullName);
Assert.IsTrue (field.HasConstant);
Assert.IsInstanceOf (typeof (char), field.Constant);
Assert.AreEqual ('s', field.Constant);
}
[TestCSharp ("Generics.cs")]
public void NestedEnumOfGenericTypeDefinition (ModuleDefinition module)
{
var dang = module.GetType ("Bongo`1/Dang");
Assert.IsNotNull (dang);
var field = dang.GetField ("Ding");
Assert.IsNotNull (field);
Assert.AreEqual (2, field.Constant);
field = dang.GetField ("Dong");
Assert.IsNotNull (field);
Assert.AreEqual (12, field.Constant);
}
[TestModule ("marshal.dll")]
public void MarshalAsFixedStr (ModuleDefinition module)
{
var boc = module.GetType ("Boc");
var field = boc.GetField ("a");
Assert.IsNotNull (field);
Assert.IsTrue (field.HasMarshalInfo);
var info = (FixedSysStringMarshalInfo) field.MarshalInfo;
Assert.AreEqual (42, info.Size);
}
[TestModule ("marshal.dll")]
public void MarshalAsFixedArray (ModuleDefinition module)
{
var boc = module.GetType ("Boc");
var field = boc.GetField ("b");
Assert.IsNotNull (field);
Assert.IsTrue (field.HasMarshalInfo);
var info = (FixedArrayMarshalInfo) field.MarshalInfo;
Assert.AreEqual (12, info.Size);
Assert.AreEqual (NativeType.Boolean, info.ElementType);
}
static TypeDefinition GetPrivateImplementationType (ModuleDefinition module)
{
foreach (var type in module.Types)
if (type.FullName.Contains ("<PrivateImplementationDetails>"))
return type;
return null;
}
static void AssertField (TypeDefinition type, string name, Type expected)
{
var field = type.GetField (name);
Assert.IsNotNull (field, name);
Assert.AreEqual (expected.FullName, field.FieldType.FullName);
}
}
}

View File

@@ -0,0 +1,179 @@
using System;
using System.IO;
using Mono.Cecil;
using Mono.Cecil.Cil;
namespace Mono.Cecil.Tests {
public static class Formatter {
public static string FormatInstruction (Instruction instruction)
{
var writer = new StringWriter ();
WriteInstruction (writer, instruction);
return writer.ToString ();
}
public static string FormatMethodBody (MethodDefinition method)
{
var writer = new StringWriter ();
WriteMethodBody (writer, method);
return writer.ToString ();
}
public static void WriteMethodBody (TextWriter writer, MethodDefinition method)
{
var body = method.Body;
WriteVariables (writer, body);
foreach (Instruction instruction in body.Instructions) {
var sequence_point = instruction.SequencePoint;
if (sequence_point != null) {
writer.Write ('\t');
WriteSequencePoint (writer, sequence_point);
writer.WriteLine ();
}
writer.Write ('\t');
WriteInstruction (writer, instruction);
writer.WriteLine ();
}
WriteExceptionHandlers (writer, body);
}
static void WriteVariables (TextWriter writer, MethodBody body)
{
var variables = body.Variables;
writer.Write ('\t');
writer.Write (".locals {0}(", body.InitLocals ? "init " : string.Empty);
for (int i = 0; i < variables.Count; i++) {
if (i > 0)
writer.Write (", ");
var variable = variables [i];
writer.Write ("{0} {1}", variable.VariableType, variable);
}
writer.WriteLine (")");
}
static void WriteInstruction (TextWriter writer, Instruction instruction)
{
writer.Write (FormatLabel (instruction.Offset));
writer.Write (": ");
writer.Write (instruction.OpCode.Name);
if (null != instruction.Operand) {
writer.Write (' ');
WriteOperand (writer, instruction.Operand);
}
}
static void WriteSequencePoint (TextWriter writer, SequencePoint sequence_point)
{
writer.Write (".line {0},{1}:{2},{3} '{4}'",
sequence_point.StartLine,
sequence_point.EndLine,
sequence_point.StartColumn,
sequence_point.EndColumn,
sequence_point.Document.Url);
}
static string FormatLabel (int offset)
{
string label = "000" + offset.ToString ("x");
return "IL_" + label.Substring (label.Length - 4);
}
static string FormatLabel (Instruction instruction)
{
return FormatLabel (instruction.Offset);
}
static void WriteOperand (TextWriter writer, object operand)
{
if (null == operand) throw new ArgumentNullException ("operand");
var target = operand as Instruction;
if (null != target) {
writer.Write (FormatLabel (target.Offset));
return;
}
var targets = operand as Instruction [];
if (null != targets) {
WriteLabelList (writer, targets);
return;
}
string s = operand as string;
if (null != s) {
writer.Write ("\"" + s + "\"");
return;
}
var parameter = operand as ParameterDefinition;
if (parameter != null) {
writer.Write (ToInvariantCultureString (parameter.Sequence));
return;
}
s = ToInvariantCultureString (operand);
writer.Write (s);
}
static void WriteLabelList (TextWriter writer, Instruction [] instructions)
{
writer.Write ("(");
for (int i = 0; i < instructions.Length; i++) {
if (i != 0) writer.Write (", ");
writer.Write (FormatLabel (instructions [i].Offset));
}
writer.Write (")");
}
static void WriteExceptionHandlers (TextWriter writer, MethodBody body)
{
if (!body.HasExceptionHandlers)
return;
foreach (var handler in body.ExceptionHandlers) {
writer.Write ("\t");
writer.WriteLine (".try {0} to {1} {2} handler {3} to {4}",
FormatLabel (handler.TryStart),
FormatLabel (handler.TryEnd),
FormatHandlerType (handler),
FormatLabel (handler.HandlerStart),
FormatLabel (handler.HandlerEnd));
}
}
static string FormatHandlerType (ExceptionHandler handler)
{
var handler_type = handler.HandlerType;
var type = handler_type.ToString ().ToLowerInvariant ();
switch (handler_type) {
case ExceptionHandlerType.Catch:
return string.Format ("{0} {1}", type, handler.CatchType.FullName);
case ExceptionHandlerType.Filter:
throw new NotImplementedException ();
default:
return type;
}
}
public static string ToInvariantCultureString (object value)
{
var convertible = value as IConvertible;
return (null != convertible)
? convertible.ToString (System.Globalization.CultureInfo.InvariantCulture)
: value.ToString ();
}
}
}

View File

@@ -0,0 +1,79 @@
using System;
using System.Linq;
using Mono.Cecil;
using Mono.Cecil.Cil;
using NUnit.Framework;
namespace Mono.Cecil.Tests {
[TestFixture]
public class ILProcessorTests : BaseTestFixture {
[Test]
public void Append ()
{
var method = CreateTestMethod ();
var il = method.GetILProcessor ();
var ret = il.Create (OpCodes.Ret);
il.Append (ret);
AssertOpCodeSequence (new [] { OpCodes.Ret }, method);
}
[Test]
public void InsertBefore ()
{
var method = CreateTestMethod (OpCodes.Ldloc_0, OpCodes.Ldloc_2, OpCodes.Ldloc_3);
var il = method.GetILProcessor ();
var ldloc_2 = method.Instructions.Where (i => i.OpCode == OpCodes.Ldloc_2).First ();
il.InsertBefore (
ldloc_2,
il.Create (OpCodes.Ldloc_1));
AssertOpCodeSequence (new [] { OpCodes.Ldloc_0, OpCodes.Ldloc_1, OpCodes.Ldloc_2, OpCodes.Ldloc_3 }, method);
}
[Test]
public void InsertAfter ()
{
var method = CreateTestMethod (OpCodes.Ldloc_0, OpCodes.Ldloc_2, OpCodes.Ldloc_3);
var il = method.GetILProcessor ();
var ldloc_0 = method.Instructions.First ();
il.InsertAfter (
ldloc_0,
il.Create (OpCodes.Ldloc_1));
AssertOpCodeSequence (new [] { OpCodes.Ldloc_0, OpCodes.Ldloc_1, OpCodes.Ldloc_2, OpCodes.Ldloc_3 }, method);
}
static void AssertOpCodeSequence (OpCode [] expected, MethodBody body)
{
var opcodes = body.Instructions.Select (i => i.OpCode).ToArray ();
Assert.AreEqual (expected.Length, opcodes.Length);
for (int i = 0; i < opcodes.Length; i++)
Assert.AreEqual (expected [i], opcodes [i]);
}
static MethodBody CreateTestMethod (params OpCode [] opcodes)
{
var method = new MethodDefinition {
Name = "function",
};
var il = method.Body.GetILProcessor ();
foreach (var opcode in opcodes)
il.Emit (opcode);
return method.Body;
}
}
}

View File

@@ -0,0 +1,144 @@
using System;
using System.IO;
using Mono.Cecil;
using Mono.Cecil.PE;
using Mono.Cecil.Metadata;
using NUnit.Framework;
namespace Mono.Cecil.Tests {
[TestFixture]
public class ImageReadTests : BaseTestFixture {
[Test]
public void ImageSections ()
{
var image = GetResourceImage ("hello.exe");
Assert.AreEqual (3, image.Sections.Length);
Assert.AreEqual (".text", image.Sections [0].Name);
Assert.AreEqual (".rsrc", image.Sections [1].Name);
Assert.AreEqual (".reloc", image.Sections [2].Name);
}
[Test]
public void ImageMetadataVersion ()
{
var image = GetResourceImage ("hello.exe");
Assert.AreEqual (TargetRuntime.Net_2_0, image.Runtime);
image = GetResourceImage ("hello1.exe");
Assert.AreEqual (TargetRuntime.Net_1_1, image.Runtime);
}
[Test]
public void ImageModuleKind ()
{
var image = GetResourceImage ("hello.exe");
Assert.AreEqual (ModuleKind.Console, image.Kind);
image = GetResourceImage ("libhello.dll");
Assert.AreEqual (ModuleKind.Dll, image.Kind);
image = GetResourceImage ("hellow.exe");
Assert.AreEqual (ModuleKind.Windows, image.Kind);
}
[Test]
public void MetadataHeaps ()
{
var image = GetResourceImage ("hello.exe");
Assert.IsNotNull (image.TableHeap);
Assert.IsNotNull (image.StringHeap);
Assert.AreEqual (string.Empty, image.StringHeap.Read (0));
Assert.AreEqual ("<Module>", image.StringHeap.Read (1));
Assert.IsNotNull (image.UserStringHeap);
Assert.AreEqual (string.Empty, image.UserStringHeap.Read (0));
Assert.AreEqual ("Hello Cecil World !", image.UserStringHeap.Read (1));
Assert.IsNotNull (image.GuidHeap);
Assert.AreEqual (new Guid (), image.GuidHeap.Read (0));
Assert.AreEqual (new Guid ("C3BC2BD3-2576-4D00-A80E-465B5632415F"), image.GuidHeap.Read (1));
Assert.IsNotNull (image.BlobHeap);
Assert.AreEqual (new byte [0], image.BlobHeap.Read (0));
}
[Test]
public void TablesHeap ()
{
var image = GetResourceImage ("hello.exe");
var heap = image.TableHeap;
Assert.IsNotNull (heap);
Assert.AreEqual (1, heap [Table.Module].Length);
Assert.AreEqual (4, heap [Table.TypeRef].Length);
Assert.AreEqual (2, heap [Table.TypeDef].Length);
Assert.AreEqual (0, heap [Table.Field].Length);
Assert.AreEqual (2, heap [Table.Method].Length);
Assert.AreEqual (4, heap [Table.MemberRef].Length);
Assert.AreEqual (2, heap [Table.CustomAttribute].Length);
Assert.AreEqual (1, heap [Table.Assembly].Length);
Assert.AreEqual (1, heap [Table.AssemblyRef].Length);
}
[TestModule ("hello.x64.exe")]
public void X64Module (ModuleDefinition module)
{
Assert.AreEqual (TargetArchitecture.AMD64, module.Image.Architecture);
Assert.AreEqual (ModuleAttributes.ILOnly, module.Image.Attributes);
}
[TestModule ("hello.ia64.exe")]
public void IA64Module (ModuleDefinition module)
{
Assert.AreEqual (TargetArchitecture.IA64, module.Image.Architecture);
Assert.AreEqual (ModuleAttributes.ILOnly, module.Image.Attributes);
}
[TestModule ("hello.x86.exe")]
public void X86Module (ModuleDefinition module)
{
Assert.AreEqual (TargetArchitecture.I386, module.Image.Architecture);
Assert.AreEqual (ModuleAttributes.ILOnly | ModuleAttributes.Required32Bit, module.Image.Attributes);
}
[TestModule ("hello.anycpu.exe")]
public void AnyCpuModule (ModuleDefinition module)
{
Assert.AreEqual (TargetArchitecture.I386, module.Image.Architecture);
Assert.AreEqual (ModuleAttributes.ILOnly, module.Image.Attributes);
}
[TestModule ("delay-signed.dll")]
public void DelaySignedAssembly (ModuleDefinition module)
{
Assert.IsNotNull (module.Assembly.Name.PublicKey);
Assert.AreNotEqual (0, module.Assembly.Name.PublicKey.Length);
Assert.AreNotEqual (ModuleAttributes.StrongNameSigned, module.Attributes & ModuleAttributes.StrongNameSigned);
Assert.AreNotEqual (0, module.Image.StrongName.VirtualAddress);
Assert.AreNotEqual (0, module.Image.StrongName.Size);
}
[TestModule ("wp7.dll", Verify = false)]
public void WindowsPhoneNonSignedAssembly (ModuleDefinition module)
{
Assert.AreEqual (0, module.Assembly.Name.PublicKey.Length);
Assert.AreNotEqual (ModuleAttributes.StrongNameSigned, module.Attributes & ModuleAttributes.StrongNameSigned);
Assert.AreEqual (0, module.Image.StrongName.VirtualAddress);
Assert.AreEqual (0, module.Image.StrongName.Size);
}
[TestModule ("metro.exe", Verify = false)]
public void MetroAssembly (ModuleDefinition module)
{
Assert.AreEqual (ModuleCharacteristics.AppContainer, module.Characteristics & ModuleCharacteristics.AppContainer);
}
}
}

View File

@@ -0,0 +1,374 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using SR = System.Reflection;
using System.Runtime.CompilerServices;
using Mono.Cecil.Cil;
using NUnit.Framework;
namespace Mono.Cecil.Tests {
[TestFixture]
public class ImportCecilTests : BaseTestFixture {
[Test]
public void ImportStringByRef ()
{
var get_string = Compile<Func<string, string>> ((module, body) => {
var type = module.Types [1];
var method_by_ref = new MethodDefinition {
Name = "ModifyString",
IsPrivate = true,
IsStatic = true,
};
type.Methods.Add (method_by_ref);
method_by_ref.MethodReturnType.ReturnType = module.Import (typeof (void).ToDefinition ());
method_by_ref.Parameters.Add (new ParameterDefinition (module.Import (typeof (string).ToDefinition ())));
method_by_ref.Parameters.Add (new ParameterDefinition (module.Import (new ByReferenceType (typeof (string).ToDefinition ()))));
var m_il = method_by_ref.Body.GetILProcessor ();
m_il.Emit (OpCodes.Ldarg_1);
m_il.Emit (OpCodes.Ldarg_0);
m_il.Emit (OpCodes.Stind_Ref);
m_il.Emit (OpCodes.Ret);
var v_0 = new VariableDefinition (module.Import (typeof (string).ToDefinition ()));
body.Variables.Add (v_0);
var il = body.GetILProcessor ();
il.Emit (OpCodes.Ldnull);
il.Emit (OpCodes.Stloc, v_0);
il.Emit (OpCodes.Ldarg_0);
il.Emit (OpCodes.Ldloca, v_0);
il.Emit (OpCodes.Call, method_by_ref);
il.Emit (OpCodes.Ldloc_0);
il.Emit (OpCodes.Ret);
});
Assert.AreEqual ("foo", get_string ("foo"));
}
[Test]
public void ImportStringArray ()
{
var identity = Compile<Func<string [,], string [,]>> ((module, body) => {
var il = body.GetILProcessor ();
il.Emit (OpCodes.Ldarg_0);
il.Emit (OpCodes.Ret);
});
var array = new string [2, 2];
Assert.AreEqual (array, identity (array));
}
[Test]
public void ImportFieldStringEmpty ()
{
var get_empty = Compile<Func<string>> ((module, body) => {
var il = body.GetILProcessor ();
il.Emit (OpCodes.Ldsfld, module.Import (typeof (string).GetField ("Empty").ToDefinition ()));
il.Emit (OpCodes.Ret);
});
Assert.AreEqual ("", get_empty ());
}
[Test]
public void ImportStringConcat ()
{
var concat = Compile<Func<string, string, string>> ((module, body) => {
var il = body.GetILProcessor ();
il.Emit (OpCodes.Ldarg_0);
il.Emit (OpCodes.Ldarg_1);
il.Emit (OpCodes.Call, module.Import (typeof (string).GetMethod ("Concat", new [] { typeof (string), typeof (string) }).ToDefinition ()));
il.Emit (OpCodes.Ret);
});
Assert.AreEqual ("FooBar", concat ("Foo", "Bar"));
}
public class Generic<T> {
public T Field;
public T Method (T t)
{
return t;
}
public TS GenericMethod<TS> (T t, TS s)
{
return s;
}
public Generic<TS> ComplexGenericMethod<TS> (T t, TS s)
{
return new Generic<TS> { Field = s };
}
}
[Test]
public void ImportGenericField ()
{
var get_field = Compile<Func<Generic<string>, string>> ((module, body) => {
var generic_def = module.Import (typeof (Generic<>)).Resolve ();
var field_def = generic_def.Fields.Where (f => f.Name == "Field").First ();
var field_string = field_def.MakeGeneric (module.Import (typeof (string)));
var field_ref = module.Import (field_string);
var il = body.GetILProcessor ();
il.Emit (OpCodes.Ldarg_0);
il.Emit (OpCodes.Ldfld, field_ref);
il.Emit (OpCodes.Ret);
});
var generic = new Generic<string> {
Field = "foo",
};
Assert.AreEqual ("foo", get_field (generic));
}
[Test]
public void ImportGenericMethod ()
{
var generic_identity = Compile<Func<Generic<int>, int, int>> ((module, body) => {
var generic_def = module.Import (typeof (Generic<>)).Resolve ();
var method_def = generic_def.Methods.Where (m => m.Name == "Method").First ();
var method_int = method_def.MakeGeneric (module.Import (typeof (int)));
var method_ref = module.Import (method_int);
var il = body.GetILProcessor ();
il.Emit (OpCodes.Ldarg_0);
il.Emit (OpCodes.Ldarg_1);
il.Emit (OpCodes.Callvirt, method_ref);
il.Emit (OpCodes.Ret);
});
Assert.AreEqual (42, generic_identity (new Generic<int> (), 42));
}
[Test]
public void ImportGenericMethodSpec ()
{
var gen_spec_id = Compile<Func<Generic<string>, int, int>> ((module, body) => {
var generic_def = module.Import (typeof (Generic<>)).Resolve ();
var method_def = generic_def.Methods.Where (m => m.Name == "GenericMethod").First ();
var method_string = method_def.MakeGeneric (module.Import (typeof (string)));
var method_instance = method_string.MakeGenericMethod (module.Import (typeof (int)));
var method_ref = module.Import (method_instance);
var il = body.GetILProcessor ();
il.Emit (OpCodes.Ldarg_0);
il.Emit (OpCodes.Ldnull);
il.Emit (OpCodes.Ldarg_1);
il.Emit (OpCodes.Callvirt, method_ref);
il.Emit (OpCodes.Ret);
});
Assert.AreEqual (42, gen_spec_id (new Generic<string> (), 42));
}
[Test]
public void ImportComplexGenericMethodSpec ()
{
var gen_spec_id = Compile<Func<Generic<string>, int, int>> ((module, body) => {
var generic_def = module.Import (typeof (Generic<>)).Resolve ();
var method_def = generic_def.Methods.Where (m => m.Name == "ComplexGenericMethod").First ();
var method_string = method_def.MakeGeneric (module.Import (typeof (string)));
var method_instance = method_string.MakeGenericMethod (module.Import (typeof (int)));
var method_ref = module.Import (method_instance);
var field_def = generic_def.Fields.Where (f => f.Name == "Field").First ();
var field_int = field_def.MakeGeneric (module.Import (typeof (int)));
var field_ref = module.Import (field_int);
var il = body.GetILProcessor ();
il.Emit (OpCodes.Ldarg_0);
il.Emit (OpCodes.Ldnull);
il.Emit (OpCodes.Ldarg_1);
il.Emit (OpCodes.Callvirt, method_ref);
il.Emit (OpCodes.Ldfld, field_ref);
il.Emit (OpCodes.Ret);
});
Assert.AreEqual (42, gen_spec_id (new Generic<string> (), 42));
}
[Test]
public void ImportMethodOnOpenGeneric ()
{
var generic = typeof (Generic<>).ToDefinition ();
var module = ModuleDefinition.CreateModule ("foo", ModuleKind.Dll);
var method = module.Import (generic.GetMethod ("Method"));
Assert.AreEqual ("T Mono.Cecil.Tests.ImportCecilTests/Generic`1::Method(T)", method.FullName);
}
public class ContextGeneric1Method2<G1>
{
public G1 GenericMethod<R1, S1> (R1 r, S1 s)
{
return default (G1);
}
}
public class ContextGeneric2Method1<G2, H2>
{
public R2 GenericMethod<R2> (G2 g, H2 h)
{
return default (R2);
}
}
public class NestedGenericsA<A>
{
public class NestedGenericsB<B>
{
public class NestedGenericsC<C>
{
public A GenericMethod (B b, C c)
{
return default (A);
}
}
}
}
[Test]
public void ContextGenericTest ()
{
var module = ModuleDefinition.ReadModule (typeof (ContextGeneric1Method2<>).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 imported_type = module.Import (type);
var method = module.Import (meth, imported_type);
Assert.AreEqual ("G1 Mono.Cecil.Tests.ImportCecilTests/ContextGeneric1Method2`1<Mono.Cecil.Tests.ImportCecilTests/ContextGeneric2Method1`2<G2,H2>>::GenericMethod<R1,S1>(R1,S1)", method.FullName);
// and the other way around
type = typeof (ContextGeneric2Method1<,>).MakeGenericType (typeof (ContextGeneric1Method2<>), typeof (IList<>));
meth = type.GetMethod ("GenericMethod");
imported_type = module.Import (type);
method = module.Import (meth, imported_type);
Assert.AreEqual ("R2 Mono.Cecil.Tests.ImportCecilTests/ContextGeneric2Method1`2<Mono.Cecil.Tests.ImportCecilTests/ContextGeneric1Method2`1<G1>,System.Collections.Generic.IList`1<T>>::GenericMethod<R2>(G2,H2)", method.FullName);
// not sure about this one
type = typeof (NestedGenericsA<string>.NestedGenericsB<int>.NestedGenericsC<float>);
meth = type.GetMethod ("GenericMethod");
imported_type = module.Import (type);
method = module.Import (meth, imported_type);
Assert.AreEqual ("A Mono.Cecil.Tests.ImportCecilTests/NestedGenericsA`1/NestedGenericsB`1/NestedGenericsC`1<System.String,System.Int32,System.Single>::GenericMethod(B,C)", method.FullName);
// We need both the method & type !
type = typeof (Generic<>).MakeGenericType (typeof (string));
meth = type.GetMethod ("ComplexGenericMethod");
imported_type = module.Import (type);
method = module.Import (meth, imported_type);
Assert.AreEqual ("Mono.Cecil.Tests.ImportCecilTests/Generic`1<TS> Mono.Cecil.Tests.ImportCecilTests/Generic`1<System.String>::ComplexGenericMethod<TS>(T,TS)", method.FullName);
}
delegate void Emitter (ModuleDefinition module, MethodBody body);
[MethodImpl (MethodImplOptions.NoInlining)]
static TDelegate Compile<TDelegate> (Emitter emitter)
where TDelegate : class
{
var name = GetTestCaseName ();
var module = CreateTestModule<TDelegate> (name, emitter);
var assembly = LoadTestModule (module);
return CreateRunDelegate<TDelegate> (GetTestCase (name, assembly));
}
static TDelegate CreateRunDelegate<TDelegate> (Type type)
where TDelegate : class
{
return (TDelegate) (object) Delegate.CreateDelegate (typeof (TDelegate), type.GetMethod ("Run"));
}
static Type GetTestCase (string name, SR.Assembly assembly)
{
return assembly.GetType (name);
}
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 ());
}
}
static ModuleDefinition CreateTestModule<TDelegate> (string name, Emitter emitter)
{
var module = CreateModule (name);
var type = new TypeDefinition (
"",
name,
TypeAttributes.Public | TypeAttributes.Sealed | TypeAttributes.Abstract,
module.Import (typeof (object)));
module.Types.Add (type);
var method = CreateMethod (type, typeof (TDelegate).GetMethod ("Invoke"));
emitter (module, method.Body);
return module;
}
static MethodDefinition CreateMethod (TypeDefinition type, SR.MethodInfo pattern)
{
var module = type.Module;
var method = new MethodDefinition {
Name = "Run",
IsPublic = true,
IsStatic = true,
};
type.Methods.Add (method);
method.MethodReturnType.ReturnType = module.Import (pattern.ReturnType);
foreach (var parameter_pattern in pattern.GetParameters ())
method.Parameters.Add (new ParameterDefinition (module.Import (parameter_pattern.ParameterType)));
return method;
}
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;
}
}
}

View File

@@ -0,0 +1,409 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using SR = System.Reflection;
using System.Runtime.CompilerServices;
using Mono.Cecil.Cil;
using NUnit.Framework;
namespace Mono.Cecil.Tests {
[TestFixture]
public class ImportReflectionTests : BaseTestFixture {
[Test]
public void ImportString ()
{
var get_string = Compile<Func<string>> ((_, body) => {
var il = body.GetILProcessor ();
il.Emit (OpCodes.Ldstr, "yo dawg!");
il.Emit (OpCodes.Ret);
});
Assert.AreEqual ("yo dawg!", get_string ());
}
[Test]
public void ImportInt ()
{
var add = Compile<Func<int, int, int>> ((_, body) => {
var il = body.GetILProcessor ();
il.Emit (OpCodes.Ldarg_0);
il.Emit (OpCodes.Ldarg_1);
il.Emit (OpCodes.Add);
il.Emit (OpCodes.Ret);
});
Assert.AreEqual (42, add (40, 2));
}
[Test]
public void ImportStringByRef ()
{
var get_string = Compile<Func<string, string>> ((module, body) => {
var type = module.Types [1];
var method_by_ref = new MethodDefinition {
Name = "ModifyString",
IsPrivate = true,
IsStatic = true,
};
type.Methods.Add (method_by_ref);
method_by_ref.MethodReturnType.ReturnType = module.Import (typeof (void));
method_by_ref.Parameters.Add (new ParameterDefinition (module.Import (typeof (string))));
method_by_ref.Parameters.Add (new ParameterDefinition (module.Import (typeof (string).MakeByRefType ())));
var m_il = method_by_ref.Body.GetILProcessor ();
m_il.Emit (OpCodes.Ldarg_1);
m_il.Emit (OpCodes.Ldarg_0);
m_il.Emit (OpCodes.Stind_Ref);
m_il.Emit (OpCodes.Ret);
var v_0 = new VariableDefinition (module.Import (typeof (string)));
body.Variables.Add (v_0);
var il = body.GetILProcessor ();
il.Emit (OpCodes.Ldnull);
il.Emit (OpCodes.Stloc, v_0);
il.Emit (OpCodes.Ldarg_0);
il.Emit (OpCodes.Ldloca, v_0);
il.Emit (OpCodes.Call, method_by_ref);
il.Emit (OpCodes.Ldloc_0);
il.Emit (OpCodes.Ret);
});
Assert.AreEqual ("foo", get_string ("foo"));
}
[Test]
public void ImportStringArray ()
{
var identity = Compile<Func<string [,], string [,]>> ((module, body) => {
var il = body.GetILProcessor ();
il.Emit (OpCodes.Ldarg_0);
il.Emit (OpCodes.Ret);
});
var array = new string [2, 2];
Assert.AreEqual (array, identity (array));
}
[Test]
public void ImportFieldStringEmpty ()
{
var get_empty = Compile<Func<string>> ((module, body) => {
var il = body.GetILProcessor ();
il.Emit (OpCodes.Ldsfld, module.Import (typeof (string).GetField ("Empty")));
il.Emit (OpCodes.Ret);
});
Assert.AreEqual ("", get_empty ());
}
[Test]
public void ImportStringConcat ()
{
var concat = Compile<Func<string, string, string>> ((module, body) => {
var il = body.GetILProcessor ();
il.Emit (OpCodes.Ldarg_0);
il.Emit (OpCodes.Ldarg_1);
il.Emit (OpCodes.Call, module.Import (typeof (string).GetMethod ("Concat", new [] { typeof (string), typeof (string) })));
il.Emit (OpCodes.Ret);
});
Assert.AreEqual ("FooBar", concat ("Foo", "Bar"));
}
public class Generic<T> {
public T Field;
public T Method (T t)
{
return t;
}
public TS GenericMethod<TS> (T t, TS s)
{
return s;
}
public Generic<TS> ComplexGenericMethod<TS> (T t, TS s)
{
return new Generic<TS> { Field = s };
}
}
[Test]
public void ImportGenericField ()
{
var get_field = Compile<Func<Generic<string>, string>> ((module, body) => {
var il = body.GetILProcessor ();
il.Emit (OpCodes.Ldarg_0);
il.Emit (OpCodes.Ldfld, module.Import (typeof (Generic<string>).GetField ("Field")));
il.Emit (OpCodes.Ret);
});
var generic = new Generic<string> {
Field = "foo",
};
Assert.AreEqual ("foo", get_field (generic));
}
[Test]
public void ImportGenericMethod ()
{
var generic_identity = Compile<Func<Generic<int>, int, int>> ((module, body) => {
var il = body.GetILProcessor ();
il.Emit (OpCodes.Ldarg_0);
il.Emit (OpCodes.Ldarg_1);
il.Emit (OpCodes.Callvirt, module.Import (typeof (Generic<int>).GetMethod ("Method")));
il.Emit (OpCodes.Ret);
});
Assert.AreEqual (42, generic_identity (new Generic<int> (), 42));
}
[Test]
public void ImportGenericMethodSpec ()
{
var gen_spec_id = Compile<Func<Generic<string>, int, int>> ((module, body) => {
var il = body.GetILProcessor ();
il.Emit (OpCodes.Ldarg_0);
il.Emit (OpCodes.Ldnull);
il.Emit (OpCodes.Ldarg_1);
il.Emit (OpCodes.Callvirt, module.Import (typeof (Generic<string>).GetMethod ("GenericMethod").MakeGenericMethod (typeof (int))));
il.Emit (OpCodes.Ret);
});
Assert.AreEqual (42, gen_spec_id (new Generic<string> (), 42));
}
[Test]
public void ImportComplexGenericMethodSpec ()
{
var gen_spec_id = Compile<Func<Generic<string>, int, int>> ((module, body) => {
var il = body.GetILProcessor ();
il.Emit (OpCodes.Ldarg_0);
il.Emit (OpCodes.Ldnull);
il.Emit (OpCodes.Ldarg_1);
il.Emit (OpCodes.Callvirt, module.Import (typeof (Generic<string>).GetMethod ("ComplexGenericMethod").MakeGenericMethod (typeof (int))));
il.Emit (OpCodes.Ldfld, module.Import (typeof (Generic<string>).GetField ("Field")));
il.Emit (OpCodes.Ret);
});
Assert.AreEqual (42, gen_spec_id (new Generic<string> (), 42));
}
public class Foo<TFoo> {
public List<TFoo> list;
}
[Test]
public void ImportGenericTypeDefOrOpen ()
{
var module = typeof (Foo<>).ToDefinition ().Module;
var foo_def = module.Import (typeof (Foo<>));
var foo_open = module.Import (typeof (Foo<>), foo_def);
Assert.AreEqual ("Mono.Cecil.Tests.ImportReflectionTests/Foo`1", foo_def.FullName);
Assert.AreEqual ("Mono.Cecil.Tests.ImportReflectionTests/Foo`1<TFoo>", foo_open.FullName);
}
[Test]
public void ImportGenericTypeFromContext ()
{
var list_foo = typeof (Foo<>).GetField ("list").FieldType;
var generic_list_foo_open = typeof (Generic<>).MakeGenericType (list_foo);
var foo_def = typeof (Foo<>).ToDefinition ();
var module = foo_def.Module;
var generic_foo = module.Import (generic_list_foo_open, foo_def);
Assert.AreEqual ("Mono.Cecil.Tests.ImportReflectionTests/Generic`1<System.Collections.Generic.List`1<TFoo>>",
generic_foo.FullName);
}
[Test]
public void ImportGenericTypeDefFromContext ()
{
var foo_open = typeof (Foo<>).MakeGenericType (typeof (Foo<>).GetGenericArguments () [0]);
var generic_foo_open = typeof (Generic<>).MakeGenericType (foo_open);
var foo_def = typeof (Foo<>).ToDefinition ();
var module = foo_def.Module;
var generic_foo = module.Import (generic_foo_open, foo_def);
Assert.AreEqual ("Mono.Cecil.Tests.ImportReflectionTests/Generic`1<Mono.Cecil.Tests.ImportReflectionTests/Foo`1<TFoo>>",
generic_foo.FullName);
}
[Test]
public void ImportArrayTypeDefFromContext ()
{
var foo_open = typeof (Foo<>).MakeGenericType (typeof (Foo<>).GetGenericArguments () [0]);
var foo_open_array = foo_open.MakeArrayType ();
var foo_def = typeof (Foo<>).ToDefinition ();
var module = foo_def.Module;
var array_foo = module.Import (foo_open_array, foo_def);
Assert.AreEqual ("Mono.Cecil.Tests.ImportReflectionTests/Foo`1<TFoo>[]",
array_foo.FullName);
}
[Test]
public void ImportGenericFieldFromContext ()
{
var list_foo = typeof (Foo<>).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 foo_def = typeof (Foo<>).ToDefinition ();
var module = foo_def.Module;
var generic_field = module.Import (generic_list_foo_open_field, foo_def);
Assert.AreEqual ("T Mono.Cecil.Tests.ImportReflectionTests/Generic`1<System.Collections.Generic.List`1<TFoo>>::Field",
generic_field.FullName);
}
[Test]
public void ImportGenericMethodFromContext ()
{
var list_foo = typeof (Foo<>).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 foo_def = typeof (Foo<>).ToDefinition ();
var module = foo_def.Module;
var generic_method = module.Import (generic_list_foo_open_method, foo_def);
Assert.AreEqual ("T Mono.Cecil.Tests.ImportReflectionTests/Generic`1<System.Collections.Generic.List`1<TFoo>>::Method(T)",
generic_method.FullName);
}
[Test]
public void ImportMethodOnOpenGenericType ()
{
var module = typeof (Generic<>).ToDefinition ().Module;
var method = module.Import (typeof (Generic<>).GetMethod ("Method"));
Assert.AreEqual ("T Mono.Cecil.Tests.ImportReflectionTests/Generic`1<T>::Method(T)", method.FullName);
}
[Test]
public void ImportGenericMethodOnOpenGenericType ()
{
var module = typeof (Generic<>).ToDefinition ().Module;
var generic_method = module.Import (typeof (Generic<>).GetMethod ("GenericMethod"));
Assert.AreEqual ("TS Mono.Cecil.Tests.ImportReflectionTests/Generic`1<T>::GenericMethod(T,TS)", generic_method.FullName);
generic_method = module.Import (typeof (Generic<>).GetMethod ("GenericMethod"), generic_method);
Assert.AreEqual ("TS Mono.Cecil.Tests.ImportReflectionTests/Generic`1<T>::GenericMethod<TS>(T,TS)", generic_method.FullName);
}
delegate void Emitter (ModuleDefinition module, MethodBody body);
[MethodImpl (MethodImplOptions.NoInlining)]
static TDelegate Compile<TDelegate> (Emitter emitter)
where TDelegate : class
{
var name = GetTestCaseName ();
var module = CreateTestModule<TDelegate> (name, emitter);
var assembly = LoadTestModule (module);
return CreateRunDelegate<TDelegate> (GetTestCase (name, assembly));
}
static TDelegate CreateRunDelegate<TDelegate> (Type type)
where TDelegate : class
{
return (TDelegate) (object) Delegate.CreateDelegate (typeof (TDelegate), type.GetMethod ("Run"));
}
static Type GetTestCase (string name, SR.Assembly assembly)
{
return assembly.GetType (name);
}
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 ());
}
}
static ModuleDefinition CreateTestModule<TDelegate> (string name, Emitter emitter)
{
var module = CreateModule (name);
var type = new TypeDefinition (
"",
name,
TypeAttributes.Public | TypeAttributes.Sealed | TypeAttributes.Abstract,
module.Import (typeof (object)));
module.Types.Add (type);
var method = CreateMethod (type, typeof (TDelegate).GetMethod ("Invoke"));
emitter (module, method.Body);
return module;
}
static MethodDefinition CreateMethod (TypeDefinition type, SR.MethodInfo pattern)
{
var module = type.Module;
var method = new MethodDefinition {
Name = "Run",
IsPublic = true,
IsStatic = true,
};
type.Methods.Add (method);
method.MethodReturnType.ReturnType = module.Import (pattern.ReturnType);
foreach (var parameter_pattern in pattern.GetParameters ())
method.Parameters.Add (new ParameterDefinition (module.Import (parameter_pattern.ParameterType)));
return method;
}
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;
}
}
}

View File

@@ -0,0 +1,47 @@
using System;
using System.Collections.Generic;
using Mono;
#if !NET_3_5 && !NET_4_0
namespace System.Linq {
static class Enumerable {
public static IEnumerable<TRet> Select<TItem, TRet> (this IEnumerable<TItem> self, Func<TItem, TRet> selector)
{
foreach (var item in self)
yield return selector (item);
}
public static IEnumerable<T> Where<T> (this IEnumerable<T> self, Func<T, bool> predicate)
{
foreach (var item in self)
if (predicate (item))
yield return item;
}
public static List<T> ToList<T> (this IEnumerable<T> self)
{
return new List<T> (self);
}
public static T [] ToArray<T> (this IEnumerable<T> self)
{
return self.ToList ().ToArray ();
}
public static T First<T> (this IEnumerable<T> self)
{
using (var enumerator = self.GetEnumerator ()) {
if (!enumerator.MoveNext ())
throw new InvalidOperationException ();
return enumerator.Current;
}
}
}
}
#endif

View File

@@ -0,0 +1,412 @@
using System;
using System.Linq;
using Mono.Cecil;
using Mono.Cecil.Cil;
using NUnit.Framework;
namespace Mono.Cecil.Tests {
[TestFixture]
public class MethodBodyTests : BaseTestFixture {
[TestIL ("hello.il")]
public void MultiplyMethod (ModuleDefinition module)
{
var foo = module.GetType ("Foo");
Assert.IsNotNull (foo);
var bar = foo.GetMethod ("Bar");
Assert.IsNotNull (bar);
Assert.IsTrue (bar.IsIL);
AssertCode (@"
.locals init (System.Int32 V_0)
IL_0000: ldarg.0
IL_0001: ldarg.1
IL_0002: mul
IL_0003: stloc.0
IL_0004: ldloc.0
IL_0005: call System.Void Foo::Baz(System.Int32)
IL_000a: ret
", bar);
}
[TestIL ("hello.il")]
public void PrintStringEmpty (ModuleDefinition module)
{
var foo = module.GetType ("Foo");
Assert.IsNotNull (foo);
var print_empty = foo.GetMethod ("PrintEmpty");
Assert.IsNotNull (print_empty);
AssertCode (@"
.locals ()
IL_0000: ldsfld System.String System.String::Empty
IL_0005: call System.Void System.Console::WriteLine(System.String)
IL_000a: ret
", print_empty);
}
[TestModule ("libhello.dll")]
public void Branch (ModuleDefinition module)
{
var lib = module.GetType ("Library");
Assert.IsNotNull (lib);
var method = lib.GetMethod ("GetHelloString");
Assert.IsNotNull (method);
AssertCode (@"
.locals init (System.String V_0)
IL_0000: nop
IL_0001: ldstr ""hello world of tomorrow""
IL_0006: stloc.0
IL_0007: br.s IL_0009
IL_0009: ldloc.0
IL_000a: ret
", method);
}
[TestModule ("switch.exe")]
public void Switch (ModuleDefinition module)
{
var program = module.GetType ("Program");
Assert.IsNotNull (program);
var method = program.GetMethod ("Main");
Assert.IsNotNull (method);
AssertCode (@"
.locals init (System.Int32 V_0)
IL_0000: ldarg.0
IL_0001: ldlen
IL_0002: conv.i4
IL_0003: stloc.0
IL_0004: ldloc.0
IL_0005: ldc.i4.8
IL_0006: bgt.s IL_0026
IL_0008: ldloc.0
IL_0009: ldc.i4.1
IL_000a: sub
IL_000b: switch (IL_0032, IL_0034, IL_0038, IL_0034)
IL_0020: ldloc.0
IL_0021: ldc.i4.8
IL_0022: beq.s IL_0036
IL_0024: br.s IL_0038
IL_0026: ldloc.0
IL_0027: ldc.i4.s 16
IL_0029: beq.s IL_0036
IL_002b: ldloc.0
IL_002c: ldc.i4.s 32
IL_002e: beq.s IL_0036
IL_0030: br.s IL_0038
IL_0032: ldc.i4.0
IL_0033: ret
IL_0034: ldc.i4.1
IL_0035: ret
IL_0036: ldc.i4.2
IL_0037: ret
IL_0038: ldc.i4.s 42
IL_003a: ret
", method);
}
[TestIL ("methodspecs.il")]
public void MethodSpec (ModuleDefinition module)
{
var tamtam = module.GetType ("Tamtam");
var bar = tamtam.GetMethod ("Bar");
Assert.IsNotNull (bar);
AssertCode (@"
.locals ()
IL_0000: ldc.i4.2
IL_0001: call System.Void Tamtam::Foo<System.Int32>(TFoo)
IL_0006: ret
", bar);
}
[TestModule ("catch.exe")]
public void NestedTryCatchFinally (ModuleDefinition module)
{
var program = module.GetType ("Program");
var main = program.GetMethod ("Main");
Assert.IsNotNull (main);
AssertCode (@"
.locals ()
IL_0000: call System.Void Program::Foo()
IL_0005: leave.s IL_000d
IL_0007: call System.Void Program::Baz()
IL_000c: endfinally
IL_000d: leave.s IL_001f
IL_000f: pop
IL_0010: call System.Void Program::Bar()
IL_0015: leave.s IL_001f
IL_0017: pop
IL_0018: call System.Void Program::Bar()
IL_001d: leave.s IL_001f
IL_001f: leave.s IL_0027
IL_0021: call System.Void Program::Baz()
IL_0026: endfinally
IL_0027: ret
.try IL_0000 to IL_0007 finally handler IL_0007 to IL_000d
.try IL_0000 to IL_000f catch System.ArgumentException handler IL_000f to IL_0017
.try IL_0000 to IL_000f catch System.Exception handler IL_0017 to IL_001f
.try IL_0000 to IL_0021 finally handler IL_0021 to IL_0027
", main);
}
[TestModule ("fptr.exe", Verify = false)]
public void FunctionPointersAndCallSites (ModuleDefinition module)
{
var type = module.Types [0];
var start = type.GetMethod ("Start");
Assert.IsNotNull (start);
AssertCode (@"
.locals init ()
IL_0000: ldc.i4.1
IL_0001: call method System.Int32 *(System.Int32) MakeDecision::Decide()
IL_0006: calli System.Int32(System.Int32)
IL_000b: call System.Void System.Console::WriteLine(System.Int32)
IL_0010: ldc.i4.1
IL_0011: call method System.Int32 *(System.Int32) MakeDecision::Decide()
IL_0016: calli System.Int32(System.Int32)
IL_001b: call System.Void System.Console::WriteLine(System.Int32)
IL_0020: ldc.i4.1
IL_0021: call method System.Int32 *(System.Int32) MakeDecision::Decide()
IL_0026: calli System.Int32(System.Int32)
IL_002b: call System.Void System.Console::WriteLine(System.Int32)
IL_0030: ret
", start);
}
[TestIL ("hello.il")]
public void ThisParameter (ModuleDefinition module)
{
var type = module.GetType ("Foo");
var method = type.GetMethod ("Gazonk");
Assert.IsNotNull (method);
AssertCode (@"
.locals ()
IL_0000: ldarg 0
IL_0004: pop
IL_0005: ret
", method);
Assert.AreEqual (method.Body.ThisParameter.ParameterType, type);
Assert.AreEqual (method.Body.ThisParameter, method.Body.Instructions [0].Operand);
}
[Test]
public void ThisParameterStaticMethod ()
{
var static_method = typeof (ModuleDefinition).ToDefinition ().Methods.Where (m => m.IsStatic).First ();
Assert.IsNull (static_method.Body.ThisParameter);
}
[Test]
public void ThisParameterPrimitive ()
{
var int32 = typeof (int).ToDefinition ();
var int_to_string = int32.Methods.Where (m => m.Name == "ToString" && m.Parameters.Count == 0).First();
Assert.IsNotNull (int_to_string);
var this_parameter_type = int_to_string.Body.ThisParameter.ParameterType;
Assert.IsTrue (this_parameter_type.IsPointer);
var element_type = ((PointerType) this_parameter_type).ElementType;
Assert.AreEqual (int32, element_type);
}
[Test]
public void ThisParameterValueType ()
{
var token = typeof (MetadataToken).ToDefinition ();
var token_to_string = token.Methods.Where (m => m.Name == "ToString" && m.Parameters.Count == 0).First ();
Assert.IsNotNull (token_to_string);
var this_parameter_type = token_to_string.Body.ThisParameter.ParameterType;
Assert.IsTrue (this_parameter_type.IsPointer);
var element_type = ((PointerType) this_parameter_type).ElementType;
Assert.AreEqual (token, element_type);
}
[Test]
public void ThisParameterObject ()
{
var module = typeof (MethodBodyTests).ToDefinition ().Module;
var @object = module.TypeSystem.Object.Resolve ();
var method = @object.Methods.Where (m => m.HasBody).First ();
var type = method.Body.ThisParameter.ParameterType;
Assert.IsFalse (type.IsValueType);
Assert.IsFalse (type.IsPrimitive);
Assert.IsFalse (type.IsPointer);
}
[TestIL ("hello.il")]
public void FilterMaxStack (ModuleDefinition module)
{
var type = module.GetType ("Foo");
var method = type.GetMethod ("TestFilter");
Assert.IsNotNull (method);
Assert.AreEqual (2, method.Body.MaxStackSize);
}
[TestModule ("iterator.exe")]
public void Iterator (ModuleDefinition module)
{
var method = module.GetType ("Program").GetMethod ("GetLittleArgs");
Assert.IsNotNull (method.Body);
}
[TestCSharp ("CustomAttributes.cs")]
public void LoadString (ModuleDefinition module)
{
var type = module.GetType ("FooAttribute");
var get_fiou = type.GetMethod ("get_Fiou");
Assert.IsNotNull (get_fiou);
var ldstr = get_fiou.Body.Instructions.Where (i => i.OpCode == OpCodes.Ldstr).First ();
Assert.AreEqual ("fiou", ldstr.Operand);
}
static void AssertCode (string expected, MethodDefinition method)
{
Assert.IsTrue (method.HasBody);
Assert.IsNotNull (method.Body);
Assert.AreEqual (Normalize (expected), Normalize (Formatter.FormatMethodBody (method)));
}
static string Normalize (string str)
{
return str.Trim ().Replace ("\r\n", "\n");
}
[Test]
public void AddInstruction ()
{
var object_ref = new TypeReference ("System", "Object", null, null, false);
var method = new MethodDefinition ("foo", MethodAttributes.Static, object_ref);
var body = new MethodBody (method);
var il = body.GetILProcessor ();
var first = il.Create (OpCodes.Nop);
var second = il.Create (OpCodes.Nop);
body.Instructions.Add (first);
body.Instructions.Add (second);
Assert.IsNull (first.Previous);
Assert.AreEqual (second, first.Next);
Assert.AreEqual (first, second.Previous);
Assert.IsNull (second.Next);
}
[Test]
public void InsertInstruction ()
{
var object_ref = new TypeReference ("System", "Object", null, null, false);
var method = new MethodDefinition ("foo", MethodAttributes.Static, object_ref);
var body = new MethodBody (method);
var il = body.GetILProcessor ();
var first = il.Create (OpCodes.Nop);
var second = il.Create (OpCodes.Nop);
var third = il.Create (OpCodes.Nop);
body.Instructions.Add (first);
body.Instructions.Add (third);
Assert.IsNull (first.Previous);
Assert.AreEqual (third, first.Next);
Assert.AreEqual (first, third.Previous);
Assert.IsNull (third.Next);
body.Instructions.Insert (1, second);
Assert.IsNull (first.Previous);
Assert.AreEqual (second, first.Next);
Assert.AreEqual (first, second.Previous);
Assert.AreEqual (third, second.Next);
Assert.AreEqual (second, third.Previous);
Assert.IsNull (third.Next);
}
[Test]
public void InsertAfterLastInstruction ()
{
var object_ref = new TypeReference ("System", "Object", null, null, false);
var method = new MethodDefinition ("foo", MethodAttributes.Static, object_ref);
var body = new MethodBody (method);
var il = body.GetILProcessor ();
var first = il.Create (OpCodes.Nop);
var second = il.Create (OpCodes.Nop);
var third = il.Create (OpCodes.Nop);
body.Instructions.Add (first);
body.Instructions.Add (second);
Assert.IsNull (first.Previous);
Assert.AreEqual (second, first.Next);
Assert.AreEqual (first, second.Previous);
Assert.IsNull (second.Next);
body.Instructions.Insert (2, third);
Assert.IsNull (first.Previous);
Assert.AreEqual (second, first.Next);
Assert.AreEqual (first, second.Previous);
Assert.AreEqual (third, second.Next);
Assert.AreEqual (second, third.Previous);
Assert.IsNull (third.Next);
}
[Test]
public void RemoveInstruction ()
{
var object_ref = new TypeReference ("System", "Object", null, null, false);
var method = new MethodDefinition ("foo", MethodAttributes.Static, object_ref);
var body = new MethodBody (method);
var il = body.GetILProcessor ();
var first = il.Create (OpCodes.Nop);
var second = il.Create (OpCodes.Nop);
var third = il.Create (OpCodes.Nop);
body.Instructions.Add (first);
body.Instructions.Add (second);
body.Instructions.Add (third);
Assert.IsNull (first.Previous);
Assert.AreEqual (second, first.Next);
Assert.AreEqual (first, second.Previous);
Assert.AreEqual (third, second.Next);
Assert.AreEqual (second, third.Previous);
Assert.IsNull (third.Next);
body.Instructions.Remove (second);
Assert.IsNull (first.Previous);
Assert.AreEqual (third, first.Next);
Assert.AreEqual (first, third.Previous);
Assert.IsNull (third.Next);
}
}
}

View File

@@ -0,0 +1,201 @@
using System;
using System.Linq;
using Mono.Cecil;
using Mono.Cecil.Metadata;
using NUnit.Framework;
namespace Mono.Cecil.Tests {
[TestFixture]
public class MethodTests : BaseTestFixture {
[TestCSharp ("Methods.cs")]
public void AbstractMethod (ModuleDefinition module)
{
var type = module.Types [1];
Assert.AreEqual ("Foo", type.Name);
Assert.AreEqual (2, type.Methods.Count);
var method = type.GetMethod ("Bar");
Assert.AreEqual ("Bar", method.Name);
Assert.IsTrue (method.IsAbstract);
Assert.IsNotNull (method.ReturnType);
Assert.AreEqual (1, method.Parameters.Count);
var parameter = method.Parameters [0];
Assert.AreEqual ("a", parameter.Name);
Assert.AreEqual ("System.Int32", parameter.ParameterType.FullName);
}
[TestCSharp ("Methods.cs")]
public void SimplePInvoke (ModuleDefinition module)
{
var bar = module.GetType ("Bar");
var pan = bar.GetMethod ("Pan");
Assert.IsTrue (pan.IsPInvokeImpl);
Assert.IsNotNull (pan.PInvokeInfo);
Assert.AreEqual ("Pan", pan.PInvokeInfo.EntryPoint);
Assert.IsNotNull (pan.PInvokeInfo.Module);
Assert.AreEqual ("foo.dll", pan.PInvokeInfo.Module.Name);
}
[TestCSharp ("Generics.cs")]
public void GenericMethodDefinition (ModuleDefinition module)
{
var baz = module.GetType ("Baz");
var gazonk = baz.GetMethod ("Gazonk");
Assert.IsNotNull (gazonk);
Assert.IsTrue (gazonk.HasGenericParameters);
Assert.AreEqual (1, gazonk.GenericParameters.Count);
Assert.AreEqual ("TBang", gazonk.GenericParameters [0].Name);
}
[TestCSharp ("Generics.cs")]
public void ReturnGenericInstance (ModuleDefinition module)
{
var bar = module.GetType ("Bar`1");
var self = bar.GetMethod ("Self");
Assert.IsNotNull (self);
var bar_t = self.ReturnType;
Assert.IsTrue (bar_t.IsGenericInstance);
var bar_t_instance = (GenericInstanceType) bar_t;
Assert.AreEqual (bar.GenericParameters [0], bar_t_instance.GenericArguments [0]);
var self_str = bar.GetMethod ("SelfString");
Assert.IsNotNull (self_str);
var bar_str = self_str.ReturnType;
Assert.IsTrue (bar_str.IsGenericInstance);
var bar_str_instance = (GenericInstanceType) bar_str;
Assert.AreEqual ("System.String", bar_str_instance.GenericArguments [0].FullName);
}
[TestCSharp ("Generics.cs")]
public void ReturnGenericInstanceWithMethodParameter (ModuleDefinition module)
{
var baz = module.GetType ("Baz");
var gazoo = baz.GetMethod ("Gazoo");
Assert.IsNotNull (gazoo);
var bar_bingo = gazoo.ReturnType;
Assert.IsTrue (bar_bingo.IsGenericInstance);
var bar_bingo_instance = (GenericInstanceType) bar_bingo;
Assert.AreEqual (gazoo.GenericParameters [0], bar_bingo_instance.GenericArguments [0]);
}
[TestCSharp ("Interfaces.cs")]
public void SimpleOverrides (ModuleDefinition module)
{
var ibingo = module.GetType ("IBingo");
var ibingo_foo = ibingo.GetMethod ("Foo");
Assert.IsNotNull (ibingo_foo);
var ibingo_bar = ibingo.GetMethod ("Bar");
Assert.IsNotNull (ibingo_bar);
var bingo = module.GetType ("Bingo");
var foo = bingo.GetMethod ("IBingo.Foo");
Assert.IsNotNull (foo);
Assert.IsTrue (foo.HasOverrides);
Assert.AreEqual (ibingo_foo, foo.Overrides [0]);
var bar = bingo.GetMethod ("IBingo.Bar");
Assert.IsNotNull (bar);
Assert.IsTrue (bar.HasOverrides);
Assert.AreEqual (ibingo_bar, bar.Overrides [0]);
}
[TestModule ("varargs.exe")]
public void VarArgs (ModuleDefinition module)
{
var module_type = module.Types [0];
Assert.AreEqual (3, module_type.Methods.Count);
var bar = module_type.GetMethod ("Bar");
var baz = module_type.GetMethod ("Baz");
var foo = module_type.GetMethod ("Foo");
Assert.IsTrue (bar.IsVarArg ());
Assert.IsFalse (baz.IsVarArg ());
Assert.IsTrue(foo.IsVarArg ());
var bar_reference = (MethodReference) baz.Body.Instructions.Where (i => i.Offset == 0x000a).First ().Operand;
Assert.IsTrue (bar_reference.IsVarArg ());
Assert.AreEqual (0, bar_reference.GetSentinelPosition ());
var foo_reference = (MethodReference) baz.Body.Instructions.Where (i => i.Offset == 0x0023).First ().Operand;
Assert.IsTrue (foo_reference.IsVarArg ());
Assert.AreEqual (1, foo_reference.GetSentinelPosition ());
}
[TestCSharp ("Generics.cs")]
public void GenericInstanceMethod (ModuleDefinition module)
{
var type = module.GetType ("It");
var method = type.GetMethod ("ReadPwow");
GenericInstanceMethod instance = null;
foreach (var instruction in method.Body.Instructions) {
instance = instruction.Operand as GenericInstanceMethod;
if (instance != null)
break;
}
Assert.IsNotNull (instance);
Assert.AreEqual (TokenType.MethodSpec, instance.MetadataToken.TokenType);
Assert.AreNotEqual (0, instance.MetadataToken.RID);
}
[TestCSharp ("Generics.cs")]
public void MethodRefDeclaredOnGenerics (ModuleDefinition module)
{
var type = module.GetType ("Tamtam");
var beta = type.GetMethod ("Beta");
var charlie = type.GetMethod ("Charlie");
var new_list_beta = (MethodReference) beta.Body.Instructions [0].Operand;
var new_list_charlie = (MethodReference) charlie.Body.Instructions [0].Operand;
Assert.AreEqual ("System.Collections.Generic.List`1<TBeta>", new_list_beta.DeclaringType.FullName);
Assert.AreEqual ("System.Collections.Generic.List`1<TCharlie>", new_list_charlie.DeclaringType.FullName);
}
[Test]
public void ReturnParameterMethod ()
{
var method = typeof (MethodTests).ToDefinition ().GetMethod ("ReturnParameterMethod");
Assert.IsNotNull (method);
Assert.AreEqual (method, method.MethodReturnType.Parameter.Method);
}
}
}

View File

@@ -0,0 +1,250 @@
using System;
using System.Diagnostics;
using System.IO;
using System.Linq;
using Mono.Cecil;
using NUnit.Framework;
namespace Mono.Cecil.Tests {
[TestFixture]
public class ModuleTests : BaseTestFixture {
[Test]
public void CreateModuleEscapesAssemblyName ()
{
var module = ModuleDefinition.CreateModule ("Test.dll", ModuleKind.Dll);
Assert.AreEqual ("Test", module.Assembly.Name.Name);
module = ModuleDefinition.CreateModule ("Test.exe", ModuleKind.Console);
Assert.AreEqual ("Test", module.Assembly.Name.Name);
}
[TestModule ("hello.exe")]
public void SingleModule (ModuleDefinition module)
{
var assembly = module.Assembly;
Assert.AreEqual (1, assembly.Modules.Count);
Assert.IsNotNull (assembly.MainModule);
}
[TestModule ("hello.exe")]
public void EntryPoint (ModuleDefinition module)
{
var entry_point = module.EntryPoint;
Assert.IsNotNull (entry_point);
Assert.AreEqual ("System.Void Program::Main()", entry_point.ToString ());
}
[TestModule ("mma.exe")]
public void MultiModules (ModuleDefinition module)
{
var assembly = module.Assembly;
Assert.AreEqual (3, assembly.Modules.Count);
Assert.AreEqual ("mma.exe", assembly.Modules [0].Name);
Assert.AreEqual (ModuleKind.Console, assembly.Modules [0].Kind);
Assert.AreEqual ("moda.netmodule", assembly.Modules [1].Name);
Assert.AreEqual ("eedb4721-6c3e-4d9a-be30-49021121dd92", assembly.Modules [1].Mvid.ToString ());
Assert.AreEqual (ModuleKind.NetModule, assembly.Modules [1].Kind);
Assert.AreEqual ("modb.netmodule", assembly.Modules [2].Name);
Assert.AreEqual ("46c5c577-11b2-4ea0-bb3c-3c71f1331dd0", assembly.Modules [2].Mvid.ToString ());
Assert.AreEqual (ModuleKind.NetModule, assembly.Modules [2].Kind);
}
[TestModule ("hello.exe")]
public void ModuleInformation (ModuleDefinition module)
{
Assert.IsNotNull (module);
Assert.AreEqual ("hello.exe", module.Name);
Assert.AreEqual (new Guid ("C3BC2BD3-2576-4D00-A80E-465B5632415F"), module.Mvid);
}
[TestModule ("hello.exe")]
public void AssemblyReferences (ModuleDefinition module)
{
Assert.AreEqual (1, module.AssemblyReferences.Count);
var reference = module.AssemblyReferences [0];
Assert.AreEqual ("mscorlib", reference.Name);
Assert.AreEqual (new Version (2, 0, 0, 0), reference.Version);
Assert.AreEqual (new byte [] { 0xB7, 0x7A, 0x5C, 0x56, 0x19, 0x34, 0xE0, 0x89 }, reference.PublicKeyToken);
}
[TestModule ("pinvoke.exe")]
public void ModuleReferences (ModuleDefinition module)
{
Assert.AreEqual (2, module.ModuleReferences.Count);
Assert.AreEqual ("kernel32.dll", module.ModuleReferences [0].Name);
Assert.AreEqual ("shell32.dll", module.ModuleReferences [1].Name);
}
[TestModule ("hello.exe")]
public void Types (ModuleDefinition module)
{
Assert.AreEqual (2, module.Types.Count);
Assert.AreEqual ("<Module>", module.Types [0].FullName);
Assert.AreEqual ("<Module>", module.GetType ("<Module>").FullName);
Assert.AreEqual ("Program", module.Types [1].FullName);
Assert.AreEqual ("Program", module.GetType ("Program").FullName);
}
[TestModule ("libres.dll")]
public void LinkedResource (ModuleDefinition module)
{
var resource = module.Resources.Where (res => res.Name == "linked.txt").First () as LinkedResource;
Assert.IsNotNull (resource);
Assert.AreEqual ("linked.txt", resource.Name);
Assert.AreEqual ("linked.txt", resource.File);
Assert.AreEqual (ResourceType.Linked, resource.ResourceType);
Assert.IsTrue (resource.IsPublic);
}
[TestModule ("libres.dll")]
public void EmbeddedResource (ModuleDefinition module)
{
var resource = module.Resources.Where (res => res.Name == "embedded1.txt").First () as EmbeddedResource;
Assert.IsNotNull (resource);
Assert.AreEqual ("embedded1.txt", resource.Name);
Assert.AreEqual (ResourceType.Embedded, resource.ResourceType);
Assert.IsTrue (resource.IsPublic);
using (var reader = new StreamReader (resource.GetResourceStream ()))
Assert.AreEqual ("Hello", reader.ReadToEnd ());
resource = module.Resources.Where (res => res.Name == "embedded2.txt").First () as EmbeddedResource;
Assert.IsNotNull (resource);
Assert.AreEqual ("embedded2.txt", resource.Name);
Assert.AreEqual (ResourceType.Embedded, resource.ResourceType);
Assert.IsTrue (resource.IsPublic);
using (var reader = new StreamReader (resource.GetResourceStream ()))
Assert.AreEqual ("World", reader.ReadToEnd ());
}
[TestModule ("mma.exe")]
public void ExportedTypeFromNetModule (ModuleDefinition module)
{
Assert.IsTrue (module.HasExportedTypes);
Assert.AreEqual (2, module.ExportedTypes.Count);
var exported_type = module.ExportedTypes [0];
Assert.AreEqual ("Module.A.Foo", exported_type.FullName);
Assert.AreEqual ("moda.netmodule", exported_type.Scope.Name);
exported_type = module.ExportedTypes [1];
Assert.AreEqual ("Module.B.Baz", exported_type.FullName);
Assert.AreEqual ("modb.netmodule", exported_type.Scope.Name);
}
[TestCSharp ("CustomAttributes.cs")]
public void NestedTypeForwarder (ModuleDefinition module)
{
Assert.IsTrue (module.HasExportedTypes);
Assert.AreEqual (2, module.ExportedTypes.Count);
var exported_type = module.ExportedTypes [0];
Assert.AreEqual ("System.Diagnostics.DebuggableAttribute", exported_type.FullName);
Assert.AreEqual ("mscorlib", exported_type.Scope.Name);
Assert.IsTrue (exported_type.IsForwarder);
var nested_exported_type = module.ExportedTypes [1];
Assert.AreEqual ("System.Diagnostics.DebuggableAttribute/DebuggingModes", nested_exported_type.FullName);
Assert.AreEqual (exported_type, nested_exported_type.DeclaringType);
Assert.AreEqual ("mscorlib", nested_exported_type.Scope.Name);
}
[TestCSharp ("CustomAttributes.cs")]
public void HasTypeReference (ModuleDefinition module)
{
Assert.IsTrue (module.HasTypeReference ("System.Attribute"));
Assert.IsTrue (module.HasTypeReference ("mscorlib", "System.Attribute"));
Assert.IsFalse (module.HasTypeReference ("System.Core", "System.Attribute"));
Assert.IsFalse (module.HasTypeReference ("System.Linq.Enumerable"));
}
[TestModule ("libhello.dll")]
public void Win32FileVersion (ModuleDefinition module)
{
var version = FileVersionInfo.GetVersionInfo (module.FullyQualifiedName);
Assert.AreEqual ("0.0.0.0", version.FileVersion);
}
[TestModule ("noblob.dll")]
public void ModuleWithoutBlob (ModuleDefinition module)
{
Assert.IsNull (module.Image.BlobHeap);
}
[Test]
public void MixedModeModule ()
{
var module = GetResourceModule ("cppcli.dll");
Assert.AreEqual (1, module.ModuleReferences.Count);
Assert.AreEqual (string.Empty, module.ModuleReferences [0].Name);
}
[Test]
[ExpectedException (typeof (BadImageFormatException))]
public void OpenIrrelevantFile ()
{
GetResourceModule ("text_file.txt");
}
[Test]
public void WriteModuleTwice ()
{
var module = GetResourceModule ("iterator.exe");
var path = Path.Combine (Path.GetTempPath (), "cecil");
var file = Path.Combine (path, "iteratorrt.exe");
module.Write (file);
module.Write (file);
}
[Test]
public void GetTypeNamespacePlusName ()
{
var module = GetResourceModule ("moda.netmodule");
var type = module.GetType ("Module.A", "Foo");
Assert.IsNotNull (type);
}
[Test]
public void OpenModuleImmediate ()
{
var module = GetResourceModule ("hello.exe", ReadingMode.Immediate);
Assert.AreEqual (ReadingMode.Immediate, module.ReadingMode);
}
[Test]
public void OpenModuleDeferred ()
{
var module = GetResourceModule ("hello.exe", ReadingMode.Deferred);
Assert.AreEqual (ReadingMode.Deferred, module.ReadingMode);
}
}
}

Some files were not shown because too many files have changed in this diff Show More