mirror of https://github.com/icsharpcode/ILSpy.git
22 changed files with 1165 additions and 103 deletions
@ -0,0 +1,114 @@ |
|||||||
|
using System; |
||||||
|
using System.Collections.Generic; |
||||||
|
using System.Linq; |
||||||
|
using System.Text; |
||||||
|
using System.IO; |
||||||
|
|
||||||
|
namespace ICSharpCode.Decompiler.Tests |
||||||
|
{ |
||||||
|
static class CodeSampleFileParser |
||||||
|
{ |
||||||
|
public static IEnumerable<string> ListSections(string s) |
||||||
|
{ |
||||||
|
var query = from line in ToLines(s) |
||||||
|
let sectionName = ReadSectionName(line) |
||||||
|
where sectionName != null |
||||||
|
select sectionName; |
||||||
|
return query; |
||||||
|
} |
||||||
|
|
||||||
|
public static string GetSection(string sectionName, string s) |
||||||
|
{ |
||||||
|
var lines = ToLines(s); |
||||||
|
|
||||||
|
bool sectionFound = false; |
||||||
|
var sectionText = new StringBuilder(); |
||||||
|
|
||||||
|
Action<string> parser = null; |
||||||
|
|
||||||
|
Action<string> commonSectionReader = line => |
||||||
|
{ |
||||||
|
if (IsCommonSectionEnd(line)) |
||||||
|
parser = null; |
||||||
|
else |
||||||
|
sectionText.AppendLine(line); |
||||||
|
}; |
||||||
|
|
||||||
|
Action<string> namedSectionReader = line => |
||||||
|
{ |
||||||
|
string name = ReadSectionName(line); |
||||||
|
if (name == null) |
||||||
|
sectionText.AppendLine(line); |
||||||
|
else if (name != sectionName) |
||||||
|
parser = null; |
||||||
|
}; |
||||||
|
|
||||||
|
Action<string> defaultReader = line => |
||||||
|
{ |
||||||
|
if (IsCommonSectionStart(line)) |
||||||
|
parser = commonSectionReader; |
||||||
|
else if (ReadSectionName(line) == sectionName) |
||||||
|
{ |
||||||
|
parser = namedSectionReader; |
||||||
|
sectionFound = true; |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
foreach(var line in lines) |
||||||
|
{ |
||||||
|
(parser ?? defaultReader)(line); |
||||||
|
} |
||||||
|
|
||||||
|
if (sectionFound) |
||||||
|
return sectionText.ToString(); |
||||||
|
else |
||||||
|
return ""; |
||||||
|
} |
||||||
|
|
||||||
|
public static bool IsCommentOrBlank(string s) |
||||||
|
{ |
||||||
|
if(String.IsNullOrWhiteSpace(s)) |
||||||
|
return true; |
||||||
|
return s.Trim().StartsWith("//"); |
||||||
|
} |
||||||
|
|
||||||
|
public static string ConcatLines(IEnumerable<string> lines) |
||||||
|
{ |
||||||
|
var buffer = new StringBuilder(); |
||||||
|
foreach (var line in lines) |
||||||
|
{ |
||||||
|
buffer.AppendLine(line); |
||||||
|
} |
||||||
|
return buffer.ToString(); |
||||||
|
} |
||||||
|
|
||||||
|
static string ReadSectionName(string line) |
||||||
|
{ |
||||||
|
line = line.TrimStart(); |
||||||
|
if (line.StartsWith("//$$")) |
||||||
|
return line.Substring(4).Trim(); |
||||||
|
else |
||||||
|
return null; |
||||||
|
} |
||||||
|
|
||||||
|
static bool IsCommonSectionStart(string line) |
||||||
|
{ |
||||||
|
return line.Trim() == "//$CS"; |
||||||
|
} |
||||||
|
|
||||||
|
static bool IsCommonSectionEnd(string line) |
||||||
|
{ |
||||||
|
return line.Trim() == "//$CE"; |
||||||
|
} |
||||||
|
|
||||||
|
static IEnumerable<string> ToLines(string s) |
||||||
|
{ |
||||||
|
var reader = new StringReader(s); |
||||||
|
string line; |
||||||
|
while ((line = reader.ReadLine()) != null) |
||||||
|
{ |
||||||
|
yield return line; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,41 @@ |
|||||||
|
using System; |
||||||
|
namespace aa |
||||||
|
{ |
||||||
|
public static class CustomAtributes |
||||||
|
{ |
||||||
|
[Flags] |
||||||
|
public enum EnumWithFlag |
||||||
|
{ |
||||||
|
All = 15, |
||||||
|
None = 0, |
||||||
|
Item1 = 1, |
||||||
|
Item2 = 2, |
||||||
|
Item3 = 4, |
||||||
|
Item4 = 8 |
||||||
|
} |
||||||
|
[AttributeUsage(AttributeTargets.All)] |
||||||
|
public class MyAttribute : Attribute |
||||||
|
{ |
||||||
|
public MyAttribute(CustomAtributes.EnumWithFlag en) |
||||||
|
{ |
||||||
|
} |
||||||
|
} |
||||||
|
[CustomAtributes.MyAttribute(CustomAtributes.EnumWithFlag.Item1 | CustomAtributes.EnumWithFlag.Item2)] |
||||||
|
private static int field; |
||||||
|
[CustomAtributes.MyAttribute(CustomAtributes.EnumWithFlag.All)] |
||||||
|
public static string Property |
||||||
|
{ |
||||||
|
get |
||||||
|
{ |
||||||
|
return "aa"; |
||||||
|
} |
||||||
|
} |
||||||
|
[Obsolete("some message")] |
||||||
|
public static void ObsoletedMethod() |
||||||
|
{ |
||||||
|
Console.WriteLine("{0} $$$ {1}", AttributeTargets.Interface, AttributeTargets.Property | AttributeTargets.Field); |
||||||
|
AttributeTargets attributeTargets = AttributeTargets.Property | AttributeTargets.Field; |
||||||
|
Console.WriteLine("{0} $$$ {1}", AttributeTargets.Interface, attributeTargets); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,30 @@ |
|||||||
|
using System; |
||||||
|
using System.Collections.Generic; |
||||||
|
using System.Linq; |
||||||
|
using System.Text; |
||||||
|
using NUnit.Framework; |
||||||
|
|
||||||
|
namespace ICSharpCode.Decompiler.Tests.CustomAttributes |
||||||
|
{ |
||||||
|
[TestFixture] |
||||||
|
public class CustomAttributeTests : DecompilerTestBase |
||||||
|
{ |
||||||
|
[Test] |
||||||
|
public void CustomAttributeSamples() |
||||||
|
{ |
||||||
|
ValidateFileRoundtrip(@"CustomAttributes\S_CustomAttributeSamples.cs"); |
||||||
|
} |
||||||
|
|
||||||
|
[Test] |
||||||
|
public void CustomAttributesMultiTest() |
||||||
|
{ |
||||||
|
ValidateFileRoundtrip(@"CustomAttributes\S_CustomAttributes.cs"); |
||||||
|
} |
||||||
|
|
||||||
|
[Test] |
||||||
|
public void AssemblyCustomAttributesMultiTest() |
||||||
|
{ |
||||||
|
ValidateFileRoundtrip(@"CustomAttributes\S_AssemblyCustomAttribute.cs"); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,6 @@ |
|||||||
|
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||||
|
// This code is distributed under MIT X11 license (for details please see \doc\license.txt)
|
||||||
|
|
||||||
|
using System; |
||||||
|
|
||||||
|
[assembly: CLSCompliant(false)] |
@ -0,0 +1,398 @@ |
|||||||
|
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||||
|
// This code is distributed under MIT X11 license (for details please see \doc\license.txt)
|
||||||
|
|
||||||
|
//$CS
|
||||||
|
using System; |
||||||
|
//$CE
|
||||||
|
|
||||||
|
//$$ TargetModule (ignored)
|
||||||
|
//[module: CLSCompliantAttribute(false)]
|
||||||
|
//$$ ParameterlessAttributeUsage
|
||||||
|
namespace ParameterLessAttributeUsage |
||||||
|
{ |
||||||
|
[Flags] |
||||||
|
public enum EnumWithFlagsAttribute |
||||||
|
{ |
||||||
|
None = 0 |
||||||
|
} |
||||||
|
} |
||||||
|
//$$ AttributeWithEnumArgument
|
||||||
|
namespace AttributeWithEnumArgument |
||||||
|
{ |
||||||
|
[AttributeUsage(AttributeTargets.All)] |
||||||
|
public class MyAttributeAttribute : Attribute |
||||||
|
{ |
||||||
|
} |
||||||
|
} |
||||||
|
//$$ AttributeWithEnumExpressionArgument
|
||||||
|
namespace AttributeWithEnumExpressionArgument |
||||||
|
{ |
||||||
|
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Interface)] |
||||||
|
public class MyAttributeAttribute : Attribute |
||||||
|
{ |
||||||
|
} |
||||||
|
} |
||||||
|
//$$ AttributeWithStringExpressionArgument
|
||||||
|
namespace AttributeWithStringExpressionArgument |
||||||
|
{ |
||||||
|
[Obsolete("message")] |
||||||
|
public class ObsoletedClass |
||||||
|
{ |
||||||
|
} |
||||||
|
} |
||||||
|
//$$ AttributeWithTypeArgument
|
||||||
|
namespace AttributeWithTypeArgument |
||||||
|
{ |
||||||
|
[AttributeUsage(AttributeTargets.All)] |
||||||
|
public class MyTypeAttribute : Attribute |
||||||
|
{ |
||||||
|
public MyTypeAttribute(Type t) : base() |
||||||
|
{ |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
[MyType(typeof(Attribute))] |
||||||
|
public class SomeClass |
||||||
|
{ |
||||||
|
} |
||||||
|
} |
||||||
|
//$$ AppliedToEvent
|
||||||
|
namespace AppliedToEvent |
||||||
|
{ |
||||||
|
[AttributeUsage(AttributeTargets.Event)] |
||||||
|
public class MyAttributeAttribute : Attribute |
||||||
|
{ |
||||||
|
} |
||||||
|
public class TestClass |
||||||
|
{ |
||||||
|
[MyAttribute] |
||||||
|
public event EventHandler MyEvent; |
||||||
|
} |
||||||
|
} |
||||||
|
//$$ AppliedToField
|
||||||
|
namespace AppliedToField |
||||||
|
{ |
||||||
|
[AttributeUsage(AttributeTargets.Field)] |
||||||
|
public class MyAttributeAttribute : Attribute |
||||||
|
{ |
||||||
|
} |
||||||
|
public class TestClass |
||||||
|
{ |
||||||
|
[MyAttribute] |
||||||
|
public int Field; |
||||||
|
} |
||||||
|
} |
||||||
|
//$$ AppliedToProperty
|
||||||
|
namespace AppliedToProperty |
||||||
|
{ |
||||||
|
public class TestClass |
||||||
|
{ |
||||||
|
[Obsolete("reason")] |
||||||
|
public int Property |
||||||
|
{ |
||||||
|
get |
||||||
|
{ |
||||||
|
return 0; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
//$$ AppliedToPropertyGet
|
||||||
|
namespace AppliedToPropertyGet |
||||||
|
{ |
||||||
|
[AttributeUsage(AttributeTargets.All)] |
||||||
|
public class MyAttributeAttribute : Attribute |
||||||
|
{ |
||||||
|
} |
||||||
|
public class TestClass |
||||||
|
{ |
||||||
|
public int Property |
||||||
|
{ |
||||||
|
[MyAttribute] |
||||||
|
get |
||||||
|
{ |
||||||
|
return 0; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
//$$ AppliedToPropertySet
|
||||||
|
namespace AppliedToPropertySet |
||||||
|
{ |
||||||
|
[AttributeUsage(AttributeTargets.All)] |
||||||
|
public class MyAttributeAttribute : Attribute |
||||||
|
{ |
||||||
|
} |
||||||
|
public class TestClass |
||||||
|
{ |
||||||
|
public int Property |
||||||
|
{ |
||||||
|
get |
||||||
|
{ |
||||||
|
return 3; |
||||||
|
} |
||||||
|
[MyAttribute] |
||||||
|
set |
||||||
|
{ |
||||||
|
return; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
//$$ AppliedToDelegate
|
||||||
|
[Obsolete("reason")] |
||||||
|
public delegate int AppliedToDelegate(); |
||||||
|
//$$ AppliedToMethod
|
||||||
|
namespace AppliedToMethod |
||||||
|
{ |
||||||
|
[AttributeUsage(AttributeTargets.Method)] |
||||||
|
public class MyAttributeAttribute : Attribute |
||||||
|
{ |
||||||
|
} |
||||||
|
public class TestClass |
||||||
|
{ |
||||||
|
[MyAttribute] |
||||||
|
public void Method() |
||||||
|
{ |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
//$$ AppliedToInterface
|
||||||
|
[Obsolete("reason")] |
||||||
|
public interface AppliedToInterface |
||||||
|
{ |
||||||
|
} |
||||||
|
//$$ AppliedToStruct
|
||||||
|
[Obsolete("reason")] |
||||||
|
public struct AppliedToStruct |
||||||
|
{ |
||||||
|
public int Field; |
||||||
|
} |
||||||
|
//$$ AppliedToParameter
|
||||||
|
namespace AppliedToParameter |
||||||
|
{ |
||||||
|
[AttributeUsage(AttributeTargets.Parameter)] |
||||||
|
public class MyAttributeAttribute : Attribute |
||||||
|
{ |
||||||
|
} |
||||||
|
public class MyClass |
||||||
|
{ |
||||||
|
public void Method([MyAttribute]int val) |
||||||
|
{ |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
//$$ NamedInitializerProperty
|
||||||
|
namespace NamedInitializerProperty |
||||||
|
{ |
||||||
|
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)] |
||||||
|
public class MyAttributeAttribute : Attribute |
||||||
|
{ |
||||||
|
} |
||||||
|
} |
||||||
|
//$$ NamedInitializerPropertyString
|
||||||
|
namespace NamedInitializerPropertyString |
||||||
|
{ |
||||||
|
[AttributeUsage(AttributeTargets.All)] |
||||||
|
public class MyAttributeAttribute : Attribute |
||||||
|
{ |
||||||
|
public string Prop |
||||||
|
{ |
||||||
|
get |
||||||
|
{ |
||||||
|
return ""; |
||||||
|
} |
||||||
|
set |
||||||
|
{ |
||||||
|
return; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
[MyAttribute(Prop = "value")] |
||||||
|
public class MyClass |
||||||
|
{ |
||||||
|
} |
||||||
|
} |
||||||
|
//$$ NamedInitializerPropertyType
|
||||||
|
namespace NamedInitializerPropertyType |
||||||
|
{ |
||||||
|
[AttributeUsage(AttributeTargets.All)] |
||||||
|
public class MyAttributeAttribute : Attribute |
||||||
|
{ |
||||||
|
public Type Prop |
||||||
|
{ |
||||||
|
get |
||||||
|
{ |
||||||
|
return null; |
||||||
|
} |
||||||
|
set |
||||||
|
{ |
||||||
|
return; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
[MyAttribute(Prop = typeof(Enum))] |
||||||
|
public class MyClass |
||||||
|
{ |
||||||
|
} |
||||||
|
} |
||||||
|
//$$ NamedInitializerPropertyEnum
|
||||||
|
namespace NamedInitializerPropertyEnum |
||||||
|
{ |
||||||
|
[AttributeUsage(AttributeTargets.All)] |
||||||
|
public class MyAttributeAttribute : Attribute |
||||||
|
{ |
||||||
|
public AttributeTargets Prop |
||||||
|
{ |
||||||
|
get |
||||||
|
{ |
||||||
|
return AttributeTargets.All; |
||||||
|
} |
||||||
|
set |
||||||
|
{ |
||||||
|
return; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
[MyAttribute(Prop = (AttributeTargets.Class | AttributeTargets.Method))] |
||||||
|
public class MyClass |
||||||
|
{ |
||||||
|
} |
||||||
|
} |
||||||
|
//$$ NamedInitializerFieldEnum
|
||||||
|
namespace NamedInitializerFieldEnum |
||||||
|
{ |
||||||
|
[AttributeUsage(AttributeTargets.All)] |
||||||
|
public class MyAttributeAttribute : Attribute |
||||||
|
{ |
||||||
|
public AttributeTargets Field; |
||||||
|
} |
||||||
|
[MyAttribute(Field = (AttributeTargets.Class | AttributeTargets.Method))] |
||||||
|
public class MyClass |
||||||
|
{ |
||||||
|
} |
||||||
|
} |
||||||
|
//$$ TargetReturn
|
||||||
|
namespace TargetReturn |
||||||
|
{ |
||||||
|
[AttributeUsage(AttributeTargets.All)] |
||||||
|
public class MyAttributeAttribute : Attribute |
||||||
|
{ |
||||||
|
} |
||||||
|
public class MyClass |
||||||
|
{ |
||||||
|
[return: MyAttribute] |
||||||
|
public int MyMethod() |
||||||
|
{ |
||||||
|
return 5; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
//$$ TargetPropertyGetReturn
|
||||||
|
namespace TargetPropertyGetReturn |
||||||
|
{ |
||||||
|
[AttributeUsage(AttributeTargets.All)] |
||||||
|
public class MyAttributeAttribute : Attribute |
||||||
|
{ |
||||||
|
} |
||||||
|
public class MyClass |
||||||
|
{ |
||||||
|
public int Prop |
||||||
|
{ |
||||||
|
[return: MyAttribute] |
||||||
|
get |
||||||
|
{ |
||||||
|
return 3; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
//$$ TargetPropertySetParam
|
||||||
|
namespace TargetPropertySetParam |
||||||
|
{ |
||||||
|
[AttributeUsage(AttributeTargets.All)] |
||||||
|
public class MyAttributeAttribute : Attribute |
||||||
|
{ |
||||||
|
} |
||||||
|
public class MyClass |
||||||
|
{ |
||||||
|
public int Prop |
||||||
|
{ |
||||||
|
[param: MyAttribute] |
||||||
|
set |
||||||
|
{ |
||||||
|
return; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
//$$ TargetPropertySetReturn
|
||||||
|
namespace TargetPropertySetReturn |
||||||
|
{ |
||||||
|
[AttributeUsage(AttributeTargets.All)] |
||||||
|
public class MyAttributeAttribute : Attribute |
||||||
|
{ |
||||||
|
} |
||||||
|
public class MyClass |
||||||
|
{ |
||||||
|
public int Prop |
||||||
|
{ |
||||||
|
get |
||||||
|
{ |
||||||
|
return 3; |
||||||
|
} |
||||||
|
[return: MyAttribute] |
||||||
|
set |
||||||
|
{ |
||||||
|
return; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
//$$ TargetPropertyIndexSetParam
|
||||||
|
namespace TargetPropertyIndexSetParam |
||||||
|
{ |
||||||
|
[AttributeUsage(AttributeTargets.All)] |
||||||
|
public class MyAttributeAttribute : Attribute |
||||||
|
{ |
||||||
|
} |
||||||
|
public class MyClass |
||||||
|
{ |
||||||
|
public string this[int index] |
||||||
|
{ |
||||||
|
get |
||||||
|
{ |
||||||
|
return ""; |
||||||
|
} |
||||||
|
[param: MyAttribute] |
||||||
|
set |
||||||
|
{ |
||||||
|
return; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
//$$ TargetPropertyIndexSetMultiParam
|
||||||
|
namespace TargetPropertyIndexSetMultiParam |
||||||
|
{ |
||||||
|
[AttributeUsage(AttributeTargets.All)] |
||||||
|
public class MyAttributeAttribute : Attribute |
||||||
|
{ |
||||||
|
public int Field; |
||||||
|
} |
||||||
|
public class MyClass |
||||||
|
{ |
||||||
|
public string this[[MyAttribute(Field = 2)]int index1, [MyAttribute(Field = 3)]int index2] |
||||||
|
{ |
||||||
|
get |
||||||
|
{ |
||||||
|
return ""; |
||||||
|
} |
||||||
|
[param: MyAttribute] |
||||||
|
set |
||||||
|
{ |
||||||
|
return; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,46 @@ |
|||||||
|
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||||
|
// This code is distributed under MIT X11 license (for details please see \doc\license.txt)
|
||||||
|
|
||||||
|
using System; |
||||||
|
|
||||||
|
namespace aa |
||||||
|
{ |
||||||
|
public static class CustomAtributes |
||||||
|
{ |
||||||
|
[Flags] |
||||||
|
public enum EnumWithFlag |
||||||
|
{ |
||||||
|
All = 15, |
||||||
|
None = 0, |
||||||
|
Item1 = 1, |
||||||
|
Item2 = 2, |
||||||
|
Item3 = 4, |
||||||
|
Item4 = 8 |
||||||
|
} |
||||||
|
[AttributeUsage(AttributeTargets.All)] |
||||||
|
public class MyAttribute : Attribute |
||||||
|
{ |
||||||
|
public MyAttribute(CustomAtributes.EnumWithFlag en) : base() |
||||||
|
{ |
||||||
|
} |
||||||
|
} |
||||||
|
[CustomAtributes.MyAttribute(CustomAtributes.EnumWithFlag.Item1 | CustomAtributes.EnumWithFlag.Item2)] |
||||||
|
private static int field; |
||||||
|
[CustomAtributes.MyAttribute(CustomAtributes.EnumWithFlag.All)] |
||||||
|
public static string Property |
||||||
|
{ |
||||||
|
get |
||||||
|
{ |
||||||
|
return "aa"; |
||||||
|
} |
||||||
|
} |
||||||
|
[Obsolete("some message")] |
||||||
|
public static void ObsoletedMethod() |
||||||
|
{ |
||||||
|
//Console.WriteLine("{0} $$$ {1}", AttributeTargets.Interface, (AttributeTargets)(AttributeTargets.Property | AttributeTargets.Field));
|
||||||
|
Console.WriteLine("{0} $$$ {1}", AttributeTargets.Interface, AttributeTargets.Property | AttributeTargets.Field); |
||||||
|
AttributeTargets attributeTargets = AttributeTargets.Property | AttributeTargets.Field; |
||||||
|
Console.WriteLine("{0} $$$ {1}", AttributeTargets.Interface, attributeTargets); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,71 @@ |
|||||||
|
using System; |
||||||
|
using System.Collections.Generic; |
||||||
|
using System.Linq; |
||||||
|
using System.Text; |
||||||
|
using Mono.Cecil; |
||||||
|
using System.IO; |
||||||
|
using Decompiler; |
||||||
|
using Microsoft.CSharp; |
||||||
|
using System.CodeDom.Compiler; |
||||||
|
using NUnit.Framework; |
||||||
|
|
||||||
|
namespace ICSharpCode.Decompiler.Tests |
||||||
|
{ |
||||||
|
public abstract class DecompilerTestBase |
||||||
|
{ |
||||||
|
protected static void ValidateFileRoundtrip(string samplesFileName) |
||||||
|
{ |
||||||
|
var lines = File.ReadAllLines(Path.Combine(@"..\..\Tests", samplesFileName)); |
||||||
|
var testCode = RemoveIgnorableLines(lines); |
||||||
|
var decompiledTestCode = RoundtripCode(testCode); |
||||||
|
Assert.AreEqual(testCode, decompiledTestCode); |
||||||
|
} |
||||||
|
|
||||||
|
static string RemoveIgnorableLines(IEnumerable<string> lines) |
||||||
|
{ |
||||||
|
return CodeSampleFileParser.ConcatLines(lines.Where(l => !CodeSampleFileParser.IsCommentOrBlank(l))); |
||||||
|
} |
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Compiles and decompiles a source code.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="code">The source code to copile.</param>
|
||||||
|
/// <returns>The decompilation result of compiled source code.</returns>
|
||||||
|
static string RoundtripCode(string code) |
||||||
|
{ |
||||||
|
AssemblyDefinition assembly = Compile(code); |
||||||
|
AstBuilder decompiler = new AstBuilder(new DecompilerContext()); |
||||||
|
decompiler.AddAssembly(assembly); |
||||||
|
decompiler.Transform(new Helpers.RemoveCompilerAttribute()); |
||||||
|
StringWriter output = new StringWriter(); |
||||||
|
decompiler.GenerateCode(new PlainTextOutput(output)); |
||||||
|
return output.ToString(); |
||||||
|
} |
||||||
|
|
||||||
|
static AssemblyDefinition Compile(string code) |
||||||
|
{ |
||||||
|
CSharpCodeProvider provider = new CSharpCodeProvider(new Dictionary<string, string> { { "CompilerVersion", "v4.0" } }); |
||||||
|
CompilerParameters options = new CompilerParameters(); |
||||||
|
options.ReferencedAssemblies.Add("System.Core.dll"); |
||||||
|
CompilerResults results = provider.CompileAssemblyFromSource(options, code); |
||||||
|
try |
||||||
|
{ |
||||||
|
if (results.Errors.Count > 0) |
||||||
|
{ |
||||||
|
StringBuilder b = new StringBuilder("Compiler error:"); |
||||||
|
foreach (var error in results.Errors) |
||||||
|
{ |
||||||
|
b.AppendLine(error.ToString()); |
||||||
|
} |
||||||
|
throw new Exception(b.ToString()); |
||||||
|
} |
||||||
|
return AssemblyDefinition.ReadAssembly(results.PathToAssembly); |
||||||
|
} |
||||||
|
finally |
||||||
|
{ |
||||||
|
File.Delete(results.PathToAssembly); |
||||||
|
results.TempFiles.Delete(); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,31 @@ |
|||||||
|
using System; |
||||||
|
using System.Collections.Generic; |
||||||
|
using System.Linq; |
||||||
|
using System.Text; |
||||||
|
using ICSharpCode.NRefactory.CSharp; |
||||||
|
using Decompiler.Transforms; |
||||||
|
|
||||||
|
namespace ICSharpCode.Decompiler.Tests.Helpers |
||||||
|
{ |
||||||
|
class RemoveCompilerAttribute : DepthFirstAstVisitor<object, object>, IAstTransform |
||||||
|
{ |
||||||
|
public override object VisitAttribute(NRefactory.CSharp.Attribute attribute, object data) |
||||||
|
{ |
||||||
|
var section = (AttributeSection)attribute.Parent; |
||||||
|
SimpleType type = attribute.Type as SimpleType; |
||||||
|
if (section.AttributeTarget == AttributeTarget.Assembly && |
||||||
|
(type.Identifier == "CompilationRelaxationsAttribute" || type.Identifier == "RuntimeCompatibilityAttribute")) |
||||||
|
{ |
||||||
|
attribute.Remove(); |
||||||
|
if (section.Attributes.Count == 0) |
||||||
|
section.Remove(); |
||||||
|
} |
||||||
|
return null; |
||||||
|
} |
||||||
|
|
||||||
|
public void Run(AstNode node) |
||||||
|
{ |
||||||
|
node.AcceptVisitor(this, null); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,18 @@ |
|||||||
|
using System; |
||||||
|
using System.Collections.Generic; |
||||||
|
using System.Linq; |
||||||
|
using System.Text; |
||||||
|
using NUnit.Framework; |
||||||
|
|
||||||
|
namespace ICSharpCode.Decompiler.Tests.Types |
||||||
|
{ |
||||||
|
[TestFixture] |
||||||
|
public class EnumTests : DecompilerTestBase |
||||||
|
{ |
||||||
|
[Test] |
||||||
|
public void EnumSamples() |
||||||
|
{ |
||||||
|
ValidateFileRoundtrip(@"Types\S_EnumSamples.cs"); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,114 @@ |
|||||||
|
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||||
|
// This code is distributed under MIT X11 license (for details please see \doc\license.txt)
|
||||||
|
|
||||||
|
//$CS
|
||||||
|
using System; |
||||||
|
//$CE
|
||||||
|
|
||||||
|
//$$ SingleValue
|
||||||
|
public class TS_SingleValue |
||||||
|
{ |
||||||
|
public AttributeTargets Method() |
||||||
|
{ |
||||||
|
return AttributeTargets.Class; |
||||||
|
} |
||||||
|
} |
||||||
|
//$$ TwoValuesOr
|
||||||
|
public class TS_TwoValuesOr |
||||||
|
{ |
||||||
|
public AttributeTargets Method() |
||||||
|
{ |
||||||
|
return AttributeTargets.Class | AttributeTargets.Method; |
||||||
|
} |
||||||
|
} |
||||||
|
//$$ ThreeValuesOr
|
||||||
|
public class TS_ThreeValuesOr |
||||||
|
{ |
||||||
|
public AttributeTargets Method() |
||||||
|
{ |
||||||
|
return AttributeTargets.Class | AttributeTargets.Method | AttributeTargets.Parameter; |
||||||
|
} |
||||||
|
} |
||||||
|
//$$ UnknownNumericValue
|
||||||
|
public class TS_UnknownNumericValue |
||||||
|
{ |
||||||
|
public AttributeTargets Method() |
||||||
|
{ |
||||||
|
return (AttributeTargets)1000000; |
||||||
|
} |
||||||
|
} |
||||||
|
//$$ AllValue
|
||||||
|
public class TS_AllValue |
||||||
|
{ |
||||||
|
public AttributeTargets Method() |
||||||
|
{ |
||||||
|
return AttributeTargets.All; |
||||||
|
} |
||||||
|
} |
||||||
|
//$$ ZeroValue
|
||||||
|
public class TS_ZeroValue |
||||||
|
{ |
||||||
|
public AttributeTargets Method() |
||||||
|
{ |
||||||
|
return (AttributeTargets)0; |
||||||
|
} |
||||||
|
} |
||||||
|
//$$ PreservingTypeWhenBoxed
|
||||||
|
public class TS_PreservingTypeWhenBoxed |
||||||
|
{ |
||||||
|
public object Method() |
||||||
|
{ |
||||||
|
return AttributeTargets.Delegate; |
||||||
|
} |
||||||
|
} |
||||||
|
//$$ PreservingTypeWhenBoxedTwoEnum
|
||||||
|
public class TS_PreservingTypeWhenBoxedTwoEnum |
||||||
|
{ |
||||||
|
public object Method() |
||||||
|
{ |
||||||
|
return AttributeTargets.Class | AttributeTargets.Delegate; |
||||||
|
} |
||||||
|
} |
||||||
|
//$$ DeclarationSimpleEnum
|
||||||
|
public enum TS_DeclarationSimpleEnum |
||||||
|
{ |
||||||
|
Item1, |
||||||
|
Item2 |
||||||
|
} |
||||||
|
//$$ DeclarationLongBasedEnum
|
||||||
|
public enum TS_DeclarationLongBasedEnum : long |
||||||
|
{ |
||||||
|
Item1, |
||||||
|
Item2 |
||||||
|
} |
||||||
|
//$$ DeclarationLongWithInitializers
|
||||||
|
public enum TS_DeclarationLongWithInitializers : long |
||||||
|
{ |
||||||
|
Item1, |
||||||
|
Item2 = 20L, |
||||||
|
Item3 |
||||||
|
} |
||||||
|
//$$ DeclarationShortWithInitializers
|
||||||
|
public enum TS_DeclarationShortWithInitializers : short |
||||||
|
{ |
||||||
|
Item1, |
||||||
|
Item2 = 20, |
||||||
|
Item3 |
||||||
|
} |
||||||
|
//$$ DeclarationByteWithInitializers
|
||||||
|
public enum TS_DeclarationByteWithInitializers : byte |
||||||
|
{ |
||||||
|
Item1, |
||||||
|
Item2 = 20, |
||||||
|
Item3 |
||||||
|
} |
||||||
|
//$$ DeclarationFlags
|
||||||
|
[Flags] |
||||||
|
public enum TS_DeclarationFlags |
||||||
|
{ |
||||||
|
None = 0, |
||||||
|
Item1 = 1, |
||||||
|
Item2 = 2, |
||||||
|
Item3 = 4, |
||||||
|
All = 7 |
||||||
|
} |
@ -0,0 +1,12 @@ |
|||||||
|
using System; |
||||||
|
using System.Collections.Generic; |
||||||
|
using System.Linq; |
||||||
|
using System.Text; |
||||||
|
using NUnit.Framework; |
||||||
|
|
||||||
|
namespace ICSharpCode.Decompiler.Tests.Types |
||||||
|
{ |
||||||
|
public class TypeTests : DecompilerTestBase |
||||||
|
{ |
||||||
|
} |
||||||
|
} |
Binary file not shown.
Loading…
Reference in new issue