Imported Upstream version 5.8.0.88

Former-commit-id: 4b7216ffda08448e562271ce733688e761120fc5
This commit is contained in:
Xamarin Public Jenkins (auto-signing) 2017-11-28 19:36:51 +00:00
parent 7d05485754
commit 6123a772ed
277 changed files with 4817 additions and 941 deletions

View File

@ -1 +1 @@
3fb2fb8eee096ec9f26b7a4dae0ff3e1d0fb7eb1
37c1b000c4419715dad5a8f78a060364b72479dd

View File

@ -1 +1 @@
3aa404de51236fe4a603243f724c4b33a6d206c1
0fcbd9917a47e8f359dbdcbd676abae3b61dc4e6

View File

@ -7,7 +7,7 @@
[assembly:System.Diagnostics.DebuggableAttribute((System.Diagnostics.DebuggableAttribute.DebuggingModes)(2))]
[assembly:System.Reflection.AssemblyCopyrightAttribute("Copyright © 2008 - 2015 Jb Evain")]
[assembly:System.Reflection.AssemblyFileVersionAttribute("0.10.0.0")]
[assembly:System.Reflection.AssemblyInformationalVersionAttribute("0.10.0.0-beta6")]
[assembly:System.Reflection.AssemblyInformationalVersionAttribute("0.10.0.0-beta7")]
[assembly:System.Reflection.AssemblyProductAttribute("Mono.Cecil")]
[assembly:System.Reflection.AssemblyTitleAttribute("Mono.Cecil.Mdb")]
[assembly:System.Runtime.CompilerServices.CompilationRelaxationsAttribute(8)]

View File

@ -1 +1 @@
9f405648ac44af0776db1fccb6ed79229217457a
dfcf34172908a18aaf781b2b50e901e96b820136

View File

@ -45,7 +45,7 @@ namespace Mono.Cecil.Cil {
return position;
}
void MoveBackTo (int position)
public void MoveBackTo (int position)
{
this.reader.context = null;
this.Position = position;
@ -62,6 +62,30 @@ namespace Mono.Cecil.Cil {
return this.body;
}
public int ReadCodeSize (MethodDefinition method)
{
var position = MoveTo (method);
var code_size = ReadCodeSize ();
MoveBackTo (position);
return code_size;
}
int ReadCodeSize ()
{
var flags = ReadByte ();
switch (flags & 0x3) {
case 0x2: // tiny
return flags >> 2;
case 0x3: // fat
Advance (-1 + 2 + 2); // go back, 2 bytes flags, 2 bytes stack size
return (int) ReadUInt32 ();
default:
throw new InvalidOperationException ();
}
}
void ReadMethodBody ()
{
var flags = ReadByte ();
@ -88,99 +112,6 @@ namespace Mono.Cecil.Cil {
ReadDebugInfo ();
}
void ReadDebugInfo ()
{
if (method.debug_info.sequence_points != null)
ReadSequencePoints ();
if (method.debug_info.scope != null)
ReadScope (method.debug_info.scope);
if (method.custom_infos != null)
ReadCustomDebugInformations (method);
}
void ReadCustomDebugInformations (MethodDefinition method)
{
var custom_infos = method.custom_infos;
for (int i = 0; i < custom_infos.Count; i++) {
var state_machine_scope = custom_infos [i] as StateMachineScopeDebugInformation;
if (state_machine_scope != null)
ReadStateMachineScope (state_machine_scope);
var async_method = custom_infos [i] as AsyncMethodBodyDebugInformation;
if (async_method != null)
ReadAsyncMethodBody (async_method);
}
}
void ReadAsyncMethodBody (AsyncMethodBodyDebugInformation async_method)
{
if (async_method.catch_handler.Offset > -1)
async_method.catch_handler = new InstructionOffset (GetInstruction (async_method.catch_handler.Offset));
if (!async_method.yields.IsNullOrEmpty ())
for (int i = 0; i < async_method.yields.Count; i++)
async_method.yields [i] = new InstructionOffset (GetInstruction (async_method.yields [i].Offset));
if (!async_method.resumes.IsNullOrEmpty ())
for (int i = 0; i < async_method.resumes.Count; i++)
async_method.resumes [i] = new InstructionOffset (GetInstruction (async_method.resumes [i].Offset));
}
void ReadStateMachineScope (StateMachineScopeDebugInformation state_machine_scope)
{
state_machine_scope.start = new InstructionOffset (GetInstruction (state_machine_scope.start.Offset));
var end_instruction = GetInstruction (state_machine_scope.end.Offset);
state_machine_scope.end = end_instruction == null
? new InstructionOffset ()
: new InstructionOffset (end_instruction);
}
void ReadSequencePoints ()
{
var symbol = method.debug_info;
for (int i = 0; i < symbol.sequence_points.Count; i++) {
var sequence_point = symbol.sequence_points [i];
var instruction = GetInstruction (sequence_point.Offset);
if (instruction != null)
sequence_point.offset = new InstructionOffset (instruction);
}
}
void ReadScopes (Collection<ScopeDebugInformation> scopes)
{
for (int i = 0; i < scopes.Count; i++)
ReadScope (scopes [i]);
}
void ReadScope (ScopeDebugInformation scope)
{
var start_instruction = GetInstruction (scope.Start.Offset);
if (start_instruction != null)
scope.Start = new InstructionOffset (start_instruction);
var end_instruction = GetInstruction (scope.End.Offset);
scope.End = end_instruction != null
? new InstructionOffset (end_instruction)
: new InstructionOffset ();
if (!scope.variables.IsNullOrEmpty ()) {
for (int i = 0; i < scope.variables.Count; i++) {
var variable_info = scope.variables [i];
var variable = GetVariable (variable_info.Index);
if (variable != null)
variable_info.index = new VariableIndex (variable);
}
}
if (!scope.scopes.IsNullOrEmpty ())
ReadScopes (scope.scopes);
}
void ReadFatMethod ()
{
var flags = ReadUInt16 ();
@ -442,6 +373,104 @@ namespace Mono.Cecil.Cil {
return new MetadataToken (ReadUInt32 ());
}
void ReadDebugInfo ()
{
if (method.debug_info.sequence_points != null)
ReadSequencePoints ();
if (method.debug_info.scope != null)
ReadScope (method.debug_info.scope);
if (method.custom_infos != null)
ReadCustomDebugInformations (method);
}
void ReadCustomDebugInformations (MethodDefinition method)
{
var custom_infos = method.custom_infos;
for (int i = 0; i < custom_infos.Count; i++) {
var state_machine_scope = custom_infos [i] as StateMachineScopeDebugInformation;
if (state_machine_scope != null)
ReadStateMachineScope (state_machine_scope);
var async_method = custom_infos [i] as AsyncMethodBodyDebugInformation;
if (async_method != null)
ReadAsyncMethodBody (async_method);
}
}
void ReadAsyncMethodBody (AsyncMethodBodyDebugInformation async_method)
{
if (async_method.catch_handler.Offset > -1)
async_method.catch_handler = new InstructionOffset (GetInstruction (async_method.catch_handler.Offset));
if (!async_method.yields.IsNullOrEmpty ())
for (int i = 0; i < async_method.yields.Count; i++)
async_method.yields [i] = new InstructionOffset (GetInstruction (async_method.yields [i].Offset));
if (!async_method.resumes.IsNullOrEmpty ())
for (int i = 0; i < async_method.resumes.Count; i++)
async_method.resumes [i] = new InstructionOffset (GetInstruction (async_method.resumes [i].Offset));
}
void ReadStateMachineScope (StateMachineScopeDebugInformation state_machine_scope)
{
if (state_machine_scope.scopes.IsNullOrEmpty ())
return;
foreach (var scope in state_machine_scope.scopes) {
scope.start = new InstructionOffset (GetInstruction (scope.start.Offset));
var end_instruction = GetInstruction (scope.end.Offset);
scope.end = end_instruction == null
? new InstructionOffset ()
: new InstructionOffset (end_instruction);
}
}
void ReadSequencePoints ()
{
var symbol = method.debug_info;
for (int i = 0; i < symbol.sequence_points.Count; i++) {
var sequence_point = symbol.sequence_points [i];
var instruction = GetInstruction (sequence_point.Offset);
if (instruction != null)
sequence_point.offset = new InstructionOffset (instruction);
}
}
void ReadScopes (Collection<ScopeDebugInformation> scopes)
{
for (int i = 0; i < scopes.Count; i++)
ReadScope (scopes [i]);
}
void ReadScope (ScopeDebugInformation scope)
{
var start_instruction = GetInstruction (scope.Start.Offset);
if (start_instruction != null)
scope.Start = new InstructionOffset (start_instruction);
var end_instruction = GetInstruction (scope.End.Offset);
scope.End = end_instruction != null
? new InstructionOffset (end_instruction)
: new InstructionOffset ();
if (!scope.variables.IsNullOrEmpty ()) {
for (int i = 0; i < scope.variables.Count; i++) {
var variable_info = scope.variables [i];
var variable = GetVariable (variable_info.Index);
if (variable != null)
variable_info.index = new VariableIndex (variable);
}
}
if (!scope.scopes.IsNullOrEmpty ())
ReadScopes (scope.scopes);
}
#if !READ_ONLY
public ByteBuffer PatchRawMethodBody (MethodDefinition method, CodeWriter writer, out int code_size, out MetadataToken local_var_token)

View File

@ -479,7 +479,7 @@ namespace Mono.Cecil.Cil {
internal InstructionOffset catch_handler;
internal Collection<InstructionOffset> yields;
internal Collection<InstructionOffset> resumes;
internal MethodDefinition move_next;
internal Collection<MethodDefinition> resume_methods;
public InstructionOffset CatchHandler {
get { return catch_handler; }
@ -494,9 +494,8 @@ namespace Mono.Cecil.Cil {
get { return resumes ?? (resumes = new Collection<InstructionOffset> ()); }
}
public MethodDefinition MoveNextMethod {
get { return move_next; }
set { move_next = value; }
public Collection<MethodDefinition> ResumeMethods {
get { return resume_methods ?? (resume_methods = new Collection<MethodDefinition> ()); }
}
public override CustomDebugInformationKind Kind {
@ -524,7 +523,7 @@ namespace Mono.Cecil.Cil {
}
}
public sealed class StateMachineScopeDebugInformation : CustomDebugInformation {
public sealed class StateMachineScope {
internal InstructionOffset start;
internal InstructionOffset end;
@ -539,24 +538,36 @@ namespace Mono.Cecil.Cil {
set { end = value; }
}
internal StateMachineScope (int start, int end)
{
this.start = new InstructionOffset (start);
this.end = new InstructionOffset (end);
}
public StateMachineScope (Instruction start, Instruction end)
{
this.start = new InstructionOffset (start);
this.end = end != null ? new InstructionOffset (end) : new InstructionOffset ();
}
}
public sealed class StateMachineScopeDebugInformation : CustomDebugInformation {
internal Collection<StateMachineScope> scopes;
public Collection<StateMachineScope> Scopes {
get { return scopes ?? (scopes = new Collection<StateMachineScope> ()); }
}
public override CustomDebugInformationKind Kind {
get { return CustomDebugInformationKind.StateMachineScope; }
}
public static Guid KindIdentifier = new Guid ("{6DA9A61E-F8C7-4874-BE62-68BC5630DF71}");
internal StateMachineScopeDebugInformation (int start, int end)
public StateMachineScopeDebugInformation ()
: base (KindIdentifier)
{
this.start = new InstructionOffset (start);
this.end = new InstructionOffset (end);
}
public StateMachineScopeDebugInformation (Instruction start, Instruction end)
: base (KindIdentifier)
{
this.start = new InstructionOffset (start);
this.end = end != null ? new InstructionOffset (end) : new InstructionOffset ();
}
}
@ -671,8 +682,10 @@ namespace Mono.Cecil.Cil {
var offset_mapping = new Dictionary<int, SequencePoint> (sequence_points.Count);
for (int i = 0; i < sequence_points.Count; i++)
offset_mapping.Add (sequence_points [i].Offset, sequence_points [i]);
for (int i = 0; i < sequence_points.Count; i++) {
if (!offset_mapping.ContainsKey (sequence_points [i].Offset))
offset_mapping.Add (sequence_points [i].Offset, sequence_points [i]);
}
var instructions = method.Body.Instructions;
@ -782,7 +795,7 @@ namespace Mono.Cecil.Cil {
try {
return SymbolProvider.GetReaderProvider (SymbolKind.NativePdb).GetSymbolReader (module, fileName);
} catch (TypeLoadException) {
} catch (Exception) {
// We might not include support for native pdbs.
}
}
@ -791,7 +804,7 @@ namespace Mono.Cecil.Cil {
if (File.Exists (mdb_file_name)) {
try {
return SymbolProvider.GetReaderProvider (SymbolKind.Mdb).GetSymbolReader (module, fileName);
} catch (TypeLoadException) {
} catch (Exception) {
// We might not include support for mdbs.
}
}

View File

@ -39,6 +39,7 @@ namespace Mono.Cecil.PE {
public uint Timestamp;
public ModuleAttributes Attributes;
public DataDirectory Win32Resources;
public DataDirectory Debug;
public DataDirectory Resources;
public DataDirectory StrongName;

View File

@ -160,12 +160,18 @@ namespace Mono.Cecil.PE {
// ExportTable 8
// ImportTable 8
Advance (pe64 ? 56 : 40);
// ResourceTable 8
image.Win32Resources = ReadDataDirectory ();
// ExceptionTable 8
// CertificateTable 8
// BaseRelocationTable 8
Advance (pe64 ? 88 : 72);
Advance (24);
// Debug 8
image.Debug = ReadDataDirectory ();

View File

@ -87,21 +87,15 @@ namespace Mono.Cecil.PE {
void GetWin32Resources ()
{
var rsrc = GetImageResourceSection ();
if (rsrc == null)
if (!module.HasImage)
return;
win32_resources = module.Image.GetReaderAt (rsrc.VirtualAddress, rsrc.SizeOfRawData, (s, reader) => new ByteBuffer (reader.ReadBytes ((int) s)));
}
DataDirectory win32_resources_directory = module.Image.Win32Resources;
var size = win32_resources_directory.Size;
Section GetImageResourceSection ()
{
if (!module.HasImage)
return null;
const string rsrc_section = ".rsrc";
return module.Image.GetSection (rsrc_section);
if (size > 0) {
win32_resources = module.Image.GetReaderAt (win32_resources_directory.VirtualAddress, size, (s, reader) => new ByteBuffer (reader.ReadBytes ((int) s)));
}
}
public static ImageWriter CreateWriter (ModuleDefinition module, MetadataBuilder metadata, Disposable<Stream> stream)
@ -846,10 +840,10 @@ namespace Mono.Cecil.PE {
void PatchResourceDataEntry (ByteBuffer resources)
{
var old_rsrc = GetImageResourceSection ();
var rva = resources.ReadUInt32 ();
resources.position -= 4;
resources.WriteUInt32 (rva - old_rsrc.VirtualAddress + rsrc.VirtualAddress);
resources.WriteUInt32 (rva - module.Image.Win32Resources.VirtualAddress + rsrc.VirtualAddress);
}
}
}

View File

@ -2,9 +2,24 @@
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<BuildDirectory>$(MSBuildProjectDirectory)</BuildDirectory>
<IsTestProject>true</IsTestProject>
</PropertyGroup>
<Import Project="Mono.Cecil.props" />
<ItemGroup>
<PropertyGroup Condition="'$(NetStandard)' == 'true'">
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
</PropertyGroup>
<ItemGroup Condition="'$(NetStandard)' == 'true'">
<PackageReference Include="NUnit">
<Version>3.7.1</Version>
</PackageReference>
<PackageReference Include="Microsoft.NET.Test.Sdk">
<Version>15.3.0</Version>
</PackageReference>
<PackageReference Include="NUnit3TestAdapter">
<Version>3.8.0</Version>
</PackageReference>
</ItemGroup>
<ItemGroup Condition="'$(NetStandard)' != 'true'">
<Reference Include="nunit.core">
<SpecificVersion>False</SpecificVersion>
<HintPath>$(MSBuildThisFileDirectory)\Test\libs\nunit-2.6.2\nunit.core.dll</HintPath>
@ -18,4 +33,14 @@
<HintPath>$(MSBuildThisFileDirectory)\Test\libs\nunit-2.6.2\nunit.framework.dll</HintPath>
</Reference>
</ItemGroup>
<!-- Workaround for https://github.com/Microsoft/msbuild/issues/1310 -->
<Target Name="ForceGenerationOfBindingRedirects"
AfterTargets="ResolveAssemblyReferences"
BeforeTargets="GenerateBindingRedirects"
Condition="'$(AutoGenerateBindingRedirects)' == 'true'">
<PropertyGroup>
<!-- Needs to be set in a target because it has to be set after the initial evaluation in the common targets -->
<GenerateBindingRedirectsOutputType>true</GenerateBindingRedirectsOutputType>
</PropertyGroup>
</Target>
</Project>

View File

@ -2,7 +2,7 @@
<package xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<metadata xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
<id>Mono.Cecil</id>
<version>0.10.0.0-beta6</version>
<version>0.10.0.0-beta7</version>
<title>Mono.Cecil</title>
<authors>Jb Evain</authors>
<owners>Jb Evain</owners>

View File

@ -36,18 +36,19 @@
</PropertyGroup>
<PropertyGroup Condition=" $(Configuration.StartsWith('net_3_5')) ">
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
<DefineConstants>$(DefineConstants);</DefineConstants>
<DefineConstants>$(DefineConstants);NET_3_5;</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition=" $(Configuration.StartsWith('net_4_0')) ">
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<DefineConstants>$(DefineConstants);NET_4_0;</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition=" $(NetStandard) ">
<TargetFramework>netstandard1.3</TargetFramework>
<PropertyGroup Condition="'$(NetStandard)' == 'true'">
<TargetFramework Condition="'$(IsTestProject)' == 'true'">netcoreapp2.0</TargetFramework>
<TargetFramework Condition="'$(IsTestProject)' != 'true'">netstandard1.3</TargetFramework>
</PropertyGroup>
<Import Project="NetStandard.props" Condition=" $(NetStandard) " />
<Import Project="NetStandard.props" Condition="'$(NetStandard)' == 'true'" />
<!-- Shared References -->
<ItemGroup Condition=" ! $(NetStandard) ">
<ItemGroup Condition="'$(NetStandard)' != 'true'">
<Reference Include="System.Core" />
<Reference Include="System" />
</ItemGroup>

View File

@ -1,6 +1,6 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 14
VisualStudioVersion = 14.0.25420.1
# Visual Studio 15
VisualStudioVersion = 15.0.26927.1
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{74E5ECE0-06B4-401C-AEBA-E8DD53E17943}"
EndProject
@ -22,6 +22,11 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Mono.Cecil.Rocks.Tests", "r
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Mono.Cecil.Rocks", "rocks\Mono.Cecil.Rocks.csproj", "{FBC6DD59-D09D-499C-B03C-99C1C78FF2AC}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{E0893F44-CB9F-49C5-B38C-70082EFC5072}"
ProjectSection(SolutionItems) = preProject
.editorconfig = .editorconfig
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
net_3_5_Debug_ReadOnly|Any CPU = net_3_5_Debug_ReadOnly|Any CPU
@ -81,9 +86,11 @@ Global
{A47B1F49-A81A-43E8-BE6B-DD28AF2C4055}.netstandard_Debug_ReadOnly|Any CPU.ActiveCfg = netstandard_Debug_ReadOnly|Any CPU
{A47B1F49-A81A-43E8-BE6B-DD28AF2C4055}.netstandard_Debug_ReadOnly|Any CPU.Build.0 = netstandard_Debug_ReadOnly|Any CPU
{A47B1F49-A81A-43E8-BE6B-DD28AF2C4055}.netstandard_Debug|Any CPU.ActiveCfg = netstandard_Debug|Any CPU
{A47B1F49-A81A-43E8-BE6B-DD28AF2C4055}.netstandard_Debug|Any CPU.Build.0 = netstandard_Debug|Any CPU
{A47B1F49-A81A-43E8-BE6B-DD28AF2C4055}.netstandard_Release_ReadOnly|Any CPU.ActiveCfg = netstandard_Release_ReadOnly|Any CPU
{A47B1F49-A81A-43E8-BE6B-DD28AF2C4055}.netstandard_Release_ReadOnly|Any CPU.Build.0 = netstandard_Release_ReadOnly|Any CPU
{A47B1F49-A81A-43E8-BE6B-DD28AF2C4055}.netstandard_Release|Any CPU.ActiveCfg = netstandard_Release|Any CPU
{A47B1F49-A81A-43E8-BE6B-DD28AF2C4055}.netstandard_Release|Any CPU.Build.0 = netstandard_Release|Any CPU
{8559DD7F-A16F-46D0-A05A-9139FAEBA8FD}.net_3_5_Debug_ReadOnly|Any CPU.ActiveCfg = net_3_5_Debug_ReadOnly|Any CPU
{8559DD7F-A16F-46D0-A05A-9139FAEBA8FD}.net_3_5_Debug_ReadOnly|Any CPU.Build.0 = net_3_5_Debug_ReadOnly|Any CPU
{8559DD7F-A16F-46D0-A05A-9139FAEBA8FD}.net_3_5_Debug|Any CPU.ActiveCfg = net_3_5_Debug|Any CPU
@ -125,10 +132,8 @@ Global
{AC71DF9C-99FA-4A63-990A-66C8010355A6}.net_4_0_Release|Any CPU.ActiveCfg = net_4_0_Release|Any CPU
{AC71DF9C-99FA-4A63-990A-66C8010355A6}.net_4_0_Release|Any CPU.Build.0 = net_4_0_Release|Any CPU
{AC71DF9C-99FA-4A63-990A-66C8010355A6}.netstandard_Debug_ReadOnly|Any CPU.ActiveCfg = netstandard_Debug_ReadOnly|Any CPU
{AC71DF9C-99FA-4A63-990A-66C8010355A6}.netstandard_Debug_ReadOnly|Any CPU.Build.0 = netstandard_Debug_ReadOnly|Any CPU
{AC71DF9C-99FA-4A63-990A-66C8010355A6}.netstandard_Debug|Any CPU.ActiveCfg = netstandard_Debug|Any CPU
{AC71DF9C-99FA-4A63-990A-66C8010355A6}.netstandard_Release_ReadOnly|Any CPU.ActiveCfg = netstandard_Release_ReadOnly|Any CPU
{AC71DF9C-99FA-4A63-990A-66C8010355A6}.netstandard_Release_ReadOnly|Any CPU.Build.0 = netstandard_Release_ReadOnly|Any CPU
{AC71DF9C-99FA-4A63-990A-66C8010355A6}.netstandard_Release|Any CPU.ActiveCfg = netstandard_Release|Any CPU
{63E6915C-7EA4-4D76-AB28-0D7191EEA626}.net_3_5_Debug_ReadOnly|Any CPU.ActiveCfg = net_3_5_Debug_ReadOnly|Any CPU
{63E6915C-7EA4-4D76-AB28-0D7191EEA626}.net_3_5_Debug_ReadOnly|Any CPU.Build.0 = net_3_5_Debug_ReadOnly|Any CPU
@ -171,10 +176,8 @@ Global
{29300103-CB76-4A1D-B6FD-FFD91C1EC8AA}.net_4_0_Release|Any CPU.ActiveCfg = net_4_0_Release|Any CPU
{29300103-CB76-4A1D-B6FD-FFD91C1EC8AA}.net_4_0_Release|Any CPU.Build.0 = net_4_0_Release|Any CPU
{29300103-CB76-4A1D-B6FD-FFD91C1EC8AA}.netstandard_Debug_ReadOnly|Any CPU.ActiveCfg = netstandard_Debug_ReadOnly|Any CPU
{29300103-CB76-4A1D-B6FD-FFD91C1EC8AA}.netstandard_Debug_ReadOnly|Any CPU.Build.0 = netstandard_Debug_ReadOnly|Any CPU
{29300103-CB76-4A1D-B6FD-FFD91C1EC8AA}.netstandard_Debug|Any CPU.ActiveCfg = netstandard_Debug|Any CPU
{29300103-CB76-4A1D-B6FD-FFD91C1EC8AA}.netstandard_Release_ReadOnly|Any CPU.ActiveCfg = netstandard_Release_ReadOnly|Any CPU
{29300103-CB76-4A1D-B6FD-FFD91C1EC8AA}.netstandard_Release_ReadOnly|Any CPU.Build.0 = netstandard_Release_ReadOnly|Any CPU
{29300103-CB76-4A1D-B6FD-FFD91C1EC8AA}.netstandard_Release|Any CPU.ActiveCfg = netstandard_Release|Any CPU
{C6CFD7E1-B855-44DC-B4CE-9CD72984AF52}.net_3_5_Debug_ReadOnly|Any CPU.ActiveCfg = net_3_5_Debug_ReadOnly|Any CPU
{C6CFD7E1-B855-44DC-B4CE-9CD72984AF52}.net_3_5_Debug_ReadOnly|Any CPU.Build.0 = net_3_5_Debug_ReadOnly|Any CPU
@ -193,10 +196,8 @@ Global
{C6CFD7E1-B855-44DC-B4CE-9CD72984AF52}.net_4_0_Release|Any CPU.ActiveCfg = net_4_0_Release|Any CPU
{C6CFD7E1-B855-44DC-B4CE-9CD72984AF52}.net_4_0_Release|Any CPU.Build.0 = net_4_0_Release|Any CPU
{C6CFD7E1-B855-44DC-B4CE-9CD72984AF52}.netstandard_Debug_ReadOnly|Any CPU.ActiveCfg = netstandard_Debug_ReadOnly|Any CPU
{C6CFD7E1-B855-44DC-B4CE-9CD72984AF52}.netstandard_Debug_ReadOnly|Any CPU.Build.0 = netstandard_Debug_ReadOnly|Any CPU
{C6CFD7E1-B855-44DC-B4CE-9CD72984AF52}.netstandard_Debug|Any CPU.ActiveCfg = netstandard_Debug|Any CPU
{C6CFD7E1-B855-44DC-B4CE-9CD72984AF52}.netstandard_Release_ReadOnly|Any CPU.ActiveCfg = netstandard_Release_ReadOnly|Any CPU
{C6CFD7E1-B855-44DC-B4CE-9CD72984AF52}.netstandard_Release_ReadOnly|Any CPU.Build.0 = netstandard_Release_ReadOnly|Any CPU
{C6CFD7E1-B855-44DC-B4CE-9CD72984AF52}.netstandard_Release|Any CPU.ActiveCfg = netstandard_Release|Any CPU
{FBC6DD59-D09D-499C-B03C-99C1C78FF2AC}.net_3_5_Debug_ReadOnly|Any CPU.ActiveCfg = net_3_5_Debug_ReadOnly|Any CPU
{FBC6DD59-D09D-499C-B03C-99C1C78FF2AC}.net_3_5_Debug_ReadOnly|Any CPU.Build.0 = net_3_5_Debug_ReadOnly|Any CPU
@ -234,4 +235,7 @@ Global
{29300103-CB76-4A1D-B6FD-FFD91C1EC8AA} = {74E5ECE0-06B4-401C-AEBA-E8DD53E17943}
{C6CFD7E1-B855-44DC-B4CE-9CD72984AF52} = {74E5ECE0-06B4-401C-AEBA-E8DD53E17943}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {D75C0801-AFCB-4B1F-90AD-2B7852A74E6A}
EndGlobalSection
EndGlobal

View File

@ -156,7 +156,6 @@ namespace Mono.Cecil {
this.module.Read (this.module, (module, reader) => {
ReadModuleManifest (reader);
ReadModule (module, resolve_attributes: true);
return module;
});
}
@ -422,10 +421,7 @@ namespace Mono.Cecil {
protected override void ReadModule ()
{
this.module.Read (this.module, (module, reader) => {
ReadModuleManifest (reader);
return module;
});
this.module.Read (this.module, (_, reader) => ReadModuleManifest (reader));
}
public override void ReadSymbols (ModuleDefinition module)
@ -943,8 +939,8 @@ namespace Mono.Cecil {
type.BaseType = GetTypeDefOrRef (ReadMetadataToken (CodedIndex.TypeDefOrRef));
type.fields_range = ReadFieldsRange (rid);
type.methods_range = ReadMethodsRange (rid);
type.fields_range = ReadListRange (rid, Table.TypeDef, Table.Field);
type.methods_range = ReadListRange (rid, Table.TypeDef, Table.Method);
if (IsNested (attributes))
type.DeclaringType = GetNestedTypeDeclaringType (type);
@ -965,21 +961,13 @@ namespace Mono.Cecil {
return GetTypeDefinition (declaring_rid);
}
Range ReadFieldsRange (uint type_index)
{
return ReadListRange (type_index, Table.TypeDef, Table.Field);
}
Range ReadMethodsRange (uint type_index)
{
return ReadListRange (type_index, Table.TypeDef, Table.Method);
}
Range ReadListRange (uint current_index, Table current, Table target)
{
var list = new Range ();
list.Start = ReadTableIndex (target);
var start = ReadTableIndex (target);
if (start == 0)
return list;
uint next_index;
var current_table = image.TableHeap [current];
@ -993,7 +981,8 @@ namespace Mono.Cecil {
this.position = position;
}
list.Length = next_index - list.Start;
list.Start = start;
list.Length = next_index - start;
return list;
}
@ -1496,16 +1485,11 @@ namespace Mono.Cecil {
for (uint i = 1; i <= length; i++) {
var type_rid = ReadTableIndex (Table.TypeDef);
Range events_range = ReadEventsRange (i);
Range events_range = ReadListRange (i, Table.EventMap, Table.Event);
metadata.AddEventsRange (type_rid, events_range);
}
}
Range ReadEventsRange (uint rid)
{
return ReadListRange (rid, Table.EventMap, Table.Event);
}
public bool HasProperties (TypeDefinition type)
{
InitializeProperties ();
@ -1585,16 +1569,11 @@ namespace Mono.Cecil {
for (uint i = 1; i <= length; i++) {
var type_rid = ReadTableIndex (Table.TypeDef);
var properties_range = ReadPropertiesRange (i);
var properties_range = ReadListRange (i, Table.PropertyMap, Table.Property);
metadata.AddPropertiesRange (type_rid, properties_range);
}
}
Range ReadPropertiesRange (uint rid)
{
return ReadListRange (rid, Table.PropertyMap, Table.Property);
}
MethodSemanticsAttributes ReadMethodSemantics (MethodDefinition method)
{
InitializeMethodSemantics ();
@ -1697,23 +1676,19 @@ namespace Mono.Cecil {
}
}
public PropertyDefinition ReadMethods (PropertyDefinition property)
public void ReadMethods (PropertyDefinition property)
{
ReadAllSemantics (property.DeclaringType);
return property;
}
public EventDefinition ReadMethods (EventDefinition @event)
public void ReadMethods (EventDefinition @event)
{
ReadAllSemantics (@event.DeclaringType);
return @event;
}
public MethodSemanticsAttributes ReadAllSemantics (MethodDefinition method)
public void ReadAllSemantics (MethodDefinition method)
{
ReadAllSemantics (method.DeclaringType);
return method.SemanticsAttributes;
}
void ReadAllSemantics (TypeDefinition type)
@ -1729,11 +1704,6 @@ namespace Mono.Cecil {
}
}
Range ReadParametersRange (uint method_rid)
{
return ReadListRange (method_rid, Table.Method, Table.Param);
}
public Collection<MethodDefinition> ReadMethods (TypeDefinition type)
{
var methods_range = type.methods_range;
@ -1794,7 +1764,7 @@ namespace Mono.Cecil {
methods.Add (method); // attach method
var signature = ReadBlobIndex ();
var param_range = ReadParametersRange (method_rid);
var param_range = ReadListRange (method_rid, Table.Method, Table.Param);
this.context = method;
@ -2121,6 +2091,11 @@ namespace Mono.Cecil {
return code.ReadMethodBody (method);
}
public int ReadCodeSize (MethodDefinition method)
{
return code.ReadCodeSize (method);
}
public CallSite ReadCallSite (MetadataToken token)
{
if (!MoveTo (Table.StandAloneSig, token.RID))
@ -2387,8 +2362,8 @@ namespace Mono.Cecil {
var type_system = module.TypeSystem;
var context = new MethodReference (string.Empty, type_system.Void);
context.DeclaringType = new TypeReference (string.Empty, string.Empty, module, type_system.CoreLibrary);
var context = new MethodDefinition (string.Empty, MethodAttributes.Static, type_system.Void);
context.DeclaringType = new TypeDefinition (string.Empty, string.Empty, TypeAttributes.Public);
var member_references = new MemberReference [length];
@ -3183,25 +3158,36 @@ namespace Mono.Cecil {
for (int i = 0; i < rows.Length; i++) {
if (rows [i].Col1 == StateMachineScopeDebugInformation.KindIdentifier) {
var signature = ReadSignature (rows [i].Col2);
infos.Add (new StateMachineScopeDebugInformation (signature.ReadInt32 (), signature.ReadInt32 ()));
var scopes = new Collection<StateMachineScope> ();
while (signature.CanReadMore ()) {
var start = signature.ReadInt32 ();
var end = start + signature.ReadInt32 ();
scopes.Add (new StateMachineScope (start, end));
}
var state_machine = new StateMachineScopeDebugInformation ();
state_machine.scopes = scopes;
infos.Add (state_machine);
} else if (rows [i].Col1 == AsyncMethodBodyDebugInformation.KindIdentifier) {
var signature = ReadSignature (rows [i].Col2);
var catch_offset = signature.ReadInt32 () - 1;
var yields = new Collection<InstructionOffset> ();
var resumes = new Collection<InstructionOffset> ();
uint move_next_rid = 0;
var resume_methods = new Collection<MethodDefinition> ();
while (signature.CanReadMore ()) {
yields.Add (new InstructionOffset (signature.ReadInt32 ()));
resumes.Add (new InstructionOffset (signature.ReadInt32 ()));
move_next_rid = signature.ReadCompressedUInt32 ();
resume_methods.Add (GetMethodDefinition (signature.ReadCompressedUInt32 ()));
}
var async_body = new AsyncMethodBodyDebugInformation (catch_offset);
async_body.yields = yields;
async_body.resumes = resumes;
async_body.move_next = GetMethodDefinition (move_next_rid);
async_body.resume_methods = resume_methods;
infos.Add (async_body);
} else if (rows [i].Col1 == EmbeddedSourceDebugInformation.KindIdentifier) {
@ -3370,7 +3356,7 @@ namespace Mono.Cecil {
switch (etype) {
case ElementType.ValueType: {
var value_type = GetTypeDefOrRef (ReadTypeTokenSignature ());
value_type.IsValueType = true;
value_type.KnownValueType ();
return value_type;
}
case ElementType.Class:
@ -3410,8 +3396,8 @@ namespace Mono.Cecil {
ReadGenericInstanceSignature (element_type, generic_instance);
if (is_value_type) {
generic_instance.IsValueType = true;
element_type.GetElementType ().IsValueType = true;
generic_instance.KnownValueType ();
element_type.GetElementType ().KnownValueType ();
}
return generic_instance;

View File

@ -2392,13 +2392,19 @@ namespace Mono.Cecil {
var method_info = ((MethodDefinition) provider).DebugInformation;
var signature = CreateSignatureWriter ();
signature.WriteUInt32 ((uint) state_machine_scope.Start.Offset);
var end_offset = state_machine_scope.End.IsEndOfMethod
? method_info.code_size
: state_machine_scope.End.Offset;
var scopes = state_machine_scope.Scopes;
signature.WriteUInt32 ((uint) (end_offset - state_machine_scope.Start.Offset));
for (int i = 0; i < scopes.Count; i++) {
var scope = scopes [i];
signature.WriteUInt32 ((uint) scope.Start.Offset);
var end_offset = scope.End.IsEndOfMethod
? method_info.code_size
: scope.End.Offset;
signature.WriteUInt32 ((uint) (end_offset - scope.Start.Offset));
}
AddCustomDebugInformation (provider, state_machine_scope, signature);
}
@ -2411,7 +2417,7 @@ namespace Mono.Cecil {
for (int i = 0; i < async_method.yields.Count; i++) {
signature.WriteUInt32 ((uint) async_method.yields [i].Offset);
signature.WriteUInt32 ((uint) async_method.resumes [i].Offset);
signature.WriteCompressedUInt32 (async_method.move_next.MetadataToken.RID);
signature.WriteCompressedUInt32 (async_method.resume_methods [i].MetadataToken.RID);
}
AddCustomDebugInformation (provider, async_method, signature);

View File

@ -11,6 +11,7 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Text;
using Mono.Collections.Generic;
@ -65,14 +66,19 @@ namespace Mono.Cecil {
#endif
}
#if !NET_CORE
public abstract class BaseAssemblyResolver : IAssemblyResolver {
static readonly bool on_mono = Type.GetType ("Mono.Runtime") != null;
readonly Collection<string> directories;
#if NET_CORE
// Maps file names of available trusted platform assemblies to their full paths.
// Internal for testing.
internal static readonly Lazy<Dictionary<string, string>> TrustedPlatformAssemblies = new Lazy<Dictionary<string, string>> (CreateTrustedPlatformAssemblyMap);
#else
Collection<string> gac_paths;
#endif
public void AddSearchDirectory (string directory)
{
@ -127,6 +133,11 @@ namespace Mono.Cecil {
};
}
#if NET_CORE
assembly = SearchTrustedPlatformAssemblies (name, parameters);
if (assembly != null)
return assembly;
#else
var framework_dir = Path.GetDirectoryName (typeof (object).Module.FullyQualifiedName);
var framework_dirs = on_mono
? new [] { framework_dir, Path.Combine (framework_dir, "Facades") }
@ -151,7 +162,7 @@ namespace Mono.Cecil {
assembly = SearchDirectory (name, framework_dirs, parameters);
if (assembly != null)
return assembly;
#endif
if (ResolveFailure != null) {
assembly = ResolveFailure (this, name);
if (assembly != null)
@ -161,7 +172,45 @@ namespace Mono.Cecil {
throw new AssemblyResolutionException (name);
}
AssemblyDefinition SearchDirectory (AssemblyNameReference name, IEnumerable<string> directories, ReaderParameters parameters)
#if NET_CORE
AssemblyDefinition SearchTrustedPlatformAssemblies (AssemblyNameReference name, ReaderParameters parameters)
{
if (name.IsWindowsRuntime)
return null;
if (TrustedPlatformAssemblies.Value.TryGetValue (name.Name, out string path))
return GetAssembly (path, parameters);
return null;
}
static Dictionary<string, string> CreateTrustedPlatformAssemblyMap ()
{
var result = new Dictionary<string, string> (StringComparer.OrdinalIgnoreCase);
string paths;
try {
// AppContext is only available on platforms that implement .NET Standard 1.6
var appContextType = Type.GetType ("System.AppContext, System.AppContext, Version=4.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", throwOnError: false);
var getData = appContextType?.GetTypeInfo ().GetDeclaredMethod ("GetData");
paths = (string) getData?.Invoke (null, new [] { "TRUSTED_PLATFORM_ASSEMBLIES" });
} catch {
paths = null;
}
if (paths == null)
return result;
foreach (var path in paths.Split (Path.PathSeparator))
if (string.Equals (Path.GetExtension (path), ".dll", StringComparison.OrdinalIgnoreCase))
result [Path.GetFileNameWithoutExtension (path)] = path;
return result;
}
#endif
protected virtual AssemblyDefinition SearchDirectory (AssemblyNameReference name, IEnumerable<string> directories, ReaderParameters parameters)
{
var extensions = name.IsWindowsRuntime ? new [] { ".winmd", ".dll" } : new [] { ".exe", ".dll" };
foreach (var directory in directories) {
@ -185,11 +234,11 @@ namespace Mono.Cecil {
return version.Major == 0 && version.Minor == 0 && version.Build == 0 && version.Revision == 0;
}
#if !NET_CORE
AssemblyDefinition GetCorlib (AssemblyNameReference reference, ReaderParameters parameters)
{
var version = reference.Version;
var corlib = typeof (object).Assembly.GetName ();
if (corlib.Version == version || IsZero (version))
return GetAssembly (typeof (object).Module.FullyQualifiedName, parameters);
@ -325,7 +374,7 @@ namespace Mono.Cecil {
return null;
}
#endif
static string GetAssemblyFile (AssemblyNameReference reference, string prefix, string gac)
{
var gac_folder = new StringBuilder ()
@ -352,5 +401,4 @@ namespace Mono.Cecil {
{
}
}
#endif
}

View File

@ -62,8 +62,10 @@ namespace Mono.Cecil {
bool HasFields { get; }
bool HasProperties { get; }
bool HasConstructorArguments { get; }
Collection<CustomAttributeNamedArgument> Fields { get; }
Collection<CustomAttributeNamedArgument> Properties { get; }
Collection<CustomAttributeArgument> ConstructorArguments { get; }
}
public sealed class CustomAttribute : ICustomAttribute {
@ -196,7 +198,6 @@ namespace Mono.Cecil {
resolved = false;
}
return this;
});
}
}

View File

@ -8,8 +8,6 @@
// Licensed under the MIT/X11 license.
//
#if !NET_CORE
using System;
using System.Collections.Generic;
@ -61,5 +59,3 @@ namespace Mono.Cecil {
}
}
}
#endif

View File

@ -143,9 +143,9 @@ namespace Mono.Cecil {
public MethodBody Body {
get {
MethodBody localBody = this.body;
if (localBody != null)
return localBody;
var local = this.body;
if (local != null)
return local;
if (!HasBody)
return null;

View File

@ -418,13 +418,11 @@ namespace Mono.Cecil {
public IAssemblyResolver AssemblyResolver {
get {
#if !NET_CORE
if (assembly_resolver.value == null) {
lock (module_lock) {
assembly_resolver = Disposable.Owned (new DefaultAssemblyResolver () as IAssemblyResolver);
}
}
#endif
return assembly_resolver.value;
}
@ -754,28 +752,16 @@ namespace Mono.Cecil {
internal FieldDefinition Resolve (FieldReference field)
{
#if NET_CORE
if (MetadataResolver == null)
throw new NotSupportedException ();
#endif
return MetadataResolver.Resolve (field);
}
internal MethodDefinition Resolve (MethodReference method)
{
#if NET_CORE
if (MetadataResolver == null)
throw new NotSupportedException ();
#endif
return MetadataResolver.Resolve (method);
}
internal TypeDefinition Resolve (TypeReference type)
{
#if NET_CORE
if (MetadataResolver == null)
throw new NotSupportedException ();
#endif
return MetadataResolver.Resolve (type);
}
@ -970,6 +956,19 @@ namespace Mono.Cecil {
get { return module_lock; }
}
internal void Read<TItem> (TItem item, Action<TItem, MetadataReader> read)
{
lock (module_lock) {
var position = reader.position;
var context = reader.context;
read (item, reader);
reader.position = position;
reader.context = context;
}
}
internal TRet Read<TItem, TRet> (TItem item, Func<TItem, MetadataReader, TRet> read)
{
lock (module_lock) {
@ -1321,6 +1320,9 @@ namespace Mono.Cecil {
public static TargetRuntime ParseRuntime (this string self)
{
if (string.IsNullOrEmpty (self))
return TargetRuntime.Net_4_0;
switch (self [1]) {
case '1':
return self [3] == '0'

View File

@ -70,6 +70,14 @@ namespace Mono.Cecil {
{
this.attribute_type = attributeType;
}
bool ICustomAttribute.HasConstructorArguments {
get { return false; }
}
Collection<CustomAttributeArgument> ICustomAttribute.ConstructorArguments {
get { throw new NotSupportedException (); }
}
}
public sealed class SecurityDeclaration {
@ -143,11 +151,7 @@ namespace Mono.Cecil {
if (resolved || !HasImage)
return;
module.Read (this, (declaration, reader) => {
reader.ReadSecurityDeclarationSignature (declaration);
return this;
});
module.Read (this, (declaration, reader) => reader.ReadSecurityDeclarationSignature (declaration));
resolved = true;
}
}

View File

@ -416,6 +416,9 @@ namespace Mono.Cecil {
return base_type.IsTypeOf ("System", "Enum") || (base_type.IsTypeOf ("System", "ValueType") && !this.IsTypeOf ("System", "Enum"));
}
set {
throw new NotSupportedException ();
}
}
public override bool IsPrimitive {

View File

@ -184,7 +184,7 @@ namespace Mono.Cecil {
return typeRef;
var type = LookupType ("System", name);
type.etype = element_type;
type.IsValueType = true;
type.KnownValueType ();
return typeRef = type;
}
}
@ -313,6 +313,12 @@ namespace Mono.Cecil {
return true;
}
public static void KnownValueType (this TypeReference type)
{
if (!type.IsDefinition)
type.IsValueType = true;
}
static bool IsCoreLibrary (AssemblyNameReference reference)
{
var name = reference.Name;

View File

@ -100,7 +100,8 @@ namespace Mono {
public static Type [] GetGenericArguments (this Type type)
{
#if NET_CORE
return type.GetTypeInfo ().GenericTypeArguments;
var info = type.GetTypeInfo ();
return info.IsGenericTypeDefinition ? info.GenericTypeParameters : info.GenericTypeArguments;
#else
return type.GetGenericArguments ();
#endif

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<DefineConstants>$(DefineConstants);NET_4_0;NET_CORE;</DefineConstants>
<DefineConstants>$(DefineConstants);NET_CORE;</DefineConstants>
<EnableDefaultCompileItems>false</EnableDefaultCompileItems>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<PublicSign Condition=" '$(OS)' != 'Windows_NT' ">true</PublicSign>

View File

@ -17,4 +17,4 @@ using System.Runtime.InteropServices;
[assembly: AssemblyVersion ("0.10.0.0")]
[assembly: AssemblyFileVersion ("0.10.0.0")]
[assembly: AssemblyInformationalVersion ("0.10.0.0-beta6")]
[assembly: AssemblyInformationalVersion ("0.10.0.0-beta7")]

View File

@ -1,10 +1,34 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\Mono.Cecil.Tests.props" />
<PropertyGroup>
<ProjectGuid>{A47B1F49-A81A-43E8-BE6B-DD28AF2C4055}</ProjectGuid>
<RootNamespace>Mono.Cecil.Tests</RootNamespace>
<AssemblyName>Mono.Cecil.Tests</AssemblyName>
</PropertyGroup>
<ItemGroup Condition="'$(NetStandard)' == 'true'">
<PackageReference Include="System.Reflection.TypeExtensions">
<Version>4.3.0</Version>
</PackageReference>
<PackageReference Include="System.Diagnostics.Process">
<Version>4.3.0</Version>
</PackageReference>
<PackageReference Include="System.Diagnostics.StackTrace">
<Version>4.3.0</Version>
</PackageReference>
<PackageReference Include="System.Diagnostics.FileVersionInfo">
<Version>4.3.0</Version>
</PackageReference>
<PackageReference Include="System.Runtime.Loader">
<Version>4.3.0</Version>
</PackageReference>
<PackageReference Include="Microsoft.CodeAnalysis.CSharp">
<Version>2.3.2</Version>
</PackageReference>
<PackageReference Include="Microsoft.CodeAnalysis.VisualBasic">
<Version>2.3.2</Version>
</PackageReference>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Mono.Cecil.csproj">
<Project>{D68133BD-1E63-496E-9EDE-4FBDBF77B486}</Project>
@ -26,6 +50,5 @@
<ItemGroup>
<None Include="Resources\**\*" />
</ItemGroup>
<Import Project="..\Mono.Cecil.Tests.props" />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" Condition="'$(NetStandard)' != 'true'" />
</Project>

View File

@ -59,6 +59,9 @@ namespace Mono.Cecil.Tests {
[Test]
public void Retargetable ()
{
if (Platform.OnCoreClr)
return;
TestModule ("RetargetableExample.dll", module => {
var type = module.Types [1];
var property = type.Properties [0];
@ -76,6 +79,9 @@ namespace Mono.Cecil.Tests {
[Test]
public void SystemRuntime ()
{
if (Platform.OnCoreClr)
return;
TestModule ("System.Runtime.dll", module => {
Assert.AreEqual ("System.Runtime", module.Assembly.Name.Name);
Assert.AreEqual (1, module.AssemblyReferences.Count);

View File

@ -0,0 +1,10 @@
#if NET_3_5 || NET_4_0
namespace System.Runtime.CompilerServices {
[AttributeUsage (AttributeTargets.Parameter, Inherited = false)]
public sealed class CallerMemberNameAttribute : Attribute {
public CallerMemberNameAttribute ()
{
}
}
}
#endif

View File

@ -4,9 +4,16 @@ using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Text;
using System.Reflection;
using NUnit.Framework;
#if NET_CORE
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Emit;
using CS = Microsoft.CodeAnalysis.CSharp;
using VB = Microsoft.CodeAnalysis.VisualBasic;
#endif
namespace Mono.Cecil.Tests {
struct CompilationResult {
@ -22,7 +29,23 @@ namespace Mono.Cecil.Tests {
public static class Platform {
public static bool OnMono { get { return typeof (object).Assembly.GetType ("Mono.Runtime") != null; } }
public static bool OnMono {
get { return TryGetType ("Mono.Runtime") != null; }
}
public static bool OnCoreClr {
get { return TryGetType ("System.Runtime.Loader.AssemblyLoadContext, System.Runtime.Loader, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a") != null; }
}
static Type TryGetType (string assemblyQualifiedName)
{
try {
// Note that throwOnError=false only suppresses some exceptions, not all.
return Type.GetType(assemblyQualifiedName, throwOnError: false);
} catch {
return null;
}
}
}
abstract class CompilationService {
@ -68,8 +91,11 @@ namespace Mono.Cecil.Tests {
return IlasmCompilationService.Instance.Compile (name);
if (extension == ".cs" || extension == ".vb")
#if NET_CORE
return RoslynCompilationService.Instance.Compile (name);
#else
return CodeDomCompilationService.Instance.Compile (name);
#endif
throw new NotSupportedException (extension);
}
@ -84,9 +110,11 @@ namespace Mono.Cecil.Tests {
public static void Verify (string name)
{
#if !NET_CORE
var output = Platform.OnMono ? ShellService.PEDump (name) : ShellService.PEVerify (name);
if (output.ExitCode != 0)
Assert.Fail (output.ToString ());
#endif
}
}
@ -112,6 +140,76 @@ namespace Mono.Cecil.Tests {
}
}
#if NET_CORE
class RoslynCompilationService : CompilationService {
public static readonly RoslynCompilationService Instance = new RoslynCompilationService ();
protected override string CompileFile (string name)
{
var compilation = GetCompilation (name);
var outputName = GetCompiledFilePath (name);
var result = compilation.Emit (outputName);
Assert.IsTrue (result.Success, GetErrorMessage (result));
return outputName;
}
static Compilation GetCompilation (string name)
{
var assemblyName = Path.GetFileNameWithoutExtension (name);
var source = File.ReadAllText (name);
var tpa = BaseAssemblyResolver.TrustedPlatformAssemblies.Value;
var references = new []
{
MetadataReference.CreateFromFile (tpa ["netstandard"]),
MetadataReference.CreateFromFile (tpa ["mscorlib"]),
MetadataReference.CreateFromFile (tpa ["System.Private.CoreLib"]),
MetadataReference.CreateFromFile (tpa ["System.Runtime"]),
MetadataReference.CreateFromFile (tpa ["System.Console"]),
MetadataReference.CreateFromFile (tpa ["System.Security.AccessControl"]),
};
var extension = Path.GetExtension (name);
switch (extension) {
case ".cs":
return CS.CSharpCompilation.Create (
assemblyName,
new [] { CS.SyntaxFactory.ParseSyntaxTree (source) },
references,
new CS.CSharpCompilationOptions (OutputKind.DynamicallyLinkedLibrary, optimizationLevel: OptimizationLevel.Release));
case ".vb":
return VB.VisualBasicCompilation.Create (
assemblyName,
new [] { VB.SyntaxFactory.ParseSyntaxTree (source) },
references,
new VB.VisualBasicCompilationOptions (OutputKind.DynamicallyLinkedLibrary, optimizationLevel: OptimizationLevel.Release));
default:
throw new NotSupportedException ();
}
}
static string GetErrorMessage (EmitResult result)
{
if (result.Success)
return string.Empty;
var builder = new StringBuilder ();
foreach (var diagnostic in result.Diagnostics)
builder.AppendLine (diagnostic.ToString ());
return builder.ToString ();
}
}
#else
class CodeDomCompilationService : CompilationService {
public static readonly CodeDomCompilationService Instance = new CodeDomCompilationService ();
@ -166,6 +264,8 @@ namespace Mono.Cecil.Tests {
}
}
#endif
class ShellService {
public class ProcessOutput {
@ -243,9 +343,13 @@ namespace Mono.Cecil.Tests {
static string NetFrameworkTool (string tool)
{
#if NET_CORE
return Path.Combine (Environment.GetFolderPath (Environment.SpecialFolder.Windows), "Microsoft.NET", "Framework", "v4.0.30319", tool + ".exe");
#else
return Path.Combine (
Path.GetDirectoryName (typeof (object).Assembly.Location),
tool + ".exe");
#endif
}
static string WinSdkTool (string tool)

View File

@ -21,15 +21,15 @@ namespace Mono.Cecil.Tests {
TestCSharp ("CustomAttributes.cs", module => {
var hamster = module.GetType ("Hamster");
Assert.IsTrue (hamster.HasCustomAttributes);
Assert.AreEqual (1, hamster.CustomAttributes.Count);
Assert.IsTrue (hamster.HasCustomAttributes);
Assert.AreEqual (1, hamster.CustomAttributes.Count);
var attribute = hamster.CustomAttributes [0];
Assert.AreEqual ("System.Void FooAttribute::.ctor(System.String)",
attribute.Constructor.FullName);
var attribute = hamster.CustomAttributes [0];
Assert.AreEqual ("System.Void FooAttribute::.ctor(System.String)",
attribute.Constructor.FullName);
Assert.IsTrue (attribute.HasConstructorArguments);
Assert.AreEqual (1, attribute.ConstructorArguments.Count);
Assert.IsTrue (attribute.HasConstructorArguments);
Assert.AreEqual (1, attribute.ConstructorArguments.Count);
AssertArgument ("bar", attribute.ConstructorArguments [0]);
});
@ -559,10 +559,10 @@ namespace Mono.Cecil.Tests {
}
switch (Type.GetTypeCode (value.GetType ())) {
case TypeCode.String:
case System.TypeCode.String:
signature.AppendFormat ("\"{0}\"", value);
break;
case TypeCode.Char:
case System.TypeCode.Char:
signature.AppendFormat ("'{0}'", (char) value);
break;
default:

View File

@ -170,6 +170,7 @@ namespace Mono.Cecil.Tests {
}, verify: false);
}
#if !NET_CORE
[Test]
public void WindowsRuntimeComponentAssembly ()
{
@ -181,7 +182,7 @@ namespace Mono.Cecil.Tests {
Assert.IsTrue (module.Assembly.Name.IsWindowsRuntime);
}, verify: false, assemblyResolver: resolver);
}
#endif
[Test]
public void DeterministicAssembly ()
{

View File

@ -1,7 +1,6 @@
#if !READ_ONLY
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using SR = System.Reflection;
@ -255,6 +254,9 @@ namespace Mono.Cecil.Tests {
[Test]
public void ContextGenericTest ()
{
if (Platform.OnCoreClr)
return;
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<,>));
@ -287,11 +289,10 @@ namespace Mono.Cecil.Tests {
delegate void Emitter (ModuleDefinition module, MethodBody body);
[MethodImpl (MethodImplOptions.NoInlining)]
static TDelegate Compile<TDelegate> (Emitter emitter)
static TDelegate Compile<TDelegate> (Emitter emitter, [CallerMemberName] string testMethodName = null)
where TDelegate : class
{
var name = GetTestCaseName ();
var name = "ImportCecil_" + testMethodName;
var module = CreateTestModule<TDelegate> (name, emitter);
var assembly = LoadTestModule (module);
@ -362,15 +363,6 @@ namespace Mono.Cecil.Tests {
{
return ModuleDefinition.CreateModule (name, ModuleKind.Dll);
}
[MethodImpl (MethodImplOptions.NoInlining)]
static string GetTestCaseName ()
{
var stack_trace = new StackTrace ();
var stack_frame = stack_trace.GetFrame (2);
return "ImportCecil_" + stack_frame.GetMethod ().Name;
}
}
}
#endif
#endif

View File

@ -1,7 +1,6 @@
#if !READ_ONLY
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using SR = System.Reflection;
using System.Runtime.CompilerServices;
@ -156,6 +155,9 @@ namespace Mono.Cecil.Tests {
[Test]
public void ImportGenericField ()
{
if (Platform.OnCoreClr)
return;
var get_field = Compile<Func<Generic<string>, string>> ((module, body) => {
var il = body.GetILProcessor ();
il.Emit (OpCodes.Ldarg_0);
@ -173,6 +175,9 @@ namespace Mono.Cecil.Tests {
[Test]
public void ImportGenericMethod ()
{
if (Platform.OnCoreClr)
return;
var generic_identity = Compile<Func<Generic<int>, int, int>> ((module, body) => {
var il = body.GetILProcessor ();
il.Emit (OpCodes.Ldarg_0);
@ -187,6 +192,9 @@ namespace Mono.Cecil.Tests {
[Test]
public void ImportGenericMethodSpec ()
{
if (Platform.OnCoreClr)
return;
var gen_spec_id = Compile<Func<Generic<string>, int, int>> ((module, body) => {
var il = body.GetILProcessor ();
il.Emit (OpCodes.Ldarg_0);
@ -202,6 +210,9 @@ namespace Mono.Cecil.Tests {
[Test]
public void ImportComplexGenericMethodSpec ()
{
if (Platform.OnCoreClr)
return;
var gen_spec_id = Compile<Func<Generic<string>, int, int>> ((module, body) => {
var il = body.GetILProcessor ();
il.Emit (OpCodes.Ldarg_0);
@ -279,6 +290,9 @@ namespace Mono.Cecil.Tests {
[Test]
public void ImportGenericFieldFromContext ()
{
if (Platform.OnCoreClr)
return;
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");
@ -295,6 +309,9 @@ namespace Mono.Cecil.Tests {
[Test]
public void ImportGenericMethodFromContext ()
{
if (Platform.OnCoreClr)
return;
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");
@ -334,11 +351,10 @@ namespace Mono.Cecil.Tests {
delegate void Emitter (ModuleDefinition module, MethodBody body);
[MethodImpl (MethodImplOptions.NoInlining)]
static TDelegate Compile<TDelegate> (Emitter emitter)
static TDelegate Compile<TDelegate> (Emitter emitter, [CallerMemberName] string testMethodName = null)
where TDelegate : class
{
var name = GetTestCaseName ();
var name = "ImportReflection_" + testMethodName;
var module = CreateTestModule<TDelegate> (name, emitter);
var assembly = LoadTestModule (module);
@ -409,15 +425,6 @@ namespace Mono.Cecil.Tests {
{
return ModuleDefinition.CreateModule (name, ModuleKind.Dll);
}
[MethodImpl (MethodImplOptions.NoInlining)]
static string GetTestCaseName ()
{
var stack_trace = new StackTrace ();
var stack_frame = stack_trace.GetFrame (2);
return "ImportReflection_" + stack_frame.GetMethod ().Name;
}
}
}
#endif
#endif

View File

@ -204,6 +204,8 @@ namespace Mono.Cecil.Tests {
var beta = type.GetMethod ("Beta");
var charlie = type.GetMethod ("Charlie");
// Note that the test depends on the C# compiler emitting the constructor call instruction as
// the first instruction of the method body. This requires optimizations to be enabled.
var new_list_beta = (MethodReference) beta.Body.Instructions [0].Operand;
var new_list_charlie = (MethodReference) charlie.Body.Instructions [0].Operand;

View File

@ -49,7 +49,10 @@ namespace Mono.Cecil.Tests {
[Test]
public void MultiModules ()
{
TestModule ("mma.exe", module => {
if (Platform.OnCoreClr)
return;
TestModule("mma.exe", module => {
var assembly = module.Assembly;
Assert.AreEqual (3, assembly.Modules.Count);
@ -157,6 +160,9 @@ namespace Mono.Cecil.Tests {
[Test]
public void ExportedTypeFromNetModule ()
{
if (Platform.OnCoreClr)
return;
TestModule ("mma.exe", module => {
Assert.IsTrue (module.HasExportedTypes);
Assert.AreEqual (2, module.ExportedTypes.Count);
@ -183,14 +189,14 @@ namespace Mono.Cecil.Tests {
var exported_type = module.ExportedTypes [0];
Assert.AreEqual ("System.Diagnostics.DebuggableAttribute", exported_type.FullName);
Assert.AreEqual ("mscorlib", exported_type.Scope.Name);
Assert.AreEqual (Platform.OnCoreClr ? "System.Private.CoreLib" : "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);
Assert.AreEqual (Platform.OnCoreClr ? "System.Private.CoreLib" : "mscorlib", nested_exported_type.Scope.Name);
});
}
@ -199,7 +205,7 @@ namespace Mono.Cecil.Tests {
{
TestCSharp ("CustomAttributes.cs", module => {
Assert.IsTrue (module.HasTypeReference ("System.Attribute"));
Assert.IsTrue (module.HasTypeReference ("mscorlib", "System.Attribute"));
Assert.IsTrue (module.HasTypeReference (Platform.OnCoreClr ? "System.Private.CoreLib" : "mscorlib", "System.Attribute"));
Assert.IsFalse (module.HasTypeReference ("System.Core", "System.Attribute"));
Assert.IsFalse (module.HasTypeReference ("System.Linq.Enumerable"));
@ -234,10 +240,9 @@ namespace Mono.Cecil.Tests {
}
[Test]
[ExpectedException (typeof (BadImageFormatException))]
public void OpenIrrelevantFile ()
{
GetResourceModule ("text_file.txt");
Assert.Throws<BadImageFormatException> (() => GetResourceModule ("text_file.txt"));
}
[Test]
@ -273,7 +278,8 @@ namespace Mono.Cecil.Tests {
{
using (var module = ModuleDefinition.ReadModule (file))
{
Assert.IsNotNullOrEmpty (module.FileName);
Assert.IsNotNull (module.FileName);
Assert.IsNotEmpty (module.FileName);
Assert.AreEqual (path, module.FileName);
}
}

View File

@ -320,8 +320,15 @@ namespace Mono.Cecil.Tests {
var state_machine_scope = move_next.CustomDebugInformations.OfType<StateMachineScopeDebugInformation> ().FirstOrDefault ();
Assert.IsNotNull (state_machine_scope);
Assert.AreEqual (0, state_machine_scope.Start.Offset);
Assert.IsTrue (state_machine_scope.End.IsEndOfMethod);
Assert.AreEqual (3, state_machine_scope.Scopes.Count);
Assert.AreEqual (0, state_machine_scope.Scopes [0].Start.Offset);
Assert.IsTrue (state_machine_scope.Scopes [0].End.IsEndOfMethod);
Assert.AreEqual (0, state_machine_scope.Scopes [1].Start.Offset);
Assert.AreEqual (0, state_machine_scope.Scopes [1].End.Offset);
Assert.AreEqual (184, state_machine_scope.Scopes [2].Start.Offset);
Assert.AreEqual (343, state_machine_scope.Scopes [2].End.Offset);
var async_body = move_next.CustomDebugInformations.OfType<AsyncMethodBodyDebugInformation> ().FirstOrDefault ();
Assert.IsNotNull (async_body);
@ -335,7 +342,8 @@ namespace Mono.Cecil.Tests {
Assert.AreEqual (91, async_body.Resumes [0].Offset);
Assert.AreEqual (252, async_body.Resumes [1].Offset);
Assert.AreEqual (move_next, async_body.MoveNextMethod);
Assert.AreEqual (move_next, async_body.ResumeMethods [0]);
Assert.AreEqual (move_next, async_body.ResumeMethods [1]);
});
}

View File

@ -26,7 +26,8 @@ namespace Mono.Cecil.Tests {
Assert.IsNotNull (definition);
Assert.AreEqual ("System.String System.String::Empty", definition.FullName);
Assert.AreEqual ("mscorlib", definition.Module.Assembly.Name.Name);
Assert.AreEqual (Platform.OnCoreClr ? "System.Private.CoreLib" : "mscorlib",
definition.Module.Assembly.Name.Name);
}
delegate string GetSubstring (string str, int start, int length);
@ -42,7 +43,8 @@ namespace Mono.Cecil.Tests {
Assert.IsNotNull (definition);
Assert.AreEqual ("System.String System.String::Substring(System.Int32,System.Int32)", definition.FullName);
Assert.AreEqual ("mscorlib", definition.Module.Assembly.Name.Name);
Assert.AreEqual (Platform.OnCoreClr ? "System.Private.CoreLib" : "mscorlib",
definition.Module.Assembly.Name.Name);
}
[Test]
@ -56,7 +58,8 @@ namespace Mono.Cecil.Tests {
Assert.AreEqual ("get_Length", definition.Name);
Assert.AreEqual ("System.String", definition.DeclaringType.FullName);
Assert.AreEqual ("mscorlib", definition.Module.Assembly.Name.Name);
Assert.AreEqual (Platform.OnCoreClr ? "System.Private.CoreLib" : "mscorlib",
definition.Module.Assembly.Name.Name);
}
[Test]
@ -72,7 +75,8 @@ namespace Mono.Cecil.Tests {
Assert.IsNotNull (definition);
Assert.AreEqual ("System.Void System.Collections.Generic.List`1::Add(T)", definition.FullName);
Assert.AreEqual ("mscorlib", definition.Module.Assembly.Name.Name);
Assert.AreEqual (Platform.OnCoreClr ? "System.Private.CoreLib" : "mscorlib",
definition.Module.Assembly.Name.Name);
}
[Test]
@ -92,7 +96,8 @@ namespace Mono.Cecil.Tests {
Assert.IsNotNull (definition);
Assert.AreEqual ("System.Boolean System.Collections.Generic.Dictionary`2::TryGetValue(TKey,TValue&)", definition.FullName);
Assert.AreEqual ("mscorlib", definition.Module.Assembly.Name.Name);
Assert.AreEqual (Platform.OnCoreClr ? "System.Private.CoreLib" : "mscorlib",
definition.Module.Assembly.Name.Name);
}
class CustomResolver : DefaultAssemblyResolver {
@ -140,7 +145,7 @@ namespace Mono.Cecil.Tests {
var definition = reference.Resolve ();
Assert.IsNotNull (definition);
Assert.AreEqual ("System.Diagnostics.DebuggableAttribute", definition.FullName);
Assert.AreEqual ("mscorlib", definition.Module.Assembly.Name.Name);
Assert.AreEqual (Platform.OnCoreClr ? "System.Private.CoreLib" : "mscorlib", definition.Module.Assembly.Name.Name);
}
[Test]
@ -162,7 +167,7 @@ namespace Mono.Cecil.Tests {
var definition = reference.Resolve ();
Assert.IsNotNull (definition);
Assert.AreEqual ("System.Diagnostics.DebuggableAttribute/DebuggingModes", definition.FullName);
Assert.AreEqual ("mscorlib", definition.Module.Assembly.Name.Name);
Assert.AreEqual (Platform.OnCoreClr ? "System.Private.CoreLib" : "mscorlib", definition.Module.Assembly.Name.Name);
}
[Test]
@ -175,6 +180,19 @@ namespace Mono.Cecil.Tests {
Assert.IsNull (get_a_b.Resolve ());
}
[Test]
public void GenericRectangularArrayGetMethodInMemberReferences ()
{
using (var module = GetResourceModule ("FSharp.Core.dll")) {
foreach (var member in module.GetMemberReferences ()) {
if (!member.DeclaringType.IsArray)
continue;
Assert.IsNull (member.Resolve ());
}
}
}
[Test]
public void ResolveFunctionPointer ()
{
@ -223,7 +241,9 @@ namespace Mono.Cecil.Tests {
Assert.IsTrue (reference.IsRetargetable);
var assembly = resolver.Resolve (reference);
Assert.IsNotNull (assembly);
Assert.AreEqual (typeof (object).Assembly.GetName ().Version, assembly.Name.Version);
if (!Platform.OnCoreClr)
Assert.AreEqual (typeof (object).Assembly.GetName ().Version, assembly.Name.Version);
}
}

View File

@ -249,10 +249,10 @@ namespace Mono.Cecil.Tests {
}
switch (Type.GetTypeCode (value.GetType ())) {
case TypeCode.String:
case System.TypeCode.String:
signature.AppendFormat ("\"{0}\"", value);
break;
case TypeCode.Char:
case System.TypeCode.Char:
signature.AppendFormat ("'{0}'", (char) value);
break;
default:

View File

@ -233,6 +233,9 @@ namespace Mono.Cecil.Tests {
[Test]
public void GenericInstanceExternArguments ()
{
if (Platform.OnCoreClr)
return;
var module = GetCurrentModule ();
var fullname = string.Format ("System.Collections.Generic.Dictionary`2[[System.Int32, {0}],[System.String, {0}]]",
@ -280,7 +283,7 @@ namespace Mono.Cecil.Tests {
var instance = type as GenericInstanceType;
Assert.IsNotNull (instance);
Assert.AreEqual (2, instance.GenericArguments.Count);
Assert.AreEqual ("mscorlib", type.Scope.Name);
Assert.AreEqual (Platform.OnCoreClr ? "System.Runtime" : "mscorlib", type.Scope.Name);
Assert.AreEqual (module, type.Module);
Assert.AreEqual ("System.Collections.Generic", type.Namespace);
Assert.AreEqual ("Dictionary`2", type.Name);
@ -296,7 +299,7 @@ namespace Mono.Cecil.Tests {
Assert.AreEqual ("TypeParserTests", argument.Name);
argument = instance.GenericArguments [1];
Assert.AreEqual ("mscorlib", argument.Scope.Name);
Assert.AreEqual (Platform.OnCoreClr ? "System.Private.CoreLib" : "mscorlib", argument.Scope.Name);
Assert.AreEqual (module, argument.Module);
Assert.AreEqual ("System", argument.Namespace);
Assert.AreEqual ("String", argument.Name);
@ -319,7 +322,7 @@ namespace Mono.Cecil.Tests {
var instance = type as GenericInstanceType;
Assert.IsNotNull (instance);
Assert.AreEqual (2, instance.GenericArguments.Count);
Assert.AreEqual ("mscorlib", type.Scope.Name);
Assert.AreEqual (Platform.OnCoreClr ? "System.Private.CoreLib" : "mscorlib", type.Scope.Name);
Assert.AreEqual (module, type.Module);
Assert.AreEqual ("System.Collections.Generic", type.Namespace);
Assert.AreEqual ("Dictionary`2", type.Name);
@ -354,7 +357,7 @@ namespace Mono.Cecil.Tests {
var instance = type as GenericInstanceType;
Assert.IsNotNull (instance);
Assert.AreEqual (2, instance.GenericArguments.Count);
Assert.AreEqual ("mscorlib", type.Scope.Name);
Assert.AreEqual (Platform.OnCoreClr ? "System.Runtime" : "mscorlib", type.Scope.Name);
Assert.AreEqual (module, type.Module);
Assert.AreEqual ("System.Collections.Generic", type.Namespace);
Assert.AreEqual ("Dictionary`2", type.Name);
@ -364,7 +367,7 @@ namespace Mono.Cecil.Tests {
Assert.AreEqual (2, type.GenericParameters.Count);
var argument = instance.GenericArguments [0];
Assert.AreEqual ("mscorlib", argument.Scope.Name);
Assert.AreEqual (Platform.OnCoreClr ? "System.Private.CoreLib" : "mscorlib", argument.Scope.Name);
Assert.AreEqual (module, argument.Module);
Assert.AreEqual ("System", argument.Namespace);
Assert.AreEqual ("String", argument.Name);
@ -385,7 +388,7 @@ namespace Mono.Cecil.Tests {
Assert.IsInstanceOf (typeof (TypeDefinition), argument);
argument = instance.GenericArguments [1];
Assert.AreEqual ("mscorlib", argument.Scope.Name);
Assert.AreEqual (Platform.OnCoreClr ? "System.Private.CoreLib" : "mscorlib", argument.Scope.Name);
Assert.AreEqual (module, argument.Module);
Assert.AreEqual ("System", argument.Namespace);
Assert.AreEqual ("Int32", argument.Name);

View File

@ -1,4 +1,6 @@
using System;
#if !NET_CORE
using System;
using System.Collections.Generic;
using System.IO;
using Microsoft.Win32;
@ -91,3 +93,4 @@ namespace Mono.Cecil.Tests {
}
}
}
#endif

View File

@ -1,4 +1,6 @@
using NUnit.Framework;
#if !NET_CORE
using NUnit.Framework;
using System;
using System.Collections.Generic;
using System.IO;
@ -141,3 +143,4 @@ namespace Mono.Cecil.Tests {
protected override string [] CustomListTypeNames { get { return new [] { "CustomList" }; } }
}
}
#endif

View File

@ -44,6 +44,7 @@ namespace Mono.Cecil.Rocks {
class ParseContext {
public CodeReader Code { get; set; }
public int Position { get; set; }
public MetadataReader Metadata { get; set; }
public Collection<VariableDefinition> Variables { get; set; }
public IILVisitor Visitor { get; set; }
@ -58,6 +59,14 @@ namespace Mono.Cecil.Rocks {
if (!method.HasBody || !method.HasImage)
throw new ArgumentException ();
method.Module.Read (method, (m, _) => {
ParseMethod (m, visitor);
return true;
});
}
static void ParseMethod (MethodDefinition method, IILVisitor visitor)
{
var context = CreateContext (method, visitor);
var code = context.Code;
@ -75,15 +84,18 @@ namespace Mono.Cecil.Rocks {
default:
throw new NotSupportedException ();
}
code.MoveBackTo (context.Position);
}
static ParseContext CreateContext (MethodDefinition method, IILVisitor visitor)
{
var code = method.Module.Read (method, (_, reader) => reader.code);
code.MoveTo (method);
var position = code.MoveTo (method);
return new ParseContext {
Code = code,
Position = position,
Metadata = code.reader,
Visitor = visitor,
};

View File

@ -189,10 +189,10 @@ namespace Mono.Cecil.Rocks {
var instruction = self.Instructions [i];
if (instruction.OpCode.Code != Code.Ldc_I8)
continue;
var l = (long)instruction.Operand;
if (l >= uint.MaxValue)
var l = (long) instruction.Operand;
if (l >= int.MaxValue || l <= int.MinValue)
continue;
ExpandMacro (instruction, OpCodes.Ldc_I4, (uint)l);
ExpandMacro (instruction, OpCodes.Ldc_I4, (int) l);
self.Instructions.Insert (++i, Instruction.Create (OpCodes.Conv_I8));
}
}

View File

@ -78,6 +78,7 @@ namespace Mono.Cecil.Mdb {
return null;
var info = new MethodDebugInformation (method);
info.code_size = ReadCodeSize (method);
var scopes = ReadScopes (entry, info);
ReadLineNumbers (entry, info);
@ -86,6 +87,11 @@ namespace Mono.Cecil.Mdb {
return info;
}
static int ReadCodeSize (MethodDefinition method)
{
return method.Module.Read (method, (m, reader) => reader.ReadCodeSize (m));
}
static void ReadLocalVariables (MethodEntry entry, ScopeDebugInformation [] scopes)
{
var locals = entry.GetLocals ();

View File

@ -234,7 +234,7 @@ namespace Mono.CompilerServices.SymbolWriter
public override string ToString ()
{
return String.Format ("[Line {0}:{1,2}-{3,4}:{5}]", File, Row, Column, EndRow, EndColumn, Offset);
return String.Format ("[Line {0}:{1},{2}-{3},{4}:{5}]", File, Row, Column, EndRow, EndColumn, Offset);
}
}

View File

@ -137,9 +137,15 @@ namespace Mono.Cecil.Pdb {
}
}
if (function.iteratorScopes != null)
foreach (var iterator_scope in function.iteratorScopes)
symbol.CustomDebugInformations.Add (new StateMachineScopeDebugInformation ((int) iterator_scope.Offset, (int) (iterator_scope.Offset + iterator_scope.Length + 1)));
if (function.iteratorScopes != null) {
var state_machine = new StateMachineScopeDebugInformation ();
foreach (var iterator_scope in function.iteratorScopes) {
state_machine.Scopes.Add (new StateMachineScope ((int) iterator_scope.Offset, (int) (iterator_scope.Offset + iterator_scope.Length + 1)));
}
symbol.CustomDebugInformations.Add (state_machine);
}
if (function.synchronizationInformation != null) {
var async_debug_info = new AsyncMethodBodyDebugInformation ((int) function.synchronizationInformation.GeneratedCatchHandlerOffset);
@ -147,11 +153,11 @@ namespace Mono.Cecil.Pdb {
foreach (var synchronization_point in function.synchronizationInformation.synchronizationPoints) {
async_debug_info.Yields.Add (new InstructionOffset ((int) synchronization_point.SynchronizeOffset));
async_debug_info.Resumes.Add (new InstructionOffset ((int) synchronization_point.ContinuationOffset));
async_debug_info.ResumeMethods.Add (method);
}
symbol.CustomDebugInformations.Add (async_debug_info);
async_debug_info.MoveNextMethod = method;
symbol.StateMachineKickOffMethod = (MethodDefinition) method.Module.LookupToken ((int) function.synchronizationInformation.kickoffMethodToken);
}
@ -280,7 +286,11 @@ namespace Mono.Cecil.Pdb {
break;
}
case 'A':
var index = used_namespace.IndexOf(' ');
var index = used_namespace.IndexOf (' ');
if (index < 0) {
target = new ImportTarget (ImportTargetKind.ImportNamespace) { @namespace = used_namespace };
break;
}
var alias_value = used_namespace.Substring (1, index - 1);
var alias_target_value = used_namespace.Substring (index + 2);
switch (used_namespace [index + 1]) {
@ -294,6 +304,15 @@ namespace Mono.Cecil.Pdb {
break;
}
break;
case '*':
target = new ImportTarget (ImportTargetKind.ImportNamespace) { @namespace = value };
break;
case '@':
if (!value.StartsWith ("P:"))
continue;
target = new ImportTarget (ImportTargetKind.ImportNamespace) { @namespace = value.Substring (2) };
break;
}
if (target != null)

View File

@ -111,10 +111,10 @@ namespace Mono.Cecil.Pdb {
}
if (info.HasCustomDebugInformations) {
var scopes = info.CustomDebugInformations.OfType<StateMachineScopeDebugInformation> ().ToArray ();
var state_machine = info.CustomDebugInformations.FirstOrDefault (cdi => cdi.Kind == CustomDebugInformationKind.StateMachineScope) as StateMachineScopeDebugInformation;
if (scopes.Length > 0)
metadata.WriteIteratorScopes (scopes, info);
if (state_machine != null)
metadata.WriteIteratorScopes (state_machine, info);
}
metadata.WriteCustomMetadata ();
@ -139,7 +139,7 @@ namespace Mono.Cecil.Pdb {
async_metadata.WriteUInt32 ((uint) async_debug_info.Resumes.Count);
for (int i = 0; i < async_debug_info.Resumes.Count; ++i) {
async_metadata.WriteUInt32 ((uint) async_debug_info.Yields [i].Offset);
async_metadata.WriteUInt32 (async_debug_info.MoveNextMethod != null ? async_debug_info.MoveNextMethod.MetadataToken.ToUInt32 () : 0);
async_metadata.WriteUInt32 (async_debug_info.resume_methods [i].MetadataToken.ToUInt32 ());
async_metadata.WriteUInt32 ((uint) async_debug_info.Resumes [i].Offset);
}
@ -312,10 +312,11 @@ namespace Mono.Cecil.Pdb {
Write (CustomMetadataType.ForwardInfo, () => writer.WriteUInt32 (import_parent.ToUInt32 ()));
}
public void WriteIteratorScopes (StateMachineScopeDebugInformation [] scopes, MethodDebugInformation debug_info)
public void WriteIteratorScopes (StateMachineScopeDebugInformation state_machine, MethodDebugInformation debug_info)
{
Write (CustomMetadataType.IteratorScopes, () => {
writer.WriteInt32 (scopes.Length);
var scopes = state_machine.Scopes;
writer.WriteInt32 (scopes.Count);
foreach (var scope in scopes) {
var start = scope.Start.Offset;
var end = scope.End.IsEndOfMethod ? debug_info.code_size : scope.End.Offset;

View File

@ -143,7 +143,7 @@ namespace Mono.Cecil.Tests {
Assert.AreEqual (DocumentHashAlgorithm.None, document.HashAlgorithm);
Assert.AreEqual (DocumentLanguage.FSharp, document.Language);
Assert.AreEqual (DocumentLanguageVendor.Microsoft, document.LanguageVendor);
}, readOnly: Platform.OnMono, symbolReaderProvider: typeof(PdbReaderProvider), symbolWriterProvider: typeof(PdbWriterProvider));
}, readOnly: Platform.OnMono, symbolReaderProvider: typeof (PdbReaderProvider), symbolWriterProvider: typeof (PdbWriterProvider));
}
[Test]
@ -157,7 +157,15 @@ namespace Mono.Cecil.Tests {
public void EmptyRootNamespace ()
{
TestModule ("EmptyRootNamespace.dll", module => {
}, readOnly: Platform.OnMono, symbolReaderProvider: typeof(PdbReaderProvider), symbolWriterProvider: typeof(PdbWriterProvider));
}, readOnly: Platform.OnMono, symbolReaderProvider: typeof (PdbReaderProvider), symbolWriterProvider: typeof (PdbWriterProvider));
}
[Test]
public void VisualBasicNamespace ()
{
TestModule ("AVbTest.exe", module => {
}, readOnly: Platform.OnMono, symbolReaderProvider: typeof (PdbReaderProvider), symbolWriterProvider: typeof (PdbWriterProvider));
}
[Test]
@ -346,8 +354,9 @@ namespace Mono.Cecil.Tests {
var state_machine_scope = move_next.DebugInformation.CustomDebugInformations [0] as StateMachineScopeDebugInformation;
Assert.IsNotNull (state_machine_scope);
Assert.AreEqual (142, state_machine_scope.Start.Offset);
Assert.AreEqual (319, state_machine_scope.End.Offset);
Assert.AreEqual (1, state_machine_scope.Scopes.Count);
Assert.AreEqual (142, state_machine_scope.Scopes [0].Start.Offset);
Assert.AreEqual (319, state_machine_scope.Scopes [0].End.Offset);
var async_body = move_next.DebugInformation.CustomDebugInformations [1] as AsyncMethodBodyDebugInformation;
Assert.IsNotNull (async_body);
@ -361,7 +370,8 @@ namespace Mono.Cecil.Tests {
Assert.AreEqual (98, async_body.Resumes [0].Offset);
Assert.AreEqual (227, async_body.Resumes [1].Offset);
Assert.AreEqual (move_next, async_body.MoveNextMethod);
Assert.AreEqual (move_next, async_body.ResumeMethods [0]);
Assert.AreEqual (move_next, async_body.ResumeMethods [1]);
}, readOnly: Platform.OnMono, symbolReaderProvider: typeof (PdbReaderProvider), symbolWriterProvider: typeof (PdbWriterProvider));
}

Binary file not shown.

View File

@ -1 +1 @@
2.0.0-preview2-005905
2.0.0

View File

@ -1 +0,0 @@

View File

@ -6,7 +6,7 @@ param
[Parameter(Mandatory=$false)][string]$SharedFrameworkSymlinkPath = (Join-Path $ToolsLocalPath "dotnetcli\shared\Microsoft.NETCore.App\version"),
[Parameter(Mandatory=$false)][string]$SharedFrameworkVersion = "<auto>",
[Parameter(Mandatory=$false)][string]$Architecture = "<auto>",
[Parameter(Mandatory=$false)][string]$DotNetInstallBranch = "rel/1.0.0",
[Parameter(Mandatory=$false)][string]$DotNetInstallBranch = "release/2.0.0",
[switch]$Force = $false
)

View File

@ -80,7 +80,7 @@ sharedFxVersion="<auto>"
force=
forcedCliLocalPath="<none>"
architecture="<auto>"
dotNetInstallBranch="rel/1.0.0"
dotNetInstallBranch="release/2.0.0"
while [ $# -ne 0 ]
do

5
external/linker/corebuild/global.json vendored Normal file
View File

@ -0,0 +1,5 @@
{
"sdk": {
"version": "2.0.0"
}
}

View File

@ -3,7 +3,6 @@
<PropertyGroup>
<TargetFrameworks>netcoreapp2.0;net46</TargetFrameworks>
<TargetFrameworks Condition=" '$(OS)' != 'Windows_NT' ">netcoreapp2.0</TargetFrameworks>
<RuntimeFrameworkVersion>2.0.0-beta-001509-00</RuntimeFrameworkVersion>
<DefineConstants>$(DefineConstants);FEATURE_ILLINK</DefineConstants>
<EnableDefaultCompileItems>false</EnableDefaultCompileItems>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>

View File

@ -3,7 +3,6 @@
<VersionPrefix>0.1.4-preview</VersionPrefix>
<TargetFrameworks>netcoreapp2.0;net46</TargetFrameworks>
<TargetFrameworks Condition=" '$(OS)' != 'Windows_NT' ">netcoreapp2.0</TargetFrameworks>
<RuntimeFrameworkVersion>2.0.0-beta-001509-00</RuntimeFrameworkVersion>
<EnableDefaultCompileItems>false</EnableDefaultCompileItems>
<BaseOutputPath>../bin/</BaseOutputPath>
<PackageOutputPath>$(BaseOutputPath)nupkgs</PackageOutputPath>

View File

@ -29,10 +29,11 @@ namespace ILLink.Tests
protected int Dotnet(string args, string workingDir, string additionalPath = null)
{
return RunCommand(context.DotnetToolPath, args, workingDir, additionalPath, out string commandOutput);
return RunCommand(Path.GetFullPath(context.DotnetToolPath), args,
workingDir, additionalPath, out string commandOutput);
}
protected int RunCommand(string command, string args, int timeout = 60000)
protected int RunCommand(string command, string args, int timeout = Int32.MaxValue)
{
return RunCommand(command, args, null, null, out string commandOutput, timeout);
}
@ -42,7 +43,7 @@ namespace ILLink.Tests
return RunCommand(command, args, workingDir, null, out string commandOutput);
}
protected int RunCommand(string command, string args, string workingDir, string additionalPath, out string commandOutput, int timeout = 60000)
protected int RunCommand(string command, string args, string workingDir, string additionalPath, out string commandOutput, int timeout = Int32.MaxValue)
{
output.WriteLine($"{command} {args}");
if (workingDir != null)
@ -64,6 +65,14 @@ namespace ILLink.Tests
var process = new Process();
process.StartInfo = psi;
// dotnet sets some environment variables that
// may cause problems in the child process.
psi.Environment.Remove("MSBuildExtensionsPath");
psi.Environment.Remove("MSBuildLoadMicrosoftTargetsReadOnly");
psi.Environment.Remove("MSBuildSDKsPath");
psi.Environment.Remove("VbcToolExe");
psi.Environment.Remove("CscToolExe");
StringBuilder processOutput = new StringBuilder();
DataReceivedEventHandler handler = (sender, e) => {
processOutput.Append(e.Data);
@ -80,6 +89,7 @@ namespace ILLink.Tests
process.BeginOutputReadLine();
process.BeginErrorReadLine();
if (!process.WaitForExit(timeout)) {
output.WriteLine($"killing process after {timeout} ms");
process.Kill();
}
// WaitForExit with timeout doesn't guarantee
@ -101,26 +111,25 @@ namespace ILLink.Tests
/// linker task package.
/// Optionally takes a list of root descriptor files.
/// </summary>
public void BuildAndLink(string csproj, List<string> rootFiles = null)
public void BuildAndLink(string csproj, List<string> rootFiles = null, Dictionary<string, string> extraPublishArgs = null)
{
string rid = context.RuntimeIdentifier;
string config = context.Configuration;
string demoRoot = Path.GetDirectoryName(csproj);
int ret = Dotnet($"restore -r {rid}", demoRoot);
if (ret != 0) {
output.WriteLine("restore failed");
Assert.True(false);
return;
}
string publishArgs = $"publish -r {rid} -c {config} /v:n /p:ShowLinkerSizeComparison=true";
string rootFilesStr;
if (rootFiles != null && rootFiles.Any()) {
rootFilesStr = String.Join(";", rootFiles);
publishArgs += $" /p:LinkerRootDescriptors={rootFilesStr}";
}
ret = Dotnet(publishArgs, demoRoot);
if (extraPublishArgs != null) {
foreach (var item in extraPublishArgs) {
publishArgs += $" /p:{item.Key}={item.Value}";
}
}
int ret = Dotnet(publishArgs, demoRoot);
if (ret != 0) {
output.WriteLine("publish failed, returning " + ret);
Assert.True(false);
@ -128,11 +137,13 @@ namespace ILLink.Tests
}
}
public int RunApp(string csproj, out string processOutput, int timeout = 60000)
public int RunApp(string csproj, out string processOutput, int timeout = Int32.MaxValue)
{
string demoRoot = Path.GetDirectoryName(csproj);
string executablePath = Path.Combine(
demoRoot, "bin", context.Configuration, "netcoreapp2.0",
// detect the target framework for which the app was published
string tfmDir = Path.Combine(demoRoot, "bin", context.Configuration);
string tfm = Directory.GetDirectories(tfmDir).Select(p => Path.GetFileName(p)).Single();
string executablePath = Path.Combine(tfmDir, tfm,
context.RuntimeIdentifier, "publish",
Path.GetFileNameWithoutExtension(csproj)
);
@ -141,17 +152,9 @@ namespace ILLink.Tests
}
Assert.True(File.Exists(executablePath));
// work around bug in prerelease .NET Core,
// where the published host isn't executable
int ret;
if (!context.RuntimeIdentifier.Contains("win")) {
ret = RunCommand("chmod", "+x " + executablePath, 1000);
Assert.True(ret == 0);
}
ret = RunCommand(executablePath, null,
Directory.GetParent(executablePath).FullName,
null, out processOutput, timeout);
int ret = RunCommand(executablePath, null,
Directory.GetParent(executablePath).FullName,
null, out processOutput, timeout);
return ret;
}

View File

@ -14,6 +14,8 @@ namespace ILLink.Tests
private static List<string> rootFiles = new List<string> { "MusicStoreReflection.xml" };
private string netcoreappVersion;
[Fact]
public void RunMusicStore()
{
@ -32,10 +34,70 @@ namespace ILLink.Tests
AddLinkerReference(csproj);
BuildAndLink(csproj, rootFiles);
Dictionary<string, string> extraPublishArgs = new Dictionary<string, string>();
extraPublishArgs.Add("JITBENCH_FRAMEWORK_VERSION", netcoreappVersion);
BuildAndLink(csproj, rootFiles, extraPublishArgs);
}
int ret = RunApp(csproj, out string commandOutput);
Assert.True(ret == 0);
string ObtainSDK(string repoDir)
{
int ret;
string dotnetDirName = ".dotnet";
string dotnetInstall = Path.Combine(repoDir, "dotnet-install");
if (context.RuntimeIdentifier.Contains("win")) {
dotnetInstall += ".ps1";
} else {
dotnetInstall += ".sh";
}
if (!File.Exists(dotnetInstall)) {
output.WriteLine($"missing dotnet-install script at {dotnetInstall}");
Assert.True(false);
}
if (context.RuntimeIdentifier.Contains("win")) {
ret = RunCommand(dotnetInstall, $"-SharedRuntime -InstallDir {dotnetDirName} -Channel master -Architecture x64", repoDir);
if (ret != 0) {
output.WriteLine("failed to retrieve shared runtime");
Assert.True(false);
}
ret = RunCommand(dotnetInstall, $"-InstallDir {dotnetDirName} -Channel master -Architecture x64", repoDir);
if (ret != 0) {
output.WriteLine("failed to retrieve sdk");
Assert.True(false);
}
} else {
ret = RunCommand(dotnetInstall, $"-sharedruntime -runtimeid {context.RuntimeIdentifier} -installdir {dotnetDirName} -channel master -architecture x64", repoDir);
if (ret != 0) {
output.WriteLine("failed to retrieve shared runtime");
Assert.True(false);
}
ret = RunCommand(dotnetInstall, $"-installdir {dotnetDirName} -channel master -architecture x64", repoDir);
if (ret != 0) {
output.WriteLine("failed to retrieve sdk");
Assert.True(false);
}
}
string dotnetDir = Path.Combine(repoDir, dotnetDirName);
string dotnetToolName = Directory.GetFiles(dotnetDir)
.Select(p => Path.GetFileName(p))
.Where(p => p.Contains("dotnet"))
.Single();
string dotnetToolPath = Path.Combine(dotnetDir, dotnetToolName);
if (!File.Exists(dotnetToolPath)) {
output.WriteLine("repo-local dotnet tool does not exist.");
Assert.True(false);
}
string ncaDir = Path.Combine(dotnetDir, "shared", "Microsoft.NETCore.App");
netcoreappVersion = Directory.GetDirectories(ncaDir)
.Select(p => Path.GetFileName(p)).Max();
if (String.IsNullOrEmpty(netcoreappVersion)) {
output.WriteLine($"no netcoreapp version found in {ncaDir}");
Assert.True(false);
}
return dotnetToolPath;
}
// returns path to .csproj project file
@ -44,7 +106,6 @@ namespace ILLink.Tests
string gitRepo = "http://github.com/aspnet/JitBench";
string repoName = "JitBench";
string gitBranch = "dev";
string demoRoot = Path.Combine("JitBench", Path.Combine("src", "MusicStore"));
int ret;
if (Directory.Exists(repoName)) {
@ -57,6 +118,7 @@ namespace ILLink.Tests
Assert.True(false);
}
string demoRoot = Path.Combine("JitBench", Path.Combine("src", "MusicStore"));
if (!Directory.Exists(demoRoot)) {
output.WriteLine($"{demoRoot} does not exist");
Assert.True(false);
@ -68,6 +130,11 @@ namespace ILLink.Tests
Assert.True(false);
}
// MusicStore targets .NET Core 2.1, so it must be built
// using an SDK that can target 2.1. We obtain that SDK
// here.
context.DotnetToolPath = ObtainSDK(repoName);
string csproj = Path.Combine(demoRoot, "MusicStore.csproj");
return csproj;
}

View File

@ -29,7 +29,7 @@ namespace ILLink.Tests
/// The path to the dotnet tool to use to run the
/// integration tests.
/// </summary>
public string DotnetToolPath { get; private set; }
public string DotnetToolPath { get; set; }
/// <summary>
/// The RID to use when restoring, building, and linking the
@ -87,6 +87,12 @@ namespace ILLink.Tests
context.DotnetToolPath = dotnetToolPath;
// This sets the RID to the RID of the currently-executing system.
context.RuntimeIdentifier = RuntimeEnvironment.GetRuntimeIdentifier();
// workaround: the osx.10.13-x64 RID doesn't exist yet.
// see https://github.com/dotnet/core-setup/issues/3301
if (context.RuntimeIdentifier == "osx.10.13-x64")
{
context.RuntimeIdentifier = "osx.10.12-x64";
}
// We want to build and link integration projects in the
// release configuration.
context.Configuration = "Release";

View File

@ -24,10 +24,10 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.0.0" />
<PackageReference Include="xunit" Version="2.2.0" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.2.0" />
<DotNetCliToolReference Include="dotnet-xunit" Version="2.3.0-beta1-build3642" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.3.0-preview-20170628-02" />
<PackageReference Include="xunit" Version="2.3.0" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.3.0" />
<DotNetCliToolReference Include="dotnet-xunit" Version="2.3.0" />
</ItemGroup>
</Project>

View File

@ -96,9 +96,9 @@ namespace Mono.Linker.Steps {
return false;
}
static ResolveFromXmlStep GetExternalResolveStep (EmbeddedResource resource, AssemblyDefinition assembly)
protected virtual IStep GetExternalResolveStep (EmbeddedResource resource, AssemblyDefinition assembly)
{
return new ResolveFromXmlStep (GetExternalDescriptor (resource), "resource " + resource.Name + " in " + assembly.FullName);
return new ResolveFromXmlStep (GetExternalDescriptor (resource), resource.Name, assembly, "resource " + resource.Name + " in " + assembly.FullName);
}
static ResolveFromXmlStep GetResolveStep (string descriptor)
@ -106,7 +106,7 @@ namespace Mono.Linker.Steps {
return new ResolveFromXmlStep (GetDescriptor (descriptor), "descriptor " + descriptor + " from " + Assembly.GetExecutingAssembly ().FullName);
}
static XPathDocument GetExternalDescriptor (EmbeddedResource resource)
protected static XPathDocument GetExternalDescriptor (EmbeddedResource resource)
{
using (var sr = new StreamReader (resource.GetResourceStream ())) {
return new XPathDocument (new StringReader (sr.ReadToEnd ()));

View File

@ -647,8 +647,7 @@ namespace Mono.Linker.Steps {
if (type.HasInterfaces) {
foreach (var iface in type.Interfaces) {
MarkCustomAttributes (iface);
MarkType (iface.InterfaceType);
MarkInterfaceImplementation (type, iface);
}
}
@ -1444,7 +1443,14 @@ namespace Mono.Linker.Steps {
return true;
case MethodAction.Parse:
AssemblyDefinition assembly = ResolveAssembly (method.DeclaringType.Scope);
return Annotations.GetAction (assembly) == AssemblyAction.Link;
switch (Annotations.GetAction (assembly)) {
case AssemblyAction.Link:
case AssemblyAction.Copy:
case AssemblyAction.CopyUsed:
return true;
default:
return false;
}
default:
return false;
}
@ -1550,12 +1556,22 @@ namespace Mono.Linker.Steps {
protected virtual void HandleUnresolvedType (TypeReference reference)
{
throw new ResolutionException (reference);
if (!_context.IgnoreUnresolved) {
throw new ResolutionException (reference);
}
}
protected virtual void HandleUnresolvedMethod (MethodReference reference)
{
throw new ResolutionException (reference);
if (!_context.IgnoreUnresolved) {
throw new ResolutionException (reference);
}
}
protected virtual void MarkInterfaceImplementation (TypeDefinition type, InterfaceImplementation iface)
{
MarkCustomAttributes (iface);
MarkType (iface.InterfaceType);
}
}
}

View File

@ -59,6 +59,8 @@ namespace Mono.Linker.Steps {
XPathDocument _document;
string _xmlDocumentLocation;
string _resourceName;
AssemblyDefinition _resourceAssembly;
public ResolveFromXmlStep (XPathDocument document, string xmlDocumentLocation = "<unspecified>")
{
@ -66,18 +68,33 @@ namespace Mono.Linker.Steps {
_xmlDocumentLocation = xmlDocumentLocation;
}
public ResolveFromXmlStep (XPathDocument document, string resourceName, AssemblyDefinition resourceAssembly, string xmlDocumentLocation = "<unspecified>")
: this (document, xmlDocumentLocation)
{
if (string.IsNullOrEmpty (resourceName))
throw new ArgumentNullException (nameof (resourceName));
if (resourceAssembly == null)
throw new ArgumentNullException (nameof (resourceAssembly));
_resourceName = resourceName;
_resourceAssembly = resourceAssembly;
}
protected override void Process ()
{
XPathNavigator nav = _document.CreateNavigator ();
nav.MoveToFirstChild ();
// This step can be created with XML files that aren't necessarily
// linker descriptor files. So bail if we don't have a <linker> element.
if (nav.LocalName != "linker")
if (!nav.MoveToChild("linker", _ns))
return;
try {
ProcessAssemblies (Context, nav.SelectChildren ("assembly", _ns));
if (!string.IsNullOrEmpty (_resourceName))
Context.Annotations.AddResourceToRemove (_resourceAssembly, _resourceName);
} catch (Exception ex) {
throw new XmlResolutionException (string.Format ("Failed to process XML description: {0}", _xmlDocumentLocation), ex);
}

View File

@ -75,11 +75,23 @@ namespace Mono.Linker.Steps {
void SweepAssembly (AssemblyDefinition assembly)
{
if (Annotations.GetAction (assembly) != AssemblyAction.Link)
switch (Annotations.GetAction (assembly)) {
case AssemblyAction.Link:
if (!IsMarkedAssembly (assembly)) {
RemoveAssembly (assembly);
return;
}
break;
case AssemblyAction.CopyUsed:
if (!IsMarkedAssembly (assembly)) {
RemoveAssembly (assembly);
} else {
Annotations.SetAction (assembly, AssemblyAction.Copy);
}
return;
if (!IsMarkedAssembly (assembly)) {
RemoveAssembly (assembly);
default:
return;
}
@ -101,6 +113,8 @@ namespace Mono.Linker.Steps {
assembly.MainModule.Types.Clear ();
foreach (TypeDefinition type in types)
assembly.MainModule.Types.Add (type);
SweepResources (assembly);
}
bool IsMarkedAssembly (AssemblyDefinition assembly)
@ -115,6 +129,23 @@ namespace Mono.Linker.Steps {
SweepReferences (assembly);
}
void SweepResources (AssemblyDefinition assembly)
{
var resourcesToRemove = Annotations.GetResourcesToRemove (assembly);
if (resourcesToRemove != null) {
var resources = assembly.MainModule.Resources;
for (int i = 0; i < resources.Count; i++) {
var resource = resources [i] as EmbeddedResource;
if (resource == null)
continue;
if (resourcesToRemove.Contains (resource.Name))
resources.RemoveAt (i--);
}
}
}
void SweepReferences (AssemblyDefinition target)
{
foreach (var assembly in assemblies)
@ -147,8 +178,8 @@ namespace Mono.Linker.Steps {
case AssemblyAction.Copy:
// Copy means even if "unlinked" we still want that assembly to be saved back
// to disk (OutputStep) without the (removed) reference
Annotations.SetAction (assembly, AssemblyAction.Save);
if (!Context.KeepTypeForwarderOnlyAssemblies) {
Annotations.SetAction (assembly, AssemblyAction.Save);
ResolveAllTypeReferences (assembly);
}
break;
@ -224,6 +255,9 @@ namespace Mono.Linker.Steps {
if (type.HasNestedTypes)
SweepNestedTypes (type);
if (type.HasInterfaces)
SweepInterfaces (type);
}
protected void SweepNestedTypes (TypeDefinition type)
@ -239,6 +273,17 @@ namespace Mono.Linker.Steps {
}
}
protected void SweepInterfaces (TypeDefinition type)
{
for (int i = type.Interfaces.Count - 1; i >= 0; i--) {
var iface = type.Interfaces [i];
if (Annotations.IsMarked (iface.InterfaceType.Resolve ()))
continue;
InterfaceRemoved (type, iface);
type.Interfaces.RemoveAt (i);
}
}
void SweepMethods (Collection<MethodDefinition> methods)
{
SweepCollection (methods);
@ -321,5 +366,9 @@ namespace Mono.Linker.Steps {
protected virtual void ReferenceRemoved (AssemblyDefinition assembly, AssemblyNameReference reference)
{
}
protected virtual void InterfaceRemoved (TypeDefinition type, InterfaceImplementation iface)
{
}
}
}

View File

@ -50,6 +50,7 @@ namespace Mono.Linker {
readonly Dictionary<AssemblyDefinition, ISymbolReader> symbol_readers = new Dictionary<AssemblyDefinition, ISymbolReader> ();
readonly Dictionary<object, Dictionary<IMetadataTokenProvider, object>> custom_annotations = new Dictionary<object, Dictionary<IMetadataTokenProvider, object>> ();
readonly Dictionary<AssemblyDefinition, HashSet<string>> resources_to_remove = new Dictionary<AssemblyDefinition, HashSet<string>> ();
Stack<object> dependency_stack;
System.Xml.XmlWriter writer;
@ -180,6 +181,25 @@ namespace Mono.Linker {
throw new NotSupportedException ();
}
public HashSet<string> GetResourcesToRemove (AssemblyDefinition assembly)
{
HashSet<string> resources;
if (resources_to_remove.TryGetValue (assembly, out resources))
return resources;
return null;
}
public void AddResourceToRemove (AssemblyDefinition assembly, string name)
{
HashSet<string> resources;
if (!resources_to_remove.TryGetValue (assembly, out resources)) {
resources = resources_to_remove [assembly] = new HashSet<string> ();
}
resources.Add (name);
}
public void SetPublic (IMetadataTokenProvider provider)
{
public_api.Add (provider);

View File

@ -32,8 +32,12 @@ namespace Mono.Linker {
// Ignore the assembly
Skip,
// Copy the existing files, assembly and symbols, into the output destination. E.g. .dll and .mdb
// The linker still analyze the assemblies (to know what they require) but does not modify them
// The linker still analyzes the assemblies (to know what they require) but does not modify them.
Copy,
// Copy the existing files, assembly and symbols, into the output destination if and only if
// anything from the assembly is used.
// The linker still analyzes the assemblies (to know what they require) but does not modify them.
CopyUsed,
// Link the assembly
Link,
// Remove the assembly from the output

View File

@ -95,6 +95,11 @@ namespace Mono.Linker {
if (token.Length < 3)
Usage ("Option is too short");
if (token == "--skip-unresolved") {
context.IgnoreUnresolved = bool.Parse (GetParam ());
continue;
}
switch (token [2]) {
case 'v':
Version ();
@ -120,6 +125,9 @@ namespace Mono.Linker {
case 'c':
context.CoreAction = ParseAssemblyAction (GetParam ());
break;
case 'u':
context.UserAction = ParseAssemblyAction (GetParam ());
break;
case 'p':
AssemblyAction action = ParseAssemblyAction (GetParam ());
context.Actions [GetParam ()] = action;
@ -275,6 +283,7 @@ namespace Mono.Linker {
{
LinkContext context = new LinkContext (pipeline);
context.CoreAction = AssemblyAction.Skip;
context.UserAction = AssemblyAction.Link;
context.OutputDirectory = "output";
return context;
}
@ -290,25 +299,27 @@ namespace Mono.Linker {
Console.WriteLine ("monolinker [options] -x|-a|-i file");
#endif
Console.WriteLine (" --about About the {0}", _linker);
Console.WriteLine (" --version Print the version number of the {0}", _linker);
Console.WriteLine (" -out Specify the output directory, default to `output'");
Console.WriteLine (" -c Action on the core assemblies, skip, copy or link, default to skip");
Console.WriteLine (" -p Action per assembly");
Console.WriteLine (" -s Add a new step to the pipeline.");
Console.WriteLine (" -t Keep assemblies in which only type forwarders are referenced.");
Console.WriteLine (" -d Add a directory where the linker will look for assemblies");
Console.WriteLine (" -b Generate debug symbols for each linked module (true or false)");
Console.WriteLine (" -g Generate a new unique guid for each linked module (true or false)");
Console.WriteLine (" -v Keep memebers needed by debugger attributes (true or false)");
Console.WriteLine (" -l List of i18n assemblies to copy to the output directory");
Console.WriteLine (" separated with a comma: none,all,cjk,mideast,other,rare,west");
Console.WriteLine (" default is all");
Console.WriteLine (" -x Link from an XML descriptor");
Console.WriteLine (" -a Link from a list of assemblies");
Console.WriteLine (" -r Link from a list of assemblies using roots visible outside of the assembly");
Console.WriteLine (" -i Link from an mono-api-info descriptor");
Console.WriteLine (" -z Include default preservations (true or false), default to true");
Console.WriteLine (" --about About the {0}", _linker);
Console.WriteLine (" --version Print the version number of the {0}", _linker);
Console.WriteLine (" --skip-unresolved Ignore unresolved types and methods (true or false)");
Console.WriteLine (" -out Specify the output directory, default to `output'");
Console.WriteLine (" -c Action on the core assemblies, skip, copy, copyused or link, default to skip");
Console.WriteLine (" -u Action on the user assemblies, skip, copy, copyused or link, default to link");
Console.WriteLine (" -p Action per assembly");
Console.WriteLine (" -s Add a new step to the pipeline.");
Console.WriteLine (" -t Keep assemblies in which only type forwarders are referenced.");
Console.WriteLine (" -d Add a directory where the linker will look for assemblies");
Console.WriteLine (" -b Generate debug symbols for each linked module (true or false)");
Console.WriteLine (" -g Generate a new unique guid for each linked module (true or false)");
Console.WriteLine (" -v Keep memebers needed by debugger attributes (true or false)");
Console.WriteLine (" -l List of i18n assemblies to copy to the output directory");
Console.WriteLine (" separated with a comma: none,all,cjk,mideast,other,rare,west");
Console.WriteLine (" default is all");
Console.WriteLine (" -x Link from an XML descriptor");
Console.WriteLine (" -a Link from a list of assemblies");
Console.WriteLine (" -r Link from a list of assemblies using roots visible outside of the assembly");
Console.WriteLine (" -i Link from an mono-api-info descriptor");
Console.WriteLine (" -z Include default preservations (true or false), default to true");
Console.WriteLine ("");
Environment.Exit (1);

View File

@ -38,12 +38,14 @@ namespace Mono.Linker {
Pipeline _pipeline;
AssemblyAction _coreAction;
AssemblyAction _userAction;
Dictionary<string, AssemblyAction> _actions;
string _outputDirectory;
readonly Dictionary<string, string> _parameters;
bool _linkSymbols;
bool _keepTypeForwarderOnlyAssemblies;
bool _keepMembersForDebuggerAttributes;
bool _ignoreUnresolved;
AssemblyResolver _resolver;
@ -71,6 +73,11 @@ namespace Mono.Linker {
set { _coreAction = value; }
}
public AssemblyAction UserAction {
get { return _userAction; }
set { _userAction = value; }
}
public bool LinkSymbols {
get { return _linkSymbols; }
set { _linkSymbols = value; }
@ -88,6 +95,12 @@ namespace Mono.Linker {
set { _keepMembersForDebuggerAttributes = value; }
}
public bool IgnoreUnresolved
{
get { return _ignoreUnresolved; }
set { _ignoreUnresolved = value; }
}
public System.Collections.IDictionary Actions {
get { return _actions; }
}
@ -247,7 +260,7 @@ namespace Mono.Linker {
} else if (IsCore (name)) {
action = _coreAction;
} else {
action = AssemblyAction.Link;
action = _userAction;
}
_annotations.SetAction (assembly, action);

View File

@ -0,0 +1,15 @@
using System;
namespace Mono.Linker.Tests.Cases.Expectations.Assertions {
/// <summary>
/// Verifies that a resource exists in the test case assembly
/// </summary>
[AttributeUsage (AttributeTargets.Class, AllowMultiple = true, Inherited = false)]
public class KeptResourceAttribute : KeptAttribute {
public KeptResourceAttribute (string name)
{
if (string.IsNullOrEmpty (name))
throw new ArgumentException ("Value cannot be null or empty.", nameof (name));
}
}
}

View File

@ -0,0 +1,18 @@
using System;
namespace Mono.Linker.Tests.Cases.Expectations.Assertions {
/// <summary>
/// Verifies that an embedded resource exists in an assembly
/// </summary>
[AttributeUsage (AttributeTargets.Class, AllowMultiple = true, Inherited = false)]
public class KeptResourceInAssemblyAttribute : BaseInAssemblyAttribute {
public KeptResourceInAssemblyAttribute (string assemblyFileName, string resourceName)
{
if (string.IsNullOrEmpty (assemblyFileName))
throw new ArgumentNullException (nameof (assemblyFileName));
if (string.IsNullOrEmpty (resourceName))
throw new ArgumentNullException (nameof (resourceName));
}
}
}

View File

@ -0,0 +1,18 @@
using System;
namespace Mono.Linker.Tests.Cases.Expectations.Assertions {
/// <summary>
/// Verifies that an embedded resource was removed from an assembly
/// </summary>
[AttributeUsage (AttributeTargets.Class, AllowMultiple = true, Inherited = false)]
public class RemovedResourceInAssemblyAttribute : BaseInAssemblyAttribute {
public RemovedResourceInAssemblyAttribute (string assemblyFileName, string resourceName)
{
if (string.IsNullOrEmpty (assemblyFileName))
throw new ArgumentNullException (nameof (assemblyFileName));
if (string.IsNullOrEmpty (resourceName))
throw new ArgumentNullException (nameof (resourceName));
}
}
}

View File

@ -1,10 +1,10 @@
using System;
namespace Mono.Linker.Tests.Cases.Expectations.Metadata {
[AttributeUsage (AttributeTargets.Class)]
[AttributeUsage (AttributeTargets.Class, AllowMultiple = true)]
public class SandboxDependencyAttribute : BaseMetadataAttribute {
public SandboxDependencyAttribute (string relativePathToFile)
public SandboxDependencyAttribute (string relativePathToFile, string destinationFileName = null)
{
if (string.IsNullOrEmpty (relativePathToFile))
throw new ArgumentException ("Value cannot be null or empty.", nameof (relativePathToFile));

View File

@ -0,0 +1,12 @@
using System;
namespace Mono.Linker.Tests.Cases.Expectations.Metadata {
[AttributeUsage (AttributeTargets.Class, AllowMultiple = false)]
public class SetupCompileAssemblyNameAttribute : BaseMetadataAttribute {
public SetupCompileAssemblyNameAttribute (string outputName)
{
if (string.IsNullOrEmpty (outputName))
throw new ArgumentNullException (nameof (outputName));
}
}
}

View File

@ -0,0 +1,12 @@
using System;
namespace Mono.Linker.Tests.Cases.Expectations.Metadata {
[AttributeUsage (AttributeTargets.Class, AllowMultiple = true)]
public class SetupCompileResourceAttribute : BaseMetadataAttribute {
public SetupCompileResourceAttribute (string relativePathToFile, string destinationFileName = null)
{
if (string.IsNullOrEmpty (relativePathToFile))
throw new ArgumentException ("Value cannot be null or empty.", nameof (relativePathToFile));
}
}
}

View File

@ -45,13 +45,17 @@
<Compile Include="Assertions\KeptBackingFieldAttribute.cs" />
<Compile Include="Assertions\KeptMemberAttribute.cs" />
<Compile Include="Assertions\KeptMemberInAssemblyAttribute.cs" />
<Compile Include="Assertions\KeptResourceAttribute.cs" />
<Compile Include="Assertions\KeptResourceInAssemblyAttribute.cs" />
<Compile Include="Assertions\KeptTypeInAssemblyAttribute.cs" />
<Compile Include="Assertions\RemovedAssemblyAttribute.cs" />
<Compile Include="Assertions\RemovedMemberInAssemblyAttribute.cs" />
<Compile Include="Assertions\RemovedResourceInAssemblyAttribute.cs" />
<Compile Include="Assertions\RemovedTypeInAssemblyAttribute.cs" />
<Compile Include="Assertions\SkipPeVerifyAttribute.cs" />
<Compile Include="Metadata\BaseMetadataAttribute.cs" />
<Compile Include="Metadata\SetupCompileAfterAttribute.cs" />
<Compile Include="Metadata\SetupCompileAssemblyNameAttribute.cs" />
<Compile Include="Metadata\SetupCompileBeforeAttribute.cs" />
<Compile Include="Metadata\DefineAttribute.cs" />
<Compile Include="Metadata\IncludeBlacklistStepAttribute.cs" />
@ -66,6 +70,7 @@
<Compile Include="Assertions\RemovedForwarderAttribute.cs" />
<Compile Include="Metadata\SetupLinkerActionAttribute.cs" />
<Compile Include="Metadata\SetupLinkerCoreActionAttribute.cs" />
<Compile Include="Metadata\SetupCompileResourceAttribute.cs" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.

View File

@ -0,0 +1,24 @@
using Mono.Linker.Tests.Cases.Expectations.Assertions;
namespace Mono.Linker.Tests.Cases.Basic
{
class UsedInterfaceIsKept
{
public static void Main ()
{
A a = new A ();
}
[Kept]
[KeptInterface (typeof (I))]
[KeptMember (".ctor()")]
class A : I
{
}
[Kept]
interface I
{
}
}
}

View File

@ -0,0 +1,15 @@
using Mono.Linker.Tests.Cases.Expectations.Assertions;
namespace Mono.Linker.Tests.Cases.LinkXml {
class UnusedTypePreservedByLinkXmlWithCommentIsKept {
public static void Main ()
{
}
}
[Kept]
[KeptMember (".ctor()")]
class UnusedTypePreservedByLinkXmlWithCommentIsKeptUnusedType
{
}
}

View File

@ -0,0 +1,6 @@
<!-- this is a comment -->
<linker>
<assembly fullname="test, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null">
<type fullname="Mono.Linker.Tests.Cases.LinkXml.UnusedTypePreservedByLinkXmlWithCommentIsKeptUnusedType" />
</assembly>
</linker>

View File

@ -59,10 +59,17 @@
<Compile Include="Basic\UsedStructIsKept.cs" />
<Compile Include="LinkXml\UnusedAssemblyWithNoDefinedPreserveHasAllTypesPreserved.cs" />
<Compile Include="LinkXml\UnusedEventPreservedByLinkXmlIsKept.cs" />
<Compile Include="LinkXml\UnusedTypePreservedByLinkXmlWithCommentIsKept.cs" />
<Compile Include="LinkXml\UnusedTypeWithNoDefinedPreserveHasAllMembersPreserved.cs" />
<Compile Include="Resources\EmbeddedLinkXmlFileIsNotProcessedIfNameDoesNotMatchAnAssembly.cs" />
<Compile Include="Resources\EmbeddedLinkXmlFileIsNotProcessedWhenBlacklistStepIsDisabled.cs" />
<Compile Include="Resources\EmbeddedLinkXmlFileIsNotProcessedWhenCoreLinkActionIsSkip.cs" />
<Compile Include="Resources\EmbeddedLinkXmlFileIsProcessed.cs" />
<Compile Include="Resources\NonLinkerEmbeddedResourceHasNoImpact.cs" />
<Compile Include="TestFramework\CanCompileILAssembly.cs" />
<Compile Include="TestFramework\VerifyDefineAttributeBehavior.cs" />
<None Include="TypeForwarding\Dependencies\ForwarderLibrary.cs" />
<Compile Include="TestFramework\VerifyResourceInAssemblyAttributesBehavior.cs" />
<Compile Include="TypeForwarding\Dependencies\ImplementationLibrary.cs" />
<Compile Include="TypeForwarding\Dependencies\LibraryUsingForwarder.cs" />
<Compile Include="TypeForwarding\Dependencies\ReferenceImplementationLibrary.cs" />
@ -140,6 +147,7 @@
<Compile Include="VirtualMethods\VirtualMethodGetsStrippedIfImplementingMethodGetsInvokedDirectly.cs" />
<Compile Include="TypeForwarding\MissingTargetReference.cs" />
<None Include="TypeForwarding\Dependencies\TypeForwarderMissingReference.il" />
<Compile Include="Basic\UsedInterfaceIsKept.cs" />
</ItemGroup>
<ItemGroup>
<Content Include="LinkXml\TypeWithPreserveFieldsHasBackingFieldsOfPropertiesRemoved.xml" />
@ -151,12 +159,19 @@
<Content Include="LinkXml\UnusedPropertyPreservedByLinkXmlIsKept.xml" />
<Content Include="LinkXml\UnusedTypeIsPresservedWhenEntireAssemblyIsPreserved.xml" />
<Content Include="LinkXml\UnusedTypePreservedByLinkXmlIsKept.xml" />
<Content Include="LinkXml\UnusedTypePreservedByLinkXmlWithCommentIsKept.xml" />
<Content Include="LinkXml\UnusedTypeWithNoDefinedPreserveHasAllMembersPreserved.xml" />
<Content Include="LinkXml\UnusedTypeWithPreserveAllHasAllMembersPreserved.xml" />
<Content Include="LinkXml\UnusedTypeWithPreserveFieldsHasMethodsRemoved.xml" />
<Content Include="LinkXml\UnusedTypeWithPreserveMethodsHasFieldsRemoved.xml" />
<Content Include="LinkXml\UnusedTypeWithPreserveNothingAndPreserveMembers.xml" />
<Content Include="LinkXml\UnusedTypeWithPreserveNothingHasMembersRemoved.xml" />
<Content Include="Resources\Dependencies\EmbeddedLinkXmlFileIsNotProcessedIfNameDoesNotMatchAnAssembly.xml" />
<Content Include="Resources\Dependencies\EmbeddedLinkXmlFileIsNotProcessedWhenBlacklistStepIsDisabled.xml" />
<Content Include="Resources\Dependencies\EmbeddedLinkXmlFileIsNotProcessedWhenCoreLinkActionIsSkip.xml" />
<Content Include="Resources\Dependencies\EmbeddedLinkXmlFileIsProcessed.xml" />
<Content Include="Resources\Dependencies\NonLinkerEmbeddedResourceHasNoImpact.xml" />
<Content Include="TestFramework\Dependencies\VerifyResourceInAssemblyAttributesBehavior.txt" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Mono.Linker.Tests.Cases.Expectations\Mono.Linker.Tests.Cases.Expectations.csproj">

View File

@ -0,0 +1,5 @@
<linker>
<assembly fullname="test, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null">
<type fullname="Mono.Linker.Tests.Cases.Resources.EmbeddedLinkXmlFileIsNotProcessedIfNameDoesNotMatchAnAssembly/Unused" />
</assembly>
</linker>

View File

@ -0,0 +1,5 @@
<linker>
<assembly fullname="test, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null">
<type fullname="Mono.Linker.Tests.Cases.Resources.EmbeddedLinkXmlFileIsNotProcessedWhenBlacklistStepIsDisabled/Unused" />
</assembly>
</linker>

View File

@ -0,0 +1,5 @@
<linker>
<assembly fullname="test, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null">
<type fullname="Mono.Linker.Tests.Cases.Resources.EmbeddedLinkXmlFileIsNotProcessedWhenCoreLinkActionIsSkip/Unused" />
</assembly>
</linker>

View File

@ -0,0 +1,5 @@
<linker>
<assembly fullname="test, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null">
<type fullname="Mono.Linker.Tests.Cases.Resources.EmbeddedLinkXmlFileIsProcessed/Unused" />
</assembly>
</linker>

View File

@ -0,0 +1,2 @@
<someotherxmlformat>
</someotherxmlformat>

View File

@ -0,0 +1,19 @@
using System;
using Mono.Linker.Tests.Cases.Expectations.Assertions;
using Mono.Linker.Tests.Cases.Expectations.Metadata;
namespace Mono.Linker.Tests.Cases.Resources {
[SetupLinkerCoreAction ("link")]
[IncludeBlacklistStep (true)]
[SetupCompileResource ("Dependencies/EmbeddedLinkXmlFileIsNotProcessedIfNameDoesNotMatchAnAssembly.xml", "NotMatchingAnAssemblyName.xml")]
[SkipPeVerify]
[KeptResource ("NotMatchingAnAssemblyName.xml")]
public class EmbeddedLinkXmlFileIsNotProcessedIfNameDoesNotMatchAnAssembly {
public static void Main ()
{
}
public class Unused {
}
}
}

View File

@ -0,0 +1,21 @@
using System;
using Mono.Linker.Tests.Cases.Expectations.Assertions;
using Mono.Linker.Tests.Cases.Expectations.Metadata;
namespace Mono.Linker.Tests.Cases.Resources {
[SetupLinkerCoreAction ("link")]
[IncludeBlacklistStep (false)]
// We need to rename the resource so that it matches the name of an assembly being processed. This is a requriement of the black list step
[SetupCompileResource ("Dependencies/EmbeddedLinkXmlFileIsNotProcessedWhenBlacklistStepIsDisabled.xml", "test.xml")]
[SkipPeVerify]
[KeptResource ("test.xml")]
public class EmbeddedLinkXmlFileIsNotProcessedWhenBlacklistStepIsDisabled {
public static void Main ()
{
}
public class Unused {
}
}
}

View File

@ -0,0 +1,23 @@
using System;
using Mono.Linker.Tests.Cases.Expectations.Assertions;
using Mono.Linker.Tests.Cases.Expectations.Metadata;
namespace Mono.Linker.Tests.Cases.Resources {
// I'm not sure why it was decided all link xml resources should be skipped when core link is set to skip, but that's the behavior
// that exists today and I don't have a reason to change it right now
[SetupLinkerCoreAction ("skip")]
[IncludeBlacklistStep (true)]
// We need to rename the resource so that it matches the name of an assembly being processed. This is a requriement of the black list step
[SetupCompileResource ("Dependencies/EmbeddedLinkXmlFileIsNotProcessedWhenCoreLinkActionIsSkip.xml", "test.xml")]
[SkipPeVerify]
[KeptResource ("test.xml")]
public class EmbeddedLinkXmlFileIsNotProcessedWhenCoreLinkActionIsSkip {
public static void Main ()
{
}
public class Unused {
}
}
}

View File

@ -0,0 +1,22 @@
using System;
using Mono.Linker.Tests.Cases.Expectations.Assertions;
using Mono.Linker.Tests.Cases.Expectations.Metadata;
namespace Mono.Linker.Tests.Cases.Resources {
[SetupLinkerCoreAction ("link")]
[IncludeBlacklistStep (true)]
// We need to rename the resource so that it matches the name of an assembly being processed. This is a requriement of the black list step
[SetupCompileResource ("Dependencies/EmbeddedLinkXmlFileIsProcessed.xml", "test.xml")]
[SkipPeVerify]
public class EmbeddedLinkXmlFileIsProcessed {
public static void Main ()
{
}
[Kept]
[KeptMember (".ctor()")]
public class Unused {
}
}
}

View File

@ -0,0 +1,18 @@
using System;
using Mono.Linker.Tests.Cases.Expectations.Assertions;
using Mono.Linker.Tests.Cases.Expectations.Metadata;
namespace Mono.Linker.Tests.Cases.Resources {
[SetupLinkerCoreAction ("link")]
[IncludeBlacklistStep (true)]
// We need to rename the resource so that it matches the name of an assembly being processed. This is a requriement of the black list step
[SetupCompileResource ("Dependencies/NonLinkerEmbeddedResourceHasNoImpact.xml", "test.xml")]
[SkipPeVerify]
[KeptResource ("test.xml")]
public class NonLinkerEmbeddedResourceHasNoImpact {
public static void Main ()
{
}
}
}

View File

@ -0,0 +1,18 @@
using System;
using Mono.Linker.Tests.Cases.Expectations.Assertions;
using Mono.Linker.Tests.Cases.Expectations.Metadata;
namespace Mono.Linker.Tests.Cases.TestFramework {
[SetupCompileResource ("Dependencies/VerifyResourceInAssemblyAttributesBehavior.txt")]
[KeptResource ("VerifyResourceInAssemblyAttributesBehavior.txt")]
// These are technically redundant, but the goal of this test is to verify the attributes are working which we can do
// by using them on the test case assembly even though you would normally use these attributes for other checking other
// supporting assemblies
[KeptResourceInAssembly ("test.exe", "VerifyResourceInAssemblyAttributesBehavior.txt")]
[RemovedResourceInAssembly ("test.exe", "NeverExistedResource.txt")]
public class VerifyResourceInAssemblyAttributesBehavior {
public static void Main ()
{
}
}
}

View File

@ -74,6 +74,7 @@
<ItemGroup>
<Compile Include="TestCasesRunner\CompilerOptions.cs" />
<Compile Include="TestCasesRunner\ILCompiler.cs" />
<Compile Include="TestCasesRunner\SourceAndDestinationPair.cs" />
<Compile Include="TestCasesRunner\SetupCompileInfo.cs" />
<Compile Include="TestCasesRunner\PeVerifier.cs" />
<Compile Include="TestCases\TestSuites.cs" />

View File

@ -54,6 +54,11 @@ namespace Mono.Linker.Tests.TestCases
return NUnitCasesByPrefix("References.");
}
public static IEnumerable<TestCaseData> ResourcesTests ()
{
return NUnitCasesByPrefix ("Resources.");
}
public static IEnumerable<TestCaseData> TypeForwardingTests ()
{
return NUnitCasesByPrefix ("TypeForwarding.");
@ -77,6 +82,7 @@ namespace Mono.Linker.Tests.TestCases
.Concat(StaticsTests())
.Concat(InteropTests())
.Concat(ReferencesTests ())
.Concat(ResourcesTests ())
.Concat(TypeForwardingTests ())
.Concat(TestFrameworkTests ())
.Select(c => ((TestCase)c.Arguments[0]).ReconstructedFullTypeName));

View File

@ -60,6 +60,12 @@ namespace Mono.Linker.Tests.TestCases
Run(testCase);
}
[TestCaseSource (typeof (TestDatabase), nameof (TestDatabase.ResourcesTests))]
public void ResourcesTests (TestCase testCase)
{
Run (testCase);
}
[TestCaseSource (typeof (TestDatabase), nameof (TestDatabase.TypeForwardingTests))]
public void TypeForwardingTests (TestCase testCase)
{

View File

@ -28,6 +28,8 @@ namespace Mono.Linker.Tests.TestCasesRunner {
VerifyCustomAttributes (linkedAssembly, originalAssembly);
VerifyResources (originalAssembly, linkedAssembly);
linkedMembers = new HashSet<string> (linkedAssembly.MainModule.AllMembers ().Select (s => {
return s.FullName;
}), StringComparer.Ordinal);
@ -298,6 +300,14 @@ namespace Mono.Linker.Tests.TestCasesRunner {
linkedMembers.Remove (srcField.FullName);
}
void VerifyResources (AssemblyDefinition original, AssemblyDefinition linked)
{
var expectedResources = original.MainModule.AllDefinedTypes ()
.SelectMany (t => GetCustomAttributeCtorValues<string> (t, nameof (KeptResourceAttribute)));
Assert.That (linked.MainModule.Resources.Select (r => r.Name), Is.EquivalentTo (expectedResources));
}
static void VerifyCustomAttributes (ICustomAttributeProvider src, ICustomAttributeProvider linked)
{
var expectedAttrs = new List<string> (GetCustomAttributeCtorValues<string> (src, nameof (KeptAttributeAttribute)));

View File

@ -7,5 +7,6 @@ namespace Mono.Linker.Tests.TestCasesRunner {
public NPath[] SourceFiles;
public string[] Defines;
public NPath[] References;
public NPath[] Resources;
}
}

View File

@ -132,6 +132,12 @@ namespace Mono.Linker.Tests.TestCasesRunner {
if (linkedAssembly.MainModule.ExportedTypes.Any (l => l.Name == expectedTypeName))
Assert.Fail ($"Forwarder `{expectedTypeName}' should have been removed");
break;
case nameof (KeptResourceInAssemblyAttribute):
VerifyKeptResourceInAssembly (checkAttrInAssembly);
break;
case nameof (RemovedResourceInAssemblyAttribute):
VerifyRemovedResourceInAssembly (checkAttrInAssembly);
break;
default:
UnhandledOtherAssemblyAssertion (expectedTypeName, checkAttrInAssembly, linkedType);
@ -220,6 +226,22 @@ namespace Mono.Linker.Tests.TestCasesRunner {
}
}
void VerifyKeptResourceInAssembly (CustomAttribute inAssemblyAttribute)
{
var assembly = ResolveLinkedAssembly (inAssemblyAttribute.ConstructorArguments [0].Value.ToString ());
var resourceName = inAssemblyAttribute.ConstructorArguments [1].Value.ToString ();
Assert.That (assembly.MainModule.Resources.Select (r => r.Name), Has.Member (resourceName));
}
void VerifyRemovedResourceInAssembly (CustomAttribute inAssemblyAttribute)
{
var assembly = ResolveLinkedAssembly (inAssemblyAttribute.ConstructorArguments [0].Value.ToString ());
var resourceName = inAssemblyAttribute.ConstructorArguments [1].Value.ToString ();
Assert.That (assembly.MainModule.Resources.Select (r => r.Name), Has.No.Member (resourceName));
}
protected TypeDefinition GetOriginalTypeFromInAssemblyAttribute (CustomAttribute inAssemblyAttribute)
{
var attributeValueAsTypeReference = inAssemblyAttribute.ConstructorArguments [1].Value as TypeReference;

View File

@ -0,0 +1,9 @@
using System;
using Mono.Linker.Tests.Extensions;
namespace Mono.Linker.Tests.TestCasesRunner {
public class SourceAndDestinationPair {
public NPath Source;
public string DestinationFileName;
}
}

View File

@ -24,7 +24,7 @@ namespace Mono.Linker.Tests.TestCasesRunner {
_metadataProvider = metadataProvider;
}
public NPath CompileTestIn (NPath outputDirectory, string outputName, IEnumerable<string> sourceFiles, IEnumerable<string> references, IEnumerable<string> defines)
public NPath CompileTestIn (NPath outputDirectory, string outputName, IEnumerable<string> sourceFiles, IEnumerable<string> references, IEnumerable<string> defines, NPath[] resources)
{
var originalReferences = references.Select (r => r.ToNPath ()).ToArray ();
var originalDefines = defines?.ToArray () ?? new string [0];
@ -38,7 +38,8 @@ namespace Mono.Linker.Tests.TestCasesRunner {
outputDirectory.Combine (outputName),
sourceFiles.Select (s => s.ToNPath ()).ToArray (),
allTestCaseReferences,
originalDefines);
originalDefines,
resources);
var testAssembly = CompileAssembly (options);
@ -55,14 +56,15 @@ namespace Mono.Linker.Tests.TestCasesRunner {
{
}
protected virtual CompilerOptions CreateOptionsForTestCase (NPath outputPath, NPath[] sourceFiles, NPath[] references, string[] defines)
protected virtual CompilerOptions CreateOptionsForTestCase (NPath outputPath, NPath[] sourceFiles, NPath[] references, string[] defines, NPath[] resources)
{
return new CompilerOptions
{
OutputPath = outputPath,
SourceFiles = sourceFiles,
References = references,
Defines = defines.Concat (_metadataProvider.GetDefines ()).ToArray ()
Defines = defines.Concat (_metadataProvider.GetDefines ()).ToArray (),
Resources = resources
};
}
@ -177,6 +179,9 @@ namespace Mono.Linker.Tests.TestCasesRunner {
compilerParameters.ReferencedAssemblies.AddRange (options.References.Select (r => r.ToString ()).ToArray ());
if (options.Resources != null)
compilerParameters.EmbeddedResources.AddRange (options.Resources.Select (r => r.ToString ()).ToArray ());
return compilerParameters;
}
}

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