Browse Source

Merge branch 'master' of https://github.com/icsharpcode/ILSpy into ppdb

pull/1420/head
Siegfried Pammer 8 years ago
parent
commit
9c640d3042
  1. 2
      .gitignore
  2. 2
      ICSharpCode.Decompiler.PdbProvider.Cecil/ICSharpCode.Decompiler.PdbProvider.Cecil.csproj
  3. 144
      ICSharpCode.Decompiler.Tests/CorrectnessTestRunner.cs
  4. 74
      ICSharpCode.Decompiler.Tests/Helpers/Tester.VB.cs
  5. 64
      ICSharpCode.Decompiler.Tests/Helpers/Tester.cs
  6. 3
      ICSharpCode.Decompiler.Tests/ICSharpCode.Decompiler.Tests.csproj
  7. 148
      ICSharpCode.Decompiler.Tests/PrettyTestRunner.cs
  8. 21
      ICSharpCode.Decompiler.Tests/TestCases/Correctness/Uninit.vb
  9. 15
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/Generics.cs
  10. 59
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/Generics.il
  11. 53
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/Generics.opt.il
  12. 50
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/Generics.opt.roslyn.il
  13. 56
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/Generics.roslyn.il
  14. 19
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/QueryExpressions.cs
  15. 176
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/QueryExpressions.il
  16. 141
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/QueryExpressions.opt.il
  17. 178
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/QueryExpressions.opt.roslyn.il
  18. 187
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/QueryExpressions.roslyn.il
  19. 32
      ICSharpCode.Decompiler.Tests/UglyTestRunner.cs
  20. 20
      ICSharpCode.Decompiler.Tests/VBPrettyTestRunner.cs
  21. 1
      ICSharpCode.Decompiler/CSharp/OutputVisitor/CSharpAmbience.cs
  22. 8
      ICSharpCode.Decompiler/CSharp/OutputVisitor/CSharpOutputVisitor.cs
  23. 53
      ICSharpCode.Decompiler/CSharp/OutputVisitor/TextWriterTokenWriter.cs
  24. 15
      ICSharpCode.Decompiler/CSharp/Syntax/TypeSystemAstBuilder.cs
  25. 130
      ICSharpCode.Decompiler/CSharp/Transforms/CombineQueryExpressions.cs
  26. 30
      ICSharpCode.Decompiler/CSharp/Transforms/DeclareVariables.cs
  27. 114
      ICSharpCode.Decompiler/CSharp/Transforms/IntroduceQueryExpressions.cs
  28. 12
      ICSharpCode.Decompiler/DebugInfo/ScopesGenerator.cs
  29. 8
      ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj
  30. 6
      ICSharpCode.Decompiler/ICSharpCode.Decompiler.nuspec.template
  31. 2
      ICSharpCode.Decompiler/IL/ControlFlow/AsyncAwaitDecompiler.cs
  32. 11
      ICSharpCode.Decompiler/IL/ILReader.cs
  33. 58
      ICSharpCode.Decompiler/IL/ILVariable.cs
  34. 28
      ICSharpCode.Decompiler/IL/Instructions/ILFunction.cs
  35. 51
      ICSharpCode.Decompiler/IL/Transforms/CombineExitsTransform.cs
  36. 7
      ICSharpCode.Decompiler/IL/Transforms/CopyPropagation.cs
  37. 24
      ICSharpCode.Decompiler/IL/Transforms/DelegateConstruction.cs
  38. 8
      ICSharpCode.Decompiler/IL/Transforms/DetectCatchWhenConditionBlocks.cs
  39. 2
      ICSharpCode.Decompiler/IL/Transforms/ExpressionTransforms.cs
  40. 1
      ICSharpCode.Decompiler/IL/Transforms/SplitVariables.cs
  41. 5
      ICSharpCode.Decompiler/Metadata/AssemblyReferences.cs
  42. 25
      ICSharpCode.Decompiler/Output/TextTokenWriter.cs
  43. 16
      ILSpy.AddIn/ILSpy.AddIn.csproj
  44. 2
      ILSpy.BamlDecompiler.Tests/Cases/AttachedEvent.xaml
  45. 38
      ILSpy.BamlDecompiler.Tests/Cases/AvalonDockBrushes.xaml
  46. 24
      ILSpy.BamlDecompiler.Tests/Cases/AvalonDockCommon.xaml
  47. 26
      ILSpy.BamlDecompiler.Tests/Cases/EscapeSequence.xaml
  48. 22
      ILSpy.BamlDecompiler.Tests/Cases/Issue445.xaml
  49. 11
      ILSpy.BamlDecompiler.Tests/Cases/MarkupExtension.xaml
  50. 8
      ILSpy.BamlDecompiler.Tests/Cases/MyControl.xaml
  51. 17
      ILSpy.BamlDecompiler.Tests/Cases/NamespacePrefix.xaml
  52. 14
      ILSpy.BamlDecompiler.Tests/Cases/Resources.xaml
  53. 2
      ILSpy.BamlDecompiler.Tests/Cases/Simple.xaml
  54. 2
      ILSpy.BamlDecompiler.Tests/Cases/SimpleDictionary.xaml
  55. 2
      ILSpy.BamlDecompiler.Tests/Cases/SimpleNames.xaml
  56. 7
      ILSpy.BamlDecompiler.Tests/Cases/SimplePropertyElement.xaml
  57. 2
      ILSpy.BamlDecompiler.Tests/ILSpy.BamlDecompiler.Tests.csproj
  58. 97
      ILSpy.BamlDecompiler/Baml/BamlContext.cs
  59. 39
      ILSpy.BamlDecompiler/Baml/BamlDocument.cs
  60. 164
      ILSpy.BamlDecompiler/Baml/BamlNode.cs
  61. 259
      ILSpy.BamlDecompiler/Baml/BamlReader.cs
  62. 992
      ILSpy.BamlDecompiler/Baml/BamlRecords.cs
  63. 65
      ILSpy.BamlDecompiler/Baml/BamlWriter.cs
  64. 297
      ILSpy.BamlDecompiler/Baml/KnownMembers.cs
  65. 80
      ILSpy.BamlDecompiler/Baml/KnownThings.cs
  66. 1321
      ILSpy.BamlDecompiler/Baml/KnownThings.g.cs
  67. 278
      ILSpy.BamlDecompiler/Baml/KnownThings.gen.cs
  68. 788
      ILSpy.BamlDecompiler/Baml/KnownTypes.cs
  69. 2325
      ILSpy.BamlDecompiler/Baml/test.cs
  70. 39
      ILSpy.BamlDecompiler/BamlConnectionId.cs
  71. 60
      ILSpy.BamlDecompiler/BamlElement.cs
  72. 185
      ILSpy.BamlDecompiler/BamlResourceEntryNode.cs
  73. 65
      ILSpy.BamlDecompiler/CecilType.cs
  74. 78
      ILSpy.BamlDecompiler/CecilTypeResolver.cs
  75. 39
      ILSpy.BamlDecompiler/Handlers/Blocks/ConstructorParametersHandler.cs
  76. 38
      ILSpy.BamlDecompiler/Handlers/Blocks/DocumentHandler.cs
  77. 56
      ILSpy.BamlDecompiler/Handlers/Blocks/ElementHandler.cs
  78. 49
      ILSpy.BamlDecompiler/Handlers/Blocks/KeyElementStartHandler.cs
  79. 47
      ILSpy.BamlDecompiler/Handlers/Blocks/PropertyArrayHandler.cs
  80. 47
      ILSpy.BamlDecompiler/Handlers/Blocks/PropertyComplexHandler.cs
  81. 47
      ILSpy.BamlDecompiler/Handlers/Blocks/PropertyDictionaryHandler.cs
  82. 47
      ILSpy.BamlDecompiler/Handlers/Blocks/PropertyListHandler.cs
  83. 31
      ILSpy.BamlDecompiler/Handlers/Records/AssemblyInfoHandler.cs
  84. 31
      ILSpy.BamlDecompiler/Handlers/Records/AttributeInfoHandler.cs
  85. 37
      ILSpy.BamlDecompiler/Handlers/Records/ConnectionIdHandler.cs
  86. 48
      ILSpy.BamlDecompiler/Handlers/Records/ConstructorParameterTypeHandler.cs
  87. 36
      ILSpy.BamlDecompiler/Handlers/Records/ContentPropertyHandler.cs
  88. 39
      ILSpy.BamlDecompiler/Handlers/Records/DefAttributeHandler.cs
  89. 49
      ILSpy.BamlDecompiler/Handlers/Records/DefAttributeKeyStringHandler.cs
  90. 56
      ILSpy.BamlDecompiler/Handlers/Records/DefAttributeKeyTypeHandler.cs
  91. 38
      ILSpy.BamlDecompiler/Handlers/Records/DeferableContentStartHandler.cs
  92. 31
      ILSpy.BamlDecompiler/Handlers/Records/LineNumberAndPositionHandler.cs
  93. 31
      ILSpy.BamlDecompiler/Handlers/Records/LinePositionHandler.cs
  94. 42
      ILSpy.BamlDecompiler/Handlers/Records/LiteralContentHandler.cs
  95. 106
      ILSpy.BamlDecompiler/Handlers/Records/OptimizedStaticResourceHandler.cs
  96. 31
      ILSpy.BamlDecompiler/Handlers/Records/PIMappingHandler.cs
  97. 40
      ILSpy.BamlDecompiler/Handlers/Records/PresentationOptionsAttributeHandler.cs
  98. 160
      ILSpy.BamlDecompiler/Handlers/Records/PropertyCustomHandler.cs
  99. 49
      ILSpy.BamlDecompiler/Handlers/Records/PropertyHandler.cs
  100. 56
      ILSpy.BamlDecompiler/Handlers/Records/PropertyTypeReferenceHandler.cs
  101. Some files were not shown because too many files have changed in this diff Show More

2
.gitignore vendored

@ -12,6 +12,8 @@ _ReSharper*/ @@ -12,6 +12,8 @@ _ReSharper*/
.vs/
/ILSpy.AddIn/Packages/*
/ILSpy.AddIn/source.extension.vsixmanifest
/ICSharpCode.Decompiler.Tests/TestCases/Disassembler/Pretty/*.dll
/ICSharpCode.Decompiler.Tests/TestCases/Disassembler/Pretty/*.result.il
/ICSharpCode.Decompiler.Tests/TestCases/Correctness/*.exe
/ICSharpCode.Decompiler.Tests/TestCases/Correctness/*.exe.config
/ICSharpCode.Decompiler/ICSharpCode.Decompiler.nuspec

2
ICSharpCode.Decompiler.PdbProvider.Cecil/ICSharpCode.Decompiler.PdbProvider.Cecil.csproj

@ -7,7 +7,7 @@ @@ -7,7 +7,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Mono.Cecil" Version="0.10.1" />
<PackageReference Include="Mono.Cecil" Version="0.10.3" />
</ItemGroup>
<ItemGroup>

144
ICSharpCode.Decompiler.Tests/CorrectnessTestRunner.cs

@ -46,152 +46,158 @@ namespace ICSharpCode.Decompiler.Tests @@ -46,152 +46,158 @@ namespace ICSharpCode.Decompiler.Tests
}
}
static readonly CSharpCompilerOptions[] noMonoOptions =
static readonly CompilerOptions[] noMonoOptions =
{
CSharpCompilerOptions.None,
CSharpCompilerOptions.Optimize,
CSharpCompilerOptions.UseRoslyn,
CSharpCompilerOptions.Optimize | CSharpCompilerOptions.UseRoslyn,
CompilerOptions.None,
CompilerOptions.Optimize,
CompilerOptions.UseRoslyn,
CompilerOptions.Optimize | CompilerOptions.UseRoslyn,
};
static readonly CSharpCompilerOptions[] defaultOptions =
static readonly CompilerOptions[] defaultOptions =
{
CSharpCompilerOptions.None,
CSharpCompilerOptions.Optimize,
CSharpCompilerOptions.UseRoslyn,
CSharpCompilerOptions.Optimize | CSharpCompilerOptions.UseRoslyn,
CSharpCompilerOptions.UseMcs,
CSharpCompilerOptions.Optimize | CSharpCompilerOptions.UseMcs
CompilerOptions.None,
CompilerOptions.Optimize,
CompilerOptions.UseRoslyn,
CompilerOptions.Optimize | CompilerOptions.UseRoslyn,
CompilerOptions.UseMcs,
CompilerOptions.Optimize | CompilerOptions.UseMcs
};
static readonly CSharpCompilerOptions[] roslynOnlyOptions =
static readonly CompilerOptions[] roslynOnlyOptions =
{
CSharpCompilerOptions.UseRoslyn,
CSharpCompilerOptions.Optimize | CSharpCompilerOptions.UseRoslyn
CompilerOptions.UseRoslyn,
CompilerOptions.Optimize | CompilerOptions.UseRoslyn
};
[Test]
public void Comparisons([ValueSource("defaultOptions")] CSharpCompilerOptions options)
public void Comparisons([ValueSource("defaultOptions")] CompilerOptions options)
{
RunCS(options: options);
}
[Test]
public void Conversions([ValueSource("defaultOptions")] CSharpCompilerOptions options)
public void Conversions([ValueSource("defaultOptions")] CompilerOptions options)
{
RunCS(options: options);
}
[Test]
public void FloatingPointArithmetic([ValueSource("defaultOptions")] CSharpCompilerOptions options)
public void FloatingPointArithmetic([ValueSource("defaultOptions")] CompilerOptions options)
{
RunCS(options: options);
}
[Test]
public void HelloWorld([ValueSource("defaultOptions")] CSharpCompilerOptions options)
public void HelloWorld([ValueSource("defaultOptions")] CompilerOptions options)
{
RunCS(options: options);
}
[Test]
public void ControlFlow([ValueSource("defaultOptions")] CSharpCompilerOptions options)
public void ControlFlow([ValueSource("defaultOptions")] CompilerOptions options)
{
RunCS(options: options);
}
[Test]
public void CompoundAssignment([ValueSource("defaultOptions")] CSharpCompilerOptions options)
public void CompoundAssignment([ValueSource("defaultOptions")] CompilerOptions options)
{
RunCS(options: options);
}
[Test]
public void PropertiesAndEvents([ValueSource("defaultOptions")] CSharpCompilerOptions options)
public void PropertiesAndEvents([ValueSource("defaultOptions")] CompilerOptions options)
{
RunCS(options: options);
}
[Test]
public void Switch([ValueSource("defaultOptions")] CSharpCompilerOptions options)
public void Switch([ValueSource("defaultOptions")] CompilerOptions options)
{
RunCS(options: options);
}
[Test]
public void Using([ValueSource("defaultOptions")] CSharpCompilerOptions options)
public void Using([ValueSource("defaultOptions")] CompilerOptions options)
{
RunCS(options: options);
}
[Test]
public void Loops([ValueSource("defaultOptions")] CSharpCompilerOptions options)
public void Loops([ValueSource("defaultOptions")] CompilerOptions options)
{
RunCS(options: options);
}
[Test]
public void NullableTests([ValueSource("defaultOptions")] CSharpCompilerOptions options)
public void NullableTests([ValueSource("defaultOptions")] CompilerOptions options)
{
RunCS(options: options);
}
[Test]
public void Generics([ValueSource("defaultOptions")] CSharpCompilerOptions options)
public void Generics([ValueSource("defaultOptions")] CompilerOptions options)
{
RunCS(options: options);
}
[Test]
public void ValueTypeCall([ValueSource("defaultOptions")] CSharpCompilerOptions options)
public void ValueTypeCall([ValueSource("defaultOptions")] CompilerOptions options)
{
RunCS(options: options);
}
[Test]
public void InitializerTests([ValueSource("defaultOptions")] CSharpCompilerOptions options)
public void InitializerTests([ValueSource("defaultOptions")] CompilerOptions options)
{
RunCS(options: options);
}
[Test]
public void DecimalFields([ValueSource("defaultOptions")] CSharpCompilerOptions options)
public void DecimalFields([ValueSource("defaultOptions")] CompilerOptions options)
{
RunCS(options: options);
}
[Test]
public void UndocumentedExpressions([ValueSource("noMonoOptions")] CSharpCompilerOptions options)
public void UndocumentedExpressions([ValueSource("noMonoOptions")] CompilerOptions options)
{
RunCS(options: options);
}
[Test]
public void MemberLookup([ValueSource("defaultOptions")] CSharpCompilerOptions options)
public void Uninit([ValueSource("noMonoOptions")] CompilerOptions options)
{
RunVB(options: options);
}
[Test]
public void MemberLookup([ValueSource("defaultOptions")] CompilerOptions options)
{
RunCS(options: options);
}
[Test]
public void OverloadResolution([ValueSource("defaultOptions")] CSharpCompilerOptions options)
public void OverloadResolution([ValueSource("defaultOptions")] CompilerOptions options)
{
RunCS(options: options);
}
[Test]
public void ExpressionTrees([ValueSource("defaultOptions")] CSharpCompilerOptions options)
public void ExpressionTrees([ValueSource("defaultOptions")] CompilerOptions options)
{
RunCS(options: options);
}
[Test]
public void NullPropagation([ValueSource("roslynOnlyOptions")] CSharpCompilerOptions options)
public void NullPropagation([ValueSource("roslynOnlyOptions")] CompilerOptions options)
{
RunCS(options: options);
}
[Test]
public void RefLocalsAndReturns([ValueSource("roslynOnlyOptions")] CSharpCompilerOptions options)
public void RefLocalsAndReturns([ValueSource("roslynOnlyOptions")] CompilerOptions options)
{
RunCS(options: options);
}
@ -199,10 +205,10 @@ namespace ICSharpCode.Decompiler.Tests @@ -199,10 +205,10 @@ namespace ICSharpCode.Decompiler.Tests
[Test]
public void BitNot([Values(false, true)] bool force32Bit)
{
CSharpCompilerOptions compiler = CSharpCompilerOptions.UseDebug;
CompilerOptions compiler = CompilerOptions.UseDebug;
AssemblerOptions asm = AssemblerOptions.None;
if (force32Bit) {
compiler |= CSharpCompilerOptions.Force32Bit;
compiler |= CompilerOptions.Force32Bit;
asm |= AssemblerOptions.Force32Bit;
}
RunIL("BitNot.il", compiler, asm);
@ -217,79 +223,79 @@ namespace ICSharpCode.Decompiler.Tests @@ -217,79 +223,79 @@ namespace ICSharpCode.Decompiler.Tests
[Test]
public void StackTypes([Values(false, true)] bool force32Bit)
{
CSharpCompilerOptions compiler = CSharpCompilerOptions.UseRoslyn | CSharpCompilerOptions.UseDebug;
CompilerOptions compiler = CompilerOptions.UseRoslyn | CompilerOptions.UseDebug;
AssemblerOptions asm = AssemblerOptions.None;
if (force32Bit) {
compiler |= CSharpCompilerOptions.Force32Bit;
compiler |= CompilerOptions.Force32Bit;
asm |= AssemblerOptions.Force32Bit;
}
RunIL("StackTypes.il", compiler, asm);
}
[Test]
public void UnsafeCode([ValueSource("defaultOptions")] CSharpCompilerOptions options)
public void UnsafeCode([ValueSource("defaultOptions")] CompilerOptions options)
{
if (options.HasFlag(CSharpCompilerOptions.UseMcs)) {
if (options.HasFlag(CompilerOptions.UseMcs)) {
Assert.Ignore("Decompiler bug with mono!");
}
RunCS(options: options);
}
[Test]
public void ConditionalAttr([ValueSource("defaultOptions")] CSharpCompilerOptions options)
public void ConditionalAttr([ValueSource("defaultOptions")] CompilerOptions options)
{
RunCS(options: options);
}
[Test]
public void TrickyTypes([ValueSource("defaultOptions")] CSharpCompilerOptions options)
public void TrickyTypes([ValueSource("defaultOptions")] CompilerOptions options)
{
RunCS(options: options);
}
[Test]
public void Capturing([ValueSource("defaultOptions")] CSharpCompilerOptions options)
public void Capturing([ValueSource("defaultOptions")] CompilerOptions options)
{
RunCS(options: options);
}
[Test]
public void YieldReturn([ValueSource("defaultOptions")] CSharpCompilerOptions options)
public void YieldReturn([ValueSource("defaultOptions")] CompilerOptions options)
{
if (options.HasFlag(CSharpCompilerOptions.UseMcs)) {
if (options.HasFlag(CompilerOptions.UseMcs)) {
Assert.Ignore("Decompiler bug with mono!");
}
RunCS(options: options);
}
[Test]
public void Async([ValueSource("noMonoOptions")] CSharpCompilerOptions options)
public void Async([ValueSource("noMonoOptions")] CompilerOptions options)
{
RunCS(options: options);
}
[Test]
public void LINQRaytracer([ValueSource("defaultOptions")] CSharpCompilerOptions options)
public void LINQRaytracer([ValueSource("defaultOptions")] CompilerOptions options)
{
RunCS(options: options);
}
[Test]
public void MiniJSON([ValueSource("defaultOptions")] CSharpCompilerOptions options)
public void MiniJSON([ValueSource("defaultOptions")] CompilerOptions options)
{
if (options.HasFlag(CSharpCompilerOptions.UseMcs)) {
if (options.HasFlag(CompilerOptions.UseMcs)) {
Assert.Ignore("Decompiler bug with mono!");
}
RunCS(options: options);
}
[Test]
public void LocalFunctions([ValueSource(nameof(roslynOnlyOptions))] CSharpCompilerOptions options)
public void LocalFunctions([ValueSource(nameof(roslynOnlyOptions))] CompilerOptions options)
{
RunCS(options: options);
}
void RunCS([CallerMemberName] string testName = null, CSharpCompilerOptions options = CSharpCompilerOptions.UseDebug)
void RunCS([CallerMemberName] string testName = null, CompilerOptions options = CompilerOptions.UseDebug)
{
string testFileName = testName + ".cs";
string testOutputFileName = testName + Tester.GetSuffix(options) + ".exe";
@ -299,12 +305,12 @@ namespace ICSharpCode.Decompiler.Tests @@ -299,12 +305,12 @@ namespace ICSharpCode.Decompiler.Tests
outputFile = Tester.CompileCSharp(Path.Combine(TestCasePath, testFileName), options,
outputFileName: Path.Combine(TestCasePath, testOutputFileName));
string decompiledCodeFile = Tester.DecompileCSharp(outputFile.PathToAssembly, Tester.GetSettings(options));
if (options.HasFlag(CSharpCompilerOptions.UseMcs)) {
if (options.HasFlag(CompilerOptions.UseMcs)) {
// For second pass, use roslyn instead of mcs.
// mcs has some compiler bugs that cause it to not accept ILSpy-generated code,
// for example when there's unreachable code due to other compiler bugs in the first mcs run.
options &= ~CSharpCompilerOptions.UseMcs;
options |= CSharpCompilerOptions.UseRoslyn;
options &= ~CompilerOptions.UseMcs;
options |= CompilerOptions.UseRoslyn;
// Also, add an .exe.config so that we consistently use the .NET 4.x runtime.
File.WriteAllText(outputFile.PathToAssembly + ".config", @"<?xml version=""1.0"" encoding=""utf-8""?>
<configuration>
@ -327,7 +333,31 @@ namespace ICSharpCode.Decompiler.Tests @@ -327,7 +333,31 @@ namespace ICSharpCode.Decompiler.Tests
}
}
void RunIL(string testFileName, CSharpCompilerOptions options = CSharpCompilerOptions.UseDebug, AssemblerOptions asmOptions = AssemblerOptions.None)
void RunVB([CallerMemberName] string testName = null, CompilerOptions options = CompilerOptions.UseDebug)
{
string testFileName = testName + ".vb";
string testOutputFileName = testName + Tester.GetSuffix(options) + ".exe";
CompilerResults outputFile = null, decompiledOutputFile = null;
try {
outputFile = Tester.CompileVB(Path.Combine(TestCasePath, testFileName), options,
outputFileName: Path.Combine(TestCasePath, testOutputFileName));
string decompiledCodeFile = Tester.DecompileCSharp(outputFile.PathToAssembly, Tester.GetSettings(options));
decompiledOutputFile = Tester.CompileCSharp(decompiledCodeFile, options);
Tester.RunAndCompareOutput(testFileName, outputFile.PathToAssembly, decompiledOutputFile.PathToAssembly, decompiledCodeFile);
File.Delete(decompiledCodeFile);
File.Delete(decompiledOutputFile.PathToAssembly);
} finally {
if (outputFile != null)
outputFile.TempFiles.Delete();
if (decompiledOutputFile != null)
decompiledOutputFile.TempFiles.Delete();
}
}
void RunIL(string testFileName, CompilerOptions options = CompilerOptions.UseDebug, AssemblerOptions asmOptions = AssemblerOptions.None)
{
string outputFile = null;
CompilerResults decompiledOutputFile = null;

74
ICSharpCode.Decompiler.Tests/Helpers/Tester.VB.cs

@ -12,71 +12,26 @@ using Microsoft.VisualBasic; @@ -12,71 +12,26 @@ using Microsoft.VisualBasic;
namespace ICSharpCode.Decompiler.Tests.Helpers
{
[Flags]
public enum VBCompilerOptions
{
None,
Optimize = 0x1,
UseDebug = 0x2,
Force32Bit = 0x4,
Library = 0x8,
UseRoslyn = 0x10,
}
partial class Tester
{
internal static string GetSuffix(VBCompilerOptions vbcOptions)
{
string suffix = "";
if ((vbcOptions & VBCompilerOptions.Optimize) != 0)
suffix += ".opt";
if ((vbcOptions & VBCompilerOptions.Force32Bit) != 0)
suffix += ".32";
if ((vbcOptions & VBCompilerOptions.UseDebug) != 0)
suffix += ".dbg";
if ((vbcOptions & VBCompilerOptions.UseRoslyn) != 0)
suffix += ".roslyn";
return suffix;
}
public static List<KeyValuePair<string, object>> GetPreprocessorSymbols(VBCompilerOptions flags)
{
var preprocessorSymbols = new List<KeyValuePair<string, object>>();
if (flags.HasFlag(VBCompilerOptions.UseDebug)) {
preprocessorSymbols.Add(new KeyValuePair<string, object>("DEBUG", 1));
}
if (flags.HasFlag(VBCompilerOptions.Optimize)) {
preprocessorSymbols.Add(new KeyValuePair<string, object>("OPT", 1));
}
if (flags.HasFlag(VBCompilerOptions.UseRoslyn)) {
preprocessorSymbols.Add(new KeyValuePair<string, object>("ROSLYN", 1));
preprocessorSymbols.Add(new KeyValuePair<string, object>("VB11", 1));
preprocessorSymbols.Add(new KeyValuePair<string, object>("VB14", 1));
preprocessorSymbols.Add(new KeyValuePair<string, object>("VB15", 1));
} else {
preprocessorSymbols.Add(new KeyValuePair<string, object>("LEGACY_VBC", 1));
}
return preprocessorSymbols;
}
public static CompilerResults CompileVB(string sourceFileName, VBCompilerOptions flags = VBCompilerOptions.UseDebug, string outputFileName = null)
public static CompilerResults CompileVB(string sourceFileName, CompilerOptions flags = CompilerOptions.UseDebug, string outputFileName = null)
{
List<string> sourceFileNames = new List<string> { sourceFileName };
foreach (Match match in Regex.Matches(File.ReadAllText(sourceFileName), @"#include ""([\w\d./]+)""")) {
sourceFileNames.Add(Path.GetFullPath(Path.Combine(Path.GetDirectoryName(sourceFileName), match.Groups[1].Value)));
}
var preprocessorSymbols = GetPreprocessorSymbols(flags);
var preprocessorSymbols = GetPreprocessorSymbols(flags).Select(symbol => new KeyValuePair<string, object>(symbol, 1)).ToList();
if (flags.HasFlag(VBCompilerOptions.UseRoslyn)) {
if (flags.HasFlag(CompilerOptions.UseRoslyn)) {
var parseOptions = new VisualBasicParseOptions(preprocessorSymbols: preprocessorSymbols, languageVersion: LanguageVersion.Latest);
var syntaxTrees = sourceFileNames.Select(f => SyntaxFactory.ParseSyntaxTree(File.ReadAllText(f), parseOptions, path: f));
var compilation = VisualBasicCompilation.Create(Path.GetFileNameWithoutExtension(sourceFileName),
syntaxTrees, defaultReferences.Value,
new VisualBasicCompilationOptions(
flags.HasFlag(VBCompilerOptions.Library) ? OutputKind.DynamicallyLinkedLibrary : OutputKind.ConsoleApplication,
platform: flags.HasFlag(VBCompilerOptions.Force32Bit) ? Platform.X86 : Platform.AnyCpu,
optimizationLevel: flags.HasFlag(VBCompilerOptions.Optimize) ? OptimizationLevel.Release : OptimizationLevel.Debug,
flags.HasFlag(CompilerOptions.Library) ? OutputKind.DynamicallyLinkedLibrary : OutputKind.ConsoleApplication,
platform: flags.HasFlag(CompilerOptions.Force32Bit) ? Platform.X86 : Platform.AnyCpu,
optimizationLevel: flags.HasFlag(CompilerOptions.Optimize) ? OptimizationLevel.Release : OptimizationLevel.Debug,
deterministic: true
));
CompilerResults results = new CompilerResults(new TempFileCollection());
@ -90,15 +45,18 @@ namespace ICSharpCode.Decompiler.Tests.Helpers @@ -90,15 +45,18 @@ namespace ICSharpCode.Decompiler.Tests.Helpers
throw new Exception(b.ToString());
}
return results;
} else if (flags.HasFlag(CompilerOptions.UseMcs)) {
throw new NotSupportedException("Cannot use mcs for VB");
} else {
var provider = new VBCodeProvider(new Dictionary<string, string> { { "CompilerVersion", "v10.0" } });
var provider = new VBCodeProvider(new Dictionary<string, string> { { "CompilerVersion", "v4.0" } });
CompilerParameters options = new CompilerParameters();
options.GenerateExecutable = !flags.HasFlag(VBCompilerOptions.Library);
options.CompilerOptions = "/o" + (flags.HasFlag(VBCompilerOptions.Optimize) ? "+" : "-");
options.CompilerOptions += (flags.HasFlag(VBCompilerOptions.UseDebug) ? " /debug" : "");
options.CompilerOptions += (flags.HasFlag(VBCompilerOptions.Force32Bit) ? " /platform:anycpu32bitpreferred" : "");
options.GenerateExecutable = !flags.HasFlag(CompilerOptions.Library);
options.CompilerOptions = "/o" + (flags.HasFlag(CompilerOptions.Optimize) ? "+" : "-");
options.CompilerOptions += (flags.HasFlag(CompilerOptions.UseDebug) ? " /debug" : "");
options.CompilerOptions += (flags.HasFlag(CompilerOptions.Force32Bit) ? " /platform:anycpu32bitpreferred" : "");
options.CompilerOptions += "/optioninfer+ /optionexplicit+";
if (preprocessorSymbols.Count > 0) {
options.CompilerOptions += " /d:" + string.Join(";", preprocessorSymbols);
options.CompilerOptions += " /d:" + string.Join(",", preprocessorSymbols.Select(p => $"{p.Key}={p.Value}"));
}
if (outputFileName != null) {
options.OutputAssembly = outputFileName;
@ -107,6 +65,7 @@ namespace ICSharpCode.Decompiler.Tests.Helpers @@ -107,6 +65,7 @@ namespace ICSharpCode.Decompiler.Tests.Helpers
options.ReferencedAssemblies.Add("System.dll");
options.ReferencedAssemblies.Add("System.Core.dll");
options.ReferencedAssemblies.Add("System.Xml.dll");
options.ReferencedAssemblies.Add("Microsoft.VisualBasic.dll");
CompilerResults results = provider.CompileAssemblyFromFile(options, sourceFileNames.ToArray());
if (results.Errors.Cast<CompilerError>().Any(e => !e.IsWarning)) {
StringBuilder b = new StringBuilder("Compiler error:");
@ -118,6 +77,5 @@ namespace ICSharpCode.Decompiler.Tests.Helpers @@ -118,6 +77,5 @@ namespace ICSharpCode.Decompiler.Tests.Helpers
return results;
}
}
}
}

64
ICSharpCode.Decompiler.Tests/Helpers/Tester.cs

@ -42,7 +42,7 @@ using NUnit.Framework; @@ -42,7 +42,7 @@ using NUnit.Framework;
namespace ICSharpCode.Decompiler.Tests.Helpers
{
[Flags]
public enum CSharpCompilerOptions
public enum CompilerOptions
{
None,
Optimize = 0x1,
@ -189,36 +189,41 @@ namespace ICSharpCode.Decompiler.Tests.Helpers @@ -189,36 +189,41 @@ namespace ICSharpCode.Decompiler.Tests.Helpers
MetadataReference.CreateFromFile(Path.Combine(refAsmPath, @"Facades\System.Runtime.dll")),
MetadataReference.CreateFromFile(Path.Combine(refAsmPath, "System.Xml.dll")),
MetadataReference.CreateFromFile(Path.Combine(refAsmPath, "Microsoft.CSharp.dll")),
MetadataReference.CreateFromFile(Path.Combine(refAsmPath, "Microsoft.VisualBasic.dll")),
MetadataReference.CreateFromFile(typeof(ValueTuple).Assembly.Location),
MetadataReference.CreateFromFile(typeof(Span<>).Assembly.Location),
};
});
public static List<string> GetPreprocessorSymbols(CSharpCompilerOptions flags)
public static List<string> GetPreprocessorSymbols(CompilerOptions flags)
{
var preprocessorSymbols = new List<string>();
if (flags.HasFlag(CSharpCompilerOptions.UseDebug)) {
if (flags.HasFlag(CompilerOptions.UseDebug)) {
preprocessorSymbols.Add("DEBUG");
}
if (flags.HasFlag(CSharpCompilerOptions.Optimize)) {
if (flags.HasFlag(CompilerOptions.Optimize)) {
preprocessorSymbols.Add("OPT");
}
if (flags.HasFlag(CSharpCompilerOptions.UseRoslyn)) {
if (flags.HasFlag(CompilerOptions.UseRoslyn)) {
preprocessorSymbols.Add("ROSLYN");
preprocessorSymbols.Add("CS60");
preprocessorSymbols.Add("CS70");
preprocessorSymbols.Add("CS71");
preprocessorSymbols.Add("CS72");
} else if (flags.HasFlag(CSharpCompilerOptions.UseMcs)) {
preprocessorSymbols.Add("CS73");
preprocessorSymbols.Add("VB11");
preprocessorSymbols.Add("VB14");
preprocessorSymbols.Add("VB15");
} else if (flags.HasFlag(CompilerOptions.UseMcs)) {
preprocessorSymbols.Add("MCS");
} else {
preprocessorSymbols.Add("LEGACY_CSC");
preprocessorSymbols.Add("LEGACY_VBC");
}
return preprocessorSymbols;
}
public static CompilerResults CompileCSharp(string sourceFileName, CSharpCompilerOptions flags = CSharpCompilerOptions.UseDebug, string outputFileName = null)
public static CompilerResults CompileCSharp(string sourceFileName, CompilerOptions flags = CompilerOptions.UseDebug, string outputFileName = null)
{
List<string> sourceFileNames = new List<string> { sourceFileName };
foreach (Match match in Regex.Matches(File.ReadAllText(sourceFileName), @"#include ""([\w\d./]+)""")) {
@ -227,15 +232,15 @@ namespace ICSharpCode.Decompiler.Tests.Helpers @@ -227,15 +232,15 @@ namespace ICSharpCode.Decompiler.Tests.Helpers
var preprocessorSymbols = GetPreprocessorSymbols(flags);
if (flags.HasFlag(CSharpCompilerOptions.UseRoslyn)) {
if (flags.HasFlag(CompilerOptions.UseRoslyn)) {
var parseOptions = new CSharpParseOptions(preprocessorSymbols: preprocessorSymbols.ToArray(), languageVersion: Microsoft.CodeAnalysis.CSharp.LanguageVersion.Latest);
var syntaxTrees = sourceFileNames.Select(f => SyntaxFactory.ParseSyntaxTree(File.ReadAllText(f), parseOptions, path: f));
var compilation = CSharpCompilation.Create(Path.GetFileNameWithoutExtension(sourceFileName),
syntaxTrees, defaultReferences.Value,
new CSharpCompilationOptions(
flags.HasFlag(CSharpCompilerOptions.Library) ? OutputKind.DynamicallyLinkedLibrary : OutputKind.ConsoleApplication,
platform: flags.HasFlag(CSharpCompilerOptions.Force32Bit) ? Platform.X86 : Platform.AnyCpu,
optimizationLevel: flags.HasFlag(CSharpCompilerOptions.Optimize) ? OptimizationLevel.Release : OptimizationLevel.Debug,
flags.HasFlag(CompilerOptions.Library) ? OutputKind.DynamicallyLinkedLibrary : OutputKind.ConsoleApplication,
platform: flags.HasFlag(CompilerOptions.Force32Bit) ? Platform.X86 : Platform.AnyCpu,
optimizationLevel: flags.HasFlag(CompilerOptions.Optimize) ? OptimizationLevel.Release : OptimizationLevel.Debug,
allowUnsafe: true,
deterministic: true
));
@ -250,7 +255,7 @@ namespace ICSharpCode.Decompiler.Tests.Helpers @@ -250,7 +255,7 @@ namespace ICSharpCode.Decompiler.Tests.Helpers
throw new Exception(b.ToString());
}
return results;
} else if (flags.HasFlag(CSharpCompilerOptions.UseMcs)) {
} else if (flags.HasFlag(CompilerOptions.UseMcs)) {
CompilerResults results = new CompilerResults(new TempFileCollection());
results.PathToAssembly = outputFileName ?? Path.GetTempFileName();
string testBasePath = RoundtripAssembly.TestDir;
@ -259,19 +264,19 @@ namespace ICSharpCode.Decompiler.Tests.Helpers @@ -259,19 +264,19 @@ namespace ICSharpCode.Decompiler.Tests.Helpers
$"git clone https://github.com/icsharpcode/ILSpy-tests \"{testBasePath}\"");
}
string mcsPath = Path.Combine(testBasePath, @"mcs\2.6.4\bin\gmcs.bat");
string otherOptions = " -unsafe -o" + (flags.HasFlag(CSharpCompilerOptions.Optimize) ? "+ " : "- ");
string otherOptions = " -unsafe -o" + (flags.HasFlag(CompilerOptions.Optimize) ? "+ " : "- ");
if (flags.HasFlag(CSharpCompilerOptions.Library)) {
if (flags.HasFlag(CompilerOptions.Library)) {
otherOptions += "-t:library ";
} else {
otherOptions += "-t:exe ";
}
if (flags.HasFlag(CSharpCompilerOptions.UseDebug)) {
if (flags.HasFlag(CompilerOptions.UseDebug)) {
otherOptions += "-g ";
}
if (flags.HasFlag(CSharpCompilerOptions.Force32Bit)) {
if (flags.HasFlag(CompilerOptions.Force32Bit)) {
otherOptions += "-platform:x86 ";
} else {
otherOptions += "-platform:anycpu ";
@ -303,10 +308,10 @@ namespace ICSharpCode.Decompiler.Tests.Helpers @@ -303,10 +308,10 @@ namespace ICSharpCode.Decompiler.Tests.Helpers
} else {
var provider = new CSharpCodeProvider(new Dictionary<string, string> { { "CompilerVersion", "v4.0" } });
CompilerParameters options = new CompilerParameters();
options.GenerateExecutable = !flags.HasFlag(CSharpCompilerOptions.Library);
options.CompilerOptions = "/unsafe /o" + (flags.HasFlag(CSharpCompilerOptions.Optimize) ? "+" : "-");
options.CompilerOptions += (flags.HasFlag(CSharpCompilerOptions.UseDebug) ? " /debug" : "");
options.CompilerOptions += (flags.HasFlag(CSharpCompilerOptions.Force32Bit) ? " /platform:anycpu32bitpreferred" : "");
options.GenerateExecutable = !flags.HasFlag(CompilerOptions.Library);
options.CompilerOptions = "/unsafe /o" + (flags.HasFlag(CompilerOptions.Optimize) ? "+" : "-");
options.CompilerOptions += (flags.HasFlag(CompilerOptions.UseDebug) ? " /debug" : "");
options.CompilerOptions += (flags.HasFlag(CompilerOptions.Force32Bit) ? " /platform:anycpu32bitpreferred" : "");
if (preprocessorSymbols.Count > 0) {
options.CompilerOptions += " /d:" + string.Join(";", preprocessorSymbols);
}
@ -318,6 +323,7 @@ namespace ICSharpCode.Decompiler.Tests.Helpers @@ -318,6 +323,7 @@ namespace ICSharpCode.Decompiler.Tests.Helpers
options.ReferencedAssemblies.Add("System.Core.dll");
options.ReferencedAssemblies.Add("System.Xml.dll");
options.ReferencedAssemblies.Add("Microsoft.CSharp.dll");
options.ReferencedAssemblies.Add("Microsoft.VisualBasic.dll");
CompilerResults results = provider.CompileAssemblyFromFile(options, sourceFileNames.ToArray());
if (results.Errors.Cast<CompilerError>().Any(e => !e.IsWarning)) {
StringBuilder b = new StringBuilder("Compiler error:");
@ -330,9 +336,9 @@ namespace ICSharpCode.Decompiler.Tests.Helpers @@ -330,9 +336,9 @@ namespace ICSharpCode.Decompiler.Tests.Helpers
}
}
internal static DecompilerSettings GetSettings(CSharpCompilerOptions cscOptions)
internal static DecompilerSettings GetSettings(CompilerOptions cscOptions)
{
if (cscOptions.HasFlag(CSharpCompilerOptions.UseRoslyn)) {
if (cscOptions.HasFlag(CompilerOptions.UseRoslyn)) {
return new DecompilerSettings(CSharp.LanguageVersion.Latest);
} else {
return new DecompilerSettings(CSharp.LanguageVersion.CSharp5);
@ -358,18 +364,18 @@ namespace ICSharpCode.Decompiler.Tests.Helpers @@ -358,18 +364,18 @@ namespace ICSharpCode.Decompiler.Tests.Helpers
return decompiler;
}
internal static string GetSuffix(CSharpCompilerOptions cscOptions)
internal static string GetSuffix(CompilerOptions cscOptions)
{
string suffix = "";
if ((cscOptions & CSharpCompilerOptions.Optimize) != 0)
if ((cscOptions & CompilerOptions.Optimize) != 0)
suffix += ".opt";
if ((cscOptions & CSharpCompilerOptions.Force32Bit) != 0)
if ((cscOptions & CompilerOptions.Force32Bit) != 0)
suffix += ".32";
if ((cscOptions & CSharpCompilerOptions.UseDebug) != 0)
if ((cscOptions & CompilerOptions.UseDebug) != 0)
suffix += ".dbg";
if ((cscOptions & CSharpCompilerOptions.UseRoslyn) != 0)
if ((cscOptions & CompilerOptions.UseRoslyn) != 0)
suffix += ".roslyn";
if ((cscOptions & CSharpCompilerOptions.UseMcs) != 0)
if ((cscOptions & CompilerOptions.UseMcs) != 0)
suffix += ".mcs";
return suffix;
}

3
ICSharpCode.Decompiler.Tests/ICSharpCode.Decompiler.Tests.csproj

@ -2,7 +2,7 @@ @@ -2,7 +2,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net46</TargetFramework>
<TargetFramework>net462</TargetFramework>
<LangVersion>7.3</LangVersion>
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
@ -52,6 +52,7 @@ @@ -52,6 +52,7 @@
<ItemGroup>
<None Include="TestCases\Correctness\Jmp.il" />
<None Include="TestCases\Correctness\StackTypes.il" />
<None Include="TestCases\Correctness\Uninit.vb" />
<None Include="TestCases\ILPretty\FSharpLoops.fs" />
<None Include="TestCases\ILPretty\FSharpLoops_Debug.il" />
<None Include="TestCases\ILPretty\FSharpLoops_Release.il" />

148
ICSharpCode.Decompiler.Tests/PrettyTestRunner.cs

@ -47,34 +47,34 @@ namespace ICSharpCode.Decompiler.Tests @@ -47,34 +47,34 @@ namespace ICSharpCode.Decompiler.Tests
}
}
static readonly CSharpCompilerOptions[] noRoslynOptions =
static readonly CompilerOptions[] noRoslynOptions =
{
CSharpCompilerOptions.None,
CSharpCompilerOptions.Optimize
CompilerOptions.None,
CompilerOptions.Optimize
};
static readonly CSharpCompilerOptions[] roslynOnlyOptions =
static readonly CompilerOptions[] roslynOnlyOptions =
{
CSharpCompilerOptions.UseRoslyn,
CSharpCompilerOptions.Optimize | CSharpCompilerOptions.UseRoslyn
CompilerOptions.UseRoslyn,
CompilerOptions.Optimize | CompilerOptions.UseRoslyn
};
static readonly CSharpCompilerOptions[] defaultOptions =
static readonly CompilerOptions[] defaultOptions =
{
CSharpCompilerOptions.None,
CSharpCompilerOptions.Optimize,
CSharpCompilerOptions.UseRoslyn,
CSharpCompilerOptions.Optimize | CSharpCompilerOptions.UseRoslyn
CompilerOptions.None,
CompilerOptions.Optimize,
CompilerOptions.UseRoslyn,
CompilerOptions.Optimize | CompilerOptions.UseRoslyn
};
static readonly CSharpCompilerOptions[] defaultOptionsWithMcs =
static readonly CompilerOptions[] defaultOptionsWithMcs =
{
CSharpCompilerOptions.None,
CSharpCompilerOptions.Optimize,
CSharpCompilerOptions.UseRoslyn,
CSharpCompilerOptions.Optimize | CSharpCompilerOptions.UseRoslyn,
CSharpCompilerOptions.UseMcs,
CSharpCompilerOptions.Optimize | CSharpCompilerOptions.UseMcs
CompilerOptions.None,
CompilerOptions.Optimize,
CompilerOptions.UseRoslyn,
CompilerOptions.Optimize | CompilerOptions.UseRoslyn,
CompilerOptions.UseMcs,
CompilerOptions.Optimize | CompilerOptions.UseMcs
};
[Test]
@ -85,316 +85,316 @@ namespace ICSharpCode.Decompiler.Tests @@ -85,316 +85,316 @@ namespace ICSharpCode.Decompiler.Tests
}
[Test]
public void InlineAssignmentTest([ValueSource(nameof(defaultOptions))] CSharpCompilerOptions cscOptions)
public void InlineAssignmentTest([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions)
{
RunForLibrary(cscOptions: cscOptions);
}
[Test]
public void CompoundAssignmentTest([ValueSource(nameof(defaultOptions))] CSharpCompilerOptions cscOptions)
public void CompoundAssignmentTest([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions)
{
RunForLibrary(cscOptions: cscOptions);
}
[Test]
public void ShortCircuit([ValueSource(nameof(defaultOptions))] CSharpCompilerOptions cscOptions)
public void ShortCircuit([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions)
{
RunForLibrary(cscOptions: cscOptions);
}
[Test]
public void CustomShortCircuitOperators([ValueSource(nameof(defaultOptions))] CSharpCompilerOptions cscOptions)
public void CustomShortCircuitOperators([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions)
{
RunForLibrary(cscOptions: cscOptions);
}
[Test]
public void ExceptionHandling([ValueSource(nameof(defaultOptions))] CSharpCompilerOptions cscOptions)
public void ExceptionHandling([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions)
{
RunForLibrary(cscOptions: cscOptions, decompilerSettings: new DecompilerSettings {
NullPropagation = false,
// legacy csc generates a dead store in debug builds
RemoveDeadCode = (cscOptions == CSharpCompilerOptions.None)
RemoveDeadCode = (cscOptions == CompilerOptions.None)
});
}
[Test]
public void Switch([ValueSource(nameof(defaultOptions))] CSharpCompilerOptions cscOptions)
public void Switch([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions)
{
RunForLibrary(cscOptions: cscOptions, decompilerSettings: new DecompilerSettings {
// legacy csc generates a dead store in debug builds
RemoveDeadCode = (cscOptions == CSharpCompilerOptions.None)
RemoveDeadCode = (cscOptions == CompilerOptions.None)
});
}
[Test]
public void ReduceNesting([ValueSource(nameof(defaultOptions))] CSharpCompilerOptions cscOptions)
public void ReduceNesting([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions)
{
RunForLibrary(cscOptions: cscOptions);
}
[Test]
public void DelegateConstruction([ValueSource(nameof(defaultOptions))] CSharpCompilerOptions cscOptions)
public void DelegateConstruction([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions)
{
RunForLibrary(cscOptions: cscOptions);
}
[Test]
public void AnonymousTypes([ValueSource(nameof(defaultOptionsWithMcs))] CSharpCompilerOptions cscOptions)
public void AnonymousTypes([ValueSource(nameof(defaultOptionsWithMcs))] CompilerOptions cscOptions)
{
RunForLibrary(cscOptions: cscOptions);
}
[Test]
public void Async([ValueSource(nameof(defaultOptions))] CSharpCompilerOptions cscOptions)
public void Async([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions)
{
RunForLibrary(cscOptions: cscOptions);
}
[Test]
public void Lock([ValueSource(nameof(defaultOptionsWithMcs))] CSharpCompilerOptions cscOptions)
public void Lock([ValueSource(nameof(defaultOptionsWithMcs))] CompilerOptions cscOptions)
{
RunForLibrary(cscOptions: cscOptions);
}
[Test]
public void Using([ValueSource(nameof(defaultOptions))] CSharpCompilerOptions cscOptions)
public void Using([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions)
{
RunForLibrary(cscOptions: cscOptions);
}
[Test]
public void LiftedOperators([ValueSource(nameof(defaultOptions))] CSharpCompilerOptions cscOptions)
public void LiftedOperators([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions)
{
RunForLibrary(cscOptions: cscOptions);
}
[Test]
public void Generics([ValueSource(nameof(defaultOptions))] CSharpCompilerOptions cscOptions)
public void Generics([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions)
{
RunForLibrary(cscOptions: cscOptions);
}
[Test]
public void Loops([ValueSource(nameof(defaultOptionsWithMcs))] CSharpCompilerOptions cscOptions)
public void Loops([ValueSource(nameof(defaultOptionsWithMcs))] CompilerOptions cscOptions)
{
RunForLibrary(cscOptions: cscOptions, decompilerSettings: new DecompilerSettings {
// legacy csc generates a dead store in debug builds
RemoveDeadCode = (cscOptions == CSharpCompilerOptions.None)
RemoveDeadCode = (cscOptions == CompilerOptions.None)
});
}
[Test]
public void PropertiesAndEvents([ValueSource(nameof(defaultOptions))] CSharpCompilerOptions cscOptions)
public void PropertiesAndEvents([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions)
{
RunForLibrary(cscOptions: cscOptions);
}
[Test]
public void AutoProperties([ValueSource(nameof(roslynOnlyOptions))] CSharpCompilerOptions cscOptions)
public void AutoProperties([ValueSource(nameof(roslynOnlyOptions))] CompilerOptions cscOptions)
{
RunForLibrary(cscOptions: cscOptions);
}
[Test]
public void QueryExpressions([ValueSource(nameof(defaultOptions))] CSharpCompilerOptions cscOptions)
public void QueryExpressions([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions)
{
RunForLibrary(cscOptions: cscOptions);
}
[Test]
public void TypeAnalysisTests([ValueSource(nameof(defaultOptions))] CSharpCompilerOptions cscOptions)
public void TypeAnalysisTests([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions)
{
RunForLibrary(cscOptions: cscOptions);
}
[Test]
public void CheckedUnchecked([ValueSource(nameof(defaultOptions))] CSharpCompilerOptions cscOptions)
public void CheckedUnchecked([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions)
{
RunForLibrary(cscOptions: cscOptions);
}
[Test]
public void UnsafeCode([ValueSource(nameof(defaultOptions))] CSharpCompilerOptions cscOptions)
public void UnsafeCode([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions)
{
RunForLibrary(cscOptions: cscOptions);
}
[Test]
public void ConstructorInitializers([ValueSource(nameof(defaultOptionsWithMcs))] CSharpCompilerOptions cscOptions)
public void ConstructorInitializers([ValueSource(nameof(defaultOptionsWithMcs))] CompilerOptions cscOptions)
{
RunForLibrary(cscOptions: cscOptions);
}
[Test]
public void PInvoke([ValueSource(nameof(defaultOptions))] CSharpCompilerOptions cscOptions)
public void PInvoke([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions)
{
// This tests needs our own disassembler; ildasm has a bug with marshalinfo.
RunForLibrary(cscOptions: cscOptions, asmOptions: AssemblerOptions.UseOwnDisassembler);
}
[Test]
public void InitializerTests([ValueSource(nameof(defaultOptions))] CSharpCompilerOptions cscOptions)
public void InitializerTests([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions)
{
RunForLibrary(cscOptions: cscOptions);
}
[Test]
public void DynamicTests([ValueSource(nameof(defaultOptions))] CSharpCompilerOptions cscOptions)
public void DynamicTests([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions)
{
RunForLibrary(cscOptions: cscOptions);
}
[Test]
public void ExpressionTrees([ValueSource(nameof(defaultOptions))] CSharpCompilerOptions cscOptions)
public void ExpressionTrees([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions)
{
RunForLibrary(cscOptions: cscOptions);
}
[Test]
public void FixProxyCalls([Values(CSharpCompilerOptions.None, CSharpCompilerOptions.Optimize, CSharpCompilerOptions.UseRoslyn)] CSharpCompilerOptions cscOptions)
public void FixProxyCalls([Values(CompilerOptions.None, CompilerOptions.Optimize, CompilerOptions.UseRoslyn)] CompilerOptions cscOptions)
{
RunForLibrary(cscOptions: cscOptions);
}
[Test]
public void VariableNaming([ValueSource(nameof(defaultOptions))] CSharpCompilerOptions cscOptions)
public void VariableNaming([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions)
{
RunForLibrary(cscOptions: cscOptions);
}
[Test]
public void VariableNamingWithoutSymbols([ValueSource(nameof(defaultOptions))] CSharpCompilerOptions cscOptions)
public void VariableNamingWithoutSymbols([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions)
{
RunForLibrary(cscOptions: cscOptions, decompilerSettings: new DecompilerSettings { UseDebugSymbols = false });
}
[Test]
public void CS72_PrivateProtected([ValueSource(nameof(roslynOnlyOptions))] CSharpCompilerOptions cscOptions)
public void CS72_PrivateProtected([ValueSource(nameof(roslynOnlyOptions))] CompilerOptions cscOptions)
{
RunForLibrary(cscOptions: cscOptions);
}
[Test]
public void AsyncMain([ValueSource(nameof(roslynOnlyOptions))] CSharpCompilerOptions cscOptions)
public void AsyncMain([ValueSource(nameof(roslynOnlyOptions))] CompilerOptions cscOptions)
{
Run(cscOptions: cscOptions);
}
[Test]
public void NullPropagation([ValueSource(nameof(roslynOnlyOptions))] CSharpCompilerOptions cscOptions)
public void NullPropagation([ValueSource(nameof(roslynOnlyOptions))] CompilerOptions cscOptions)
{
RunForLibrary(cscOptions: cscOptions);
}
[Test]
public void CS6_StringInterpolation([ValueSource(nameof(roslynOnlyOptions))] CSharpCompilerOptions cscOptions)
public void CS6_StringInterpolation([ValueSource(nameof(roslynOnlyOptions))] CompilerOptions cscOptions)
{
Run(cscOptions: cscOptions);
}
[Test]
public void CS73_StackAllocInitializers([ValueSource(nameof(roslynOnlyOptions))] CSharpCompilerOptions cscOptions)
public void CS73_StackAllocInitializers([ValueSource(nameof(roslynOnlyOptions))] CompilerOptions cscOptions)
{
RunForLibrary(cscOptions: cscOptions);
}
[Test]
public void RefLocalsAndReturns([ValueSource(nameof(roslynOnlyOptions))] CSharpCompilerOptions cscOptions)
public void RefLocalsAndReturns([ValueSource(nameof(roslynOnlyOptions))] CompilerOptions cscOptions)
{
RunForLibrary(cscOptions: cscOptions);
}
[Test]
public void WellKnownConstants([ValueSource(nameof(defaultOptions))] CSharpCompilerOptions cscOptions)
public void WellKnownConstants([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions)
{
RunForLibrary(cscOptions: cscOptions);
}
[Test]
public void QualifierTests([ValueSource(nameof(defaultOptions))] CSharpCompilerOptions cscOptions)
public void QualifierTests([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions)
{
RunForLibrary(cscOptions: cscOptions);
}
[Test]
public void TupleTests([ValueSource(nameof(roslynOnlyOptions))] CSharpCompilerOptions cscOptions)
public void TupleTests([ValueSource(nameof(roslynOnlyOptions))] CompilerOptions cscOptions)
{
RunForLibrary(cscOptions: cscOptions);
}
[Test]
public void NamedArguments([ValueSource(nameof(defaultOptions))] CSharpCompilerOptions cscOptions)
public void NamedArguments([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions)
{
RunForLibrary(cscOptions: cscOptions);
}
[Test]
public void OptionalArguments([ValueSource(nameof(defaultOptions))] CSharpCompilerOptions cscOptions)
public void OptionalArguments([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions)
{
RunForLibrary(cscOptions: cscOptions);
}
[Test]
public void ConstantsTests([ValueSource(nameof(defaultOptions))] CSharpCompilerOptions cscOptions)
public void ConstantsTests([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions)
{
RunForLibrary(cscOptions: cscOptions);
}
[Test]
public void Issue1080([ValueSource(nameof(roslynOnlyOptions))] CSharpCompilerOptions cscOptions)
public void Issue1080([ValueSource(nameof(roslynOnlyOptions))] CompilerOptions cscOptions)
{
RunForLibrary(cscOptions: cscOptions);
}
[Test]
public void AssemblyCustomAttributes([ValueSource(nameof(defaultOptions))] CSharpCompilerOptions cscOptions)
public void AssemblyCustomAttributes([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions)
{
RunForLibrary(cscOptions: cscOptions);
}
[Test]
public void CustomAttributes([ValueSource(nameof(defaultOptions))] CSharpCompilerOptions cscOptions)
public void CustomAttributes([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions)
{
RunForLibrary(cscOptions: cscOptions);
}
[Test]
public void CustomAttributeConflicts([ValueSource(nameof(defaultOptions))] CSharpCompilerOptions cscOptions)
public void CustomAttributeConflicts([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions)
{
RunForLibrary(cscOptions: cscOptions);
}
[Test]
public void CustomAttributeSamples([ValueSource(nameof(defaultOptions))] CSharpCompilerOptions cscOptions)
public void CustomAttributeSamples([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions)
{
RunForLibrary(cscOptions: cscOptions);
}
[Test]
public void MemberTests([ValueSource(nameof(defaultOptions))] CSharpCompilerOptions cscOptions)
public void MemberTests([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions)
{
RunForLibrary(cscOptions: cscOptions);
}
[Test]
public void TypeTests([ValueSource(nameof(defaultOptions))] CSharpCompilerOptions cscOptions)
public void TypeTests([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions)
{
RunForLibrary(cscOptions: cscOptions);
}
[Test]
public void YieldReturn([ValueSource(nameof(defaultOptions))] CSharpCompilerOptions cscOptions)
public void YieldReturn([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions)
{
RunForLibrary(cscOptions: cscOptions);
}
void RunForLibrary([CallerMemberName] string testName = null, AssemblerOptions asmOptions = AssemblerOptions.None, CSharpCompilerOptions cscOptions = CSharpCompilerOptions.None, DecompilerSettings decompilerSettings = null)
void RunForLibrary([CallerMemberName] string testName = null, AssemblerOptions asmOptions = AssemblerOptions.None, CompilerOptions cscOptions = CompilerOptions.None, DecompilerSettings decompilerSettings = null)
{
Run(testName, asmOptions | AssemblerOptions.Library, cscOptions | CSharpCompilerOptions.Library, decompilerSettings);
Run(testName, asmOptions | AssemblerOptions.Library, cscOptions | CompilerOptions.Library, decompilerSettings);
}
void Run([CallerMemberName] string testName = null, AssemblerOptions asmOptions = AssemblerOptions.None, CSharpCompilerOptions cscOptions = CSharpCompilerOptions.None, DecompilerSettings decompilerSettings = null)
void Run([CallerMemberName] string testName = null, AssemblerOptions asmOptions = AssemblerOptions.None, CompilerOptions cscOptions = CompilerOptions.None, DecompilerSettings decompilerSettings = null)
{
var ilFile = Path.Combine(TestCasePath, testName) + Tester.GetSuffix(cscOptions) + ".il";
var csFile = Path.Combine(TestCasePath, testName + ".cs");
@ -404,7 +404,7 @@ namespace ICSharpCode.Decompiler.Tests @@ -404,7 +404,7 @@ namespace ICSharpCode.Decompiler.Tests
CompilerResults output = null;
try {
string outputFile = Path.ChangeExtension(ilFile,
cscOptions.HasFlag(CSharpCompilerOptions.Library) ? ".dll" : ".exe");
cscOptions.HasFlag(CompilerOptions.Library) ? ".dll" : ".exe");
output = Tester.CompileCSharp(csFile, cscOptions, outputFile);
Tester.Disassemble(output.PathToAssembly, ilFile, asmOptions);
} finally {

21
ICSharpCode.Decompiler.Tests/TestCases/Correctness/Uninit.vb

@ -0,0 +1,21 @@ @@ -0,0 +1,21 @@
Imports System
Module UninitTest
Sub Main()
Dim i = 0
Dim result As Integer = -5
Dim num As Integer
Do
If num > result Then
num += 5
result += 5
End If
result += 1
i += 1
If i > 10 Then
Exit Do
End If
Loop
Console.WriteLine(result)
End Sub
End Module

15
ICSharpCode.Decompiler.Tests/TestCases/Pretty/Generics.cs

@ -16,6 +16,7 @@ @@ -16,6 +16,7 @@
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using System;
using System.Collections.Generic;
namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
{
@ -96,5 +97,19 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty @@ -96,5 +97,19 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
{
return new T[size1, size2];
}
public Type[] TestTypeOf()
{
return new Type[8] {
typeof(int),
typeof(int[]),
typeof(GenericClass<>),
typeof(GenericClass<int>),
typeof(GenericClass<int[]>),
typeof(Dictionary<, >),
typeof(List<int>.Enumerator),
typeof(List<>.Enumerator)
};
}
}
}

59
ICSharpCode.Decompiler.Tests/TestCases/Pretty/Generics.il

@ -304,6 +304,65 @@ @@ -304,6 +304,65 @@
IL_000c: ret
} // end of method Generics::NewArray
.method public hidebysig instance class [mscorlib]System.Type[]
TestTypeOf() cil managed
{
// Code size 118 (0x76)
.maxstack 3
.locals init (class [mscorlib]System.Type[] V_0,
class [mscorlib]System.Type[] V_1)
IL_0000: nop
IL_0001: ldc.i4.8
IL_0002: newarr [mscorlib]System.Type
IL_0007: stloc.1
IL_0008: ldloc.1
IL_0009: ldc.i4.0
IL_000a: ldtoken [mscorlib]System.Int32
IL_000f: call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle)
IL_0014: stelem.ref
IL_0015: ldloc.1
IL_0016: ldc.i4.1
IL_0017: ldtoken int32[]
IL_001c: call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle)
IL_0021: stelem.ref
IL_0022: ldloc.1
IL_0023: ldc.i4.2
IL_0024: ldtoken ICSharpCode.Decompiler.Tests.TestCases.Pretty.Generics/GenericClass`1
IL_0029: call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle)
IL_002e: stelem.ref
IL_002f: ldloc.1
IL_0030: ldc.i4.3
IL_0031: ldtoken class ICSharpCode.Decompiler.Tests.TestCases.Pretty.Generics/GenericClass`1<int32>
IL_0036: call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle)
IL_003b: stelem.ref
IL_003c: ldloc.1
IL_003d: ldc.i4.4
IL_003e: ldtoken class ICSharpCode.Decompiler.Tests.TestCases.Pretty.Generics/GenericClass`1<int32[]>
IL_0043: call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle)
IL_0048: stelem.ref
IL_0049: ldloc.1
IL_004a: ldc.i4.5
IL_004b: ldtoken [mscorlib]System.Collections.Generic.Dictionary`2
IL_0050: call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle)
IL_0055: stelem.ref
IL_0056: ldloc.1
IL_0057: ldc.i4.6
IL_0058: ldtoken valuetype [mscorlib]System.Collections.Generic.List`1/Enumerator<int32>
IL_005d: call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle)
IL_0062: stelem.ref
IL_0063: ldloc.1
IL_0064: ldc.i4.7
IL_0065: ldtoken [mscorlib]System.Collections.Generic.List`1/Enumerator
IL_006a: call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle)
IL_006f: stelem.ref
IL_0070: ldloc.1
IL_0071: stloc.0
IL_0072: br.s IL_0074
IL_0074: ldloc.0
IL_0075: ret
} // end of method Generics::TestTypeOf
.method public hidebysig specialname rtspecialname
instance void .ctor() cil managed
{

53
ICSharpCode.Decompiler.Tests/TestCases/Pretty/Generics.opt.il

@ -231,6 +231,59 @@ @@ -231,6 +231,59 @@
IL_0007: ret
} // end of method Generics::NewArray
.method public hidebysig instance class [mscorlib]System.Type[]
TestTypeOf() cil managed
{
// Code size 113 (0x71)
.maxstack 3
.locals init (class [mscorlib]System.Type[] V_0)
IL_0000: ldc.i4.8
IL_0001: newarr [mscorlib]System.Type
IL_0006: stloc.0
IL_0007: ldloc.0
IL_0008: ldc.i4.0
IL_0009: ldtoken [mscorlib]System.Int32
IL_000e: call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle)
IL_0013: stelem.ref
IL_0014: ldloc.0
IL_0015: ldc.i4.1
IL_0016: ldtoken int32[]
IL_001b: call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle)
IL_0020: stelem.ref
IL_0021: ldloc.0
IL_0022: ldc.i4.2
IL_0023: ldtoken ICSharpCode.Decompiler.Tests.TestCases.Pretty.Generics/GenericClass`1
IL_0028: call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle)
IL_002d: stelem.ref
IL_002e: ldloc.0
IL_002f: ldc.i4.3
IL_0030: ldtoken class ICSharpCode.Decompiler.Tests.TestCases.Pretty.Generics/GenericClass`1<int32>
IL_0035: call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle)
IL_003a: stelem.ref
IL_003b: ldloc.0
IL_003c: ldc.i4.4
IL_003d: ldtoken class ICSharpCode.Decompiler.Tests.TestCases.Pretty.Generics/GenericClass`1<int32[]>
IL_0042: call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle)
IL_0047: stelem.ref
IL_0048: ldloc.0
IL_0049: ldc.i4.5
IL_004a: ldtoken [mscorlib]System.Collections.Generic.Dictionary`2
IL_004f: call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle)
IL_0054: stelem.ref
IL_0055: ldloc.0
IL_0056: ldc.i4.6
IL_0057: ldtoken valuetype [mscorlib]System.Collections.Generic.List`1/Enumerator<int32>
IL_005c: call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle)
IL_0061: stelem.ref
IL_0062: ldloc.0
IL_0063: ldc.i4.7
IL_0064: ldtoken [mscorlib]System.Collections.Generic.List`1/Enumerator
IL_0069: call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle)
IL_006e: stelem.ref
IL_006f: ldloc.0
IL_0070: ret
} // end of method Generics::TestTypeOf
.method public hidebysig specialname rtspecialname
instance void .ctor() cil managed
{

50
ICSharpCode.Decompiler.Tests/TestCases/Pretty/Generics.opt.roslyn.il

@ -222,6 +222,56 @@ @@ -222,6 +222,56 @@
IL_0007: ret
} // end of method Generics::NewArray
.method public hidebysig instance class [mscorlib]System.Type[]
TestTypeOf() cil managed
{
// Code size 111 (0x6f)
.maxstack 4
IL_0000: ldc.i4.8
IL_0001: newarr [mscorlib]System.Type
IL_0006: dup
IL_0007: ldc.i4.0
IL_0008: ldtoken [mscorlib]System.Int32
IL_000d: call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle)
IL_0012: stelem.ref
IL_0013: dup
IL_0014: ldc.i4.1
IL_0015: ldtoken int32[]
IL_001a: call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle)
IL_001f: stelem.ref
IL_0020: dup
IL_0021: ldc.i4.2
IL_0022: ldtoken ICSharpCode.Decompiler.Tests.TestCases.Pretty.Generics/GenericClass`1
IL_0027: call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle)
IL_002c: stelem.ref
IL_002d: dup
IL_002e: ldc.i4.3
IL_002f: ldtoken class ICSharpCode.Decompiler.Tests.TestCases.Pretty.Generics/GenericClass`1<int32>
IL_0034: call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle)
IL_0039: stelem.ref
IL_003a: dup
IL_003b: ldc.i4.4
IL_003c: ldtoken class ICSharpCode.Decompiler.Tests.TestCases.Pretty.Generics/GenericClass`1<int32[]>
IL_0041: call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle)
IL_0046: stelem.ref
IL_0047: dup
IL_0048: ldc.i4.5
IL_0049: ldtoken [mscorlib]System.Collections.Generic.Dictionary`2
IL_004e: call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle)
IL_0053: stelem.ref
IL_0054: dup
IL_0055: ldc.i4.6
IL_0056: ldtoken valuetype [mscorlib]System.Collections.Generic.List`1/Enumerator<int32>
IL_005b: call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle)
IL_0060: stelem.ref
IL_0061: dup
IL_0062: ldc.i4.7
IL_0063: ldtoken [mscorlib]System.Collections.Generic.List`1/Enumerator
IL_0068: call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle)
IL_006d: stelem.ref
IL_006e: ret
} // end of method Generics::TestTypeOf
.method public hidebysig specialname rtspecialname
instance void .ctor() cil managed
{

56
ICSharpCode.Decompiler.Tests/TestCases/Pretty/Generics.roslyn.il

@ -298,6 +298,62 @@ @@ -298,6 +298,62 @@
IL_000c: ret
} // end of method Generics::NewArray
.method public hidebysig instance class [mscorlib]System.Type[]
TestTypeOf() cil managed
{
// Code size 116 (0x74)
.maxstack 4
.locals init (class [mscorlib]System.Type[] V_0)
IL_0000: nop
IL_0001: ldc.i4.8
IL_0002: newarr [mscorlib]System.Type
IL_0007: dup
IL_0008: ldc.i4.0
IL_0009: ldtoken [mscorlib]System.Int32
IL_000e: call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle)
IL_0013: stelem.ref
IL_0014: dup
IL_0015: ldc.i4.1
IL_0016: ldtoken int32[]
IL_001b: call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle)
IL_0020: stelem.ref
IL_0021: dup
IL_0022: ldc.i4.2
IL_0023: ldtoken ICSharpCode.Decompiler.Tests.TestCases.Pretty.Generics/GenericClass`1
IL_0028: call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle)
IL_002d: stelem.ref
IL_002e: dup
IL_002f: ldc.i4.3
IL_0030: ldtoken class ICSharpCode.Decompiler.Tests.TestCases.Pretty.Generics/GenericClass`1<int32>
IL_0035: call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle)
IL_003a: stelem.ref
IL_003b: dup
IL_003c: ldc.i4.4
IL_003d: ldtoken class ICSharpCode.Decompiler.Tests.TestCases.Pretty.Generics/GenericClass`1<int32[]>
IL_0042: call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle)
IL_0047: stelem.ref
IL_0048: dup
IL_0049: ldc.i4.5
IL_004a: ldtoken [mscorlib]System.Collections.Generic.Dictionary`2
IL_004f: call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle)
IL_0054: stelem.ref
IL_0055: dup
IL_0056: ldc.i4.6
IL_0057: ldtoken valuetype [mscorlib]System.Collections.Generic.List`1/Enumerator<int32>
IL_005c: call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle)
IL_0061: stelem.ref
IL_0062: dup
IL_0063: ldc.i4.7
IL_0064: ldtoken [mscorlib]System.Collections.Generic.List`1/Enumerator
IL_0069: call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle)
IL_006e: stelem.ref
IL_006f: stloc.0
IL_0070: br.s IL_0072
IL_0072: ldloc.0
IL_0073: ret
} // end of method Generics::TestTypeOf
.method public hidebysig specialname rtspecialname
instance void .ctor() cil managed
{

19
ICSharpCode.Decompiler.Tests/TestCases/Pretty/QueryExpressions.cs

@ -213,6 +213,25 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty @@ -213,6 +213,25 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
select (x);
}
public static IEnumerable<char> Issue1310a(bool test)
{
#if ROSLYN && OPT
IEnumerable<char> obj = test ? (from c in Enumerable.Range(0, 255)
where char.IsLetter((char)c)
select (char)c) : (from c in Enumerable.Range(0, 255)
where char.IsDigit((char)c)
select (char)c);
return obj.Concat(obj);
#else
IEnumerable<char> enumerable = test ? (from c in Enumerable.Range(0, 255)
where char.IsLetter((char)c)
select (char)c) : (from c in Enumerable.Range(0, 255)
where char.IsDigit((char)c)
select (char)c);
return enumerable.Concat(enumerable);
#endif
}
public static Maybe<TB> Cast<TA, TB>(Maybe<TA> a) where TB : class
{
return from m in a

176
ICSharpCode.Decompiler.Tests/TestCases/Pretty/QueryExpressions.il

@ -17,8 +17,8 @@ @@ -17,8 +17,8 @@
{
.custom instance void [mscorlib]System.Runtime.CompilerServices.RuntimeCompatibilityAttribute::.ctor() = ( 01 00 01 00 54 02 16 57 72 61 70 4E 6F 6E 45 78 // ....T..WrapNonEx
63 65 70 74 69 6F 6E 54 68 72 6F 77 73 01 ) // ceptionThrows.
.custom instance void [mscorlib]System.Runtime.CompilerServices.ExtensionAttribute::.ctor() = ( 01 00 00 00 )
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = ( 01 00 08 00 00 00 00 00 )
.custom instance void [mscorlib]System.Runtime.CompilerServices.ExtensionAttribute::.ctor() = ( 01 00 00 00 )
.permissionset reqmin
= {[mscorlib]System.Security.Permissions.SecurityPermissionAttribute = {property bool 'SkipVerification' = bool(true)}}
.hash algorithm 0x00008004
@ -273,6 +273,14 @@ @@ -273,6 +273,14 @@
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
.field private static class [mscorlib]System.Func`2<bool,bool> 'CS$<>9__CachedAnonymousMethodDelegate6a'
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
.field private static class [mscorlib]System.Func`2<int32,bool> 'CS$<>9__CachedAnonymousMethodDelegate6f'
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
.field private static class [mscorlib]System.Func`2<int32,char> 'CS$<>9__CachedAnonymousMethodDelegate70'
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
.field private static class [mscorlib]System.Func`2<int32,bool> 'CS$<>9__CachedAnonymousMethodDelegate71'
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
.field private static class [mscorlib]System.Func`2<int32,char> 'CS$<>9__CachedAnonymousMethodDelegate72'
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
.method public hidebysig instance object
MultipleWhere() cil managed
{
@ -1097,6 +1105,92 @@ @@ -1097,6 +1105,92 @@
IL_004e: ret
} // end of method QueryExpressions::Issue437
.method public hidebysig static class [mscorlib]System.Collections.Generic.IEnumerable`1<char>
Issue1310a(bool test) cil managed
{
// Code size 186 (0xba)
.maxstack 3
.locals init (class [mscorlib]System.Collections.Generic.IEnumerable`1<char> V_0,
class [mscorlib]System.Collections.Generic.IEnumerable`1<char> V_1)
IL_0000: nop
IL_0001: ldarg.0
IL_0002: brtrue.s IL_0059
IL_0004: ldc.i4.0
IL_0005: ldc.i4 0xff
IL_000a: call class [mscorlib]System.Collections.Generic.IEnumerable`1<int32> [System.Core]System.Linq.Enumerable::Range(int32,
int32)
IL_000f: ldsfld class [mscorlib]System.Func`2<int32,bool> ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions::'CS$<>9__CachedAnonymousMethodDelegate71'
IL_0014: brtrue.s IL_0029
IL_0016: ldnull
IL_0017: ldftn bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions::'<Issue1310a>b__6d'(int32)
IL_001d: newobj instance void class [mscorlib]System.Func`2<int32,bool>::.ctor(object,
native int)
IL_0022: stsfld class [mscorlib]System.Func`2<int32,bool> ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions::'CS$<>9__CachedAnonymousMethodDelegate71'
IL_0027: br.s IL_0029
IL_0029: ldsfld class [mscorlib]System.Func`2<int32,bool> ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions::'CS$<>9__CachedAnonymousMethodDelegate71'
IL_002e: call class [mscorlib]System.Collections.Generic.IEnumerable`1<!!0> [System.Core]System.Linq.Enumerable::Where<int32>(class [mscorlib]System.Collections.Generic.IEnumerable`1<!!0>,
class [mscorlib]System.Func`2<!!0,bool>)
IL_0033: ldsfld class [mscorlib]System.Func`2<int32,char> ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions::'CS$<>9__CachedAnonymousMethodDelegate72'
IL_0038: brtrue.s IL_004d
IL_003a: ldnull
IL_003b: ldftn char ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions::'<Issue1310a>b__6e'(int32)
IL_0041: newobj instance void class [mscorlib]System.Func`2<int32,char>::.ctor(object,
native int)
IL_0046: stsfld class [mscorlib]System.Func`2<int32,char> ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions::'CS$<>9__CachedAnonymousMethodDelegate72'
IL_004b: br.s IL_004d
IL_004d: ldsfld class [mscorlib]System.Func`2<int32,char> ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions::'CS$<>9__CachedAnonymousMethodDelegate72'
IL_0052: call class [mscorlib]System.Collections.Generic.IEnumerable`1<!!1> [System.Core]System.Linq.Enumerable::Select<int32,char>(class [mscorlib]System.Collections.Generic.IEnumerable`1<!!0>,
class [mscorlib]System.Func`2<!!0,!!1>)
IL_0057: br.s IL_00ac
IL_0059: ldc.i4.0
IL_005a: ldc.i4 0xff
IL_005f: call class [mscorlib]System.Collections.Generic.IEnumerable`1<int32> [System.Core]System.Linq.Enumerable::Range(int32,
int32)
IL_0064: ldsfld class [mscorlib]System.Func`2<int32,bool> ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions::'CS$<>9__CachedAnonymousMethodDelegate6f'
IL_0069: brtrue.s IL_007e
IL_006b: ldnull
IL_006c: ldftn bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions::'<Issue1310a>b__6b'(int32)
IL_0072: newobj instance void class [mscorlib]System.Func`2<int32,bool>::.ctor(object,
native int)
IL_0077: stsfld class [mscorlib]System.Func`2<int32,bool> ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions::'CS$<>9__CachedAnonymousMethodDelegate6f'
IL_007c: br.s IL_007e
IL_007e: ldsfld class [mscorlib]System.Func`2<int32,bool> ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions::'CS$<>9__CachedAnonymousMethodDelegate6f'
IL_0083: call class [mscorlib]System.Collections.Generic.IEnumerable`1<!!0> [System.Core]System.Linq.Enumerable::Where<int32>(class [mscorlib]System.Collections.Generic.IEnumerable`1<!!0>,
class [mscorlib]System.Func`2<!!0,bool>)
IL_0088: ldsfld class [mscorlib]System.Func`2<int32,char> ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions::'CS$<>9__CachedAnonymousMethodDelegate70'
IL_008d: brtrue.s IL_00a2
IL_008f: ldnull
IL_0090: ldftn char ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions::'<Issue1310a>b__6c'(int32)
IL_0096: newobj instance void class [mscorlib]System.Func`2<int32,char>::.ctor(object,
native int)
IL_009b: stsfld class [mscorlib]System.Func`2<int32,char> ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions::'CS$<>9__CachedAnonymousMethodDelegate70'
IL_00a0: br.s IL_00a2
IL_00a2: ldsfld class [mscorlib]System.Func`2<int32,char> ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions::'CS$<>9__CachedAnonymousMethodDelegate70'
IL_00a7: call class [mscorlib]System.Collections.Generic.IEnumerable`1<!!1> [System.Core]System.Linq.Enumerable::Select<int32,char>(class [mscorlib]System.Collections.Generic.IEnumerable`1<!!0>,
class [mscorlib]System.Func`2<!!0,!!1>)
IL_00ac: nop
IL_00ad: stloc.0
IL_00ae: ldloc.0
IL_00af: ldloc.0
IL_00b0: call class [mscorlib]System.Collections.Generic.IEnumerable`1<!!0> [System.Core]System.Linq.Enumerable::Concat<char>(class [mscorlib]System.Collections.Generic.IEnumerable`1<!!0>,
class [mscorlib]System.Collections.Generic.IEnumerable`1<!!0>)
IL_00b5: stloc.1
IL_00b6: br.s IL_00b8
IL_00b8: ldloc.1
IL_00b9: ret
} // end of method QueryExpressions::Issue1310a
.method public hidebysig static valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.Maybe`1<!!TB>
Cast<TA,class TB>(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.Maybe`1<!!TA> a) cil managed
{
@ -1106,19 +1200,19 @@ @@ -1106,19 +1200,19 @@
IL_0000: nop
IL_0001: ldarg.0
IL_0002: ldnull
IL_0003: ldftn class '<>f__AnonymousType11`2'<!!0,!!1> ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions::'<Cast>b__6c'<!!0,!!1>(!!0)
IL_0003: ldftn class '<>f__AnonymousType11`2'<!!0,!!1> ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions::'<Cast>b__74'<!!0,!!1>(!!0)
IL_0009: newobj instance void class [mscorlib]System.Func`2<!!TA,class '<>f__AnonymousType11`2'<!!TA,!!TB>>::.ctor(object,
native int)
IL_000e: call valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.Maybe`1<!!1> ICSharpCode.Decompiler.Tests.TestCases.Pretty.MaybeExtensions::Select<!!0,class '<>f__AnonymousType11`2'<!!0,!!1>>(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.Maybe`1<!!0>,
class [mscorlib]System.Func`2<!!0,!!1>)
IL_0013: ldnull
IL_0014: ldftn bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions::'<Cast>b__6d'<!!0,!!1>(class '<>f__AnonymousType11`2'<!!0,!!1>)
IL_0014: ldftn bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions::'<Cast>b__75'<!!0,!!1>(class '<>f__AnonymousType11`2'<!!0,!!1>)
IL_001a: newobj instance void class [mscorlib]System.Func`2<class '<>f__AnonymousType11`2'<!!TA,!!TB>,bool>::.ctor(object,
native int)
IL_001f: call valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.Maybe`1<!!0> ICSharpCode.Decompiler.Tests.TestCases.Pretty.MaybeExtensions::Where<class '<>f__AnonymousType11`2'<!!0,!!1>>(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.Maybe`1<!!0>,
class [mscorlib]System.Func`2<!!0,bool>)
IL_0024: ldnull
IL_0025: ldftn !!1 ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions::'<Cast>b__6e'<!!0,!!1>(class '<>f__AnonymousType11`2'<!!0,!!1>)
IL_0025: ldftn !!1 ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions::'<Cast>b__76'<!!0,!!1>(class '<>f__AnonymousType11`2'<!!0,!!1>)
IL_002b: newobj instance void class [mscorlib]System.Func`2<class '<>f__AnonymousType11`2'<!!TA,!!TB>,!!TB>::.ctor(object,
native int)
IL_0030: call valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.Maybe`1<!!1> ICSharpCode.Decompiler.Tests.TestCases.Pretty.MaybeExtensions::Select<class '<>f__AnonymousType11`2'<!!0,!!1>,!!1>(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.Maybe`1<!!0>,
@ -2055,8 +2149,70 @@ @@ -2055,8 +2149,70 @@
IL_0005: ret
} // end of method QueryExpressions::'<Issue437>b__68'
.method private hidebysig static bool '<Issue1310a>b__6b'(int32 c) cil managed
{
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
// Code size 12 (0xc)
.maxstack 1
.locals init (bool V_0)
IL_0000: ldarg.0
IL_0001: conv.u2
IL_0002: call bool [mscorlib]System.Char::IsLetter(char)
IL_0007: stloc.0
IL_0008: br.s IL_000a
IL_000a: ldloc.0
IL_000b: ret
} // end of method QueryExpressions::'<Issue1310a>b__6b'
.method private hidebysig static char '<Issue1310a>b__6c'(int32 c) cil managed
{
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
// Code size 7 (0x7)
.maxstack 1
.locals init (char V_0)
IL_0000: ldarg.0
IL_0001: conv.u2
IL_0002: stloc.0
IL_0003: br.s IL_0005
IL_0005: ldloc.0
IL_0006: ret
} // end of method QueryExpressions::'<Issue1310a>b__6c'
.method private hidebysig static bool '<Issue1310a>b__6d'(int32 c) cil managed
{
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
// Code size 12 (0xc)
.maxstack 1
.locals init (bool V_0)
IL_0000: ldarg.0
IL_0001: conv.u2
IL_0002: call bool [mscorlib]System.Char::IsDigit(char)
IL_0007: stloc.0
IL_0008: br.s IL_000a
IL_000a: ldloc.0
IL_000b: ret
} // end of method QueryExpressions::'<Issue1310a>b__6d'
.method private hidebysig static char '<Issue1310a>b__6e'(int32 c) cil managed
{
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
// Code size 7 (0x7)
.maxstack 1
.locals init (char V_0)
IL_0000: ldarg.0
IL_0001: conv.u2
IL_0002: stloc.0
IL_0003: br.s IL_0005
IL_0005: ldloc.0
IL_0006: ret
} // end of method QueryExpressions::'<Issue1310a>b__6e'
.method private hidebysig static class '<>f__AnonymousType11`2'<!!TA,!!TB>
'<Cast>b__6c'<TA,class TB>(!!TA m) cil managed
'<Cast>b__74'<TA,class TB>(!!TA m) cil managed
{
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
// Code size 27 (0x1b)
@ -2074,9 +2230,9 @@ @@ -2074,9 +2230,9 @@
IL_0019: ldloc.0
IL_001a: ret
} // end of method QueryExpressions::'<Cast>b__6c'
} // end of method QueryExpressions::'<Cast>b__74'
.method private hidebysig static bool '<Cast>b__6d'<TA,class TB>(class '<>f__AnonymousType11`2'<!!TA,!!TB> '<>h__TransparentIdentifier6b') cil managed
.method private hidebysig static bool '<Cast>b__75'<TA,class TB>(class '<>f__AnonymousType11`2'<!!TA,!!TB> '<>h__TransparentIdentifier73') cil managed
{
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
// Code size 22 (0x16)
@ -2094,9 +2250,9 @@ @@ -2094,9 +2250,9 @@
IL_0014: ldloc.0
IL_0015: ret
} // end of method QueryExpressions::'<Cast>b__6d'
} // end of method QueryExpressions::'<Cast>b__75'
.method private hidebysig static !!TB '<Cast>b__6e'<TA,class TB>(class '<>f__AnonymousType11`2'<!!TA,!!TB> '<>h__TransparentIdentifier6b') cil managed
.method private hidebysig static !!TB '<Cast>b__76'<TA,class TB>(class '<>f__AnonymousType11`2'<!!TA,!!TB> '<>h__TransparentIdentifier73') cil managed
{
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
// Code size 11 (0xb)
@ -2109,7 +2265,7 @@ @@ -2109,7 +2265,7 @@
IL_0009: ldloc.0
IL_000a: ret
} // end of method QueryExpressions::'<Cast>b__6e'
} // end of method QueryExpressions::'<Cast>b__76'
} // end of class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions

141
ICSharpCode.Decompiler.Tests/TestCases/Pretty/QueryExpressions.opt.il

@ -17,8 +17,8 @@ @@ -17,8 +17,8 @@
{
.custom instance void [mscorlib]System.Runtime.CompilerServices.RuntimeCompatibilityAttribute::.ctor() = ( 01 00 01 00 54 02 16 57 72 61 70 4E 6F 6E 45 78 // ....T..WrapNonEx
63 65 70 74 69 6F 6E 54 68 72 6F 77 73 01 ) // ceptionThrows.
.custom instance void [mscorlib]System.Runtime.CompilerServices.ExtensionAttribute::.ctor() = ( 01 00 00 00 )
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = ( 01 00 08 00 00 00 00 00 )
.custom instance void [mscorlib]System.Runtime.CompilerServices.ExtensionAttribute::.ctor() = ( 01 00 00 00 )
.permissionset reqmin
= {[mscorlib]System.Security.Permissions.SecurityPermissionAttribute = {property bool 'SkipVerification' = bool(true)}}
.hash algorithm 0x00008004
@ -263,6 +263,14 @@ @@ -263,6 +263,14 @@
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
.field private static class [mscorlib]System.Func`2<bool,bool> 'CS$<>9__CachedAnonymousMethodDelegate6a'
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
.field private static class [mscorlib]System.Func`2<int32,bool> 'CS$<>9__CachedAnonymousMethodDelegate6f'
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
.field private static class [mscorlib]System.Func`2<int32,char> 'CS$<>9__CachedAnonymousMethodDelegate70'
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
.field private static class [mscorlib]System.Func`2<int32,bool> 'CS$<>9__CachedAnonymousMethodDelegate71'
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
.field private static class [mscorlib]System.Func`2<int32,char> 'CS$<>9__CachedAnonymousMethodDelegate72'
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
.method public hidebysig instance object
MultipleWhere() cil managed
{
@ -909,6 +917,77 @@ @@ -909,6 +917,77 @@
IL_0045: ret
} // end of method QueryExpressions::Issue437
.method public hidebysig static class [mscorlib]System.Collections.Generic.IEnumerable`1<char>
Issue1310a(bool test) cil managed
{
// Code size 172 (0xac)
.maxstack 3
.locals init (class [mscorlib]System.Collections.Generic.IEnumerable`1<char> V_0)
IL_0000: ldarg.0
IL_0001: brtrue.s IL_0054
IL_0003: ldc.i4.0
IL_0004: ldc.i4 0xff
IL_0009: call class [mscorlib]System.Collections.Generic.IEnumerable`1<int32> [System.Core]System.Linq.Enumerable::Range(int32,
int32)
IL_000e: ldsfld class [mscorlib]System.Func`2<int32,bool> ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions::'CS$<>9__CachedAnonymousMethodDelegate71'
IL_0013: brtrue.s IL_0026
IL_0015: ldnull
IL_0016: ldftn bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions::'<Issue1310a>b__6d'(int32)
IL_001c: newobj instance void class [mscorlib]System.Func`2<int32,bool>::.ctor(object,
native int)
IL_0021: stsfld class [mscorlib]System.Func`2<int32,bool> ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions::'CS$<>9__CachedAnonymousMethodDelegate71'
IL_0026: ldsfld class [mscorlib]System.Func`2<int32,bool> ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions::'CS$<>9__CachedAnonymousMethodDelegate71'
IL_002b: call class [mscorlib]System.Collections.Generic.IEnumerable`1<!!0> [System.Core]System.Linq.Enumerable::Where<int32>(class [mscorlib]System.Collections.Generic.IEnumerable`1<!!0>,
class [mscorlib]System.Func`2<!!0,bool>)
IL_0030: ldsfld class [mscorlib]System.Func`2<int32,char> ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions::'CS$<>9__CachedAnonymousMethodDelegate72'
IL_0035: brtrue.s IL_0048
IL_0037: ldnull
IL_0038: ldftn char ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions::'<Issue1310a>b__6e'(int32)
IL_003e: newobj instance void class [mscorlib]System.Func`2<int32,char>::.ctor(object,
native int)
IL_0043: stsfld class [mscorlib]System.Func`2<int32,char> ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions::'CS$<>9__CachedAnonymousMethodDelegate72'
IL_0048: ldsfld class [mscorlib]System.Func`2<int32,char> ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions::'CS$<>9__CachedAnonymousMethodDelegate72'
IL_004d: call class [mscorlib]System.Collections.Generic.IEnumerable`1<!!1> [System.Core]System.Linq.Enumerable::Select<int32,char>(class [mscorlib]System.Collections.Generic.IEnumerable`1<!!0>,
class [mscorlib]System.Func`2<!!0,!!1>)
IL_0052: br.s IL_00a3
IL_0054: ldc.i4.0
IL_0055: ldc.i4 0xff
IL_005a: call class [mscorlib]System.Collections.Generic.IEnumerable`1<int32> [System.Core]System.Linq.Enumerable::Range(int32,
int32)
IL_005f: ldsfld class [mscorlib]System.Func`2<int32,bool> ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions::'CS$<>9__CachedAnonymousMethodDelegate6f'
IL_0064: brtrue.s IL_0077
IL_0066: ldnull
IL_0067: ldftn bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions::'<Issue1310a>b__6b'(int32)
IL_006d: newobj instance void class [mscorlib]System.Func`2<int32,bool>::.ctor(object,
native int)
IL_0072: stsfld class [mscorlib]System.Func`2<int32,bool> ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions::'CS$<>9__CachedAnonymousMethodDelegate6f'
IL_0077: ldsfld class [mscorlib]System.Func`2<int32,bool> ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions::'CS$<>9__CachedAnonymousMethodDelegate6f'
IL_007c: call class [mscorlib]System.Collections.Generic.IEnumerable`1<!!0> [System.Core]System.Linq.Enumerable::Where<int32>(class [mscorlib]System.Collections.Generic.IEnumerable`1<!!0>,
class [mscorlib]System.Func`2<!!0,bool>)
IL_0081: ldsfld class [mscorlib]System.Func`2<int32,char> ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions::'CS$<>9__CachedAnonymousMethodDelegate70'
IL_0086: brtrue.s IL_0099
IL_0088: ldnull
IL_0089: ldftn char ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions::'<Issue1310a>b__6c'(int32)
IL_008f: newobj instance void class [mscorlib]System.Func`2<int32,char>::.ctor(object,
native int)
IL_0094: stsfld class [mscorlib]System.Func`2<int32,char> ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions::'CS$<>9__CachedAnonymousMethodDelegate70'
IL_0099: ldsfld class [mscorlib]System.Func`2<int32,char> ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions::'CS$<>9__CachedAnonymousMethodDelegate70'
IL_009e: call class [mscorlib]System.Collections.Generic.IEnumerable`1<!!1> [System.Core]System.Linq.Enumerable::Select<int32,char>(class [mscorlib]System.Collections.Generic.IEnumerable`1<!!0>,
class [mscorlib]System.Func`2<!!0,!!1>)
IL_00a3: stloc.0
IL_00a4: ldloc.0
IL_00a5: ldloc.0
IL_00a6: call class [mscorlib]System.Collections.Generic.IEnumerable`1<!!0> [System.Core]System.Linq.Enumerable::Concat<char>(class [mscorlib]System.Collections.Generic.IEnumerable`1<!!0>,
class [mscorlib]System.Collections.Generic.IEnumerable`1<!!0>)
IL_00ab: ret
} // end of method QueryExpressions::Issue1310a
.method public hidebysig static valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.Maybe`1<!!TB>
Cast<TA,class TB>(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.Maybe`1<!!TA> a) cil managed
{
@ -916,19 +995,19 @@ @@ -916,19 +995,19 @@
.maxstack 8
IL_0000: ldarg.0
IL_0001: ldnull
IL_0002: ldftn class '<>f__AnonymousType11`2'<!!0,!!1> ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions::'<Cast>b__6c'<!!0,!!1>(!!0)
IL_0002: ldftn class '<>f__AnonymousType11`2'<!!0,!!1> ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions::'<Cast>b__74'<!!0,!!1>(!!0)
IL_0008: newobj instance void class [mscorlib]System.Func`2<!!TA,class '<>f__AnonymousType11`2'<!!TA,!!TB>>::.ctor(object,
native int)
IL_000d: call valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.Maybe`1<!!1> ICSharpCode.Decompiler.Tests.TestCases.Pretty.MaybeExtensions::Select<!!0,class '<>f__AnonymousType11`2'<!!0,!!1>>(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.Maybe`1<!!0>,
class [mscorlib]System.Func`2<!!0,!!1>)
IL_0012: ldnull
IL_0013: ldftn bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions::'<Cast>b__6d'<!!0,!!1>(class '<>f__AnonymousType11`2'<!!0,!!1>)
IL_0013: ldftn bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions::'<Cast>b__75'<!!0,!!1>(class '<>f__AnonymousType11`2'<!!0,!!1>)
IL_0019: newobj instance void class [mscorlib]System.Func`2<class '<>f__AnonymousType11`2'<!!TA,!!TB>,bool>::.ctor(object,
native int)
IL_001e: call valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.Maybe`1<!!0> ICSharpCode.Decompiler.Tests.TestCases.Pretty.MaybeExtensions::Where<class '<>f__AnonymousType11`2'<!!0,!!1>>(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.Maybe`1<!!0>,
class [mscorlib]System.Func`2<!!0,bool>)
IL_0023: ldnull
IL_0024: ldftn !!1 ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions::'<Cast>b__6e'<!!0,!!1>(class '<>f__AnonymousType11`2'<!!0,!!1>)
IL_0024: ldftn !!1 ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions::'<Cast>b__76'<!!0,!!1>(class '<>f__AnonymousType11`2'<!!0,!!1>)
IL_002a: newobj instance void class [mscorlib]System.Func`2<class '<>f__AnonymousType11`2'<!!TA,!!TB>,!!TB>::.ctor(object,
native int)
IL_002f: call valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.Maybe`1<!!1> ICSharpCode.Decompiler.Tests.TestCases.Pretty.MaybeExtensions::Select<class '<>f__AnonymousType11`2'<!!0,!!1>,!!1>(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.Maybe`1<!!0>,
@ -1626,8 +1705,50 @@ @@ -1626,8 +1705,50 @@
IL_0001: ret
} // end of method QueryExpressions::'<Issue437>b__68'
.method private hidebysig static bool '<Issue1310a>b__6b'(int32 c) cil managed
{
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
// Code size 8 (0x8)
.maxstack 8
IL_0000: ldarg.0
IL_0001: conv.u2
IL_0002: call bool [mscorlib]System.Char::IsLetter(char)
IL_0007: ret
} // end of method QueryExpressions::'<Issue1310a>b__6b'
.method private hidebysig static char '<Issue1310a>b__6c'(int32 c) cil managed
{
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
// Code size 3 (0x3)
.maxstack 8
IL_0000: ldarg.0
IL_0001: conv.u2
IL_0002: ret
} // end of method QueryExpressions::'<Issue1310a>b__6c'
.method private hidebysig static bool '<Issue1310a>b__6d'(int32 c) cil managed
{
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
// Code size 8 (0x8)
.maxstack 8
IL_0000: ldarg.0
IL_0001: conv.u2
IL_0002: call bool [mscorlib]System.Char::IsDigit(char)
IL_0007: ret
} // end of method QueryExpressions::'<Issue1310a>b__6d'
.method private hidebysig static char '<Issue1310a>b__6e'(int32 c) cil managed
{
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
// Code size 3 (0x3)
.maxstack 8
IL_0000: ldarg.0
IL_0001: conv.u2
IL_0002: ret
} // end of method QueryExpressions::'<Issue1310a>b__6e'
.method private hidebysig static class '<>f__AnonymousType11`2'<!!TA,!!TB>
'<Cast>b__6c'<TA,class TB>(!!TA m) cil managed
'<Cast>b__74'<TA,class TB>(!!TA m) cil managed
{
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
// Code size 23 (0x17)
@ -1640,9 +1761,9 @@ @@ -1640,9 +1761,9 @@
IL_0011: newobj instance void class '<>f__AnonymousType11`2'<!!TA,!!TB>::.ctor(!0,
!1)
IL_0016: ret
} // end of method QueryExpressions::'<Cast>b__6c'
} // end of method QueryExpressions::'<Cast>b__74'
.method private hidebysig static bool '<Cast>b__6d'<TA,class TB>(class '<>f__AnonymousType11`2'<!!TA,!!TB> '<>h__TransparentIdentifier6b') cil managed
.method private hidebysig static bool '<Cast>b__75'<TA,class TB>(class '<>f__AnonymousType11`2'<!!TA,!!TB> '<>h__TransparentIdentifier73') cil managed
{
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
// Code size 18 (0x12)
@ -1655,9 +1776,9 @@ @@ -1655,9 +1776,9 @@
IL_000e: ldc.i4.0
IL_000f: ceq
IL_0011: ret
} // end of method QueryExpressions::'<Cast>b__6d'
} // end of method QueryExpressions::'<Cast>b__75'
.method private hidebysig static !!TB '<Cast>b__6e'<TA,class TB>(class '<>f__AnonymousType11`2'<!!TA,!!TB> '<>h__TransparentIdentifier6b') cil managed
.method private hidebysig static !!TB '<Cast>b__76'<TA,class TB>(class '<>f__AnonymousType11`2'<!!TA,!!TB> '<>h__TransparentIdentifier73') cil managed
{
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
// Code size 7 (0x7)
@ -1665,7 +1786,7 @@ @@ -1665,7 +1786,7 @@
IL_0000: ldarg.0
IL_0001: callvirt instance !1 class '<>f__AnonymousType11`2'<!!TA,!!TB>::get_t()
IL_0006: ret
} // end of method QueryExpressions::'<Cast>b__6e'
} // end of method QueryExpressions::'<Cast>b__76'
} // end of class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions

178
ICSharpCode.Decompiler.Tests/TestCases/Pretty/QueryExpressions.opt.roslyn.il

@ -3857,6 +3857,10 @@ @@ -3857,6 +3857,10 @@
.field public static class [mscorlib]System.Func`2<class [System.Core]System.Linq.IGrouping`2<string,class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/Customer>,class '<>f__AnonymousType16`2'<string,int32>> '<>9__19_1'
.field public static class [mscorlib]System.Func`2<bool,bool> '<>9__20_0'
.field public static class [mscorlib]System.Func`2<bool,bool> '<>9__20_1'
.field public static class [mscorlib]System.Func`2<int32,bool> '<>9__21_0'
.field public static class [mscorlib]System.Func`2<int32,char> '<>9__21_1'
.field public static class [mscorlib]System.Func`2<int32,bool> '<>9__21_2'
.field public static class [mscorlib]System.Func`2<int32,char> '<>9__21_3'
.method private hidebysig specialname rtspecialname static
void .cctor() cil managed
{
@ -4499,25 +4503,67 @@ @@ -4499,25 +4503,67 @@
IL_0001: ret
} // end of method '<>c'::'<Issue437>b__20_1'
.method assembly hidebysig instance bool
'<Issue1310a>b__21_0'(int32 c) cil managed
{
// Code size 8 (0x8)
.maxstack 8
IL_0000: ldarg.1
IL_0001: conv.u2
IL_0002: call bool [mscorlib]System.Char::IsLetter(char)
IL_0007: ret
} // end of method '<>c'::'<Issue1310a>b__21_0'
.method assembly hidebysig instance char
'<Issue1310a>b__21_1'(int32 c) cil managed
{
// Code size 3 (0x3)
.maxstack 8
IL_0000: ldarg.1
IL_0001: conv.u2
IL_0002: ret
} // end of method '<>c'::'<Issue1310a>b__21_1'
.method assembly hidebysig instance bool
'<Issue1310a>b__21_2'(int32 c) cil managed
{
// Code size 8 (0x8)
.maxstack 8
IL_0000: ldarg.1
IL_0001: conv.u2
IL_0002: call bool [mscorlib]System.Char::IsDigit(char)
IL_0007: ret
} // end of method '<>c'::'<Issue1310a>b__21_2'
.method assembly hidebysig instance char
'<Issue1310a>b__21_3'(int32 c) cil managed
{
// Code size 3 (0x3)
.maxstack 8
IL_0000: ldarg.1
IL_0001: conv.u2
IL_0002: ret
} // end of method '<>c'::'<Issue1310a>b__21_3'
} // end of class '<>c'
.class auto ansi serializable sealed nested private beforefieldinit '<>c__21`2'<TA,class TB>
.class auto ansi serializable sealed nested private beforefieldinit '<>c__22`2'<TA,class TB>
extends [mscorlib]System.Object
{
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
.field public static initonly class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__21`2'<!TA,!TB> '<>9'
.field public static class [mscorlib]System.Func`2<!TA,class '<>f__AnonymousType17`2'<!TA,!TB>> '<>9__21_0'
.field public static class [mscorlib]System.Func`2<class '<>f__AnonymousType17`2'<!TA,!TB>,bool> '<>9__21_1'
.field public static class [mscorlib]System.Func`2<class '<>f__AnonymousType17`2'<!TA,!TB>,!TB> '<>9__21_2'
.field public static initonly class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__22`2'<!TA,!TB> '<>9'
.field public static class [mscorlib]System.Func`2<!TA,class '<>f__AnonymousType17`2'<!TA,!TB>> '<>9__22_0'
.field public static class [mscorlib]System.Func`2<class '<>f__AnonymousType17`2'<!TA,!TB>,bool> '<>9__22_1'
.field public static class [mscorlib]System.Func`2<class '<>f__AnonymousType17`2'<!TA,!TB>,!TB> '<>9__22_2'
.method private hidebysig specialname rtspecialname static
void .cctor() cil managed
{
// Code size 11 (0xb)
.maxstack 8
IL_0000: newobj instance void class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__21`2'<!TA,!TB>::.ctor()
IL_0005: stsfld class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__21`2'<!0,!1> class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__21`2'<!TA,!TB>::'<>9'
IL_0000: newobj instance void class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__22`2'<!TA,!TB>::.ctor()
IL_0005: stsfld class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__22`2'<!0,!1> class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__22`2'<!TA,!TB>::'<>9'
IL_000a: ret
} // end of method '<>c__21`2'::.cctor
} // end of method '<>c__22`2'::.cctor
.method public hidebysig specialname rtspecialname
instance void .ctor() cil managed
@ -4527,10 +4573,10 @@ @@ -4527,10 +4573,10 @@
IL_0000: ldarg.0
IL_0001: call instance void [mscorlib]System.Object::.ctor()
IL_0006: ret
} // end of method '<>c__21`2'::.ctor
} // end of method '<>c__22`2'::.ctor
.method assembly hidebysig instance class '<>f__AnonymousType17`2'<!TA,!TB>
'<Cast>b__21_0'(!TA m) cil managed
'<Cast>b__22_0'(!TA m) cil managed
{
// Code size 23 (0x17)
.maxstack 8
@ -4542,10 +4588,10 @@ @@ -4542,10 +4588,10 @@
IL_0011: newobj instance void class '<>f__AnonymousType17`2'<!TA,!TB>::.ctor(!0,
!1)
IL_0016: ret
} // end of method '<>c__21`2'::'<Cast>b__21_0'
} // end of method '<>c__22`2'::'<Cast>b__22_0'
.method assembly hidebysig instance bool
'<Cast>b__21_1'(class '<>f__AnonymousType17`2'<!TA,!TB> '<>h__TransparentIdentifier0') cil managed
'<Cast>b__22_1'(class '<>f__AnonymousType17`2'<!TA,!TB> '<>h__TransparentIdentifier0') cil managed
{
// Code size 15 (0xf)
.maxstack 8
@ -4555,19 +4601,19 @@ @@ -4555,19 +4601,19 @@
IL_000b: ldnull
IL_000c: cgt.un
IL_000e: ret
} // end of method '<>c__21`2'::'<Cast>b__21_1'
} // end of method '<>c__22`2'::'<Cast>b__22_1'
.method assembly hidebysig instance !TB
'<Cast>b__21_2'(class '<>f__AnonymousType17`2'<!TA,!TB> '<>h__TransparentIdentifier0') cil managed
'<Cast>b__22_2'(class '<>f__AnonymousType17`2'<!TA,!TB> '<>h__TransparentIdentifier0') cil managed
{
// Code size 7 (0x7)
.maxstack 8
IL_0000: ldarg.1
IL_0001: callvirt instance !1 class '<>f__AnonymousType17`2'<!TA,!TB>::get_t()
IL_0006: ret
} // end of method '<>c__21`2'::'<Cast>b__21_2'
} // end of method '<>c__22`2'::'<Cast>b__22_2'
} // end of class '<>c__21`2'
} // end of class '<>c__22`2'
.field public class [mscorlib]System.Collections.Generic.IEnumerable`1<class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/Customer> customers
.field public class [mscorlib]System.Collections.Generic.IEnumerable`1<class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/Order> orders
@ -5305,49 +5351,125 @@ @@ -5305,49 +5351,125 @@
IL_0049: ret
} // end of method QueryExpressions::Issue437
.method public hidebysig static class [mscorlib]System.Collections.Generic.IEnumerable`1<char>
Issue1310a(bool test) cil managed
{
// Code size 178 (0xb2)
.maxstack 3
IL_0000: ldarg.0
IL_0001: brtrue.s IL_0058
IL_0003: ldc.i4.0
IL_0004: ldc.i4 0xff
IL_0009: call class [mscorlib]System.Collections.Generic.IEnumerable`1<int32> [System.Core]System.Linq.Enumerable::Range(int32,
int32)
IL_000e: ldsfld class [mscorlib]System.Func`2<int32,bool> ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c'::'<>9__21_2'
IL_0013: dup
IL_0014: brtrue.s IL_002d
IL_0016: pop
IL_0017: ldsfld class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c' ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c'::'<>9'
IL_001c: ldftn instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c'::'<Issue1310a>b__21_2'(int32)
IL_0022: newobj instance void class [mscorlib]System.Func`2<int32,bool>::.ctor(object,
native int)
IL_0027: dup
IL_0028: stsfld class [mscorlib]System.Func`2<int32,bool> ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c'::'<>9__21_2'
IL_002d: call class [mscorlib]System.Collections.Generic.IEnumerable`1<!!0> [System.Core]System.Linq.Enumerable::Where<int32>(class [mscorlib]System.Collections.Generic.IEnumerable`1<!!0>,
class [mscorlib]System.Func`2<!!0,bool>)
IL_0032: ldsfld class [mscorlib]System.Func`2<int32,char> ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c'::'<>9__21_3'
IL_0037: dup
IL_0038: brtrue.s IL_0051
IL_003a: pop
IL_003b: ldsfld class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c' ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c'::'<>9'
IL_0040: ldftn instance char ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c'::'<Issue1310a>b__21_3'(int32)
IL_0046: newobj instance void class [mscorlib]System.Func`2<int32,char>::.ctor(object,
native int)
IL_004b: dup
IL_004c: stsfld class [mscorlib]System.Func`2<int32,char> ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c'::'<>9__21_3'
IL_0051: call class [mscorlib]System.Collections.Generic.IEnumerable`1<!!1> [System.Core]System.Linq.Enumerable::Select<int32,char>(class [mscorlib]System.Collections.Generic.IEnumerable`1<!!0>,
class [mscorlib]System.Func`2<!!0,!!1>)
IL_0056: br.s IL_00ab
IL_0058: ldc.i4.0
IL_0059: ldc.i4 0xff
IL_005e: call class [mscorlib]System.Collections.Generic.IEnumerable`1<int32> [System.Core]System.Linq.Enumerable::Range(int32,
int32)
IL_0063: ldsfld class [mscorlib]System.Func`2<int32,bool> ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c'::'<>9__21_0'
IL_0068: dup
IL_0069: brtrue.s IL_0082
IL_006b: pop
IL_006c: ldsfld class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c' ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c'::'<>9'
IL_0071: ldftn instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c'::'<Issue1310a>b__21_0'(int32)
IL_0077: newobj instance void class [mscorlib]System.Func`2<int32,bool>::.ctor(object,
native int)
IL_007c: dup
IL_007d: stsfld class [mscorlib]System.Func`2<int32,bool> ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c'::'<>9__21_0'
IL_0082: call class [mscorlib]System.Collections.Generic.IEnumerable`1<!!0> [System.Core]System.Linq.Enumerable::Where<int32>(class [mscorlib]System.Collections.Generic.IEnumerable`1<!!0>,
class [mscorlib]System.Func`2<!!0,bool>)
IL_0087: ldsfld class [mscorlib]System.Func`2<int32,char> ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c'::'<>9__21_1'
IL_008c: dup
IL_008d: brtrue.s IL_00a6
IL_008f: pop
IL_0090: ldsfld class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c' ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c'::'<>9'
IL_0095: ldftn instance char ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c'::'<Issue1310a>b__21_1'(int32)
IL_009b: newobj instance void class [mscorlib]System.Func`2<int32,char>::.ctor(object,
native int)
IL_00a0: dup
IL_00a1: stsfld class [mscorlib]System.Func`2<int32,char> ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c'::'<>9__21_1'
IL_00a6: call class [mscorlib]System.Collections.Generic.IEnumerable`1<!!1> [System.Core]System.Linq.Enumerable::Select<int32,char>(class [mscorlib]System.Collections.Generic.IEnumerable`1<!!0>,
class [mscorlib]System.Func`2<!!0,!!1>)
IL_00ab: dup
IL_00ac: call class [mscorlib]System.Collections.Generic.IEnumerable`1<!!0> [System.Core]System.Linq.Enumerable::Concat<char>(class [mscorlib]System.Collections.Generic.IEnumerable`1<!!0>,
class [mscorlib]System.Collections.Generic.IEnumerable`1<!!0>)
IL_00b1: ret
} // end of method QueryExpressions::Issue1310a
.method public hidebysig static valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.Maybe`1<!!TB>
Cast<TA,class TB>(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.Maybe`1<!!TA> a) cil managed
{
// Code size 110 (0x6e)
.maxstack 3
IL_0000: ldarg.0
IL_0001: ldsfld class [mscorlib]System.Func`2<!0,class '<>f__AnonymousType17`2'<!0,!1>> class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__21`2'<!!TA,!!TB>::'<>9__21_0'
IL_0001: ldsfld class [mscorlib]System.Func`2<!0,class '<>f__AnonymousType17`2'<!0,!1>> class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__22`2'<!!TA,!!TB>::'<>9__22_0'
IL_0006: dup
IL_0007: brtrue.s IL_0020
IL_0009: pop
IL_000a: ldsfld class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__21`2'<!0,!1> class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__21`2'<!!TA,!!TB>::'<>9'
IL_000f: ldftn instance class '<>f__AnonymousType17`2'<!0,!1> class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__21`2'<!!TA,!!TB>::'<Cast>b__21_0'(!0)
IL_000a: ldsfld class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__22`2'<!0,!1> class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__22`2'<!!TA,!!TB>::'<>9'
IL_000f: ldftn instance class '<>f__AnonymousType17`2'<!0,!1> class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__22`2'<!!TA,!!TB>::'<Cast>b__22_0'(!0)
IL_0015: newobj instance void class [mscorlib]System.Func`2<!!TA,class '<>f__AnonymousType17`2'<!!TA,!!TB>>::.ctor(object,
native int)
IL_001a: dup
IL_001b: stsfld class [mscorlib]System.Func`2<!0,class '<>f__AnonymousType17`2'<!0,!1>> class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__21`2'<!!TA,!!TB>::'<>9__21_0'
IL_001b: stsfld class [mscorlib]System.Func`2<!0,class '<>f__AnonymousType17`2'<!0,!1>> class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__22`2'<!!TA,!!TB>::'<>9__22_0'
IL_0020: call valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.Maybe`1<!!1> ICSharpCode.Decompiler.Tests.TestCases.Pretty.MaybeExtensions::Select<!!0,class '<>f__AnonymousType17`2'<!!0,!!1>>(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.Maybe`1<!!0>,
class [mscorlib]System.Func`2<!!0,!!1>)
IL_0025: ldsfld class [mscorlib]System.Func`2<class '<>f__AnonymousType17`2'<!0,!1>,bool> class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__21`2'<!!TA,!!TB>::'<>9__21_1'
IL_0025: ldsfld class [mscorlib]System.Func`2<class '<>f__AnonymousType17`2'<!0,!1>,bool> class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__22`2'<!!TA,!!TB>::'<>9__22_1'
IL_002a: dup
IL_002b: brtrue.s IL_0044
IL_002d: pop
IL_002e: ldsfld class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__21`2'<!0,!1> class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__21`2'<!!TA,!!TB>::'<>9'
IL_0033: ldftn instance bool class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__21`2'<!!TA,!!TB>::'<Cast>b__21_1'(class '<>f__AnonymousType17`2'<!0,!1>)
IL_002e: ldsfld class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__22`2'<!0,!1> class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__22`2'<!!TA,!!TB>::'<>9'
IL_0033: ldftn instance bool class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__22`2'<!!TA,!!TB>::'<Cast>b__22_1'(class '<>f__AnonymousType17`2'<!0,!1>)
IL_0039: newobj instance void class [mscorlib]System.Func`2<class '<>f__AnonymousType17`2'<!!TA,!!TB>,bool>::.ctor(object,
native int)
IL_003e: dup
IL_003f: stsfld class [mscorlib]System.Func`2<class '<>f__AnonymousType17`2'<!0,!1>,bool> class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__21`2'<!!TA,!!TB>::'<>9__21_1'
IL_003f: stsfld class [mscorlib]System.Func`2<class '<>f__AnonymousType17`2'<!0,!1>,bool> class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__22`2'<!!TA,!!TB>::'<>9__22_1'
IL_0044: call valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.Maybe`1<!!0> ICSharpCode.Decompiler.Tests.TestCases.Pretty.MaybeExtensions::Where<class '<>f__AnonymousType17`2'<!!0,!!1>>(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.Maybe`1<!!0>,
class [mscorlib]System.Func`2<!!0,bool>)
IL_0049: ldsfld class [mscorlib]System.Func`2<class '<>f__AnonymousType17`2'<!0,!1>,!1> class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__21`2'<!!TA,!!TB>::'<>9__21_2'
IL_0049: ldsfld class [mscorlib]System.Func`2<class '<>f__AnonymousType17`2'<!0,!1>,!1> class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__22`2'<!!TA,!!TB>::'<>9__22_2'
IL_004e: dup
IL_004f: brtrue.s IL_0068
IL_0051: pop
IL_0052: ldsfld class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__21`2'<!0,!1> class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__21`2'<!!TA,!!TB>::'<>9'
IL_0057: ldftn instance !1 class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__21`2'<!!TA,!!TB>::'<Cast>b__21_2'(class '<>f__AnonymousType17`2'<!0,!1>)
IL_0052: ldsfld class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__22`2'<!0,!1> class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__22`2'<!!TA,!!TB>::'<>9'
IL_0057: ldftn instance !1 class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__22`2'<!!TA,!!TB>::'<Cast>b__22_2'(class '<>f__AnonymousType17`2'<!0,!1>)
IL_005d: newobj instance void class [mscorlib]System.Func`2<class '<>f__AnonymousType17`2'<!!TA,!!TB>,!!TB>::.ctor(object,
native int)
IL_0062: dup
IL_0063: stsfld class [mscorlib]System.Func`2<class '<>f__AnonymousType17`2'<!0,!1>,!1> class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__21`2'<!!TA,!!TB>::'<>9__21_2'
IL_0063: stsfld class [mscorlib]System.Func`2<class '<>f__AnonymousType17`2'<!0,!1>,!1> class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__22`2'<!!TA,!!TB>::'<>9__22_2'
IL_0068: call valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.Maybe`1<!!1> ICSharpCode.Decompiler.Tests.TestCases.Pretty.MaybeExtensions::Select<class '<>f__AnonymousType17`2'<!!0,!!1>,!!1>(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.Maybe`1<!!0>,
class [mscorlib]System.Func`2<!!0,!!1>)
IL_006d: ret

187
ICSharpCode.Decompiler.Tests/TestCases/Pretty/QueryExpressions.roslyn.il

@ -3960,6 +3960,10 @@ @@ -3960,6 +3960,10 @@
.field public static class [mscorlib]System.Func`2<class [System.Core]System.Linq.IGrouping`2<string,class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/Customer>,class '<>f__AnonymousType16`2'<string,int32>> '<>9__19_1'
.field public static class [mscorlib]System.Func`2<bool,bool> '<>9__20_0'
.field public static class [mscorlib]System.Func`2<bool,bool> '<>9__20_1'
.field public static class [mscorlib]System.Func`2<int32,bool> '<>9__21_0'
.field public static class [mscorlib]System.Func`2<int32,char> '<>9__21_1'
.field public static class [mscorlib]System.Func`2<int32,bool> '<>9__21_2'
.field public static class [mscorlib]System.Func`2<int32,char> '<>9__21_3'
.method private hidebysig specialname rtspecialname static
void .cctor() cil managed
{
@ -4605,25 +4609,67 @@ @@ -4605,25 +4609,67 @@
IL_0001: ret
} // end of method '<>c'::'<Issue437>b__20_1'
.method assembly hidebysig instance bool
'<Issue1310a>b__21_0'(int32 c) cil managed
{
// Code size 8 (0x8)
.maxstack 8
IL_0000: ldarg.1
IL_0001: conv.u2
IL_0002: call bool [mscorlib]System.Char::IsLetter(char)
IL_0007: ret
} // end of method '<>c'::'<Issue1310a>b__21_0'
.method assembly hidebysig instance char
'<Issue1310a>b__21_1'(int32 c) cil managed
{
// Code size 3 (0x3)
.maxstack 8
IL_0000: ldarg.1
IL_0001: conv.u2
IL_0002: ret
} // end of method '<>c'::'<Issue1310a>b__21_1'
.method assembly hidebysig instance bool
'<Issue1310a>b__21_2'(int32 c) cil managed
{
// Code size 8 (0x8)
.maxstack 8
IL_0000: ldarg.1
IL_0001: conv.u2
IL_0002: call bool [mscorlib]System.Char::IsDigit(char)
IL_0007: ret
} // end of method '<>c'::'<Issue1310a>b__21_2'
.method assembly hidebysig instance char
'<Issue1310a>b__21_3'(int32 c) cil managed
{
// Code size 3 (0x3)
.maxstack 8
IL_0000: ldarg.1
IL_0001: conv.u2
IL_0002: ret
} // end of method '<>c'::'<Issue1310a>b__21_3'
} // end of class '<>c'
.class auto ansi serializable sealed nested private beforefieldinit '<>c__21`2'<TA,class TB>
.class auto ansi serializable sealed nested private beforefieldinit '<>c__22`2'<TA,class TB>
extends [mscorlib]System.Object
{
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
.field public static initonly class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__21`2'<!TA,!TB> '<>9'
.field public static class [mscorlib]System.Func`2<!TA,class '<>f__AnonymousType17`2'<!TA,!TB>> '<>9__21_0'
.field public static class [mscorlib]System.Func`2<class '<>f__AnonymousType17`2'<!TA,!TB>,bool> '<>9__21_1'
.field public static class [mscorlib]System.Func`2<class '<>f__AnonymousType17`2'<!TA,!TB>,!TB> '<>9__21_2'
.field public static initonly class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__22`2'<!TA,!TB> '<>9'
.field public static class [mscorlib]System.Func`2<!TA,class '<>f__AnonymousType17`2'<!TA,!TB>> '<>9__22_0'
.field public static class [mscorlib]System.Func`2<class '<>f__AnonymousType17`2'<!TA,!TB>,bool> '<>9__22_1'
.field public static class [mscorlib]System.Func`2<class '<>f__AnonymousType17`2'<!TA,!TB>,!TB> '<>9__22_2'
.method private hidebysig specialname rtspecialname static
void .cctor() cil managed
{
// Code size 11 (0xb)
.maxstack 8
IL_0000: newobj instance void class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__21`2'<!TA,!TB>::.ctor()
IL_0005: stsfld class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__21`2'<!0,!1> class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__21`2'<!TA,!TB>::'<>9'
IL_0000: newobj instance void class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__22`2'<!TA,!TB>::.ctor()
IL_0005: stsfld class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__22`2'<!0,!1> class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__22`2'<!TA,!TB>::'<>9'
IL_000a: ret
} // end of method '<>c__21`2'::.cctor
} // end of method '<>c__22`2'::.cctor
.method public hidebysig specialname rtspecialname
instance void .ctor() cil managed
@ -4634,10 +4680,10 @@ @@ -4634,10 +4680,10 @@
IL_0001: call instance void [mscorlib]System.Object::.ctor()
IL_0006: nop
IL_0007: ret
} // end of method '<>c__21`2'::.ctor
} // end of method '<>c__22`2'::.ctor
.method assembly hidebysig instance class '<>f__AnonymousType17`2'<!TA,!TB>
'<Cast>b__21_0'(!TA m) cil managed
'<Cast>b__22_0'(!TA m) cil managed
{
// Code size 23 (0x17)
.maxstack 8
@ -4649,10 +4695,10 @@ @@ -4649,10 +4695,10 @@
IL_0011: newobj instance void class '<>f__AnonymousType17`2'<!TA,!TB>::.ctor(!0,
!1)
IL_0016: ret
} // end of method '<>c__21`2'::'<Cast>b__21_0'
} // end of method '<>c__22`2'::'<Cast>b__22_0'
.method assembly hidebysig instance bool
'<Cast>b__21_1'(class '<>f__AnonymousType17`2'<!TA,!TB> '<>h__TransparentIdentifier0') cil managed
'<Cast>b__22_1'(class '<>f__AnonymousType17`2'<!TA,!TB> '<>h__TransparentIdentifier0') cil managed
{
// Code size 15 (0xf)
.maxstack 8
@ -4662,19 +4708,19 @@ @@ -4662,19 +4708,19 @@
IL_000b: ldnull
IL_000c: cgt.un
IL_000e: ret
} // end of method '<>c__21`2'::'<Cast>b__21_1'
} // end of method '<>c__22`2'::'<Cast>b__22_1'
.method assembly hidebysig instance !TB
'<Cast>b__21_2'(class '<>f__AnonymousType17`2'<!TA,!TB> '<>h__TransparentIdentifier0') cil managed
'<Cast>b__22_2'(class '<>f__AnonymousType17`2'<!TA,!TB> '<>h__TransparentIdentifier0') cil managed
{
// Code size 7 (0x7)
.maxstack 8
IL_0000: ldarg.1
IL_0001: callvirt instance !1 class '<>f__AnonymousType17`2'<!TA,!TB>::get_t()
IL_0006: ret
} // end of method '<>c__21`2'::'<Cast>b__21_2'
} // end of method '<>c__22`2'::'<Cast>b__22_2'
} // end of class '<>c__21`2'
} // end of class '<>c__22`2'
.field public class [mscorlib]System.Collections.Generic.IEnumerable`1<class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/Customer> customers
.field public class [mscorlib]System.Collections.Generic.IEnumerable`1<class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/Order> orders
@ -5502,6 +5548,91 @@ @@ -5502,6 +5548,91 @@
IL_004e: ret
} // end of method QueryExpressions::Issue437
.method public hidebysig static class [mscorlib]System.Collections.Generic.IEnumerable`1<char>
Issue1310a(bool test) cil managed
{
// Code size 185 (0xb9)
.maxstack 3
.locals init (class [mscorlib]System.Collections.Generic.IEnumerable`1<char> V_0,
class [mscorlib]System.Collections.Generic.IEnumerable`1<char> V_1)
IL_0000: nop
IL_0001: ldarg.0
IL_0002: brtrue.s IL_0059
IL_0004: ldc.i4.0
IL_0005: ldc.i4 0xff
IL_000a: call class [mscorlib]System.Collections.Generic.IEnumerable`1<int32> [System.Core]System.Linq.Enumerable::Range(int32,
int32)
IL_000f: ldsfld class [mscorlib]System.Func`2<int32,bool> ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c'::'<>9__21_2'
IL_0014: dup
IL_0015: brtrue.s IL_002e
IL_0017: pop
IL_0018: ldsfld class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c' ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c'::'<>9'
IL_001d: ldftn instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c'::'<Issue1310a>b__21_2'(int32)
IL_0023: newobj instance void class [mscorlib]System.Func`2<int32,bool>::.ctor(object,
native int)
IL_0028: dup
IL_0029: stsfld class [mscorlib]System.Func`2<int32,bool> ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c'::'<>9__21_2'
IL_002e: call class [mscorlib]System.Collections.Generic.IEnumerable`1<!!0> [System.Core]System.Linq.Enumerable::Where<int32>(class [mscorlib]System.Collections.Generic.IEnumerable`1<!!0>,
class [mscorlib]System.Func`2<!!0,bool>)
IL_0033: ldsfld class [mscorlib]System.Func`2<int32,char> ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c'::'<>9__21_3'
IL_0038: dup
IL_0039: brtrue.s IL_0052
IL_003b: pop
IL_003c: ldsfld class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c' ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c'::'<>9'
IL_0041: ldftn instance char ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c'::'<Issue1310a>b__21_3'(int32)
IL_0047: newobj instance void class [mscorlib]System.Func`2<int32,char>::.ctor(object,
native int)
IL_004c: dup
IL_004d: stsfld class [mscorlib]System.Func`2<int32,char> ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c'::'<>9__21_3'
IL_0052: call class [mscorlib]System.Collections.Generic.IEnumerable`1<!!1> [System.Core]System.Linq.Enumerable::Select<int32,char>(class [mscorlib]System.Collections.Generic.IEnumerable`1<!!0>,
class [mscorlib]System.Func`2<!!0,!!1>)
IL_0057: br.s IL_00ac
IL_0059: ldc.i4.0
IL_005a: ldc.i4 0xff
IL_005f: call class [mscorlib]System.Collections.Generic.IEnumerable`1<int32> [System.Core]System.Linq.Enumerable::Range(int32,
int32)
IL_0064: ldsfld class [mscorlib]System.Func`2<int32,bool> ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c'::'<>9__21_0'
IL_0069: dup
IL_006a: brtrue.s IL_0083
IL_006c: pop
IL_006d: ldsfld class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c' ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c'::'<>9'
IL_0072: ldftn instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c'::'<Issue1310a>b__21_0'(int32)
IL_0078: newobj instance void class [mscorlib]System.Func`2<int32,bool>::.ctor(object,
native int)
IL_007d: dup
IL_007e: stsfld class [mscorlib]System.Func`2<int32,bool> ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c'::'<>9__21_0'
IL_0083: call class [mscorlib]System.Collections.Generic.IEnumerable`1<!!0> [System.Core]System.Linq.Enumerable::Where<int32>(class [mscorlib]System.Collections.Generic.IEnumerable`1<!!0>,
class [mscorlib]System.Func`2<!!0,bool>)
IL_0088: ldsfld class [mscorlib]System.Func`2<int32,char> ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c'::'<>9__21_1'
IL_008d: dup
IL_008e: brtrue.s IL_00a7
IL_0090: pop
IL_0091: ldsfld class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c' ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c'::'<>9'
IL_0096: ldftn instance char ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c'::'<Issue1310a>b__21_1'(int32)
IL_009c: newobj instance void class [mscorlib]System.Func`2<int32,char>::.ctor(object,
native int)
IL_00a1: dup
IL_00a2: stsfld class [mscorlib]System.Func`2<int32,char> ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c'::'<>9__21_1'
IL_00a7: call class [mscorlib]System.Collections.Generic.IEnumerable`1<!!1> [System.Core]System.Linq.Enumerable::Select<int32,char>(class [mscorlib]System.Collections.Generic.IEnumerable`1<!!0>,
class [mscorlib]System.Func`2<!!0,!!1>)
IL_00ac: stloc.0
IL_00ad: ldloc.0
IL_00ae: ldloc.0
IL_00af: call class [mscorlib]System.Collections.Generic.IEnumerable`1<!!0> [System.Core]System.Linq.Enumerable::Concat<char>(class [mscorlib]System.Collections.Generic.IEnumerable`1<!!0>,
class [mscorlib]System.Collections.Generic.IEnumerable`1<!!0>)
IL_00b4: stloc.1
IL_00b5: br.s IL_00b7
IL_00b7: ldloc.1
IL_00b8: ret
} // end of method QueryExpressions::Issue1310a
.method public hidebysig static valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.Maybe`1<!!TB>
Cast<TA,class TB>(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.Maybe`1<!!TA> a) cil managed
{
@ -5510,43 +5641,43 @@ @@ -5510,43 +5641,43 @@
.locals init (valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.Maybe`1<!!TB> V_0)
IL_0000: nop
IL_0001: ldarg.0
IL_0002: ldsfld class [mscorlib]System.Func`2<!0,class '<>f__AnonymousType17`2'<!0,!1>> class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__21`2'<!!TA,!!TB>::'<>9__21_0'
IL_0002: ldsfld class [mscorlib]System.Func`2<!0,class '<>f__AnonymousType17`2'<!0,!1>> class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__22`2'<!!TA,!!TB>::'<>9__22_0'
IL_0007: dup
IL_0008: brtrue.s IL_0021
IL_000a: pop
IL_000b: ldsfld class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__21`2'<!0,!1> class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__21`2'<!!TA,!!TB>::'<>9'
IL_0010: ldftn instance class '<>f__AnonymousType17`2'<!0,!1> class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__21`2'<!!TA,!!TB>::'<Cast>b__21_0'(!0)
IL_000b: ldsfld class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__22`2'<!0,!1> class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__22`2'<!!TA,!!TB>::'<>9'
IL_0010: ldftn instance class '<>f__AnonymousType17`2'<!0,!1> class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__22`2'<!!TA,!!TB>::'<Cast>b__22_0'(!0)
IL_0016: newobj instance void class [mscorlib]System.Func`2<!!TA,class '<>f__AnonymousType17`2'<!!TA,!!TB>>::.ctor(object,
native int)
IL_001b: dup
IL_001c: stsfld class [mscorlib]System.Func`2<!0,class '<>f__AnonymousType17`2'<!0,!1>> class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__21`2'<!!TA,!!TB>::'<>9__21_0'
IL_001c: stsfld class [mscorlib]System.Func`2<!0,class '<>f__AnonymousType17`2'<!0,!1>> class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__22`2'<!!TA,!!TB>::'<>9__22_0'
IL_0021: call valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.Maybe`1<!!1> ICSharpCode.Decompiler.Tests.TestCases.Pretty.MaybeExtensions::Select<!!0,class '<>f__AnonymousType17`2'<!!0,!!1>>(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.Maybe`1<!!0>,
class [mscorlib]System.Func`2<!!0,!!1>)
IL_0026: ldsfld class [mscorlib]System.Func`2<class '<>f__AnonymousType17`2'<!0,!1>,bool> class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__21`2'<!!TA,!!TB>::'<>9__21_1'
IL_0026: ldsfld class [mscorlib]System.Func`2<class '<>f__AnonymousType17`2'<!0,!1>,bool> class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__22`2'<!!TA,!!TB>::'<>9__22_1'
IL_002b: dup
IL_002c: brtrue.s IL_0045
IL_002e: pop
IL_002f: ldsfld class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__21`2'<!0,!1> class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__21`2'<!!TA,!!TB>::'<>9'
IL_0034: ldftn instance bool class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__21`2'<!!TA,!!TB>::'<Cast>b__21_1'(class '<>f__AnonymousType17`2'<!0,!1>)
IL_002f: ldsfld class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__22`2'<!0,!1> class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__22`2'<!!TA,!!TB>::'<>9'
IL_0034: ldftn instance bool class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__22`2'<!!TA,!!TB>::'<Cast>b__22_1'(class '<>f__AnonymousType17`2'<!0,!1>)
IL_003a: newobj instance void class [mscorlib]System.Func`2<class '<>f__AnonymousType17`2'<!!TA,!!TB>,bool>::.ctor(object,
native int)
IL_003f: dup
IL_0040: stsfld class [mscorlib]System.Func`2<class '<>f__AnonymousType17`2'<!0,!1>,bool> class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__21`2'<!!TA,!!TB>::'<>9__21_1'
IL_0040: stsfld class [mscorlib]System.Func`2<class '<>f__AnonymousType17`2'<!0,!1>,bool> class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__22`2'<!!TA,!!TB>::'<>9__22_1'
IL_0045: call valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.Maybe`1<!!0> ICSharpCode.Decompiler.Tests.TestCases.Pretty.MaybeExtensions::Where<class '<>f__AnonymousType17`2'<!!0,!!1>>(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.Maybe`1<!!0>,
class [mscorlib]System.Func`2<!!0,bool>)
IL_004a: ldsfld class [mscorlib]System.Func`2<class '<>f__AnonymousType17`2'<!0,!1>,!1> class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__21`2'<!!TA,!!TB>::'<>9__21_2'
IL_004a: ldsfld class [mscorlib]System.Func`2<class '<>f__AnonymousType17`2'<!0,!1>,!1> class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__22`2'<!!TA,!!TB>::'<>9__22_2'
IL_004f: dup
IL_0050: brtrue.s IL_0069
IL_0052: pop
IL_0053: ldsfld class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__21`2'<!0,!1> class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__21`2'<!!TA,!!TB>::'<>9'
IL_0058: ldftn instance !1 class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__21`2'<!!TA,!!TB>::'<Cast>b__21_2'(class '<>f__AnonymousType17`2'<!0,!1>)
IL_0053: ldsfld class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__22`2'<!0,!1> class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__22`2'<!!TA,!!TB>::'<>9'
IL_0058: ldftn instance !1 class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__22`2'<!!TA,!!TB>::'<Cast>b__22_2'(class '<>f__AnonymousType17`2'<!0,!1>)
IL_005e: newobj instance void class [mscorlib]System.Func`2<class '<>f__AnonymousType17`2'<!!TA,!!TB>,!!TB>::.ctor(object,
native int)
IL_0063: dup
IL_0064: stsfld class [mscorlib]System.Func`2<class '<>f__AnonymousType17`2'<!0,!1>,!1> class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__21`2'<!!TA,!!TB>::'<>9__21_2'
IL_0064: stsfld class [mscorlib]System.Func`2<class '<>f__AnonymousType17`2'<!0,!1>,!1> class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__22`2'<!!TA,!!TB>::'<>9__22_2'
IL_0069: call valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.Maybe`1<!!1> ICSharpCode.Decompiler.Tests.TestCases.Pretty.MaybeExtensions::Select<class '<>f__AnonymousType17`2'<!!0,!!1>,!!1>(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.Maybe`1<!!0>,
class [mscorlib]System.Func`2<!!0,!!1>)
IL_006e: stloc.0

32
ICSharpCode.Decompiler.Tests/UglyTestRunner.cs

@ -47,28 +47,28 @@ namespace ICSharpCode.Decompiler.Tests @@ -47,28 +47,28 @@ namespace ICSharpCode.Decompiler.Tests
}
}
static readonly CSharpCompilerOptions[] noRoslynOptions =
static readonly CompilerOptions[] noRoslynOptions =
{
CSharpCompilerOptions.None,
CSharpCompilerOptions.Optimize
CompilerOptions.None,
CompilerOptions.Optimize
};
static readonly CSharpCompilerOptions[] roslynOnlyOptions =
static readonly CompilerOptions[] roslynOnlyOptions =
{
CSharpCompilerOptions.UseRoslyn,
CSharpCompilerOptions.Optimize | CSharpCompilerOptions.UseRoslyn
CompilerOptions.UseRoslyn,
CompilerOptions.Optimize | CompilerOptions.UseRoslyn
};
static readonly CSharpCompilerOptions[] defaultOptions =
static readonly CompilerOptions[] defaultOptions =
{
CSharpCompilerOptions.None,
CSharpCompilerOptions.Optimize,
CSharpCompilerOptions.UseRoslyn,
CSharpCompilerOptions.Optimize | CSharpCompilerOptions.UseRoslyn
CompilerOptions.None,
CompilerOptions.Optimize,
CompilerOptions.UseRoslyn,
CompilerOptions.Optimize | CompilerOptions.UseRoslyn
};
[Test]
public void NoArrayInitializers([ValueSource("roslynOnlyOptions")] CSharpCompilerOptions cscOptions)
public void NoArrayInitializers([ValueSource("roslynOnlyOptions")] CompilerOptions cscOptions)
{
RunForLibrary(cscOptions: cscOptions, decompilerSettings: new DecompilerSettings {
ArrayInitializers = false
@ -76,19 +76,19 @@ namespace ICSharpCode.Decompiler.Tests @@ -76,19 +76,19 @@ namespace ICSharpCode.Decompiler.Tests
}
[Test]
public void NoDecimalConstants([ValueSource("roslynOnlyOptions")] CSharpCompilerOptions cscOptions)
public void NoDecimalConstants([ValueSource("roslynOnlyOptions")] CompilerOptions cscOptions)
{
RunForLibrary(cscOptions: cscOptions, decompilerSettings: new DecompilerSettings {
DecimalConstants = false
});
}
void RunForLibrary([CallerMemberName] string testName = null, AssemblerOptions asmOptions = AssemblerOptions.None, CSharpCompilerOptions cscOptions = CSharpCompilerOptions.None, DecompilerSettings decompilerSettings = null)
void RunForLibrary([CallerMemberName] string testName = null, AssemblerOptions asmOptions = AssemblerOptions.None, CompilerOptions cscOptions = CompilerOptions.None, DecompilerSettings decompilerSettings = null)
{
Run(testName, asmOptions | AssemblerOptions.Library, cscOptions | CSharpCompilerOptions.Library, decompilerSettings);
Run(testName, asmOptions | AssemblerOptions.Library, cscOptions | CompilerOptions.Library, decompilerSettings);
}
void Run([CallerMemberName] string testName = null, AssemblerOptions asmOptions = AssemblerOptions.None, CSharpCompilerOptions cscOptions = CSharpCompilerOptions.None, DecompilerSettings decompilerSettings = null)
void Run([CallerMemberName] string testName = null, AssemblerOptions asmOptions = AssemblerOptions.None, CompilerOptions cscOptions = CompilerOptions.None, DecompilerSettings decompilerSettings = null)
{
var ilFile = Path.Combine(TestCasePath, testName) + Tester.GetSuffix(cscOptions) + ".il";
var csFile = Path.Combine(TestCasePath, testName + ".cs");

20
ICSharpCode.Decompiler.Tests/VBPrettyTestRunner.cs

@ -46,27 +46,27 @@ namespace ICSharpCode.Decompiler.Tests @@ -46,27 +46,27 @@ namespace ICSharpCode.Decompiler.Tests
}
}
static readonly VBCompilerOptions[] defaultOptions =
static readonly CompilerOptions[] defaultOptions =
{
VBCompilerOptions.None,
VBCompilerOptions.Optimize,
VBCompilerOptions.UseRoslyn,
VBCompilerOptions.Optimize | VBCompilerOptions.UseRoslyn,
CompilerOptions.None,
CompilerOptions.Optimize,
CompilerOptions.UseRoslyn,
CompilerOptions.Optimize | CompilerOptions.UseRoslyn,
};
static readonly VBCompilerOptions[] roslynOnlyOptions =
static readonly CompilerOptions[] roslynOnlyOptions =
{
VBCompilerOptions.UseRoslyn,
VBCompilerOptions.Optimize | VBCompilerOptions.UseRoslyn,
CompilerOptions.UseRoslyn,
CompilerOptions.Optimize | CompilerOptions.UseRoslyn,
};
[Test, Ignore("Implement VB async/await")]
public void Async([ValueSource("defaultOptions")] VBCompilerOptions options)
public void Async([ValueSource("defaultOptions")] CompilerOptions options)
{
Run(options: options);
}
void Run([CallerMemberName] string testName = null, VBCompilerOptions options = VBCompilerOptions.UseDebug, DecompilerSettings settings = null)
void Run([CallerMemberName] string testName = null, CompilerOptions options = CompilerOptions.UseDebug, DecompilerSettings settings = null)
{
var vbFile = Path.Combine(TestCasePath, testName + ".vb");
var csFile = Path.Combine(TestCasePath, testName + ".cs");

1
ICSharpCode.Decompiler/CSharp/OutputVisitor/CSharpAmbience.cs

@ -184,6 +184,7 @@ namespace ICSharpCode.Decompiler.CSharp.OutputVisitor @@ -184,6 +184,7 @@ namespace ICSharpCode.Decompiler.CSharp.OutputVisitor
{
TypeSystemAstBuilder astBuilder = new TypeSystemAstBuilder();
astBuilder.AddTypeReferenceAnnotations = true;
astBuilder.ShowTypeParametersForUnboundTypes = true;
astBuilder.ShowModifiers = (ConversionFlags & ConversionFlags.ShowModifiers) == ConversionFlags.ShowModifiers;
astBuilder.ShowAccessibility = (ConversionFlags & ConversionFlags.ShowAccessibility) == ConversionFlags.ShowAccessibility;
astBuilder.AlwaysUseShortTypeNames = (ConversionFlags & ConversionFlags.UseFullyQualifiedTypeNames) != ConversionFlags.UseFullyQualifiedTypeNames;

8
ICSharpCode.Decompiler/CSharp/OutputVisitor/CSharpOutputVisitor.cs

@ -1141,11 +1141,8 @@ namespace ICSharpCode.Decompiler.CSharp.OutputVisitor @@ -1141,11 +1141,8 @@ namespace ICSharpCode.Decompiler.CSharp.OutputVisitor
public virtual void VisitQueryExpression(QueryExpression queryExpression)
{
StartNode(queryExpression);
bool indent = queryExpression.Parent is QueryClause && !(queryExpression.Parent is QueryContinuationClause);
if (indent) {
if (queryExpression.Role != QueryContinuationClause.PrecedingQueryRole)
writer.Indent();
NewLine();
}
bool first = true;
foreach (var clause in queryExpression.Clauses) {
if (first) {
@ -1157,9 +1154,8 @@ namespace ICSharpCode.Decompiler.CSharp.OutputVisitor @@ -1157,9 +1154,8 @@ namespace ICSharpCode.Decompiler.CSharp.OutputVisitor
}
clause.AcceptVisitor(this);
}
if (indent) {
if (queryExpression.Role != QueryContinuationClause.PrecedingQueryRole)
writer.Unindent();
}
EndNode(queryExpression);
}

53
ICSharpCode.Decompiler/CSharp/OutputVisitor/TextWriterTokenWriter.cs

@ -63,8 +63,9 @@ namespace ICSharpCode.Decompiler.CSharp.OutputVisitor @@ -63,8 +63,9 @@ namespace ICSharpCode.Decompiler.CSharp.OutputVisitor
textWriter.Write('@');
column++;
}
textWriter.Write(identifier.Name);
column += identifier.Name.Length;
string name = EscapeIdentifier(identifier.Name);
textWriter.Write(name);
column += name.Length;
isAtStartOfLine = false;
}
@ -417,6 +418,54 @@ namespace ICSharpCode.Decompiler.CSharp.OutputVisitor @@ -417,6 +418,54 @@ namespace ICSharpCode.Decompiler.CSharp.OutputVisitor
}
return sb.ToString();
}
public static string EscapeIdentifier(string identifier)
{
if (string.IsNullOrEmpty(identifier))
return identifier;
StringBuilder sb = new StringBuilder();
for (int i = 0; i < identifier.Length; i++) {
if (IsPrintableIdentifierChar(identifier, i)) {
if (char.IsSurrogatePair(identifier, i)) {
sb.Append(identifier.Substring(i, 2));
i++;
} else {
sb.Append(identifier[i]);
}
} else {
if (char.IsSurrogatePair(identifier, i)) {
sb.AppendFormat("\\U{0:x8}", char.ConvertToUtf32(identifier, i));
i++;
} else {
sb.AppendFormat("\\u{0:x4}", (int)identifier[i]);
}
}
}
return sb.ToString();
}
static bool IsPrintableIdentifierChar(string identifier, int index)
{
switch (char.GetUnicodeCategory(identifier, index)) {
case UnicodeCategory.ModifierLetter:
case UnicodeCategory.NonSpacingMark:
case UnicodeCategory.SpacingCombiningMark:
case UnicodeCategory.EnclosingMark:
case UnicodeCategory.LineSeparator:
case UnicodeCategory.ParagraphSeparator:
case UnicodeCategory.Control:
case UnicodeCategory.Format:
case UnicodeCategory.Surrogate:
case UnicodeCategory.PrivateUse:
case UnicodeCategory.ConnectorPunctuation:
case UnicodeCategory.ModifierSymbol:
case UnicodeCategory.OtherNotAssigned:
case UnicodeCategory.SpaceSeparator:
return false;
default:
return true;
}
}
public override void WritePrimitiveType(string type)
{

15
ICSharpCode.Decompiler/CSharp/Syntax/TypeSystemAstBuilder.cs

@ -111,6 +111,12 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax @@ -111,6 +111,12 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
/// The default value is <c>true</c>.
/// </summary>
public bool ShowTypeParameters { get; set; }
/// <summary>
/// Controls whether type parameter names are shown for unbound types.
/// The default value is <c>false</c>.
/// </summary>
public bool ShowTypeParametersForUnboundTypes { get; set; }
/// <summary>
/// Controls whether constraints on type parameter declarations are shown.
@ -262,6 +268,8 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax @@ -262,6 +268,8 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
return astType;
}
if (type is ITypeDefinition typeDef) {
if (ShowTypeParametersForUnboundTypes)
return ConvertTypeHelper(typeDef, typeDef.TypeArguments);
if (typeDef.TypeParameterCount > 0) {
// Unbound type
IType[] typeArguments = new IType[typeDef.TypeParameterCount];
@ -272,6 +280,7 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax @@ -272,6 +280,7 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
} else {
return ConvertTypeHelper(typeDef, EmptyList<IType>.Instance);
}
}
return new SimpleType(type.Name);
}
@ -742,7 +751,9 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax @@ -742,7 +751,9 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
expression = null;
if (!specialConstants.TryGetValue(constant, out var info))
return false;
if (!UseSpecialConstants) {
// if the field definition cannot be found, do not generate a reference to the field.
var field = type.GetFields(p => p.Name == info.Member).SingleOrDefault();
if (!UseSpecialConstants || field == null) {
// +Infty, -Infty and NaN, cannot be represented in their encoded form.
// Use an equivalent arithmetic expression instead.
if (info.Type == KnownTypeCode.Double) {
@ -800,7 +811,7 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax @@ -800,7 +811,7 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
expression = new MemberReferenceExpression(expression, info.Member);
if (AddResolveResultAnnotations)
expression.AddAnnotation(new MemberResolveResult(new TypeResolveResult(type), type.GetFields(p => p.Name == info.Member).Single()));
expression.AddAnnotation(new MemberResolveResult(new TypeResolveResult(type), field));
return true;
}

130
ICSharpCode.Decompiler/CSharp/Transforms/CombineQueryExpressions.cs

@ -17,6 +17,7 @@ @@ -17,6 +17,7 @@
// DEALINGS IN THE SOFTWARE.
using System;
using System.Collections.Generic;
using System.Linq;
using ICSharpCode.Decompiler.CSharp.Syntax;
using ICSharpCode.Decompiler.CSharp.Syntax.PatternMatching;
@ -32,7 +33,7 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms @@ -32,7 +33,7 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
{
if (!context.Settings.QueryExpressions)
return;
CombineQueries(rootNode);
CombineQueries(rootNode, new Dictionary<string, object>());
}
static readonly InvocationExpression castPattern = new InvocationExpression {
@ -42,18 +43,18 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms @@ -42,18 +43,18 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
TypeArguments = { new AnyNode("targetType") }
}};
void CombineQueries(AstNode node)
void CombineQueries(AstNode node, Dictionary<string, object> letIdentifiers)
{
for (AstNode child = node.FirstChild; child != null; child = child.NextSibling) {
CombineQueries(child);
CombineQueries(child, letIdentifiers);
}
QueryExpression query = node as QueryExpression;
if (query != null) {
QueryFromClause fromClause = (QueryFromClause)query.Clauses.First();
QueryExpression innerQuery = fromClause.Expression as QueryExpression;
if (innerQuery != null) {
if (TryRemoveTransparentIdentifier(query, fromClause, innerQuery)) {
RemoveTransparentIdentifierReferences(query);
if (TryRemoveTransparentIdentifier(query, fromClause, innerQuery, letIdentifiers)) {
RemoveTransparentIdentifierReferences(query, letIdentifiers);
} else {
QueryContinuationClause continuation = new QueryContinuationClause();
continuation.PrecedingQuery = innerQuery.Detach();
@ -69,80 +70,65 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms @@ -69,80 +70,65 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
}
}
}
static readonly QuerySelectClause selectTransparentIdentifierPattern = new QuerySelectClause {
Expression = new Choice {
new AnonymousTypeCreateExpression {
Initializers = {
new NamedExpression {
Name = Pattern.AnyString,
Expression = new IdentifierExpression(Pattern.AnyString)
}.WithName("nae1"),
new NamedExpression {
Name = Pattern.AnyString,
Expression = new AnyNode("nae2Expr")
}.WithName("nae2")
}
},
new AnonymousTypeCreateExpression {
Initializers = {
new NamedNode("identifier", new IdentifierExpression(Pattern.AnyString)),
new AnyNode("nae2Expr")
}
Expression = new AnonymousTypeCreateExpression {
Initializers = {
new Repeat(
new Choice {
new IdentifierExpression(Pattern.AnyString).WithName("expr"), // capture variable with same name
new NamedExpression {
Name = Pattern.AnyString,
Expression = new AnyNode()
}.WithName("expr")
}
) { MinCount = 1 }
}
}};
}
};
bool IsTransparentIdentifier(string identifier)
{
return identifier.StartsWith("<>", StringComparison.Ordinal) && (identifier.Contains("TransparentIdentifier") || identifier.Contains("TranspIdent"));
}
bool TryRemoveTransparentIdentifier(QueryExpression query, QueryFromClause fromClause, QueryExpression innerQuery)
bool TryRemoveTransparentIdentifier(QueryExpression query, QueryFromClause fromClause, QueryExpression innerQuery, Dictionary<string, object> letClauses)
{
if (!IsTransparentIdentifier(fromClause.Identifier))
return false;
Match match = selectTransparentIdentifierPattern.Match(innerQuery.Clauses.Last());
QuerySelectClause selectClause = innerQuery.Clauses.Last() as QuerySelectClause;
Match match = selectTransparentIdentifierPattern.Match(selectClause);
if (!match.Success)
return false;
QuerySelectClause selectClause = (QuerySelectClause)innerQuery.Clauses.Last();
NamedExpression nae1 = match.Get<NamedExpression>("nae1").SingleOrDefault();
NamedExpression nae2 = match.Get<NamedExpression>("nae2").SingleOrDefault();
if (nae1 != null && nae1.Name != ((IdentifierExpression)nae1.Expression).Identifier)
return false;
Expression nae2Expr = match.Get<Expression>("nae2Expr").Single();
IdentifierExpression nae2IdentExpr = nae2Expr as IdentifierExpression;
if (nae2IdentExpr != null && (nae2 == null || nae2.Name == nae2IdentExpr.Identifier)) {
// from * in (from x in ... select new { x = x, y = y }) ...
// =>
// from x in ... ...
fromClause.Remove();
selectClause.Remove();
// Move clauses from innerQuery to query
QueryClause insertionPos = null;
foreach (var clause in innerQuery.Clauses) {
query.Clauses.InsertAfter(insertionPos, insertionPos = clause.Detach());
}
} else {
// from * in (from x in ... select new { x = x, y = expr }) ...
// =>
// from x in ... let y = expr ...
fromClause.Remove();
selectClause.Remove();
// Move clauses from innerQuery to query
QueryClause insertionPos = null;
foreach (var clause in innerQuery.Clauses) {
query.Clauses.InsertAfter(insertionPos, insertionPos = clause.Detach());
// from * in (from x in ... select new { members of anonymous type }) ...
// =>
// from x in ... { let x = ... } ...
fromClause.Remove();
selectClause.Remove();
// Move clauses from innerQuery to query
QueryClause insertionPos = null;
foreach (var clause in innerQuery.Clauses) {
query.Clauses.InsertAfter(insertionPos, insertionPos = clause.Detach());
}
foreach (var expr in match.Get<Expression>("expr")) {
switch (expr) {
case IdentifierExpression identifier:
// nothing to add
continue;
case NamedExpression namedExpression:
if (namedExpression.Expression is IdentifierExpression identifierExpression && namedExpression.Name == identifierExpression.Identifier) {
letClauses[namedExpression.Name] = identifierExpression.Annotation<ILVariableResolveResult>();
continue;
}
QueryLetClause letClause = new QueryLetClause { Identifier = namedExpression.Name, Expression = namedExpression.Expression.Detach() };
var annotation = new LetIdentifierAnnotation();
letClause.AddAnnotation(annotation);
letClauses[namedExpression.Name] = annotation;
query.Clauses.InsertAfter(insertionPos, letClause);
break;
}
string ident;
if (nae2 != null)
ident = nae2.Name;
else if (nae2Expr is IdentifierExpression)
ident = ((IdentifierExpression)nae2Expr).Identifier;
else if (nae2Expr is MemberReferenceExpression)
ident = ((MemberReferenceExpression)nae2Expr).MemberName;
else
throw new InvalidOperationException("Could not infer name from initializer in AnonymousTypeCreateExpression");
query.Clauses.InsertAfter(insertionPos, new QueryLetClause { Identifier = ident, Expression = nae2Expr.Detach() });
}
return true;
}
@ -150,10 +136,10 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms @@ -150,10 +136,10 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
/// <summary>
/// Removes all occurrences of transparent identifiers
/// </summary>
void RemoveTransparentIdentifierReferences(AstNode node)
void RemoveTransparentIdentifierReferences(AstNode node, Dictionary<string, object> letClauses)
{
foreach (AstNode child in node.Children) {
RemoveTransparentIdentifierReferences(child);
RemoveTransparentIdentifierReferences(child, letClauses);
}
MemberReferenceExpression mre = node as MemberReferenceExpression;
if (mre != null) {
@ -162,11 +148,17 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms @@ -162,11 +148,17 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
IdentifierExpression newIdent = new IdentifierExpression(mre.MemberName);
mre.TypeArguments.MoveTo(newIdent.TypeArguments);
newIdent.CopyAnnotationsFrom(mre);
newIdent.RemoveAnnotations<PropertyDeclaration>(); // remove the reference to the property of the anonymous type
newIdent.RemoveAnnotations<Semantics.MemberResolveResult>(); // remove the reference to the property of the anonymous type
if (letClauses.TryGetValue(mre.MemberName, out var annotation))
newIdent.AddAnnotation(annotation);
mre.ReplaceWith(newIdent);
return;
}
}
}
}
public class LetIdentifierAnnotation
{
}
}

30
ICSharpCode.Decompiler/CSharp/Transforms/DeclareVariables.cs

@ -187,10 +187,10 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms @@ -187,10 +187,10 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
private static bool IsValidInStatementExpression(Expression expr)
{
switch (expr) {
case InvocationExpression ie:
case ObjectCreateExpression oce:
case AssignmentExpression ae:
case ErrorExpression ee:
case InvocationExpression _:
case ObjectCreateExpression _:
case AssignmentExpression _:
case ErrorExpression _:
return true;
case UnaryOperatorExpression uoe:
switch (uoe.Operator) {
@ -249,12 +249,27 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms @@ -249,12 +249,27 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
newPoint = scopeTracking[startIndex + 1].InsertionPoint;
} else {
newPoint = new InsertionPoint { level = nodeLevel, nextNode = identExpr };
if (variable.HasInitialValue) {
// Uninitialized variables are logically initialized at the beginning of the functin
// Because it's possible that the variable has a loop-carried dependency,
// declare it outside of any loops.
while (startIndex >= 0) {
if (scopeTracking[startIndex].Scope.EntryPoint.IncomingEdgeCount > 1) {
// declare variable outside of loop
newPoint = scopeTracking[startIndex].InsertionPoint;
} else if (scopeTracking[startIndex].Scope.Parent is ILFunction) {
// stop at beginning of function
break;
}
startIndex--;
}
}
}
VariableToDeclare v;
if (variableDict.TryGetValue(rr.Variable, out v)) {
if (variableDict.TryGetValue(variable, out v)) {
v.InsertionPoint = FindCommonParent(v.InsertionPoint, newPoint);
} else {
v = new VariableToDeclare(rr.Variable, rr.Variable.HasInitialValue,
v = new VariableToDeclare(variable, variable.HasInitialValue,
newPoint, identExpr, sourceOrder: variableDict.Count);
variableDict.Add(rr.Variable, v);
}
@ -271,7 +286,8 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms @@ -271,7 +286,8 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
switch (kind) {
case VariableKind.PinnedLocal:
case VariableKind.Parameter:
case VariableKind.Exception:
case VariableKind.ExceptionLocal:
case VariableKind.ExceptionStackSlot:
case VariableKind.UsingLocal:
case VariableKind.ForeachLocal:
return false;

114
ICSharpCode.Decompiler/CSharp/Transforms/IntroduceQueryExpressions.cs

@ -40,7 +40,7 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms @@ -40,7 +40,7 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
QueryFromClause fromClause = (QueryFromClause)query.Clauses.First();
if (IsDegenerateQuery(query)) {
// introduce select for degenerate query
query.Clauses.Add(new QuerySelectClause { Expression = new IdentifierExpression(fromClause.Identifier) });
query.Clauses.Add(new QuerySelectClause { Expression = new IdentifierExpression(fromClause.Identifier).CopyAnnotationsFrom(fromClause) });
}
// See if the data source of this query is a degenerate query,
// and combine the queries if possible.
@ -74,7 +74,10 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms @@ -74,7 +74,10 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
QueryExpression query = DecompileQuery(node as InvocationExpression);
if (query != null)
node.ReplaceWith(query);
for (AstNode child = (query ?? node).FirstChild; child != null; child = child.NextSibling) {
AstNode next;
for (AstNode child = (query ?? node).FirstChild; child != null; child = next) {
// store referece to next child before transformation
next = child.NextSibling;
DecompileQueries(child);
}
}
@ -91,12 +94,12 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms @@ -91,12 +94,12 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
{
if (invocation.Arguments.Count != 1)
return null;
string parameterName;
ParameterDeclaration parameter;
Expression body;
if (MatchSimpleLambda(invocation.Arguments.Single(), out parameterName, out body)) {
if (MatchSimpleLambda(invocation.Arguments.Single(), out parameter, out body)) {
QueryExpression query = new QueryExpression();
query.Clauses.Add(new QueryFromClause { Identifier = parameterName, Expression = mre.Target.Detach() });
query.Clauses.Add(new QuerySelectClause { Expression = WrapExpressionInParenthesesIfNecessary(body.Detach(), parameterName) });
query.Clauses.Add(MakeFromClause(parameter, mre.Target.Detach()));
query.Clauses.Add(new QuerySelectClause { Expression = WrapExpressionInParenthesesIfNecessary(body.Detach(), parameter.Name) });
return query;
}
return null;
@ -104,24 +107,24 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms @@ -104,24 +107,24 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
case "GroupBy":
{
if (invocation.Arguments.Count == 2) {
string parameterName1, parameterName2;
ParameterDeclaration parameter1, parameter2;
Expression keySelector, elementSelector;
if (MatchSimpleLambda(invocation.Arguments.ElementAt(0), out parameterName1, out keySelector)
&& MatchSimpleLambda(invocation.Arguments.ElementAt(1), out parameterName2, out elementSelector)
&& parameterName1 == parameterName2)
if (MatchSimpleLambda(invocation.Arguments.ElementAt(0), out parameter1, out keySelector)
&& MatchSimpleLambda(invocation.Arguments.ElementAt(1), out parameter2, out elementSelector)
&& parameter1.Name == parameter2.Name)
{
QueryExpression query = new QueryExpression();
query.Clauses.Add(new QueryFromClause { Identifier = parameterName1, Expression = mre.Target.Detach() });
query.Clauses.Add(MakeFromClause(parameter1, mre.Target.Detach()));
query.Clauses.Add(new QueryGroupClause { Projection = elementSelector.Detach(), Key = keySelector.Detach() });
return query;
}
} else if (invocation.Arguments.Count == 1) {
string parameterName;
ParameterDeclaration parameter;
Expression keySelector;
if (MatchSimpleLambda(invocation.Arguments.Single(), out parameterName, out keySelector)) {
if (MatchSimpleLambda(invocation.Arguments.Single(), out parameter, out keySelector)) {
QueryExpression query = new QueryExpression();
query.Clauses.Add(new QueryFromClause { Identifier = parameterName, Expression = mre.Target.Detach() });
query.Clauses.Add(new QueryGroupClause { Projection = new IdentifierExpression(parameterName), Key = keySelector.Detach() });
query.Clauses.Add(MakeFromClause(parameter, mre.Target.Detach()));
query.Clauses.Add(new QueryGroupClause { Projection = new IdentifierExpression(parameter.Name).CopyAnnotationsFrom(parameter), Key = keySelector.Detach() });
return query;
}
}
@ -131,9 +134,9 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms @@ -131,9 +134,9 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
{
if (invocation.Arguments.Count != 2)
return null;
string parameterName;
ParameterDeclaration parameter;
Expression collectionSelector;
if (!MatchSimpleLambda(invocation.Arguments.ElementAt(0), out parameterName, out collectionSelector))
if (!MatchSimpleLambda(invocation.Arguments.ElementAt(0), out parameter, out collectionSelector))
return null;
if (IsNullConditional(collectionSelector))
return null;
@ -141,11 +144,11 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms @@ -141,11 +144,11 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
if (lambda != null && lambda.Parameters.Count == 2 && lambda.Body is Expression) {
ParameterDeclaration p1 = lambda.Parameters.ElementAt(0);
ParameterDeclaration p2 = lambda.Parameters.ElementAt(1);
if (p1.Name == parameterName) {
if (p1.Name == parameter.Name) {
QueryExpression query = new QueryExpression();
query.Clauses.Add(new QueryFromClause { Identifier = p1.Name, Expression = mre.Target.Detach() });
query.Clauses.Add(new QueryFromClause { Identifier = p2.Name, Expression = collectionSelector.Detach() });
query.Clauses.Add(new QuerySelectClause { Expression = WrapExpressionInParenthesesIfNecessary(((Expression)lambda.Body).Detach(), parameterName) });
query.Clauses.Add(MakeFromClause(p1, mre.Target.Detach()));
query.Clauses.Add(MakeFromClause(p2, collectionSelector.Detach()));
query.Clauses.Add(new QuerySelectClause { Expression = WrapExpressionInParenthesesIfNecessary(((Expression)lambda.Body).Detach(), parameter.Name) });
return query;
}
}
@ -155,11 +158,11 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms @@ -155,11 +158,11 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
{
if (invocation.Arguments.Count != 1)
return null;
string parameterName;
ParameterDeclaration parameter;
Expression body;
if (MatchSimpleLambda(invocation.Arguments.Single(), out parameterName, out body)) {
if (MatchSimpleLambda(invocation.Arguments.Single(), out parameter, out body)) {
QueryExpression query = new QueryExpression();
query.Clauses.Add(new QueryFromClause { Identifier = parameterName, Expression = mre.Target.Detach() });
query.Clauses.Add(MakeFromClause(parameter, mre.Target.Detach()));
query.Clauses.Add(new QueryWhereClause { Condition = body.Detach() });
return query;
}
@ -172,10 +175,10 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms @@ -172,10 +175,10 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
{
if (invocation.Arguments.Count != 1)
return null;
string parameterName;
ParameterDeclaration parameter;
Expression orderExpression;
if (MatchSimpleLambda(invocation.Arguments.Single(), out parameterName, out orderExpression)) {
if (ValidateThenByChain(invocation, parameterName)) {
if (MatchSimpleLambda(invocation.Arguments.Single(), out parameter, out orderExpression)) {
if (ValidateThenByChain(invocation, parameter.Name)) {
QueryOrderClause orderClause = new QueryOrderClause();
InvocationExpression tmp = invocation;
while (mre.MemberName == "ThenBy" || mre.MemberName == "ThenByDescending") {
@ -188,7 +191,7 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms @@ -188,7 +191,7 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
tmp = (InvocationExpression)mre.Target;
mre = (MemberReferenceExpression)tmp.Target;
MatchSimpleLambda(tmp.Arguments.Single(), out parameterName, out orderExpression);
MatchSimpleLambda(tmp.Arguments.Single(), out parameter, out orderExpression);
}
// insert new ordering at beginning
orderClause.Orderings.InsertAfter(
@ -198,7 +201,7 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms @@ -198,7 +201,7 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
});
QueryExpression query = new QueryExpression();
query.Clauses.Add(new QueryFromClause { Identifier = parameterName, Expression = mre.Target.Detach() });
query.Clauses.Add(MakeFromClause(parameter, mre.Target.Detach()));
query.Clauses.Add(orderClause);
return query;
}
@ -214,21 +217,21 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms @@ -214,21 +217,21 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
Expression source2 = invocation.Arguments.ElementAt(0);
if (IsNullConditional(source2))
return null;
string elementName1, elementName2;
ParameterDeclaration element1, element2;
Expression key1, key2;
if (!MatchSimpleLambda(invocation.Arguments.ElementAt(1), out elementName1, out key1))
if (!MatchSimpleLambda(invocation.Arguments.ElementAt(1), out element1, out key1))
return null;
if (!MatchSimpleLambda(invocation.Arguments.ElementAt(2), out elementName2, out key2))
if (!MatchSimpleLambda(invocation.Arguments.ElementAt(2), out element2, out key2))
return null;
LambdaExpression lambda = invocation.Arguments.ElementAt(3) as LambdaExpression;
if (lambda != null && lambda.Parameters.Count == 2 && lambda.Body is Expression) {
ParameterDeclaration p1 = lambda.Parameters.ElementAt(0);
ParameterDeclaration p2 = lambda.Parameters.ElementAt(1);
if (p1.Name == elementName1 && (p2.Name == elementName2 || mre.MemberName == "GroupJoin")) {
if (p1.Name == element1.Name && (p2.Name == element2.Name || mre.MemberName == "GroupJoin")) {
QueryExpression query = new QueryExpression();
query.Clauses.Add(new QueryFromClause { Identifier = elementName1, Expression = source1.Detach() });
query.Clauses.Add(MakeFromClause(element1, source1.Detach()));
QueryJoinClause joinClause = new QueryJoinClause();
joinClause.JoinIdentifier = elementName2; // join elementName2
joinClause.JoinIdentifier = element2.Name; // join elementName2
joinClause.InExpression = source2.Detach(); // in source2
joinClause.OnExpression = key1.Detach(); // on key1
joinClause.EqualsExpression = key2.Detach(); // equals key2
@ -247,6 +250,35 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms @@ -247,6 +250,35 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
}
}
QueryFromClause MakeFromClause(ParameterDeclaration parameter, Expression body)
{
QueryFromClause fromClause = new QueryFromClause {
Identifier = parameter.Name,
Expression = body
};
fromClause.CopyAnnotationsFrom(parameter);
return fromClause;
}
class ApplyAnnotationVisitor : DepthFirstAstVisitor<AstNode>
{
private LetIdentifierAnnotation annotation;
private string identifier;
public ApplyAnnotationVisitor(LetIdentifierAnnotation annotation, string identifier)
{
this.annotation = annotation;
this.identifier = identifier;
}
public override AstNode VisitIdentifier(Identifier identifier)
{
if (identifier.Name == this.identifier)
identifier.AddAnnotation(annotation);
return identifier;
}
}
bool IsNullConditional(Expression target)
{
return target is UnaryOperatorExpression uoe && uoe.Operator == UnaryOperatorType.NullConditional;
@ -275,11 +307,11 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms @@ -275,11 +307,11 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
MemberReferenceExpression mre = invocation.Target as MemberReferenceExpression;
if (mre == null)
return false;
string parameterName;
ParameterDeclaration parameter;
Expression body;
if (!MatchSimpleLambda(invocation.Arguments.Single(), out parameterName, out body))
if (!MatchSimpleLambda(invocation.Arguments.Single(), out parameter, out body))
return false;
if (parameterName != expectedParameterName)
if (parameter.Name != expectedParameterName)
return false;
if (mre.MemberName == "OrderBy" || mre.MemberName == "OrderByDescending")
@ -291,7 +323,7 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms @@ -291,7 +323,7 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
}
/// <summary>Matches simple lambdas of the form "a => b"</summary>
bool MatchSimpleLambda(Expression expr, out string parameterName, out Expression body)
bool MatchSimpleLambda(Expression expr, out ParameterDeclaration parameter, out Expression body)
{
// HACK : remove workaround after all unnecessary casts are eliminated.
LambdaExpression lambda;
@ -302,12 +334,12 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms @@ -302,12 +334,12 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
if (lambda != null && lambda.Parameters.Count == 1 && lambda.Body is Expression) {
ParameterDeclaration p = lambda.Parameters.Single();
if (p.ParameterModifier == ParameterModifier.None) {
parameterName = p.Name;
parameter = p;
body = (Expression)lambda.Body;
return true;
}
}
parameterName = null;
parameter = null;
body = null;
return false;
}

12
ICSharpCode.Decompiler/DebugInfo/ScopesGenerator.cs

@ -18,6 +18,7 @@ @@ -18,6 +18,7 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection.Metadata;
using System.Reflection.Metadata.Ecma335;
@ -33,7 +34,7 @@ namespace ICSharpCode.Decompiler.DebugInfo @@ -33,7 +34,7 @@ namespace ICSharpCode.Decompiler.DebugInfo
{
class ScopesGenerator : DepthFirstAstVisitor<ImportScopeInfo, ImportScopeInfo>
{
static readonly KeyComparer<ILVariable, int> ILVariableKeyComparer = new KeyComparer<ILVariable, int>(l => l.Index, Comparer<int>.Default, EqualityComparer<int>.Default);
static readonly KeyComparer<ILVariable, int> ILVariableKeyComparer = new KeyComparer<ILVariable, int>(l => l.Index.Value, Comparer<int>.Default, EqualityComparer<int>.Default);
IDecompilerTypeSystem typeSystem;
ImportScopeInfo currentImportScope;
@ -59,7 +60,7 @@ namespace ICSharpCode.Decompiler.DebugInfo @@ -59,7 +60,7 @@ namespace ICSharpCode.Decompiler.DebugInfo
var firstLocalVariable = MetadataTokens.LocalVariableHandle(nextRow);
foreach (var local in localScope.Locals.OrderBy(l => l.Index)) {
metadata.AddLocalVariable(LocalVariableAttributes.None, local.Index, metadata.GetOrAddString(local.Name));
metadata.AddLocalVariable(LocalVariableAttributes.None, local.Index.Value, metadata.GetOrAddString(local.Name));
}
metadata.AddLocalScope(localScope.Method, localScope.Import.Handle, firstLocalVariable,
@ -191,14 +192,15 @@ namespace ICSharpCode.Decompiler.DebugInfo @@ -191,14 +192,15 @@ namespace ICSharpCode.Decompiler.DebugInfo
new TypeSystem.GenericContext(function.Method));
foreach (var v in function.Variables) {
if (v.Index == null)
continue;
switch (v.Kind) {
case VariableKind.Local:
case VariableKind.PinnedLocal:
case VariableKind.UsingLocal:
case VariableKind.ForeachLocal:
if (v.Index < types.Length && v.Type.Equals(types[v.Index])) {
localVariables.Add(v);
}
Debug.Assert(v.Index < types.Length && v.Type.Equals(types[v.Index.Value]));
localVariables.Add(v);
break;
default:
continue;

8
ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj

@ -3,13 +3,12 @@ @@ -3,13 +3,12 @@
<Import Sdk="Microsoft.NET.Sdk" Project="Sdk.props" />
<PropertyGroup>
<TargetFramework Condition=" '$(OS)' != 'Windows_NT' ">netstandard2.0</TargetFramework>
<TargetFrameworks Condition=" '$(OS)' == 'Windows_NT' ">netstandard2.0;net46;net45</TargetFrameworks>
<TargetFramework>netstandard2.0</TargetFramework>
<Description>IL decompiler engine</Description>
<Company>ic#code</Company>
<Product>ILSpy</Product>
<Copyright>Copyright 2011-2018 AlphaSierraPapa for the SharpDevelop Team</Copyright>
<Copyright>Copyright 2011-2019 AlphaSierraPapa for the SharpDevelop Team</Copyright>
<NeutralLanguage>en-US</NeutralLanguage>
<GenerateAssemblyVersionAttribute>False</GenerateAssemblyVersionAttribute>
<GenerateAssemblyFileVersionAttribute>False</GenerateAssemblyFileVersionAttribute>
@ -74,7 +73,7 @@ @@ -74,7 +73,7 @@
<Compile Include="CSharp\Syntax\ErrorNode.cs" />
<Compile Include="CSharp\Syntax\Expressions\AnonymousMethodExpression.cs" />
<Compile Include="CSharp\Syntax\Expressions\AnonymousTypeCreateExpression.cs" />
<Compile Include="CSharp\Syntax\Expressions\ArrayCreateExpression.cs" />
<Compile Include="CSharp\Syntax\Expressions\ArrayCreateExpression.cs" />
<Compile Include="CSharp\Syntax\Expressions\ArrayInitializerExpression.cs" />
<Compile Include="CSharp\Syntax\Expressions\AsExpression.cs" />
<Compile Include="CSharp\Syntax\Expressions\AssignmentExpression.cs" />
@ -267,6 +266,7 @@ @@ -267,6 +266,7 @@
<Compile Include="CSharp\Transforms\AddXmlDocumentationTransform.cs" />
<Compile Include="DecompileRun.cs" />
<Compile Include="Disassembler\ILParser.cs" />
<Compile Include="IL\Transforms\CombineExitsTransform.cs" />
<Compile Include="IL\Transforms\ReduceNestingTransform.cs" />
<Compile Include="IL\Transforms\LocalFunctionDecompiler.cs" />
<Compile Include="IL\Transforms\UserDefinedLogicTransform.cs" />

6
ICSharpCode.Decompiler/ICSharpCode.Decompiler.nuspec.template

@ -22,12 +22,6 @@ @@ -22,12 +22,6 @@
</dependencies>
</metadata>
<files>
<file src="bin\$Configuration$\net46\ICSharpCode.Decompiler.dll" target="lib\net46" />
<file src="bin\$Configuration$\net46\ICSharpCode.Decompiler.pdb" target="lib\net46" />
<file src="bin\$Configuration$\net45\ICSharpCode.Decompiler.dll" target="lib\net45" />
<file src="bin\$Configuration$\net45\ICSharpCode.Decompiler.pdb" target="lib\net45" />
<file src="bin\$Configuration$\netstandard2.0\ICSharpCode.Decompiler.dll" target="lib\netstandard2.0" />
<file src="bin\$Configuration$\netstandard2.0\ICSharpCode.Decompiler.pdb" target="lib\netstandard2.0" />
</files>

2
ICSharpCode.Decompiler/IL/ControlFlow/AsyncAwaitDecompiler.cs

@ -565,7 +565,7 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow @@ -565,7 +565,7 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow
}
awaitBlocks.Add(block, (awaiterVar, awaiterField));
if (awaiterVar.Index < smallestAwaiterVarIndex) {
smallestAwaiterVarIndex = awaiterVar.Index;
smallestAwaiterVarIndex = awaiterVar.Index.Value;
}
}
}

11
ICSharpCode.Decompiler/IL/ILReader.cs

@ -225,11 +225,6 @@ namespace ICSharpCode.Decompiler.IL @@ -225,11 +225,6 @@ namespace ICSharpCode.Decompiler.IL
ILVariable CreateILVariable(int index, IType parameterType, string name)
{
Debug.Assert(!parameterType.IsUnbound());
if (parameterType.IsUnbound()) {
// parameter types should not be unbound, the only known cause for these is a Cecil bug:
Debug.Assert(index < 0); // cecil bug occurs only for "this"
parameterType = new ParameterizedType(parameterType.GetDefinition(), parameterType.TypeArguments);
}
ITypeDefinition def = parameterType.GetDefinition();
if (def != null && index < 0 && def.IsReferenceType == false) {
parameterType = new ByReferenceType(parameterType);
@ -352,14 +347,14 @@ namespace ICSharpCode.Decompiler.IL @@ -352,14 +347,14 @@ namespace ICSharpCode.Decompiler.IL
ImmutableStack<ILVariable> ehStack = null;
if (eh.Kind == ExceptionRegionKind.Catch) {
var catchType = module.ResolveType(eh.CatchType, genericContext);
var v = new ILVariable(VariableKind.Exception, catchType, eh.HandlerOffset) {
var v = new ILVariable(VariableKind.ExceptionStackSlot, catchType, eh.HandlerOffset) {
Name = "E_" + eh.HandlerOffset,
HasGeneratedName = true
};
variableByExceptionHandler.Add(eh, v);
ehStack = ImmutableStack.Create(v);
} else if (eh.Kind == ExceptionRegionKind.Filter) {
var v = new ILVariable(VariableKind.Exception, compilation.FindType(KnownTypeCode.Object), eh.HandlerOffset) {
var v = new ILVariable(VariableKind.ExceptionStackSlot, compilation.FindType(KnownTypeCode.Object), eh.HandlerOffset) {
Name = "E_" + eh.HandlerOffset,
HasGeneratedName = true
};
@ -1060,7 +1055,7 @@ namespace ICSharpCode.Decompiler.IL @@ -1060,7 +1055,7 @@ namespace ICSharpCode.Decompiler.IL
{
Debug.Assert(inst.ResultType != StackType.Void);
IType type = compilation.FindType(inst.ResultType.ToKnownTypeCode());
var v = new ILVariable(VariableKind.StackSlot, type, inst.ResultType, inst.ILRange.Start);
var v = new ILVariable(VariableKind.StackSlot, type, inst.ResultType);
v.HasGeneratedName = true;
currentStack = currentStack.Push(v);
return new StLoc(v, inst);

58
ICSharpCode.Decompiler/IL/ILVariable.cs

@ -51,9 +51,13 @@ namespace ICSharpCode.Decompiler.IL @@ -51,9 +51,13 @@ namespace ICSharpCode.Decompiler.IL
/// </summary>
Parameter,
/// <summary>
/// Variable created for exception handler
/// Variable created for exception handler.
/// </summary>
Exception,
ExceptionStackSlot,
/// <summary>
/// Local variable used in a catch block.
/// </summary>
ExceptionLocal,
/// <summary>
/// Variable created from stack slot.
/// </summary>
@ -96,9 +100,40 @@ namespace ICSharpCode.Decompiler.IL @@ -96,9 +100,40 @@ namespace ICSharpCode.Decompiler.IL
/// <summary>
/// The index of the local variable or parameter (depending on Kind)
///
/// For VariableKinds with "Local" in the name:
/// * if non-null, the Index refers to the LocalVariableSignature.
/// * index may be null for variables that used to be fields (captured by lambda/async)
/// For Parameters, the Index refers to the method's list of parameters.
/// The special "this" parameter has index -1.
/// For ExceptionStackSlot, the index is the IL offset of the exception handler.
/// For other kinds, the index has no meaning, and is usually null.
/// </summary>
public readonly int Index;
public readonly int? Index;
[Conditional("DEBUG")]
internal void CheckInvariant()
{
switch (kind) {
case VariableKind.Local:
case VariableKind.ForeachLocal:
case VariableKind.PinnedLocal:
case VariableKind.UsingLocal:
case VariableKind.ExceptionLocal:
// in range of LocalVariableSignature
Debug.Assert(Index == null || Index >= 0);
break;
case VariableKind.Parameter:
// -1 for the "this" parameter
Debug.Assert(Index >= -1);
Debug.Assert(Function == null || Index < Function.Parameters.Count);
break;
case VariableKind.ExceptionStackSlot:
Debug.Assert(Index >= 0);
break;
}
}
public string Name { get; set; }
public bool HasGeneratedName { get; set; }
@ -268,7 +303,7 @@ namespace ICSharpCode.Decompiler.IL @@ -268,7 +303,7 @@ namespace ICSharpCode.Decompiler.IL
/// </summary>
public IField StateMachineField;
public ILVariable(VariableKind kind, IType type, int index)
public ILVariable(VariableKind kind, IType type, int? index = null)
{
if (type == null)
throw new ArgumentNullException(nameof(type));
@ -278,9 +313,10 @@ namespace ICSharpCode.Decompiler.IL @@ -278,9 +313,10 @@ namespace ICSharpCode.Decompiler.IL
this.Index = index;
if (kind == VariableKind.Parameter)
this.HasInitialValue = true;
CheckInvariant();
}
public ILVariable(VariableKind kind, IType type, StackType stackType, int index)
public ILVariable(VariableKind kind, IType type, StackType stackType, int? index = null)
{
if (type == null)
throw new ArgumentNullException(nameof(type));
@ -290,8 +326,9 @@ namespace ICSharpCode.Decompiler.IL @@ -290,8 +326,9 @@ namespace ICSharpCode.Decompiler.IL
this.Index = index;
if (kind == VariableKind.Parameter)
this.HasInitialValue = true;
CheckInvariant();
}
public override string ToString()
{
return Name;
@ -309,8 +346,11 @@ namespace ICSharpCode.Decompiler.IL @@ -309,8 +346,11 @@ namespace ICSharpCode.Decompiler.IL
case VariableKind.Parameter:
output.Write("param ");
break;
case VariableKind.Exception:
output.Write("exception ");
case VariableKind.ExceptionLocal:
output.Write("exception local ");
break;
case VariableKind.ExceptionStackSlot:
output.Write("exception stack ");
break;
case VariableKind.StackSlot:
output.Write("stack ");
@ -403,7 +443,7 @@ namespace ICSharpCode.Decompiler.IL @@ -403,7 +443,7 @@ namespace ICSharpCode.Decompiler.IL
return false;
if (x.Kind == VariableKind.StackSlot || y.Kind == VariableKind.StackSlot)
return false;
return x.Function == y.Function && x.Kind == y.Kind && x.Index == y.Index;
return x.Index != null && x.Function == y.Function && x.Kind == y.Kind && x.Index == y.Index;
}
public int GetHashCode(ILVariable obj)

28
ICSharpCode.Decompiler/IL/Instructions/ILFunction.cs

@ -98,6 +98,7 @@ namespace ICSharpCode.Decompiler.IL @@ -98,6 +98,7 @@ namespace ICSharpCode.Decompiler.IL
for (int i = 0; i < Variables.Count; i++) {
Debug.Assert(Variables[i].Function == this);
Debug.Assert(Variables[i].IndexInFunction == i);
Variables[i].CheckInvariant();
}
base.CheckInvariant(phase);
}
@ -213,32 +214,13 @@ namespace ICSharpCode.Decompiler.IL @@ -213,32 +214,13 @@ namespace ICSharpCode.Decompiler.IL
}
}
int helperVariableCount;
public ILVariable RegisterVariable(VariableKind kind, IType type, string name = null)
{
int index = Variables.Where(v => v.Kind == kind).MaxOrDefault(v => v.Index, -1) + 1;
var variable = new ILVariable(kind, type, index);
var variable = new ILVariable(kind, type);
if (string.IsNullOrWhiteSpace(name)) {
switch (kind) {
case VariableKind.Local:
case VariableKind.ForeachLocal:
name = "V_";
break;
case VariableKind.Parameter:
name = "P_";
break;
case VariableKind.Exception:
name = "E_";
break;
case VariableKind.StackSlot:
name = "S_";
break;
case VariableKind.InitializerTarget:
name = "I_";
break;
default:
throw new ArgumentOutOfRangeException(nameof(kind));
}
name += index;
name = "I_" + (helperVariableCount++);
variable.HasGeneratedName = true;
}
variable.Name = name;

51
ICSharpCode.Decompiler/IL/Transforms/CombineExitsTransform.cs

@ -0,0 +1,51 @@ @@ -0,0 +1,51 @@
// Copyright (c) 2019 Siegfried Pammer
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software
// without restriction, including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
// to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or
// substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
namespace ICSharpCode.Decompiler.IL.Transforms
{
class CombineExitsTransform : IILTransform
{
public void Run(ILFunction function, ILTransformContext context)
{
if (!(function.Body is BlockContainer container && container.Blocks.Count == 1))
return;
var block = container.EntryPoint;
if (!(block.Instructions.SecondToLastOrDefault() is IfInstruction ifInst && block.Instructions.LastOrDefault() is Leave leaveElse))
return;
if (!ifInst.FalseInst.MatchNop())
return;
if (!(Block.Unwrap(ifInst.TrueInst) is Leave leave))
return;
if (!(leave.IsLeavingFunction && leaveElse.IsLeavingFunction))
return;
if (leave.Value.MatchNop() || leaveElse.Value.MatchNop())
return;
// if (cond) {
// leave (value)
// }
// leave (elseValue)
// =>
// leave (if (cond) value else elseValue)
IfInstruction value = new IfInstruction(ifInst.Condition, leave.Value, leaveElse.Value) { ILRange = ifInst.ILRange };
Leave combinedLeave = new Leave(leave.TargetContainer, value) { ILRange = leaveElse.ILRange };
combinedLeave.AddILRange(leave.ILRange);
ifInst.ReplaceWith(combinedLeave);
block.Instructions.RemoveAt(combinedLeave.ChildIndex + 1);
}
}
}

7
ICSharpCode.Decompiler/IL/Transforms/CopyPropagation.cs

@ -89,7 +89,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -89,7 +89,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
// note: the initialization by the caller is the first store -> StoreCount must be 1
return v.IsSingleDefinition;
case VariableKind.StackSlot:
case VariableKind.Exception: // Exception variables are normally generated as well.
case VariableKind.ExceptionStackSlot:
// Variables are be copied only if both they and the target copy variable are generated,
// and if the variable has only a single assignment
return v.IsSingleDefinition && target.Kind == VariableKind.StackSlot;
@ -110,8 +110,9 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -110,8 +110,9 @@ namespace ICSharpCode.Decompiler.IL.Transforms
for (int j = 0; j < uninlinedArgs.Length; j++) {
var arg = copiedExpr.Children[j];
var type = context.TypeSystem.FindType(arg.ResultType.ToKnownTypeCode());
uninlinedArgs[j] = new ILVariable(VariableKind.StackSlot, type, arg.ResultType, arg.ILRange.Start) {
Name = "C_" + arg.ILRange.Start
uninlinedArgs[j] = new ILVariable(VariableKind.StackSlot, type, arg.ResultType) {
Name = "C_" + arg.ILRange.Start,
HasGeneratedName = true,
};
block.Instructions.Insert(i++, new StLoc(uninlinedArgs[j], arg));
}

24
ICSharpCode.Decompiler/IL/Transforms/DelegateConstruction.cs

@ -105,13 +105,24 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -105,13 +105,24 @@ namespace ICSharpCode.Decompiler.IL.Transforms
static bool IsAnonymousMethod(ITypeDefinition decompiledTypeDefinition, IMethod method)
{
if (method == null || !(method.HasGeneratedName() || method.Name.Contains("$")))
if (method == null || !(method.HasGeneratedName() || method.Name.Contains("$") || ContainsAnonymousType(method)))
return false;
if (!(method.IsCompilerGeneratedOrIsInCompilerGeneratedClass() || IsPotentialClosure(decompiledTypeDefinition, method.DeclaringTypeDefinition)))
return false;
return true;
}
static bool ContainsAnonymousType(IMethod method)
{
if (method.ReturnType.ContainsAnonymousType())
return true;
foreach (var p in method.Parameters) {
if (p.Type.ContainsAnonymousType())
return true;
}
return false;
}
static bool IsPotentialClosure(ITypeDefinition decompiledTypeDefinition, ITypeDefinition potentialDisplayClass)
{
if (potentialDisplayClass == null || !potentialDisplayClass.IsCompilerGeneratedOrIsInCompilerGeneratedClass())
@ -178,7 +189,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -178,7 +189,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
}
var nestedContext = new ILTransformContext(context, function);
function.RunTransforms(CSharpDecompiler.GetILTransforms().TakeWhile(t => !(t is DelegateConstruction)), nestedContext);
function.RunTransforms(CSharpDecompiler.GetILTransforms().TakeWhile(t => !(t is DelegateConstruction)).Concat(GetTransforms()), nestedContext);
function.AcceptVisitor(new ReplaceDelegateTargetVisitor(target, function.Variables.SingleOrDefault(v => v.Index == -1 && v.Kind == VariableKind.Parameter)));
// handle nested lambdas
((IILTransform)new DelegateConstruction()).Run(function, nestedContext);
@ -186,7 +197,12 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -186,7 +197,12 @@ namespace ICSharpCode.Decompiler.IL.Transforms
function.AddILRange(value.Arguments[1].ILRange);
return function;
}
private IEnumerable<IILTransform> GetTransforms()
{
yield return new CombineExitsTransform();
}
/// <summary>
/// Replaces loads of 'this' with the target expression.
/// Async delegates use: ldobj(ldloca this).

8
ICSharpCode.Decompiler/IL/Transforms/DetectCatchWhenConditionBlocks.cs

@ -27,7 +27,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -27,7 +27,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
public void Run(ILFunction function, ILTransformContext context)
{
foreach (var catchBlock in function.Descendants.OfType<TryCatchHandler>()) {
if (catchBlock.Filter is BlockContainer container && MatchCatchWhenEntryPoint(container, container.EntryPoint, out var exceptionType, out var exceptionSlot, out var whenConditionBlock)) {
if (catchBlock.Filter is BlockContainer container && MatchCatchWhenEntryPoint(catchBlock.Variable, container, container.EntryPoint, out var exceptionType, out var exceptionSlot, out var whenConditionBlock)) {
// set exceptionType
catchBlock.Variable.Type = exceptionType;
// Block entryPoint (incoming: 1) {
@ -67,7 +67,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -67,7 +67,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
/// br falseBlock
/// }
/// </summary>
bool MatchCatchWhenEntryPoint(BlockContainer container, Block entryPoint, out IType exceptionType, out ILInstruction exceptionSlot, out Block whenConditionBlock)
bool MatchCatchWhenEntryPoint(ILVariable exceptionVar, BlockContainer container, Block entryPoint, out IType exceptionType, out ILInstruction exceptionSlot, out Block whenConditionBlock)
{
exceptionType = null;
exceptionSlot = null;
@ -81,7 +81,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -81,7 +81,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
if (!entryPoint.Instructions[0].MatchStLoc(out var temp, out var isinst) ||
temp.Kind != VariableKind.StackSlot || !isinst.MatchIsInst(out exceptionSlot, out exceptionType))
return false;
if (!exceptionSlot.MatchLdLoc(out var exceptionVar) || exceptionVar.Kind != VariableKind.Exception)
if (!exceptionSlot.MatchLdLoc(exceptionVar))
return false;
if (!entryPoint.Instructions[1].MatchIfInstruction(out var condition, out var branch))
return false;
@ -103,7 +103,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -103,7 +103,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
return false;
if (!left.MatchIsInst(out exceptionSlot, out exceptionType))
return false;
if (!exceptionSlot.MatchLdLoc(out var exceptionVar) || exceptionVar.Kind != VariableKind.Exception)
if (!exceptionSlot.MatchLdLoc(exceptionVar))
return false;
if (right.MatchLdNull()) {
return branch.MatchBranch(out whenConditionBlock);

2
ICSharpCode.Decompiler/IL/Transforms/ExpressionTransforms.cs

@ -613,7 +613,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -613,7 +613,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
if (!exceptionSlotLoad.MatchLdLoc(handler.Variable) || !handler.Variable.IsSingleDefinition || handler.Variable.LoadCount != 1)
return;
handler.Variable = exceptionVar;
exceptionVar.Kind = VariableKind.Exception;
exceptionVar.Kind = VariableKind.ExceptionLocal;
entryPoint.Instructions.RemoveAt(0);
}

1
ICSharpCode.Decompiler/IL/Transforms/SplitVariables.cs

@ -47,7 +47,6 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -47,7 +47,6 @@ namespace ICSharpCode.Decompiler.IL.Transforms
{
switch (v.Kind) {
case VariableKind.Local:
case VariableKind.Exception:
foreach (var ldloca in v.AddressInstructions) {
if (DetermineAddressUse(ldloca, ldloca.Variable) == AddressUse.Unknown) {
// If we don't understand how the address is being used,

5
ICSharpCode.Decompiler/Metadata/AssemblyReferences.cs

@ -156,6 +156,11 @@ namespace ICSharpCode.Decompiler.Metadata @@ -156,6 +156,11 @@ namespace ICSharpCode.Decompiler.Metadata
return name;
}
public override string ToString()
{
return FullName;
}
}
public class AssemblyReference : IAssemblyReference

25
ICSharpCode.Decompiler/Output/TextTokenWriter.cs

@ -63,34 +63,35 @@ namespace ICSharpCode.Decompiler @@ -63,34 +63,35 @@ namespace ICSharpCode.Decompiler
}
var definition = GetCurrentDefinition();
string name = TextWriterTokenWriter.EscapeIdentifier(identifier.Name);
switch (definition) {
case IType t:
output.WriteReference(t, identifier.Name, true);
output.WriteReference(t, name, true);
return;
case IMember m:
output.WriteReference(m, identifier.Name, true);
output.WriteReference(m, name, true);
return;
}
var member = GetCurrentMemberReference();
switch (member) {
case IType t:
output.WriteReference(t, identifier.Name, false);
output.WriteReference(t, name, false);
return;
case IMember m:
output.WriteReference(m, identifier.Name, false);
output.WriteReference(m, name, false);
return;
}
var localDefinition = GetCurrentLocalDefinition();
if (localDefinition != null) {
output.WriteLocalReference(identifier.Name, localDefinition, isDefinition: true);
output.WriteLocalReference(name, localDefinition, isDefinition: true);
return;
}
var localRef = GetCurrentLocalReference();
if (localRef != null) {
output.WriteLocalReference(identifier.Name, localRef);
output.WriteLocalReference(name, localRef);
return;
}
@ -99,7 +100,7 @@ namespace ICSharpCode.Decompiler @@ -99,7 +100,7 @@ namespace ICSharpCode.Decompiler
firstUsingDeclaration = false;
}
output.Write(identifier.Name);
output.Write(name);
}
ISymbol GetCurrentMemberReference()
@ -140,6 +141,10 @@ namespace ICSharpCode.Decompiler @@ -140,6 +141,10 @@ namespace ICSharpCode.Decompiler
if (variable != null)
return variable;
var letClauseVariable = node.Annotation<CSharp.Transforms.LetIdentifierAnnotation>();
if (letClauseVariable != null)
return letClauseVariable;
var gotoStatement = node as GotoStatement;
if (gotoStatement != null)
{
@ -163,6 +168,12 @@ namespace ICSharpCode.Decompiler @@ -163,6 +168,12 @@ namespace ICSharpCode.Decompiler
return variable;
}
if (node is QueryLetClause) {
var variable = node.Annotation<CSharp.Transforms.LetIdentifierAnnotation>();
if (variable != null)
return variable;
}
var label = node as LabelStatement;
if (label != null) {
var method = nodeStack.Select(nd => nd.GetSymbol() as IMethod).FirstOrDefault(mr => mr != null);

16
ILSpy.AddIn/ILSpy.AddIn.csproj

@ -7,7 +7,7 @@ @@ -7,7 +7,7 @@
</PropertyGroup>
<PropertyGroup>
<TargetFramework>net46</TargetFramework>
<TargetFramework>net462</TargetFramework>
<RootNamespace>ICSharpCode.ILSpy.AddIn</RootNamespace>
<Company>IC#Code</Company>
@ -56,7 +56,7 @@ @@ -56,7 +56,7 @@
<PackageReference Include="Microsoft.VisualStudio.Text.UI" Version="15.6.27740" />
<PackageReference Include="Microsoft.VisualStudio.Text.UI.Wpf" Version="15.6.27740" />
<PackageReference Include="Microsoft.VisualStudio.Threading" Version="15.6.56" />
<PackageReference Include="Mono.Cecil" Version="0.10.1" />
<PackageReference Include="Mono.Cecil" Version="0.10.3" />
<PackageReference Include="VSLangProj" Version="7.0.3301" />
</ItemGroup>
@ -111,7 +111,7 @@ @@ -111,7 +111,7 @@
<PropertyGroup>
<ILSpyBuildPath>..\ILSpy\bin\$(Configuration)\$(TargetFramework)\</ILSpyBuildPath>
</PropertyGroup>
<ItemGroup>
<AdditionalDependencies Include="$(ILSpyBuildPath)System.ValueTuple.dll" />
<AdditionalDependencies Include="$(ILSpyBuildPath)System.Collections.Immutable.dll" />
@ -138,7 +138,7 @@ @@ -138,7 +138,7 @@
</Content>
</ItemGroup>
<!-- END WORKAROUND -->
<ItemGroup>
<None Include="ILSpyAddIn.vsct" />
<None Include="source.extension.vsixmanifest.template" />
@ -183,12 +183,4 @@ @@ -183,12 +183,4 @@
<Import Project="$(VSToolsPath)\VSSDK\Microsoft.VsSDK.targets" Condition="Exists('$(VSToolsPath)\VSSDK\Microsoft.VsSDK.targets')" />
<ItemGroup>
<!-- https://github.com/dotnet/sdk/issues/433 -->
<ProjectReference Update="@(ProjectReference)" AdditionalProperties="TargetFramework=net46" />
<!-- https://github.com/Microsoft/extendvs/issues/57 -->
<ProjectReference Update="@(ProjectReference)" Name="%(Filename)" />
</ItemGroup>
</Project>

2
ILSpy.BamlDecompiler.Tests/Cases/AttachedEvent.xaml

@ -1,3 +1,3 @@ @@ -1,3 +1,3 @@
<Window x:Class="ILSpy.BamlDecompiler.Tests.Cases.AttachedEvent" Title="ILSpy.BamlDecompiler.Tests.Cases" Height="300" Width="300" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Window x:Class="ILSpy.BamlDecompiler.Tests.Cases.AttachedEvent" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:cases="clr-namespace:ILSpy.BamlDecompiler.Tests.Cases" Title="ILSpy.BamlDecompiler.Tests.Cases" Height="300" Width="300">
<Grid AccessKeyManager.AccessKeyPressed="GridAccessKeyPressed" />
</Window>

38
ILSpy.BamlDecompiler.Tests/Cases/AvalonDockBrushes.xaml

@ -1,23 +1,23 @@ @@ -1,23 +1,23 @@
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:ad="clr-namespace:AvalonDock">
<SolidColorBrush x:Key="ManagedContentTabControlNormalBorderBrush" Color="#919B9C" />
<SolidColorBrush x:Key="{ComponentResourceKey TypeInTargetAssembly={x:Type ad:DockingManager}, ResourceId={x:Static ad:AvalonDockBrushes.DefaultBackgroundBrush}}" Color="#FFF4F2E8" />
<SolidColorBrush x:Key="{ComponentResourceKey ResourceId={x:Static ad:AvalonDockBrushes.DefaultBackgroundBrush}, TypeInTargetAssembly={x:Type ad:DockingManager}}" Color="#FFF4F2E8" />
<LinearGradientBrush x:Key="ManagedContentTabItemNormalBackground" StartPoint="0,0" EndPoint="0,1">
<LinearGradientBrush.GradientStops>
<GradientBrush.GradientStops>
<GradientStop Color="#FFECEBE6" Offset="0" />
<GradientStop Color="#FFFFFFFF" Offset="1" />
</LinearGradientBrush.GradientStops>
</GradientBrush.GradientStops>
</LinearGradientBrush>
<LinearGradientBrush x:Key="ManagedContentTabItemInvNormalBackground" StartPoint="0,0" EndPoint="0,1">
<LinearGradientBrush.GradientStops>
<GradientBrush.GradientStops>
<GradientStop Color="#FFFFFFFF" Offset="0" />
<GradientStop Color="#FFECEBE6" Offset="1" />
</LinearGradientBrush.GradientStops>
</GradientBrush.GradientStops>
</LinearGradientBrush>
<LinearGradientBrush x:Key="ManagedContentTabItemHotBackground" StartPoint="0,0" EndPoint="0,1">
<LinearGradientBrush.GradientStops>
<GradientBrush.GradientStops>
<GradientStop Color="#FFFFFFFF" Offset="0" />
<GradientStop Color="#FFECEBE6" Offset="1" />
</LinearGradientBrush.GradientStops>
</GradientBrush.GradientStops>
</LinearGradientBrush>
<SolidColorBrush x:Key="ManagedContentTabItemSelectedBackground" Color="#FFFCFCFE" />
<SolidColorBrush x:Key="ManagedContentTabItemDisabledBackground" Color="#FFF5F4EA" />
@ -29,25 +29,25 @@ @@ -29,25 +29,25 @@
<SolidColorBrush x:Key="ManagedContentTabItemHotBorderBackround" Color="#FFFFC73C" />
<SolidColorBrush x:Key="ManagedContentTabItemHotBorderBrush" Color="#FFE68B2C" />
<SolidColorBrush x:Key="ManagedContentTabItemDisabledBorderBrush" Color="#FFC9C7BA" />
<LinearGradientBrush x:Key="{ComponentResourceKey TypeInTargetAssembly={x:Type ad:DockingManager}, ResourceId={x:Static ad:AvalonDockBrushes.DockablePaneTitleBackgroundSelected}}" StartPoint="0,0" EndPoint="0,1">
<LinearGradientBrush.GradientStops>
<LinearGradientBrush x:Key="{ComponentResourceKey ResourceId={x:Static ad:AvalonDockBrushes.DockablePaneTitleBackgroundSelected}, TypeInTargetAssembly={x:Type ad:DockingManager}}" StartPoint="0,0" EndPoint="0,1">
<GradientBrush.GradientStops>
<GradientStop Color="#FF3B80ED" Offset="0" />
<GradientStop Color="#FF316AC5" Offset="1" />
</LinearGradientBrush.GradientStops>
</GradientBrush.GradientStops>
</LinearGradientBrush>
<SolidColorBrush x:Key="{ComponentResourceKey TypeInTargetAssembly={x:Type ad:DockingManager}, ResourceId={x:Static ad:AvalonDockBrushes.DockablePaneTitleBackground}}" Color="#FFCCC5BA" />
<SolidColorBrush x:Key="{ComponentResourceKey TypeInTargetAssembly={x:Type ad:DockingManager}, ResourceId={x:Static ad:AvalonDockBrushes.DockablePaneTitleForeground}}" Color="Black" />
<SolidColorBrush x:Key="{ComponentResourceKey TypeInTargetAssembly={x:Type ad:DockingManager}, ResourceId={x:Static ad:AvalonDockBrushes.DockablePaneTitleForegroundSelected}}" Color="White" />
<SolidColorBrush x:Key="{ComponentResourceKey TypeInTargetAssembly={x:Type ad:DockingManager}, ResourceId={x:Static ad:AvalonDockBrushes.PaneHeaderCommandBackground}}" Color="{x:Static SystemColors.ControlLightLightColor}" Opacity="0.5" />
<SolidColorBrush x:Key="{ComponentResourceKey TypeInTargetAssembly={x:Type ad:DockingManager}, ResourceId={x:Static ad:AvalonDockBrushes.PaneHeaderCommandBorderBrush}}" Color="{x:Static SystemColors.ControlDarkColor}" />
<LinearGradientBrush x:Key="{ComponentResourceKey TypeInTargetAssembly={x:Type ad:DockingManager}, ResourceId={x:Static ad:AvalonDockBrushes.DocumentHeaderBackground}}" StartPoint="0,0" EndPoint="0,1">
<SolidColorBrush x:Key="{ComponentResourceKey ResourceId={x:Static ad:AvalonDockBrushes.DockablePaneTitleBackground}, TypeInTargetAssembly={x:Type ad:DockingManager}}" Color="#FFCCC5BA" />
<SolidColorBrush x:Key="{ComponentResourceKey ResourceId={x:Static ad:AvalonDockBrushes.DockablePaneTitleForeground}, TypeInTargetAssembly={x:Type ad:DockingManager}}" Color="Black" />
<SolidColorBrush x:Key="{ComponentResourceKey ResourceId={x:Static ad:AvalonDockBrushes.DockablePaneTitleForegroundSelected}, TypeInTargetAssembly={x:Type ad:DockingManager}}" Color="White" />
<SolidColorBrush x:Key="{ComponentResourceKey ResourceId={x:Static ad:AvalonDockBrushes.PaneHeaderCommandBackground}, TypeInTargetAssembly={x:Type ad:DockingManager}}" Color="{x:Static SystemColors.ControlLightLightColor}" Opacity="0.5" />
<SolidColorBrush x:Key="{ComponentResourceKey ResourceId={x:Static ad:AvalonDockBrushes.PaneHeaderCommandBorderBrush}, TypeInTargetAssembly={x:Type ad:DockingManager}}" Color="{x:Static SystemColors.ControlDarkColor}" />
<LinearGradientBrush x:Key="{ComponentResourceKey ResourceId={x:Static ad:AvalonDockBrushes.DocumentHeaderBackground}, TypeInTargetAssembly={x:Type ad:DockingManager}}" StartPoint="0,0" EndPoint="0,1">
<GradientStop Color="#FFFFFFFF" Offset="0" />
<GradientStop Color="#FFE0E0E0" Offset="1" />
</LinearGradientBrush>
<SolidColorBrush x:Key="{ComponentResourceKey TypeInTargetAssembly={x:Type ad:DockingManager}, ResourceId={x:Static ad:AvalonDockBrushes.DocumentHeaderForeground}}" Color="{x:Static SystemColors.WindowTextColor}" />
<LinearGradientBrush x:Key="{ComponentResourceKey TypeInTargetAssembly={x:Type ad:DockingManager}, ResourceId={x:Static ad:AvalonDockBrushes.DocumentHeaderBackgroundSelected}}" StartPoint="0,0" EndPoint="0,1">
<SolidColorBrush x:Key="{ComponentResourceKey ResourceId={x:Static ad:AvalonDockBrushes.DocumentHeaderForeground}, TypeInTargetAssembly={x:Type ad:DockingManager}}" Color="{x:Static SystemColors.WindowTextColor}" />
<LinearGradientBrush x:Key="{ComponentResourceKey ResourceId={x:Static ad:AvalonDockBrushes.DocumentHeaderBackgroundSelected}, TypeInTargetAssembly={x:Type ad:DockingManager}}" StartPoint="0,0" EndPoint="0,1">
<GradientStop Color="#FFFFFFFF" Offset="0" />
<GradientStop Color="#FFC1D2EE" Offset="1" />
</LinearGradientBrush>
<SolidColorBrush x:Key="{ComponentResourceKey TypeInTargetAssembly={x:Type ad:DockingManager}, ResourceId={x:Static ad:AvalonDockBrushes.DocumentHeaderBackgroundMouseOver}}" Color="White" />
<SolidColorBrush x:Key="{ComponentResourceKey ResourceId={x:Static ad:AvalonDockBrushes.DocumentHeaderBackgroundMouseOver}, TypeInTargetAssembly={x:Type ad:DockingManager}}" Color="White" />
</ResourceDictionary>

24
ILSpy.BamlDecompiler.Tests/Cases/AvalonDockCommon.xaml

@ -2,7 +2,7 @@ @@ -2,7 +2,7 @@
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/AvalonDock;component/Resources/Brushes.xaml" />
</ResourceDictionary.MergedDictionaries>
<ContextMenu x:Key="{ComponentResourceKey TypeInTargetAssembly={x:Type ad:DockingManager}, ResourceId={x:Static ad:ContextMenuElement.DockableFloatingWindow}}">
<ContextMenu x:Key="{ComponentResourceKey ResourceId={x:Static ad:ContextMenuElement.DockableFloatingWindow}, TypeInTargetAssembly={x:Type ad:DockingManager}}">
<MenuItem Command="ad:ManagedContentCommands.Show" />
<MenuItem Command="ad:ManagedContentCommands.Hide" />
<MenuItem Command="ad:DockableContentCommands.ShowAsDocument" />
@ -10,24 +10,24 @@ @@ -10,24 +10,24 @@
<MenuItem Command="ad:DockableFloatingWindowCommands.SetAsFloatingWindow" />
<MenuItem Command="ad:DockableFloatingWindowCommands.SetAsDockableWindow" />
</ContextMenu>
<ContextMenu x:Key="{ComponentResourceKey TypeInTargetAssembly={x:Type ad:DockingManager}, ResourceId={x:Static ad:ContextMenuElement.DocumentFloatingWindow}}">
<ContextMenu x:Key="{ComponentResourceKey ResourceId={x:Static ad:ContextMenuElement.DocumentFloatingWindow}, TypeInTargetAssembly={x:Type ad:DockingManager}}">
<MenuItem Command="ad:ManagedContentCommands.Close" />
<Separator />
<MenuItem Command="ad:DocumentContentCommands.FloatingDocument" />
<MenuItem Command="ad:DocumentContentCommands.TabbedDocument" />
</ContextMenu>
<Style x:Key="{x:Type ad:Resizer}" TargetType="{x:Type ad:Resizer}">
<Setter Property="Control.Background" Value="#00FFFFFF" />
<Setter Property="Control.Template">
<Setter Property="Background" Value="#00FFFFFF" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ad:Resizer}">
<Border Background="{TemplateBinding Control.Background}" />
<Border Background="{TemplateBinding Background}" />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="PaneHeaderCommandStyle" TargetType="{x:Type Button}">
<Setter Property="Control.Template">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border Name="PaneHeaderCommandIntBorder" Background="#00FFFFFF" BorderThickness="1" Margin="0" Opacity="0.8">
@ -35,8 +35,8 @@ @@ -35,8 +35,8 @@
</Border>
<ControlTemplate.Triggers>
<Trigger Property="UIElement.IsMouseOver" Value="True">
<Setter TargetName="PaneHeaderCommandIntBorder" Value="{DynamicResource {ComponentResourceKey {x:Type ad:DockingManager}, {x:Static ad:AvalonDockBrushes.PaneHeaderCommandBorderBrush}}}" Property="Border.BorderBrush" />
<Setter TargetName="PaneHeaderCommandIntBorder" Value="{DynamicResource {ComponentResourceKey {x:Type ad:DockingManager}, {x:Static ad:AvalonDockBrushes.PaneHeaderCommandBackground}}}" Property="Border.Background" />
<Setter TargetName="PaneHeaderCommandIntBorder" Property="BorderBrush" Value="{DynamicResource {ComponentResourceKey {x:Type ad:DockingManager}, {x:Static ad:AvalonDockBrushes.PaneHeaderCommandBorderBrush}}}" />
<Setter TargetName="PaneHeaderCommandIntBorder" Property="Background" Value="{DynamicResource {ComponentResourceKey {x:Type ad:DockingManager}, {x:Static ad:AvalonDockBrushes.PaneHeaderCommandBackground}}}" />
<Setter TargetName="PaneHeaderCommandIntBorder" Property="UIElement.Opacity" Value="1" />
</Trigger>
</ControlTemplate.Triggers>
@ -45,12 +45,12 @@ @@ -45,12 +45,12 @@
</Setter>
</Style>
<Style x:Key="PaneHeaderContextMenuCommandStyle" TargetType="{x:Type Border}">
<Setter Property="Border.Background" Value="#00FFFFFF" />
<Setter Property="Border.BorderThickness" Value="1" />
<Setter Property="Background" Value="#00FFFFFF" />
<Setter Property="BorderThickness" Value="1" />
<Style.Triggers>
<Trigger Property="UIElement.IsMouseOver" Value="True">
<Setter Property="Border.BorderBrush" Value="{DynamicResource {ComponentResourceKey {x:Type ad:DockingManager}, {x:Static ad:AvalonDockBrushes.PaneHeaderCommandBorderBrush}}}" />
<Setter Property="Border.Background" Value="{DynamicResource {ComponentResourceKey {x:Type ad:DockingManager}, {x:Static ad:AvalonDockBrushes.PaneHeaderCommandBackground}}}" />
<Setter Property="BorderBrush" Value="{DynamicResource {ComponentResourceKey {x:Type ad:DockingManager}, {x:Static ad:AvalonDockBrushes.PaneHeaderCommandBorderBrush}}}" />
<Setter Property="Background" Value="{DynamicResource {ComponentResourceKey {x:Type ad:DockingManager}, {x:Static ad:AvalonDockBrushes.PaneHeaderCommandBackground}}}" />
<Setter Property="UIElement.Opacity" Value="1" />
</Trigger>
</Style.Triggers>

26
ILSpy.BamlDecompiler.Tests/Cases/EscapeSequence.xaml

@ -1,16 +1,18 @@ @@ -1,16 +1,18 @@
<UserControl xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:system="clr-namespace:System;assembly=mscorlib">
<StackPanel>
<StackPanel.Resources>
<DataTemplate x:Key="key" DataType="{}{http://planetsNS}Planet">
<StackPanel Orientation="Horizontal">
<TextBlock Width="100" Text="{Binding Path=Element[{http://planetsNS}DiameterKM].Value}" />
<TextBlock Width="100" Text="{Binding Path=Attribute[Name].Value}" />
<TextBlock Text="{Binding Path=Element[{http://planetsNS}Details].Value}" />
<TextBlock Text="{Binding Source={x:Static system:DateTime.Now}, StringFormat=Date: {0:dddd, MMMM dd}}" />
<TextBlock Text="{Binding Source={x:Static system:DateTime.Now}, StringFormat=Time: {0:HH:mm}}" />
</StackPanel>
</DataTemplate>
</StackPanel.Resources>
<FrameworkElement.Resources>
<ResourceDictionary>
<DataTemplate x:Key="key" DataType="{}{http://planetsNS}Planet">
<StackPanel Orientation="Horizontal">
<TextBlock Width="100" Text="{Binding Path=Element[{http://planetsNS}DiameterKM].Value}" />
<TextBlock Width="100" Text="{Binding Path=Attribute[Name].Value}" />
<TextBlock Text="{Binding Path=Element[{http://planetsNS}Details].Value}" />
<TextBlock Text="{Binding Source={x:Static system:DateTime.Now}, StringFormat=Date: {0:dddd, MMMM dd}}" />
<TextBlock Text="{Binding Source={x:Static system:DateTime.Now}, StringFormat=Time: {0:HH:mm}}" />
</StackPanel>
</DataTemplate>
</ResourceDictionary>
</FrameworkElement.Resources>
<TextBlock Text="{Binding Path=ActualWidth, StringFormat=Window width: {0:#,#.0}}" />
<TextBlock Text="{Binding Path=ActualHeight, StringFormat=Window height: {0:C}}" />
<WrapPanel Margin="10">
@ -23,4 +25,4 @@ @@ -23,4 +25,4 @@
</StackPanel>
</WrapPanel>
</StackPanel>
</UserControl>
</UserControl>

22
ILSpy.BamlDecompiler.Tests/Cases/Issue445.xaml

@ -1,14 +1,18 @@ @@ -1,14 +1,18 @@
<UserControl x:Class="BamlTest.UserControl1" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<UserControl.Resources>
<Style x:Key="baseStyle" TargetType="{x:Type Control}" />
</UserControl.Resources>
<UserControl x:Class="BamlTest.UserControl1" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:bamltest="clr-namespace:BamlTest">
<FrameworkElement.Resources>
<ResourceDictionary>
<Style x:Key="baseStyle" TargetType="{x:Type Control}" />
</ResourceDictionary>
</FrameworkElement.Resources>
<Grid>
<Grid.ContextMenu>
<FrameworkElement.ContextMenu>
<ContextMenu>
<ContextMenu.Resources>
<Style TargetType="{x:Type Control}" BasedOn="{StaticResource baseStyle}" />
</ContextMenu.Resources>
<FrameworkElement.Resources>
<ResourceDictionary>
<Style x:Key="{x:Type Control}" BasedOn="{StaticResource baseStyle}" TargetType="{x:Type Control}" />
</ResourceDictionary>
</FrameworkElement.Resources>
</ContextMenu>
</Grid.ContextMenu>
</FrameworkElement.ContextMenu>
</Grid>
</UserControl>

11
ILSpy.BamlDecompiler.Tests/Cases/MarkupExtension.xaml

@ -1,8 +1,5 @@ @@ -1,8 +1,5 @@
<Label DataContext="{Binding Blub}" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Label.Style>
<Style />
</Label.Style>
<Label.Content>
<Binding Path="Blah" StringFormat="{}{0} items" />
</Label.Content>
<Label xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" DataContext="{Binding Blub}" Content="{Binding Path=Blah, StringFormat={}{0} items}">
<FrameworkElement.Style>
<Style />
</FrameworkElement.Style>
</Label>

8
ILSpy.BamlDecompiler.Tests/Cases/MyControl.xaml

@ -1,7 +1,3 @@ @@ -1,7 +1,3 @@
<UserControl x:Class="ILSpy.BamlDecompiler.Tests.Cases.MyControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Grid>
</Grid>
<UserControl x:Class="ILSpy.BamlDecompiler.Tests.Cases.MyControl" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:cases="clr-namespace:ILSpy.BamlDecompiler.Tests.Cases">
<Grid />
</UserControl>

17
ILSpy.BamlDecompiler.Tests/Cases/NamespacePrefix.xaml

@ -1,17 +1,12 @@ @@ -1,17 +1,12 @@
<Grid xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:cc="clr-namespace:ILSpy.BamlDecompiler.Tests.Cases">
<cc:CustomControl>
<cc:CustomControl.Style>
<cc:CustomControl Grid.Row="0" Tag="{}{}{Test}" CustomName="Custom1">
<FrameworkElement.Style>
<Style />
</cc:CustomControl.Style>
<Grid.Row>0</Grid.Row>
<cc:CustomControl.Tag>{}{Test}</cc:CustomControl.Tag>
<cc:CustomControl.CustomName>Custom1</cc:CustomControl.CustomName>
</FrameworkElement.Style>
</cc:CustomControl>
<Label ToolTip="{DynamicResource {x:Static cc:CustomControl.SimpleProperty}}">
<Label.Style>
<Label ToolTip="{DynamicResource cc:CustomControl.SimpleProperty}" Grid.Row="0" cc:CustomControl.CustomName="Label1">
<FrameworkElement.Style>
<Style />
</Label.Style>
<Grid.Row>0</Grid.Row>
<cc:CustomControl.CustomName>Label1</cc:CustomControl.CustomName>
</FrameworkElement.Style>
</Label>
</Grid>

14
ILSpy.BamlDecompiler.Tests/Cases/Resources.xaml

@ -1,16 +1,18 @@ @@ -1,16 +1,18 @@
<Window x:Class="ILSpy.BamlDecompiler.Tests.Cases.Resources" Title="ILSpy.BamlDecompiler.Tests.Cases" Height="300" Width="300" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Window x:Class="ILSpy.BamlDecompiler.Tests.Cases.Resources" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:cases="clr-namespace:ILSpy.BamlDecompiler.Tests.Cases" Title="ILSpy.BamlDecompiler.Tests.Cases" Height="300" Width="300">
<Grid>
<Canvas>
<Canvas.Resources>
<FrameworkElement.Resources>
<ResourceDictionary>
<BooleanToVisibilityConverter x:Key="b" />
</ResourceDictionary>
</Canvas.Resources>
</FrameworkElement.Resources>
</Canvas>
<Canvas>
<Canvas.Resources>
<BooleanToVisibilityConverter x:Key="b" />
</Canvas.Resources>
<FrameworkElement.Resources>
<ResourceDictionary>
<BooleanToVisibilityConverter x:Key="b" />
</ResourceDictionary>
</FrameworkElement.Resources>
</Canvas>
</Grid>
</Window>

2
ILSpy.BamlDecompiler.Tests/Cases/Simple.xaml

@ -1,3 +1,3 @@ @@ -1,3 +1,3 @@
<Window x:Class="ILSpy.BamlDecompiler.Tests.Cases.Simple" Title="ILSpy.BamlDecompiler.Tests.Cases" Height="300" Width="300" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Window x:Class="ILSpy.BamlDecompiler.Tests.Cases.Simple" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:cases="clr-namespace:ILSpy.BamlDecompiler.Tests.Cases" Title="ILSpy.BamlDecompiler.Tests.Cases" Height="300" Width="300">
<Grid />
</Window>

2
ILSpy.BamlDecompiler.Tests/Cases/SimpleDictionary.xaml

@ -1 +1 @@ @@ -1 +1 @@
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"></ResourceDictionary>
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" />

2
ILSpy.BamlDecompiler.Tests/Cases/SimpleNames.xaml

@ -1,4 +1,4 @@ @@ -1,4 +1,4 @@
<Window x:Class="ILSpy.BamlDecompiler.Tests.Cases.SimpleNames" Title="ILSpy.BamlDecompiler.Tests.Cases" Height="300" Width="300" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc="clr-namespace:ILSpy.BamlDecompiler.Tests.Cases">
<Window x:Class="ILSpy.BamlDecompiler.Tests.Cases.SimpleNames" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc="clr-namespace:ILSpy.BamlDecompiler.Tests.Cases" Title="ILSpy.BamlDecompiler.Tests.Cases" Height="300" Width="300">
<Grid>
<Button Name="test" />
<mc:MyControl x:Name="test2" />

7
ILSpy.BamlDecompiler.Tests/Cases/SimplePropertyElement.xaml

@ -1,6 +1,5 @@ @@ -1,6 +1,5 @@
<Label xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Label.Style>
<Label xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Content="Blah">
<FrameworkElement.Style>
<Style />
</Label.Style>
<Label.Content>Blah</Label.Content>
</FrameworkElement.Style>
</Label>

2
ILSpy.BamlDecompiler.Tests/ILSpy.BamlDecompiler.Tests.csproj

@ -2,7 +2,7 @@ @@ -2,7 +2,7 @@
<Project Sdk="MSBuild.Sdk.Extras">
<PropertyGroup>
<TargetFramework>net46</TargetFramework>
<TargetFramework>net462</TargetFramework>
<GenerateAssemblyInfo>False</GenerateAssemblyInfo>

97
ILSpy.BamlDecompiler/Baml/BamlContext.cs

@ -0,0 +1,97 @@ @@ -0,0 +1,97 @@
/*
Copyright (c) 2015 Ki
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
using System;
using System.Linq;
using System.Collections.Generic;
using System.Threading;
using ICSharpCode.Decompiler.TypeSystem;
using Metadata = ICSharpCode.Decompiler.Metadata;
namespace ILSpy.BamlDecompiler.Baml {
internal class BamlContext {
public IDecompilerTypeSystem TypeSystem { get; }
public KnownThings KnownThings { get; }
Dictionary<ushort, IModule> assemblyMap = new Dictionary<ushort, IModule>();
public Dictionary<ushort, AssemblyInfoRecord> AssemblyIdMap { get; }
public Dictionary<ushort, AttributeInfoRecord> AttributeIdMap { get; }
public Dictionary<ushort, StringInfoRecord> StringIdMap { get; }
public Dictionary<ushort, TypeInfoRecord> TypeIdMap { get; }
BamlContext(IDecompilerTypeSystem typeSystem) {
this.TypeSystem = typeSystem;
KnownThings = new KnownThings(typeSystem);
AssemblyIdMap = new Dictionary<ushort, AssemblyInfoRecord>();
AttributeIdMap = new Dictionary<ushort, AttributeInfoRecord>();
StringIdMap = new Dictionary<ushort, StringInfoRecord>();
TypeIdMap = new Dictionary<ushort, TypeInfoRecord>();
}
public static BamlContext ConstructContext(IDecompilerTypeSystem typeSystem, BamlDocument document, CancellationToken token) {
var ctx = new BamlContext(typeSystem);
foreach (var record in document) {
token.ThrowIfCancellationRequested();
if (record is AssemblyInfoRecord assemblyInfo) {
if (assemblyInfo.AssemblyId == ctx.AssemblyIdMap.Count)
ctx.AssemblyIdMap.Add(assemblyInfo.AssemblyId, assemblyInfo);
}
else if (record is AttributeInfoRecord attrInfo) {
if (attrInfo.AttributeId == ctx.AttributeIdMap.Count)
ctx.AttributeIdMap.Add(attrInfo.AttributeId, attrInfo);
}
else if (record is StringInfoRecord strInfo) {
if (strInfo.StringId == ctx.StringIdMap.Count)
ctx.StringIdMap.Add(strInfo.StringId, strInfo);
}
else if (record is TypeInfoRecord typeInfo) {
if (typeInfo.TypeId == ctx.TypeIdMap.Count)
ctx.TypeIdMap.Add(typeInfo.TypeId, typeInfo);
}
}
return ctx;
}
public IModule ResolveAssembly(ushort id) {
id &= 0xfff;
if (!assemblyMap.TryGetValue(id, out var assembly)) {
if (AssemblyIdMap.TryGetValue(id, out var assemblyRec)) {
var assemblyName = Metadata.AssemblyNameReference.Parse(assemblyRec.AssemblyFullName);
if (assemblyName.Name == TypeSystem.MainModule.AssemblyName)
assembly = TypeSystem.MainModule;
else
assembly = TypeSystem.ReferencedModules.FirstOrDefault(m => m.FullAssemblyName == assemblyName.FullName);
} else
assembly = null;
assemblyMap[id] = assembly;
}
return assembly;
}
}
}

39
ILSpy.BamlDecompiler/Baml/BamlDocument.cs

@ -0,0 +1,39 @@ @@ -0,0 +1,39 @@
/*
Copyright (c) 2015 Ki
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
using System.Collections.Generic;
namespace ILSpy.BamlDecompiler.Baml {
internal class BamlDocument : List<BamlRecord> {
public string DocumentName { get; set; }
public string Signature { get; set; }
public BamlVersion ReaderVersion { get; set; }
public BamlVersion UpdaterVersion { get; set; }
public BamlVersion WriterVersion { get; set; }
public struct BamlVersion {
public ushort Major;
public ushort Minor;
}
}
}

164
ILSpy.BamlDecompiler/Baml/BamlNode.cs

@ -0,0 +1,164 @@ @@ -0,0 +1,164 @@
/*
Copyright (c) 2015 Ki
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Threading;
namespace ILSpy.BamlDecompiler.Baml {
internal abstract class BamlNode {
public BamlBlockNode Parent { get; set; }
public abstract BamlRecordType Type { get; }
public object Annotation { get; set; }
public abstract BamlRecord Record { get; }
public static bool IsHeader(BamlRecord rec) {
switch (rec.Type) {
case BamlRecordType.ConstructorParametersStart:
case BamlRecordType.DocumentStart:
case BamlRecordType.ElementStart:
case BamlRecordType.KeyElementStart:
case BamlRecordType.NamedElementStart:
case BamlRecordType.PropertyArrayStart:
case BamlRecordType.PropertyComplexStart:
case BamlRecordType.PropertyDictionaryStart:
case BamlRecordType.PropertyListStart:
case BamlRecordType.StaticResourceStart:
return true;
}
return false;
}
public static bool IsFooter(BamlRecord rec) {
switch (rec.Type) {
case BamlRecordType.ConstructorParametersEnd:
case BamlRecordType.DocumentEnd:
case BamlRecordType.ElementEnd:
case BamlRecordType.KeyElementEnd:
case BamlRecordType.PropertyArrayEnd:
case BamlRecordType.PropertyComplexEnd:
case BamlRecordType.PropertyDictionaryEnd:
case BamlRecordType.PropertyListEnd:
case BamlRecordType.StaticResourceEnd:
return true;
}
return false;
}
public static bool IsMatch(BamlRecord header, BamlRecord footer) {
switch (header.Type) {
case BamlRecordType.ConstructorParametersStart:
return footer.Type == BamlRecordType.ConstructorParametersEnd;
case BamlRecordType.DocumentStart:
return footer.Type == BamlRecordType.DocumentEnd;
case BamlRecordType.KeyElementStart:
return footer.Type == BamlRecordType.KeyElementEnd;
case BamlRecordType.PropertyArrayStart:
return footer.Type == BamlRecordType.PropertyArrayEnd;
case BamlRecordType.PropertyComplexStart:
return footer.Type == BamlRecordType.PropertyComplexEnd;
case BamlRecordType.PropertyDictionaryStart:
return footer.Type == BamlRecordType.PropertyDictionaryEnd;
case BamlRecordType.PropertyListStart:
return footer.Type == BamlRecordType.PropertyListEnd;
case BamlRecordType.StaticResourceStart:
return footer.Type == BamlRecordType.StaticResourceEnd;
case BamlRecordType.ElementStart:
case BamlRecordType.NamedElementStart:
return footer.Type == BamlRecordType.ElementEnd;
}
return false;
}
public static BamlNode Parse(BamlDocument document, CancellationToken token) {
Debug.Assert(document.Count > 0 && document[0].Type == BamlRecordType.DocumentStart);
BamlBlockNode current = null;
var stack = new Stack<BamlBlockNode>();
for (int i = 0; i < document.Count; i++) {
token.ThrowIfCancellationRequested();
if (IsHeader(document[i])) {
var prev = current;
current = new BamlBlockNode {
Header = document[i]
};
if (prev != null) {
prev.Children.Add(current);
current.Parent = prev;
stack.Push(prev);
}
}
else if (IsFooter(document[i])) {
if (current == null)
throw new Exception("Unexpected footer.");
while (!IsMatch(current.Header, document[i])) {
// End record can be omited (sometimes).
if (stack.Count > 0)
current = stack.Pop();
}
current.Footer = document[i];
if (stack.Count > 0)
current = stack.Pop();
}
else
current.Children.Add(new BamlRecordNode(document[i]) { Parent = current });
}
Debug.Assert(stack.Count == 0);
return current;
}
}
internal class BamlRecordNode : BamlNode {
BamlRecord record;
public override BamlRecord Record => record;
public override BamlRecordType Type => Record.Type;
public BamlRecordNode(BamlRecord record) => this.record = record;
}
internal class BamlBlockNode : BamlNode {
public BamlRecord Header { get; set; }
public IList<BamlNode> Children { get; }
public BamlRecord Footer { get; set; }
public override BamlRecord Record => Header;
public override BamlRecordType Type => Header.Type;
public BamlBlockNode() => Children = new List<BamlNode>();
}
}

259
ILSpy.BamlDecompiler/Baml/BamlReader.cs

@ -0,0 +1,259 @@ @@ -0,0 +1,259 @@
/*
Copyright (c) 2015 Ki
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Threading;
namespace ILSpy.BamlDecompiler.Baml {
internal class BamlBinaryReader : BinaryReader {
public BamlBinaryReader(Stream stream)
: base(stream) {
}
public int ReadEncodedInt() => Read7BitEncodedInt();
}
internal class BamlReader {
const string MSBAML_SIG = "MSBAML";
internal static bool IsBamlHeader(Stream str) {
var pos = str.Position;
try {
var rdr = new BinaryReader(str, Encoding.Unicode);
int len = (int)(rdr.ReadUInt32() >> 1);
if (len != MSBAML_SIG.Length)
return false;
var sig = new string(rdr.ReadChars(len));
return sig == MSBAML_SIG;
}
finally {
str.Position = pos;
}
}
static string ReadSignature(Stream str) {
var rdr = new BinaryReader(str, Encoding.Unicode);
uint len = rdr.ReadUInt32();
var sig = new string(rdr.ReadChars((int)(len >> 1)));
rdr.ReadBytes((int)(((len + 3) & ~3) - len));
return sig;
}
public static BamlDocument ReadDocument(Stream str, CancellationToken token) {
var ret = new BamlDocument();
var reader = new BamlBinaryReader(str);
ret.Signature = ReadSignature(str);
if (ret.Signature != MSBAML_SIG) throw new NotSupportedException();
ret.ReaderVersion = new BamlDocument.BamlVersion { Major = reader.ReadUInt16(), Minor = reader.ReadUInt16() };
ret.UpdaterVersion = new BamlDocument.BamlVersion { Major = reader.ReadUInt16(), Minor = reader.ReadUInt16() };
ret.WriterVersion = new BamlDocument.BamlVersion { Major = reader.ReadUInt16(), Minor = reader.ReadUInt16() };
if (ret.ReaderVersion.Major != 0 || ret.ReaderVersion.Minor != 0x60 ||
ret.UpdaterVersion.Major != 0 || ret.UpdaterVersion.Minor != 0x60 ||
ret.WriterVersion.Major != 0 || ret.WriterVersion.Minor != 0x60)
throw new NotSupportedException();
var recs = new Dictionary<long, BamlRecord>();
while (str.Position < str.Length) {
token.ThrowIfCancellationRequested();
long pos = str.Position;
var type = (BamlRecordType)reader.ReadByte();
BamlRecord rec = null;
switch (type) {
case BamlRecordType.AssemblyInfo:
rec = new AssemblyInfoRecord();
break;
case BamlRecordType.AttributeInfo:
rec = new AttributeInfoRecord();
break;
case BamlRecordType.ConstructorParametersStart:
rec = new ConstructorParametersStartRecord();
break;
case BamlRecordType.ConstructorParametersEnd:
rec = new ConstructorParametersEndRecord();
break;
case BamlRecordType.ConstructorParameterType:
rec = new ConstructorParameterTypeRecord();
break;
case BamlRecordType.ConnectionId:
rec = new ConnectionIdRecord();
break;
case BamlRecordType.ContentProperty:
rec = new ContentPropertyRecord();
break;
case BamlRecordType.DefAttribute:
rec = new DefAttributeRecord();
break;
case BamlRecordType.DefAttributeKeyString:
rec = new DefAttributeKeyStringRecord();
break;
case BamlRecordType.DefAttributeKeyType:
rec = new DefAttributeKeyTypeRecord();
break;
case BamlRecordType.DeferableContentStart:
rec = new DeferableContentStartRecord();
break;
case BamlRecordType.DocumentEnd:
rec = new DocumentEndRecord();
break;
case BamlRecordType.DocumentStart:
rec = new DocumentStartRecord();
break;
case BamlRecordType.ElementEnd:
rec = new ElementEndRecord();
break;
case BamlRecordType.ElementStart:
rec = new ElementStartRecord();
break;
case BamlRecordType.KeyElementEnd:
rec = new KeyElementEndRecord();
break;
case BamlRecordType.KeyElementStart:
rec = new KeyElementStartRecord();
break;
case BamlRecordType.LineNumberAndPosition:
rec = new LineNumberAndPositionRecord();
break;
case BamlRecordType.LinePosition:
rec = new LinePositionRecord();
break;
case BamlRecordType.LiteralContent:
rec = new LiteralContentRecord();
break;
case BamlRecordType.NamedElementStart:
rec = new NamedElementStartRecord();
break;
case BamlRecordType.OptimizedStaticResource:
rec = new OptimizedStaticResourceRecord();
break;
case BamlRecordType.PIMapping:
rec = new PIMappingRecord();
break;
case BamlRecordType.PresentationOptionsAttribute:
rec = new PresentationOptionsAttributeRecord();
break;
case BamlRecordType.Property:
rec = new PropertyRecord();
break;
case BamlRecordType.PropertyArrayEnd:
rec = new PropertyArrayEndRecord();
break;
case BamlRecordType.PropertyArrayStart:
rec = new PropertyArrayStartRecord();
break;
case BamlRecordType.PropertyComplexEnd:
rec = new PropertyComplexEndRecord();
break;
case BamlRecordType.PropertyComplexStart:
rec = new PropertyComplexStartRecord();
break;
case BamlRecordType.PropertyCustom:
rec = new PropertyCustomRecord();
break;
case BamlRecordType.PropertyDictionaryEnd:
rec = new PropertyDictionaryEndRecord();
break;
case BamlRecordType.PropertyDictionaryStart:
rec = new PropertyDictionaryStartRecord();
break;
case BamlRecordType.PropertyListEnd:
rec = new PropertyListEndRecord();
break;
case BamlRecordType.PropertyListStart:
rec = new PropertyListStartRecord();
break;
case BamlRecordType.PropertyStringReference:
rec = new PropertyStringReferenceRecord();
break;
case BamlRecordType.PropertyTypeReference:
rec = new PropertyTypeReferenceRecord();
break;
case BamlRecordType.PropertyWithConverter:
rec = new PropertyWithConverterRecord();
break;
case BamlRecordType.PropertyWithExtension:
rec = new PropertyWithExtensionRecord();
break;
case BamlRecordType.PropertyWithStaticResourceId:
rec = new PropertyWithStaticResourceIdRecord();
break;
case BamlRecordType.RoutedEvent:
rec = new RoutedEventRecord();
break;
case BamlRecordType.StaticResourceEnd:
rec = new StaticResourceEndRecord();
break;
case BamlRecordType.StaticResourceId:
rec = new StaticResourceIdRecord();
break;
case BamlRecordType.StaticResourceStart:
rec = new StaticResourceStartRecord();
break;
case BamlRecordType.StringInfo:
rec = new StringInfoRecord();
break;
case BamlRecordType.Text:
rec = new TextRecord();
break;
case BamlRecordType.TextWithConverter:
rec = new TextWithConverterRecord();
break;
case BamlRecordType.TextWithId:
rec = new TextWithIdRecord();
break;
case BamlRecordType.TypeInfo:
rec = new TypeInfoRecord();
break;
case BamlRecordType.TypeSerializerInfo:
rec = new TypeSerializerInfoRecord();
break;
case BamlRecordType.XmlnsProperty:
rec = new XmlnsPropertyRecord();
break;
case BamlRecordType.XmlAttribute:
case BamlRecordType.ProcessingInstruction:
case BamlRecordType.LastRecordType:
case BamlRecordType.EndAttributes:
case BamlRecordType.DefTag:
case BamlRecordType.ClrEvent:
case BamlRecordType.Comment:
default:
throw new NotSupportedException();
}
rec.Position = pos;
rec.Read(reader);
ret.Add(rec);
recs.Add(pos, rec);
}
for (int i = 0; i < ret.Count; i++) {
if (ret[i] is IBamlDeferRecord defer)
defer.ReadDefer(ret, i, _ => recs[_]);
}
return ret;
}
}
}

992
ILSpy.BamlDecompiler/Baml/BamlRecords.cs

@ -0,0 +1,992 @@ @@ -0,0 +1,992 @@
/*
Copyright (c) 2015 Ki
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
using System;
using System.Diagnostics;
using System.IO;
namespace ILSpy.BamlDecompiler.Baml {
internal enum BamlRecordType : byte {
ClrEvent = 0x13,
Comment = 0x17,
AssemblyInfo = 0x1c,
AttributeInfo = 0x1f,
ConstructorParametersStart = 0x2a,
ConstructorParametersEnd = 0x2b,
ConstructorParameterType = 0x2c,
ConnectionId = 0x2d,
ContentProperty = 0x2e,
DefAttribute = 0x19,
DefAttributeKeyString = 0x26,
DefAttributeKeyType = 0x27,
DeferableContentStart = 0x25,
DefTag = 0x18,
DocumentEnd = 0x2,
DocumentStart = 0x1,
ElementEnd = 0x4,
ElementStart = 0x3,
EndAttributes = 0x1a,
KeyElementEnd = 0x29,
KeyElementStart = 0x28,
LastRecordType = 0x39,
LineNumberAndPosition = 0x35,
LinePosition = 0x36,
LiteralContent = 0xf,
NamedElementStart = 0x2f,
OptimizedStaticResource = 0x37,
PIMapping = 0x1b,
PresentationOptionsAttribute = 0x34,
ProcessingInstruction = 0x16,
Property = 0x5,
PropertyArrayEnd = 0xa,
PropertyArrayStart = 0x9,
PropertyComplexEnd = 0x8,
PropertyComplexStart = 0x7,
PropertyCustom = 0x6,
PropertyDictionaryEnd = 0xe,
PropertyDictionaryStart = 0xd,
PropertyListEnd = 0xc,
PropertyListStart = 0xb,
PropertyStringReference = 0x21,
PropertyTypeReference = 0x22,
PropertyWithConverter = 0x24,
PropertyWithExtension = 0x23,
PropertyWithStaticResourceId = 0x38,
RoutedEvent = 0x12,
StaticResourceEnd = 0x31,
StaticResourceId = 0x32,
StaticResourceStart = 0x30,
StringInfo = 0x20,
Text = 0x10,
TextWithConverter = 0x11,
TextWithId = 0x33,
TypeInfo = 0x1d,
TypeSerializerInfo = 0x1e,
XmlAttribute = 0x15,
XmlnsProperty = 0x14
}
internal abstract class BamlRecord {
public abstract BamlRecordType Type { get; }
public long Position { get; internal set; }
public abstract void Read(BamlBinaryReader reader);
public abstract void Write(BamlBinaryWriter writer);
}
internal abstract class SizedBamlRecord : BamlRecord {
public override void Read(BamlBinaryReader reader) {
long pos = reader.BaseStream.Position;
int size = reader.ReadEncodedInt();
ReadData(reader, size - (int)(reader.BaseStream.Position - pos));
Debug.Assert(reader.BaseStream.Position - pos == size);
}
int SizeofEncodedInt(int val) {
if ((val & ~0x7F) == 0) {
return 1;
}
if ((val & ~0x3FFF) == 0) {
return 2;
}
if ((val & ~0x1FFFFF) == 0) {
return 3;
}
if ((val & ~0xFFFFFFF) == 0) {
return 4;
}
return 5;
}
public override void Write(BamlBinaryWriter writer) {
long pos = writer.BaseStream.Position;
WriteData(writer);
var size = (int)(writer.BaseStream.Position - pos);
size = SizeofEncodedInt(SizeofEncodedInt(size) + size) + size;
writer.BaseStream.Position = pos;
writer.WriteEncodedInt(size);
WriteData(writer);
}
protected abstract void ReadData(BamlBinaryReader reader, int size);
protected abstract void WriteData(BamlBinaryWriter writer);
}
internal interface IBamlDeferRecord {
long Position { get; }
BamlRecord Record { get; set; }
void ReadDefer(BamlDocument doc, int index, Func<long, BamlRecord> resolve);
void WriteDefer(BamlDocument doc, int index, BinaryWriter wtr);
}
internal class XmlnsPropertyRecord : SizedBamlRecord {
public override BamlRecordType Type => BamlRecordType.XmlnsProperty;
public string Prefix { get; set; }
public string XmlNamespace { get; set; }
public ushort[] AssemblyIds { get; set; }
protected override void ReadData(BamlBinaryReader reader, int size) {
Prefix = reader.ReadString();
XmlNamespace = reader.ReadString();
AssemblyIds = new ushort[reader.ReadUInt16()];
for (int i = 0; i < AssemblyIds.Length; i++)
AssemblyIds[i] = reader.ReadUInt16();
}
protected override void WriteData(BamlBinaryWriter writer) {
writer.Write(Prefix);
writer.Write(XmlNamespace);
writer.Write((ushort)AssemblyIds.Length);
foreach (ushort i in AssemblyIds)
writer.Write(i);
}
}
internal class PresentationOptionsAttributeRecord : SizedBamlRecord {
public override BamlRecordType Type => BamlRecordType.PresentationOptionsAttribute;
public string Value { get; set; }
public ushort NameId { get; set; }
protected override void ReadData(BamlBinaryReader reader, int size) {
Value = reader.ReadString();
NameId = reader.ReadUInt16();
}
protected override void WriteData(BamlBinaryWriter writer) {
writer.Write(Value);
writer.Write(NameId);
}
}
internal class PIMappingRecord : SizedBamlRecord {
public override BamlRecordType Type => BamlRecordType.PIMapping;
public string XmlNamespace { get; set; }
public string ClrNamespace { get; set; }
public ushort AssemblyId { get; set; }
protected override void ReadData(BamlBinaryReader reader, int size) {
XmlNamespace = reader.ReadString();
ClrNamespace = reader.ReadString();
AssemblyId = reader.ReadUInt16();
}
protected override void WriteData(BamlBinaryWriter writer) {
writer.Write(XmlNamespace);
writer.Write(ClrNamespace);
writer.Write(AssemblyId);
}
}
internal class AssemblyInfoRecord : SizedBamlRecord {
public override BamlRecordType Type => BamlRecordType.AssemblyInfo;
public ushort AssemblyId { get; set; }
public string AssemblyFullName { get; set; }
protected override void ReadData(BamlBinaryReader reader, int size) {
AssemblyId = reader.ReadUInt16();
AssemblyFullName = reader.ReadString();
}
protected override void WriteData(BamlBinaryWriter writer) {
writer.Write(AssemblyId);
writer.Write(AssemblyFullName);
}
}
internal class PropertyRecord : SizedBamlRecord {
public override BamlRecordType Type => BamlRecordType.Property;
public ushort AttributeId { get; set; }
public string Value { get; set; }
protected override void ReadData(BamlBinaryReader reader, int size) {
AttributeId = reader.ReadUInt16();
Value = reader.ReadString();
}
protected override void WriteData(BamlBinaryWriter writer) {
writer.Write(AttributeId);
writer.Write(Value);
}
}
internal class PropertyWithConverterRecord : PropertyRecord {
public override BamlRecordType Type => BamlRecordType.PropertyWithConverter;
public ushort ConverterTypeId { get; set; }
protected override void ReadData(BamlBinaryReader reader, int size) {
base.ReadData(reader, size);
ConverterTypeId = reader.ReadUInt16();
}
protected override void WriteData(BamlBinaryWriter writer) {
base.WriteData(writer);
writer.Write(ConverterTypeId);
}
}
internal class PropertyCustomRecord : SizedBamlRecord {
public override BamlRecordType Type => BamlRecordType.PropertyCustom;
public ushort AttributeId { get; set; }
public ushort SerializerTypeId { get; set; }
public byte[] Data { get; set; }
protected override void ReadData(BamlBinaryReader reader, int size) {
long pos = reader.BaseStream.Position;
AttributeId = reader.ReadUInt16();
SerializerTypeId = reader.ReadUInt16();
Data = reader.ReadBytes(size - (int)(reader.BaseStream.Position - pos));
}
protected override void WriteData(BamlBinaryWriter writer) {
writer.Write(AttributeId);
writer.Write(SerializerTypeId);
writer.Write(Data);
}
}
internal class DefAttributeRecord : SizedBamlRecord {
public override BamlRecordType Type => BamlRecordType.DefAttribute;
public string Value { get; set; }
public ushort NameId { get; set; }
protected override void ReadData(BamlBinaryReader reader, int size) {
Value = reader.ReadString();
NameId = reader.ReadUInt16();
}
protected override void WriteData(BamlBinaryWriter writer) {
writer.Write(Value);
writer.Write(NameId);
}
}
internal class DefAttributeKeyStringRecord : SizedBamlRecord, IBamlDeferRecord {
internal uint pos = 0xffffffff;
public override BamlRecordType Type => BamlRecordType.DefAttributeKeyString;
public ushort ValueId { get; set; }
public bool Shared { get; set; }
public bool SharedSet { get; set; }
public BamlRecord Record { get; set; }
public void ReadDefer(BamlDocument doc, int index, Func<long, BamlRecord> resolve) {
bool keys = true;
do {
switch (doc[index].Type) {
case BamlRecordType.DefAttributeKeyString:
case BamlRecordType.DefAttributeKeyType:
case BamlRecordType.OptimizedStaticResource:
keys = true;
break;
case BamlRecordType.StaticResourceStart:
NavigateTree(doc, BamlRecordType.StaticResourceStart, BamlRecordType.StaticResourceEnd, ref index);
keys = true;
break;
case BamlRecordType.KeyElementStart:
NavigateTree(doc, BamlRecordType.KeyElementStart, BamlRecordType.KeyElementEnd, ref index);
keys = true;
break;
default:
keys = false;
index--;
break;
}
index++;
} while (keys);
Record = resolve(doc[index].Position + pos);
}
public void WriteDefer(BamlDocument doc, int index, BinaryWriter wtr) {
bool keys = true;
do {
switch (doc[index].Type) {
case BamlRecordType.DefAttributeKeyString:
case BamlRecordType.DefAttributeKeyType:
case BamlRecordType.OptimizedStaticResource:
keys = true;
break;
case BamlRecordType.StaticResourceStart:
NavigateTree(doc, BamlRecordType.StaticResourceStart, BamlRecordType.StaticResourceEnd, ref index);
keys = true;
break;
case BamlRecordType.KeyElementStart:
NavigateTree(doc, BamlRecordType.KeyElementStart, BamlRecordType.KeyElementEnd, ref index);
keys = true;
break;
default:
keys = false;
index--;
break;
}
index++;
} while (keys);
wtr.BaseStream.Seek(pos, SeekOrigin.Begin);
wtr.Write((uint)(Record.Position - doc[index].Position));
}
protected override void ReadData(BamlBinaryReader reader, int size) {
ValueId = reader.ReadUInt16();
pos = reader.ReadUInt32();
Shared = reader.ReadBoolean();
SharedSet = reader.ReadBoolean();
}
protected override void WriteData(BamlBinaryWriter writer) {
writer.Write(ValueId);
pos = (uint)writer.BaseStream.Position;
writer.Write((uint)0);
writer.Write(Shared);
writer.Write(SharedSet);
}
static void NavigateTree(BamlDocument doc, BamlRecordType start, BamlRecordType end, ref int index) {
index++;
while (true) //Assume there alway is a end
{
if (doc[index].Type == start)
NavigateTree(doc, start, end, ref index);
else if (doc[index].Type == end)
return;
index++;
}
}
}
internal class TypeInfoRecord : SizedBamlRecord {
public override BamlRecordType Type => BamlRecordType.TypeInfo;
public ushort TypeId { get; set; }
public ushort AssemblyId { get; set; }
public string TypeFullName { get; set; }
protected override void ReadData(BamlBinaryReader reader, int size) {
TypeId = reader.ReadUInt16();
AssemblyId = reader.ReadUInt16();
TypeFullName = reader.ReadString();
}
protected override void WriteData(BamlBinaryWriter writer) {
writer.Write(TypeId);
writer.Write(AssemblyId);
writer.Write(TypeFullName);
}
}
internal class TypeSerializerInfoRecord : TypeInfoRecord {
public override BamlRecordType Type => BamlRecordType.TypeSerializerInfo;
public ushort SerializerTypeId { get; set; }
protected override void ReadData(BamlBinaryReader reader, int size) {
base.ReadData(reader, size);
SerializerTypeId = reader.ReadUInt16();
}
protected override void WriteData(BamlBinaryWriter writer) {
base.WriteData(writer);
writer.Write(SerializerTypeId);
}
}
internal class AttributeInfoRecord : SizedBamlRecord {
public override BamlRecordType Type => BamlRecordType.AttributeInfo;
public ushort AttributeId { get; set; }
public ushort OwnerTypeId { get; set; }
public byte AttributeUsage { get; set; }
public string Name { get; set; }
protected override void ReadData(BamlBinaryReader reader, int size) {
AttributeId = reader.ReadUInt16();
OwnerTypeId = reader.ReadUInt16();
AttributeUsage = reader.ReadByte();
Name = reader.ReadString();
}
protected override void WriteData(BamlBinaryWriter writer) {
writer.Write(AttributeId);
writer.Write(OwnerTypeId);
writer.Write(AttributeUsage);
writer.Write(Name);
}
}
internal class StringInfoRecord : SizedBamlRecord {
public override BamlRecordType Type => BamlRecordType.StringInfo;
public ushort StringId { get; set; }
public string Value { get; set; }
protected override void ReadData(BamlBinaryReader reader, int size) {
StringId = reader.ReadUInt16();
Value = reader.ReadString();
}
protected override void WriteData(BamlBinaryWriter writer) {
writer.Write(StringId);
writer.Write(Value);
}
}
internal class TextRecord : SizedBamlRecord {
public override BamlRecordType Type => BamlRecordType.Text;
public string Value { get; set; }
protected override void ReadData(BamlBinaryReader reader, int size) => Value = reader.ReadString();
protected override void WriteData(BamlBinaryWriter writer) => writer.Write(Value);
}
internal class TextWithConverterRecord : TextRecord {
public override BamlRecordType Type => BamlRecordType.TextWithConverter;
public ushort ConverterTypeId { get; set; }
protected override void ReadData(BamlBinaryReader reader, int size) {
base.ReadData(reader, size);
ConverterTypeId = reader.ReadUInt16();
}
protected override void WriteData(BamlBinaryWriter writer) {
base.WriteData(writer);
writer.Write(ConverterTypeId);
}
}
internal class TextWithIdRecord : SizedBamlRecord {
public override BamlRecordType Type => BamlRecordType.TextWithId;
public ushort ValueId { get; set; }
protected override void ReadData(BamlBinaryReader reader, int size) => ValueId = reader.ReadUInt16();
protected override void WriteData(BamlBinaryWriter writer) => writer.Write(ValueId);
}
internal class LiteralContentRecord : SizedBamlRecord {
public override BamlRecordType Type => BamlRecordType.LiteralContent;
public string Value { get; set; }
public uint Reserved0 { get; set; }
public uint Reserved1 { get; set; }
protected override void ReadData(BamlBinaryReader reader, int size) {
Value = reader.ReadString();
Reserved0 = reader.ReadUInt32();
Reserved1 = reader.ReadUInt32();
}
protected override void WriteData(BamlBinaryWriter writer) {
writer.Write(Value);
writer.Write(Reserved0);
writer.Write(Reserved1);
}
}
internal class RoutedEventRecord : SizedBamlRecord {
public override BamlRecordType Type => BamlRecordType.RoutedEvent;
public string Value { get; set; }
public ushort AttributeId { get; set; }
public uint Reserved1 { get; set; }
protected override void ReadData(BamlBinaryReader reader, int size) {
AttributeId = reader.ReadUInt16();
Value = reader.ReadString();
}
protected override void WriteData(BamlBinaryWriter writer) {
writer.Write(Value);
writer.Write(AttributeId);
}
}
internal class DocumentStartRecord : BamlRecord {
public override BamlRecordType Type => BamlRecordType.DocumentStart;
public bool LoadAsync { get; set; }
public uint MaxAsyncRecords { get; set; }
public bool DebugBaml { get; set; }
public override void Read(BamlBinaryReader reader) {
LoadAsync = reader.ReadBoolean();
MaxAsyncRecords = reader.ReadUInt32();
DebugBaml = reader.ReadBoolean();
}
public override void Write(BamlBinaryWriter writer) {
writer.Write(LoadAsync);
writer.Write(MaxAsyncRecords);
writer.Write(DebugBaml);
}
}
internal class DocumentEndRecord : BamlRecord {
public override BamlRecordType Type => BamlRecordType.DocumentEnd;
public override void Read(BamlBinaryReader reader) {
}
public override void Write(BamlBinaryWriter writer) {
}
}
internal class ElementStartRecord : BamlRecord {
public override BamlRecordType Type => BamlRecordType.ElementStart;
public ushort TypeId { get; set; }
public byte Flags { get; set; }
public override void Read(BamlBinaryReader reader) {
TypeId = reader.ReadUInt16();
Flags = reader.ReadByte();
}
public override void Write(BamlBinaryWriter writer) {
writer.Write(TypeId);
writer.Write(Flags);
}
}
internal class ElementEndRecord : BamlRecord {
public override BamlRecordType Type => BamlRecordType.ElementEnd;
public override void Read(BamlBinaryReader reader) {
}
public override void Write(BamlBinaryWriter writer) {
}
}
internal class KeyElementStartRecord : DefAttributeKeyTypeRecord {
public override BamlRecordType Type => BamlRecordType.KeyElementStart;
}
internal class KeyElementEndRecord : BamlRecord {
public override BamlRecordType Type => BamlRecordType.KeyElementEnd;
public override void Read(BamlBinaryReader reader) {
}
public override void Write(BamlBinaryWriter writer) {
}
}
internal class ConnectionIdRecord : BamlRecord {
public override BamlRecordType Type => BamlRecordType.ConnectionId;
public uint ConnectionId { get; set; }
public override void Read(BamlBinaryReader reader) => ConnectionId = reader.ReadUInt32();
public override void Write(BamlBinaryWriter writer) => writer.Write(ConnectionId);
}
internal class PropertyWithExtensionRecord : BamlRecord {
public override BamlRecordType Type => BamlRecordType.PropertyWithExtension;
public ushort AttributeId { get; set; }
public ushort Flags { get; set; }
public ushort ValueId { get; set; }
public override void Read(BamlBinaryReader reader) {
AttributeId = reader.ReadUInt16();
Flags = reader.ReadUInt16();
ValueId = reader.ReadUInt16();
}
public override void Write(BamlBinaryWriter writer) {
writer.Write(AttributeId);
writer.Write(Flags);
writer.Write(ValueId);
}
}
internal class PropertyTypeReferenceRecord : PropertyComplexStartRecord {
public override BamlRecordType Type => BamlRecordType.PropertyTypeReference;
public ushort TypeId { get; set; }
public override void Read(BamlBinaryReader reader) {
base.Read(reader);
TypeId = reader.ReadUInt16();
}
public override void Write(BamlBinaryWriter writer) {
base.Write(writer);
writer.Write(TypeId);
}
}
internal class PropertyStringReferenceRecord : PropertyComplexStartRecord {
public override BamlRecordType Type => BamlRecordType.PropertyStringReference;
public ushort StringId { get; set; }
public override void Read(BamlBinaryReader reader) {
base.Read(reader);
StringId = reader.ReadUInt16();
}
public override void Write(BamlBinaryWriter writer) {
base.Write(writer);
writer.Write(StringId);
}
}
internal class PropertyWithStaticResourceIdRecord : StaticResourceIdRecord {
public override BamlRecordType Type => BamlRecordType.PropertyWithStaticResourceId;
public ushort AttributeId { get; set; }
public override void Read(BamlBinaryReader reader) {
AttributeId = reader.ReadUInt16();
base.Read(reader);
}
public override void Write(BamlBinaryWriter writer) {
writer.Write(AttributeId);
base.Write(writer);
}
}
internal class ContentPropertyRecord : BamlRecord {
public override BamlRecordType Type => BamlRecordType.ContentProperty;
public ushort AttributeId { get; set; }
public override void Read(BamlBinaryReader reader) => AttributeId = reader.ReadUInt16();
public override void Write(BamlBinaryWriter writer) => writer.Write(AttributeId);
}
internal class DefAttributeKeyTypeRecord : ElementStartRecord, IBamlDeferRecord {
internal uint pos = 0xffffffff;
public override BamlRecordType Type => BamlRecordType.DefAttributeKeyType;
public bool Shared { get; set; }
public bool SharedSet { get; set; }
public BamlRecord Record { get; set; }
public void ReadDefer(BamlDocument doc, int index, Func<long, BamlRecord> resolve) {
bool keys = true;
do {
switch (doc[index].Type) {
case BamlRecordType.DefAttributeKeyString:
case BamlRecordType.DefAttributeKeyType:
case BamlRecordType.OptimizedStaticResource:
keys = true;
break;
case BamlRecordType.StaticResourceStart:
NavigateTree(doc, BamlRecordType.StaticResourceStart, BamlRecordType.StaticResourceEnd, ref index);
keys = true;
break;
case BamlRecordType.KeyElementStart:
NavigateTree(doc, BamlRecordType.KeyElementStart, BamlRecordType.KeyElementEnd, ref index);
keys = true;
break;
default:
keys = false;
index--;
break;
}
index++;
} while (keys);
Record = resolve(doc[index].Position + pos);
}
public void WriteDefer(BamlDocument doc, int index, BinaryWriter wtr) {
bool keys = true;
do {
switch (doc[index].Type) {
case BamlRecordType.DefAttributeKeyString:
case BamlRecordType.DefAttributeKeyType:
case BamlRecordType.OptimizedStaticResource:
keys = true;
break;
case BamlRecordType.StaticResourceStart:
NavigateTree(doc, BamlRecordType.StaticResourceStart, BamlRecordType.StaticResourceEnd, ref index);
keys = true;
break;
case BamlRecordType.KeyElementStart:
NavigateTree(doc, BamlRecordType.KeyElementStart, BamlRecordType.KeyElementEnd, ref index);
keys = true;
break;
default:
keys = false;
index--;
break;
}
index++;
} while (keys);
wtr.BaseStream.Seek(pos, SeekOrigin.Begin);
wtr.Write((uint)(Record.Position - doc[index].Position));
}
public override void Read(BamlBinaryReader reader) {
base.Read(reader);
pos = reader.ReadUInt32();
Shared = reader.ReadBoolean();
SharedSet = reader.ReadBoolean();
}
public override void Write(BamlBinaryWriter writer) {
base.Write(writer);
pos = (uint)writer.BaseStream.Position;
writer.Write((uint)0);
writer.Write(Shared);
writer.Write(SharedSet);
}
static void NavigateTree(BamlDocument doc, BamlRecordType start, BamlRecordType end, ref int index) {
index++;
while (true) {
if (doc[index].Type == start)
NavigateTree(doc, start, end, ref index);
else if (doc[index].Type == end)
return;
index++;
}
}
}
internal class PropertyListStartRecord : PropertyComplexStartRecord {
public override BamlRecordType Type => BamlRecordType.PropertyListStart;
}
internal class PropertyListEndRecord : BamlRecord {
public override BamlRecordType Type => BamlRecordType.PropertyListEnd;
public override void Read(BamlBinaryReader reader) {
}
public override void Write(BamlBinaryWriter writer) {
}
}
internal class PropertyDictionaryStartRecord : PropertyComplexStartRecord {
public override BamlRecordType Type => BamlRecordType.PropertyDictionaryStart;
}
internal class PropertyDictionaryEndRecord : BamlRecord {
public override BamlRecordType Type => BamlRecordType.PropertyDictionaryEnd;
public override void Read(BamlBinaryReader reader) {
}
public override void Write(BamlBinaryWriter writer) {
}
}
internal class PropertyArrayStartRecord : PropertyComplexStartRecord {
public override BamlRecordType Type => BamlRecordType.PropertyArrayStart;
}
internal class PropertyArrayEndRecord : BamlRecord {
public override BamlRecordType Type => BamlRecordType.PropertyArrayEnd;
public override void Read(BamlBinaryReader reader) {
}
public override void Write(BamlBinaryWriter writer) {
}
}
internal class PropertyComplexStartRecord : BamlRecord {
public override BamlRecordType Type => BamlRecordType.PropertyComplexStart;
public ushort AttributeId { get; set; }
public override void Read(BamlBinaryReader reader) => AttributeId = reader.ReadUInt16();
public override void Write(BamlBinaryWriter writer) => writer.Write(AttributeId);
}
internal class PropertyComplexEndRecord : BamlRecord {
public override BamlRecordType Type => BamlRecordType.PropertyComplexEnd;
public override void Read(BamlBinaryReader reader) {
}
public override void Write(BamlBinaryWriter writer) {
}
}
internal class ConstructorParametersStartRecord : BamlRecord {
public override BamlRecordType Type => BamlRecordType.ConstructorParametersStart;
public override void Read(BamlBinaryReader reader) {
}
public override void Write(BamlBinaryWriter writer) {
}
}
internal class ConstructorParametersEndRecord : BamlRecord {
public override BamlRecordType Type => BamlRecordType.ConstructorParametersEnd;
public override void Read(BamlBinaryReader reader) {
}
public override void Write(BamlBinaryWriter writer) {
}
}
internal class ConstructorParameterTypeRecord : BamlRecord {
public override BamlRecordType Type => BamlRecordType.ConstructorParameterType;
public ushort TypeId { get; set; }
public override void Read(BamlBinaryReader reader) => TypeId = reader.ReadUInt16();
public override void Write(BamlBinaryWriter writer) => writer.Write(TypeId);
}
internal class DeferableContentStartRecord : BamlRecord, IBamlDeferRecord {
long pos;
internal uint size = 0xffffffff;
public override BamlRecordType Type => BamlRecordType.DeferableContentStart;
public BamlRecord Record { get; set; }
public void ReadDefer(BamlDocument doc, int index, Func<long, BamlRecord> resolve) => Record = resolve(pos + size);
public void WriteDefer(BamlDocument doc, int index, BinaryWriter wtr) {
wtr.BaseStream.Seek(pos, SeekOrigin.Begin);
wtr.Write((uint)(Record.Position - (pos + 4)));
}
public override void Read(BamlBinaryReader reader) {
size = reader.ReadUInt32();
pos = reader.BaseStream.Position;
}
public override void Write(BamlBinaryWriter writer) {
pos = writer.BaseStream.Position;
writer.Write((uint)0);
}
}
internal class StaticResourceStartRecord : ElementStartRecord {
public override BamlRecordType Type => BamlRecordType.StaticResourceStart;
}
internal class StaticResourceEndRecord : BamlRecord {
public override BamlRecordType Type => BamlRecordType.StaticResourceEnd;
public override void Read(BamlBinaryReader reader) {
}
public override void Write(BamlBinaryWriter writer) {
}
}
internal class StaticResourceIdRecord : BamlRecord {
public override BamlRecordType Type => BamlRecordType.StaticResourceId;
public ushort StaticResourceId { get; set; }
public override void Read(BamlBinaryReader reader) => StaticResourceId = reader.ReadUInt16();
public override void Write(BamlBinaryWriter writer) => writer.Write(StaticResourceId);
}
internal class OptimizedStaticResourceRecord : BamlRecord {
public override BamlRecordType Type => BamlRecordType.OptimizedStaticResource;
public byte Flags { get; set; }
public ushort ValueId { get; set; }
public bool IsType => (Flags & 1) != 0;
public bool IsStatic => (Flags & 2) != 0;
public override void Read(BamlBinaryReader reader) {
Flags = reader.ReadByte();
ValueId = reader.ReadUInt16();
}
public override void Write(BamlBinaryWriter writer) {
writer.Write(Flags);
writer.Write(ValueId);
}
}
internal class LineNumberAndPositionRecord : BamlRecord {
public override BamlRecordType Type => BamlRecordType.LineNumberAndPosition;
public uint LineNumber { get; set; }
public uint LinePosition { get; set; }
public override void Read(BamlBinaryReader reader) {
LineNumber = reader.ReadUInt32();
LinePosition = reader.ReadUInt32();
}
public override void Write(BamlBinaryWriter writer) {
writer.Write(LineNumber);
writer.Write(LinePosition);
}
}
internal class LinePositionRecord : BamlRecord {
public override BamlRecordType Type => BamlRecordType.LinePosition;
public uint LinePosition { get; set; }
public override void Read(BamlBinaryReader reader) => LinePosition = reader.ReadUInt32();
public override void Write(BamlBinaryWriter writer) => writer.Write(LinePosition);
}
internal class NamedElementStartRecord : ElementStartRecord {
public override BamlRecordType Type => BamlRecordType.NamedElementStart;
public string RuntimeName { get; set; }
public override void Read(BamlBinaryReader reader) {
TypeId = reader.ReadUInt16();
RuntimeName = reader.ReadString();
}
public override void Write(BamlBinaryWriter writer) {
writer.Write(TypeId);
if (RuntimeName != null) {
writer.Write(RuntimeName);
}
}
}
}

65
ILSpy.BamlDecompiler/Baml/BamlWriter.cs

@ -0,0 +1,65 @@ @@ -0,0 +1,65 @@
/*
Copyright (c) 2015 Ki
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
using System.Collections.Generic;
using System.IO;
using System.Text;
namespace ILSpy.BamlDecompiler.Baml {
internal class BamlBinaryWriter : BinaryWriter {
public BamlBinaryWriter(Stream stream)
: base(stream) {
}
public void WriteEncodedInt(int val) => Write7BitEncodedInt(val);
}
internal class BamlWriter {
public static void WriteDocument(BamlDocument doc, Stream str) {
var writer = new BamlBinaryWriter(str);
{
var wtr = new BinaryWriter(str, Encoding.Unicode);
int len = doc.Signature.Length * 2;
wtr.Write(len);
wtr.Write(doc.Signature.ToCharArray());
wtr.Write(new byte[((len + 3) & ~3) - len]);
}
writer.Write(doc.ReaderVersion.Major);
writer.Write(doc.ReaderVersion.Minor);
writer.Write(doc.UpdaterVersion.Major);
writer.Write(doc.UpdaterVersion.Minor);
writer.Write(doc.WriterVersion.Major);
writer.Write(doc.WriterVersion.Minor);
var defers = new List<int>();
for (int i = 0; i < doc.Count; i++) {
BamlRecord rec = doc[i];
rec.Position = str.Position;
writer.Write((byte)rec.Type);
rec.Write(writer);
if (rec is IBamlDeferRecord) defers.Add(i);
}
foreach (int i in defers)
(doc[i] as IBamlDeferRecord).WriteDefer(doc, i, writer);
}
}
}

297
ILSpy.BamlDecompiler/Baml/KnownMembers.cs

@ -0,0 +1,297 @@ @@ -0,0 +1,297 @@
/*
Copyright (c) 2015 Ki
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
namespace ILSpy.BamlDecompiler.Baml {
// Auto generated. Do not modify.
internal enum KnownMembers : short {
Unknown = 0,
AccessText_Text = 1,
BeginStoryboard_Storyboard = 2,
BitmapEffectGroup_Children = 3,
Border_Background = 4,
Border_BorderBrush = 5,
Border_BorderThickness = 6,
ButtonBase_Command = 7,
ButtonBase_CommandParameter = 8,
ButtonBase_CommandTarget = 9,
ButtonBase_IsPressed = 10,
ColumnDefinition_MaxWidth = 11,
ColumnDefinition_MinWidth = 12,
ColumnDefinition_Width = 13,
ContentControl_Content = 14,
ContentControl_ContentTemplate = 15,
ContentControl_ContentTemplateSelector = 16,
ContentControl_HasContent = 17,
ContentElement_Focusable = 18,
ContentPresenter_Content = 19,
ContentPresenter_ContentSource = 20,
ContentPresenter_ContentTemplate = 21,
ContentPresenter_ContentTemplateSelector = 22,
ContentPresenter_RecognizesAccessKey = 23,
Control_Background = 24,
Control_BorderBrush = 25,
Control_BorderThickness = 26,
Control_FontFamily = 27,
Control_FontSize = 28,
Control_FontStretch = 29,
Control_FontStyle = 30,
Control_FontWeight = 31,
Control_Foreground = 32,
Control_HorizontalContentAlignment = 33,
Control_IsTabStop = 34,
Control_Padding = 35,
Control_TabIndex = 36,
Control_Template = 37,
Control_VerticalContentAlignment = 38,
DockPanel_Dock = 39,
DockPanel_LastChildFill = 40,
DocumentViewerBase_Document = 41,
DrawingGroup_Children = 42,
FlowDocumentReader_Document = 43,
FlowDocumentScrollViewer_Document = 44,
FrameworkContentElement_Style = 45,
FrameworkElement_FlowDirection = 46,
FrameworkElement_Height = 47,
FrameworkElement_HorizontalAlignment = 48,
FrameworkElement_Margin = 49,
FrameworkElement_MaxHeight = 50,
FrameworkElement_MaxWidth = 51,
FrameworkElement_MinHeight = 52,
FrameworkElement_MinWidth = 53,
FrameworkElement_Name = 54,
FrameworkElement_Style = 55,
FrameworkElement_VerticalAlignment = 56,
FrameworkElement_Width = 57,
GeneralTransformGroup_Children = 58,
GeometryGroup_Children = 59,
GradientBrush_GradientStops = 60,
Grid_Column = 61,
Grid_ColumnSpan = 62,
Grid_Row = 63,
Grid_RowSpan = 64,
GridViewColumn_Header = 65,
HeaderedContentControl_HasHeader = 66,
HeaderedContentControl_Header = 67,
HeaderedContentControl_HeaderTemplate = 68,
HeaderedContentControl_HeaderTemplateSelector = 69,
HeaderedItemsControl_HasHeader = 70,
HeaderedItemsControl_Header = 71,
HeaderedItemsControl_HeaderTemplate = 72,
HeaderedItemsControl_HeaderTemplateSelector = 73,
Hyperlink_NavigateUri = 74,
Image_Source = 75,
Image_Stretch = 76,
ItemsControl_ItemContainerStyle = 77,
ItemsControl_ItemContainerStyleSelector = 78,
ItemsControl_ItemTemplate = 79,
ItemsControl_ItemTemplateSelector = 80,
ItemsControl_ItemsPanel = 81,
ItemsControl_ItemsSource = 82,
MaterialGroup_Children = 83,
Model3DGroup_Children = 84,
Page_Content = 85,
Panel_Background = 86,
Path_Data = 87,
PathFigure_Segments = 88,
PathGeometry_Figures = 89,
Popup_Child = 90,
Popup_IsOpen = 91,
Popup_Placement = 92,
Popup_PopupAnimation = 93,
RowDefinition_Height = 94,
RowDefinition_MaxHeight = 95,
RowDefinition_MinHeight = 96,
ScrollViewer_CanContentScroll = 97,
ScrollViewer_HorizontalScrollBarVisibility = 98,
ScrollViewer_VerticalScrollBarVisibility = 99,
Shape_Fill = 100,
Shape_Stroke = 101,
Shape_StrokeThickness = 102,
TextBlock_Background = 103,
TextBlock_FontFamily = 104,
TextBlock_FontSize = 105,
TextBlock_FontStretch = 106,
TextBlock_FontStyle = 107,
TextBlock_FontWeight = 108,
TextBlock_Foreground = 109,
TextBlock_Text = 110,
TextBlock_TextDecorations = 111,
TextBlock_TextTrimming = 112,
TextBlock_TextWrapping = 113,
TextBox_Text = 114,
TextElement_Background = 115,
TextElement_FontFamily = 116,
TextElement_FontSize = 117,
TextElement_FontStretch = 118,
TextElement_FontStyle = 119,
TextElement_FontWeight = 120,
TextElement_Foreground = 121,
TimelineGroup_Children = 122,
Track_IsDirectionReversed = 123,
Track_Maximum = 124,
Track_Minimum = 125,
Track_Orientation = 126,
Track_Value = 127,
Track_ViewportSize = 128,
Transform3DGroup_Children = 129,
TransformGroup_Children = 130,
UIElement_ClipToBounds = 131,
UIElement_Focusable = 132,
UIElement_IsEnabled = 133,
UIElement_RenderTransform = 134,
UIElement_Visibility = 135,
Viewport3D_Children = 136,
AdornedElementPlaceholder_Child = 138,
AdornerDecorator_Child = 139,
AnchoredBlock_Blocks = 140,
ArrayExtension_Items = 141,
BlockUIContainer_Child = 142,
Bold_Inlines = 143,
BooleanAnimationUsingKeyFrames_KeyFrames = 144,
Border_Child = 145,
BulletDecorator_Child = 146,
Button_Content = 147,
ButtonBase_Content = 148,
ByteAnimationUsingKeyFrames_KeyFrames = 149,
Canvas_Children = 150,
CharAnimationUsingKeyFrames_KeyFrames = 151,
CheckBox_Content = 152,
ColorAnimationUsingKeyFrames_KeyFrames = 153,
ComboBox_Items = 154,
ComboBoxItem_Content = 155,
ContextMenu_Items = 156,
ControlTemplate_VisualTree = 157,
DataTemplate_VisualTree = 158,
DataTrigger_Setters = 159,
DecimalAnimationUsingKeyFrames_KeyFrames = 160,
Decorator_Child = 161,
DockPanel_Children = 162,
DocumentViewer_Document = 163,
DoubleAnimationUsingKeyFrames_KeyFrames = 164,
EventTrigger_Actions = 165,
Expander_Content = 166,
Figure_Blocks = 167,
FixedDocument_Pages = 168,
FixedDocumentSequence_References = 169,
FixedPage_Children = 170,
Floater_Blocks = 171,
FlowDocument_Blocks = 172,
FlowDocumentPageViewer_Document = 173,
FrameworkTemplate_VisualTree = 174,
Grid_Children = 175,
GridView_Columns = 176,
GridViewColumnHeader_Content = 177,
GroupBox_Content = 178,
GroupItem_Content = 179,
HeaderedContentControl_Content = 180,
HeaderedItemsControl_Items = 181,
HierarchicalDataTemplate_VisualTree = 182,
Hyperlink_Inlines = 183,
InkCanvas_Children = 184,
InkPresenter_Child = 185,
InlineUIContainer_Child = 186,
InputScopeName_NameValue = 187,
Int16AnimationUsingKeyFrames_KeyFrames = 188,
Int32AnimationUsingKeyFrames_KeyFrames = 189,
Int64AnimationUsingKeyFrames_KeyFrames = 190,
Italic_Inlines = 191,
ItemsControl_Items = 192,
ItemsPanelTemplate_VisualTree = 193,
Label_Content = 194,
LinearGradientBrush_GradientStops = 195,
List_ListItems = 196,
ListBox_Items = 197,
ListBoxItem_Content = 198,
ListItem_Blocks = 199,
ListView_Items = 200,
ListViewItem_Content = 201,
MatrixAnimationUsingKeyFrames_KeyFrames = 202,
Menu_Items = 203,
MenuBase_Items = 204,
MenuItem_Items = 205,
ModelVisual3D_Children = 206,
MultiBinding_Bindings = 207,
MultiDataTrigger_Setters = 208,
MultiTrigger_Setters = 209,
ObjectAnimationUsingKeyFrames_KeyFrames = 210,
PageContent_Child = 211,
PageFunctionBase_Content = 212,
Panel_Children = 213,
Paragraph_Inlines = 214,
ParallelTimeline_Children = 215,
Point3DAnimationUsingKeyFrames_KeyFrames = 216,
PointAnimationUsingKeyFrames_KeyFrames = 217,
PriorityBinding_Bindings = 218,
QuaternionAnimationUsingKeyFrames_KeyFrames = 219,
RadialGradientBrush_GradientStops = 220,
RadioButton_Content = 221,
RectAnimationUsingKeyFrames_KeyFrames = 222,
RepeatButton_Content = 223,
RichTextBox_Document = 224,
Rotation3DAnimationUsingKeyFrames_KeyFrames = 225,
Run_Text = 226,
ScrollViewer_Content = 227,
Section_Blocks = 228,
Selector_Items = 229,
SingleAnimationUsingKeyFrames_KeyFrames = 230,
SizeAnimationUsingKeyFrames_KeyFrames = 231,
Span_Inlines = 232,
StackPanel_Children = 233,
StatusBar_Items = 234,
StatusBarItem_Content = 235,
Storyboard_Children = 236,
StringAnimationUsingKeyFrames_KeyFrames = 237,
Style_Setters = 238,
TabControl_Items = 239,
TabItem_Content = 240,
TabPanel_Children = 241,
Table_RowGroups = 242,
TableCell_Blocks = 243,
TableRow_Cells = 244,
TableRowGroup_Rows = 245,
TextBlock_Inlines = 246,
ThicknessAnimationUsingKeyFrames_KeyFrames = 247,
ToggleButton_Content = 248,
ToolBar_Items = 249,
ToolBarOverflowPanel_Children = 250,
ToolBarPanel_Children = 251,
ToolBarTray_ToolBars = 252,
ToolTip_Content = 253,
TreeView_Items = 254,
TreeViewItem_Items = 255,
Trigger_Setters = 256,
Underline_Inlines = 257,
UniformGrid_Children = 258,
UserControl_Content = 259,
Vector3DAnimationUsingKeyFrames_KeyFrames = 260,
VectorAnimationUsingKeyFrames_KeyFrames = 261,
Viewbox_Child = 262,
Viewport3DVisual_Children = 263,
VirtualizingPanel_Children = 264,
VirtualizingStackPanel_Children = 265,
Window_Content = 266,
WrapPanel_Children = 267,
XmlDataProvider_XmlSerializer = 268,
}
}

80
ILSpy.BamlDecompiler/Baml/KnownThings.cs

@ -0,0 +1,80 @@ @@ -0,0 +1,80 @@
/*
Copyright (c) 2015 Ki
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using ICSharpCode.Decompiler.Metadata;
using ICSharpCode.Decompiler.TypeSystem;
namespace ILSpy.BamlDecompiler.Baml {
internal partial class KnownThings {
readonly IDecompilerTypeSystem typeSystem;
readonly Dictionary<int, IModule> assemblies;
readonly Dictionary<KnownMembers, KnownMember> members;
readonly Dictionary<KnownTypes, ITypeDefinition> types;
readonly Dictionary<int, string> strings;
readonly Dictionary<int, (string, string, string)> resources;
public KnownThings(IDecompilerTypeSystem typeSystem) {
this.typeSystem = typeSystem;
assemblies = new Dictionary<int, IModule>();
types = new Dictionary<KnownTypes, ITypeDefinition>();
members = new Dictionary<KnownMembers, KnownMember>();
strings = new Dictionary<int, string>();
resources = new Dictionary<int, (string, string, string)>();
InitAssemblies();
InitTypes();
InitMembers();
InitStrings();
InitResources();
}
public Func<KnownTypes, ITypeDefinition> Types => id => types[id];
public Func<KnownMembers, KnownMember> Members => id => members[id];
public Func<short, string> Strings => id => strings[id];
public Func<short, (string, string, string)> Resources => id => resources[id];
public IModule FrameworkAssembly => assemblies[0];
IModule ResolveAssembly(string name) => typeSystem.Modules.First(m => m.FullAssemblyName == name);
ITypeDefinition InitType(IModule assembly, string ns, string name) => assembly.GetTypeDefinition(new TopLevelTypeName(ns, name));
KnownMember InitMember(KnownTypes parent, string name, ITypeDefinition type) => new KnownMember(parent, types[parent], name, type);
}
internal class KnownMember {
public KnownMember(KnownTypes parent, ITypeDefinition declType, string name, ITypeDefinition type) {
Parent = parent;
Property = declType.GetProperties(p => p.Name == name, GetMemberOptions.IgnoreInheritedMembers).SingleOrDefault();
DeclaringType = declType;
Name = name;
Type = type;
}
public KnownTypes Parent { get; }
public ITypeDefinition DeclaringType { get; }
public IProperty Property { get; }
public string Name { get; }
public ITypeDefinition Type { get; }
}
}

1321
ILSpy.BamlDecompiler/Baml/KnownThings.g.cs

File diff suppressed because it is too large Load Diff

278
ILSpy.BamlDecompiler/Baml/KnownThings.gen.cs

@ -0,0 +1,278 @@ @@ -0,0 +1,278 @@
/*
Copyright (c) 2015 Ki
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Text;
namespace Test {
internal class Program {
static T GetMember<T>(Func<string, BindingFlags, T> func, string name) =>
func(name, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static);
static Assembly GetDeclAssembly(Type type) {
if (type.IsDefined(typeof(TypeForwardedFromAttribute), false)) {
var attr = (TypeForwardedFromAttribute)type.GetCustomAttributes(typeof(TypeForwardedFromAttribute), false)[0];
return Assembly.Load(attr.AssemblyFullName);
}
return type.Assembly;
}
static void Main(string[] args) {
var asmName = "PresentationFramework, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35";
var assembly = Assembly.Load(asmName);
var ctx = assembly.GetType("System.Windows.Baml2006.WpfSharedBamlSchemaContext");
var instance = Activator.CreateInstance(ctx);
var assemblies = ExtractAssemblies(ctx, instance);
var types = ExtractTypes(ctx, instance);
var members = ExtractMembers(ctx, instance);
var strings = ExtractStrings(ctx, instance);
var resources = ExtractResources(assembly);
var code = new StringBuilder();
foreach (var type in types) {
if (type == null)
continue;
if (!assemblies.Contains(GetDeclAssembly(type)))
assemblies.Add(GetDeclAssembly(type));
}
foreach (var member in members) {
if (member == null)
continue;
if (!assemblies.Contains(GetDeclAssembly(member.Item3)))
assemblies.Add(GetDeclAssembly(member.Item3));
}
code.AppendLine("\tinternal enum KnownTypes : short {");
code.AppendLine("\t\tUnknown = 0,");
for (int i = 1; i < types.Count; i++) {
if (types[i] == null) {
code.AppendLine();
continue;
}
var line = "\t\t{0} = {1},";
code.AppendLine(string.Format(line, types[i].Name, i));
}
code.AppendLine("\t}").AppendLine();
code.AppendLine("\tinternal enum KnownMembers : short {");
code.AppendLine("\t\tUnknown = 0,");
for (int i = 1; i < members.Count; i++) {
if (members[i] == null) {
code.AppendLine();
continue;
}
var line = "\t\t{0}_{1} = {2},";
code.AppendLine(string.Format(line, members[i].Item1.Name, members[i].Item2, i));
}
code.AppendLine("\t}").AppendLine();
code.AppendLine("\t\tvoid InitAssemblies() {");
for (int i = 0; i < assemblies.Count; i++) {
var line = "\t\t\tassemblies[{0}] = ResolveAssembly(\"{1}\");";
code.AppendLine(string.Format(line, i, assemblies[i]));
}
code.AppendLine("\t\t}").AppendLine();
code.AppendLine("\t\tvoid InitTypes() {");
for (int i = 0; i < types.Count; i++) {
var type = types[i];
if (type == null) {
code.AppendLine();
continue;
}
var line = "\t\t\ttypes[KnownTypes.{0}] = InitType(assemblies[{1}], \"{2}\", \"{3}\");";
code.AppendLine(string.Format(line, new object[] {
type.Name,
assemblies.IndexOf(GetDeclAssembly(type)),
type.Namespace,
type.Name
}));
}
code.AppendLine("\t\t}").AppendLine();
code.AppendLine("\t\tvoid InitMembers() {");
for (int i = 0; i < members.Count; i++) {
var member = members[i];
if (member == null) {
code.AppendLine();
continue;
}
var line = "\t\t\tmembers[KnownMembers.{0}_{1}] = InitMember(KnownTypes.{0}, \"{1}\", InitType(assemblies[{2}], \"{3}\", \"{4}\"));";
code.AppendLine(string.Format(line, new object[] {
member.Item1.Name,
member.Item2,
assemblies.IndexOf(GetDeclAssembly(member.Item3)),
member.Item3.Namespace,
member.Item3.Name
}));
}
code.AppendLine("\t\t}").AppendLine();
code.AppendLine("\t\tvoid InitStrings() {");
for (int i = 0; i < strings.Count; i++) {
if (strings[i] == null)
continue;
var line = "\t\t\tstrings[{0}] = \"{1}\";";
code.AppendLine(string.Format(line, i, strings[i]));
}
code.AppendLine("\t\t}").AppendLine();
code.AppendLine("\t\tvoid InitResources() {");
for (int i = 0; i < resources.Count; i++) {
if (resources[i] == null) {
code.AppendLine();
continue;
}
var res = resources[i];
var line = "\t\t\tresources[{0}] = (\"{1}\", \"{2}\", \"{3}\");";
code.AppendLine(string.Format(line, i, res.Item1.Name, res.Item2, res.Item3));
}
code.AppendLine("\t\t}").AppendLine();
Console.WriteLine(code);
}
static List<Assembly> ExtractAssemblies(Type ctx, object instance) {
var getAssembly = GetMember(ctx.GetMethod, "GetKnownBamlAssembly");
var assemblies = (Array)GetMember(ctx.GetField, "_knownBamlAssemblies").GetValue(instance);
var bamlAssembly = ctx.Assembly.GetType("System.Windows.Baml2006.Baml6Assembly");
var property = GetMember(bamlAssembly.GetProperty, "Assembly");
var extract = new List<Assembly>();
for (int i = 0; i < assemblies.Length; i++) {
try {
var asm = getAssembly.Invoke(instance, new object[] { (short)(-i) });
var asmValue = (Assembly)property.GetValue(asm, null);
extract.Add(asmValue);
}
catch {
extract.Add(null);
}
}
return extract;
}
static List<Type> ExtractTypes(Type ctx, object instance) {
var getType = GetMember(ctx.GetMethod, "GetKnownBamlType");
var types = (Array)GetMember(ctx.GetField, "_knownBamlTypes").GetValue(instance);
var bamlType = ctx.Assembly.GetType("System.Windows.Baml2006.WpfKnownType");
var field = GetMember(bamlType.GetField, "_underlyingType");
var extract = new List<Type>() { null };
for (int i = 1; i < types.Length; i++) {
try {
var type = getType.Invoke(instance, new object[] { (short)(-i) });
var typeValue = (Type)field.GetValue(type);
extract.Add(typeValue);
}
catch {
extract.Add(null);
}
}
return extract;
}
static List<Tuple<Type, string, Type>> ExtractMembers(Type ctx, object instance) {
var getMember = GetMember(ctx.GetMethod, "GetKnownBamlMember");
var members = (Array)GetMember(ctx.GetField, "_knownBamlMembers").GetValue(instance);
var bamlMember = ctx.Assembly.GetType("System.Windows.Baml2006.WpfKnownMember");
var propertyName = GetMember(bamlMember.GetProperty, "Name");
var propertyType = GetMember(bamlMember.GetProperty, "Type");
var bamlType = ctx.Assembly.GetType("System.Windows.Baml2006.WpfKnownType");
var propertyUnderlyType = GetMember(bamlType.GetProperty, "UnderlyingType");
var mapTable = ctx.Assembly.GetType("System.Windows.Markup.BamlMapTable");
var getAttrRecord = mapTable.GetMethod("GetAttributeInfoFromId", BindingFlags.Instance | BindingFlags.NonPublic, null, new[] { typeof(short) }, null);
var getAttrOwner = GetMember(mapTable.GetMethod, "GetAttributeOwnerType");
var tbl = mapTable.GetConstructors(BindingFlags.NonPublic | BindingFlags.Instance)[0].Invoke(new object[] { null });
var extract = new List<Tuple<Type, string, Type>>() { null };
for (int i = 1; i < members.Length; i++) {
try {
var member = getMember.Invoke(instance, new object[] { (short)(-i) });
var name = (string)propertyName.GetValue(member, null);
var type = (Type)propertyUnderlyType.GetValue(propertyType.GetValue(member, null), null);
var declType = (Type)getAttrOwner.Invoke(tbl, new object[] { getAttrRecord.Invoke(tbl, new object[] { (short)(-i) }) });
extract.Add(Tuple.Create(declType, name, type));
}
catch {
extract.Add(null);
}
}
return extract;
}
static List<string> ExtractStrings(Type ctx, object instance) {
var getString = GetMember(ctx.GetMethod, "GetKnownBamlString");
var extract = new List<string>();
for (int i = 0; i < 10; i++) {
try {
var str = (string)getString.Invoke(instance, new object[] { (short)(-i) });
extract.Add(str);
}
catch {
extract.Add(null);
}
}
return extract;
}
static List<Tuple<Type, string, string>> ExtractResources(Assembly asm) {
var resIdType = asm.GetType("System.Windows.SystemResourceKeyID");
var cvrtType = asm.GetType("System.Windows.Markup.SystemKeyConverter");
var getSysType = GetMember(cvrtType.GetMethod, "GetSystemClassType");
var getSysKeyName = GetMember(cvrtType.GetMethod, "GetSystemKeyName");
var getSysPropertyName = GetMember(cvrtType.GetMethod, "GetSystemPropertyName");
var values = Enum.GetValues(resIdType);
var extract = new List<Tuple<Type, string, string>>();
for (int i = 0; i < values.Length; i++) {
var value = values.GetValue(i);
if (Enum.GetName(resIdType, value).StartsWith("Internal")) {
extract.Add(null);
continue;
}
var type = (Type)getSysType.Invoke(null, new object[] { value });
var keyName = (string)getSysKeyName.Invoke(null, new object[] { value });
var propName = (string)getSysPropertyName.Invoke(null, new object[] { value });
extract.Add(Tuple.Create(type, keyName, propName));
}
return extract;
}
}
}

788
ILSpy.BamlDecompiler/Baml/KnownTypes.cs

@ -0,0 +1,788 @@ @@ -0,0 +1,788 @@
/*
Copyright (c) 2015 Ki
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
namespace ILSpy.BamlDecompiler.Baml {
// Auto generated. Do not modify.
internal enum KnownTypes : short {
Unknown = 0,
AccessText = 1,
AdornedElementPlaceholder = 2,
Adorner = 3,
AdornerDecorator = 4,
AdornerLayer = 5,
AffineTransform3D = 6,
AmbientLight = 7,
AnchoredBlock = 8,
Animatable = 9,
AnimationClock = 10,
AnimationTimeline = 11,
Application = 12,
ArcSegment = 13,
ArrayExtension = 14,
AxisAngleRotation3D = 15,
BaseIListConverter = 16,
BeginStoryboard = 17,
BevelBitmapEffect = 18,
BezierSegment = 19,
Binding = 20,
BindingBase = 21,
BindingExpression = 22,
BindingExpressionBase = 23,
BindingListCollectionView = 24,
BitmapDecoder = 25,
BitmapEffect = 26,
BitmapEffectCollection = 27,
BitmapEffectGroup = 28,
BitmapEffectInput = 29,
BitmapEncoder = 30,
BitmapFrame = 31,
BitmapImage = 32,
BitmapMetadata = 33,
BitmapPalette = 34,
BitmapSource = 35,
Block = 36,
BlockUIContainer = 37,
BlurBitmapEffect = 38,
BmpBitmapDecoder = 39,
BmpBitmapEncoder = 40,
Bold = 41,
BoolIListConverter = 42,
Boolean = 43,
BooleanAnimationBase = 44,
BooleanAnimationUsingKeyFrames = 45,
BooleanConverter = 46,
BooleanKeyFrame = 47,
BooleanKeyFrameCollection = 48,
BooleanToVisibilityConverter = 49,
Border = 50,
BorderGapMaskConverter = 51,
Brush = 52,
BrushConverter = 53,
BulletDecorator = 54,
Button = 55,
ButtonBase = 56,
Byte = 57,
ByteAnimation = 58,
ByteAnimationBase = 59,
ByteAnimationUsingKeyFrames = 60,
ByteConverter = 61,
ByteKeyFrame = 62,
ByteKeyFrameCollection = 63,
CachedBitmap = 64,
Camera = 65,
Canvas = 66,
Char = 67,
CharAnimationBase = 68,
CharAnimationUsingKeyFrames = 69,
CharConverter = 70,
CharIListConverter = 71,
CharKeyFrame = 72,
CharKeyFrameCollection = 73,
CheckBox = 74,
Clock = 75,
ClockController = 76,
ClockGroup = 77,
CollectionContainer = 78,
CollectionView = 79,
CollectionViewSource = 80,
Color = 81,
ColorAnimation = 82,
ColorAnimationBase = 83,
ColorAnimationUsingKeyFrames = 84,
ColorConvertedBitmap = 85,
ColorConvertedBitmapExtension = 86,
ColorConverter = 87,
ColorKeyFrame = 88,
ColorKeyFrameCollection = 89,
ColumnDefinition = 90,
CombinedGeometry = 91,
ComboBox = 92,
ComboBoxItem = 93,
CommandConverter = 94,
ComponentResourceKey = 95,
ComponentResourceKeyConverter = 96,
CompositionTarget = 97,
Condition = 98,
ContainerVisual = 99,
ContentControl = 100,
ContentElement = 101,
ContentPresenter = 102,
ContentPropertyAttribute = 103,
ContentWrapperAttribute = 104,
ContextMenu = 105,
ContextMenuService = 106,
Control = 107,
ControlTemplate = 108,
ControllableStoryboardAction = 109,
CornerRadius = 110,
CornerRadiusConverter = 111,
CroppedBitmap = 112,
CultureInfo = 113,
CultureInfoConverter = 114,
CultureInfoIetfLanguageTagConverter = 115,
Cursor = 116,
CursorConverter = 117,
DashStyle = 118,
DataChangedEventManager = 119,
DataTemplate = 120,
DataTemplateKey = 121,
DataTrigger = 122,
DateTime = 123,
DateTimeConverter = 124,
DateTimeConverter2 = 125,
Decimal = 126,
DecimalAnimation = 127,
DecimalAnimationBase = 128,
DecimalAnimationUsingKeyFrames = 129,
DecimalConverter = 130,
DecimalKeyFrame = 131,
DecimalKeyFrameCollection = 132,
Decorator = 133,
DefinitionBase = 134,
DependencyObject = 135,
DependencyProperty = 136,
DependencyPropertyConverter = 137,
DialogResultConverter = 138,
DiffuseMaterial = 139,
DirectionalLight = 140,
DiscreteBooleanKeyFrame = 141,
DiscreteByteKeyFrame = 142,
DiscreteCharKeyFrame = 143,
DiscreteColorKeyFrame = 144,
DiscreteDecimalKeyFrame = 145,
DiscreteDoubleKeyFrame = 146,
DiscreteInt16KeyFrame = 147,
DiscreteInt32KeyFrame = 148,
DiscreteInt64KeyFrame = 149,
DiscreteMatrixKeyFrame = 150,
DiscreteObjectKeyFrame = 151,
DiscretePoint3DKeyFrame = 152,
DiscretePointKeyFrame = 153,
DiscreteQuaternionKeyFrame = 154,
DiscreteRectKeyFrame = 155,
DiscreteRotation3DKeyFrame = 156,
DiscreteSingleKeyFrame = 157,
DiscreteSizeKeyFrame = 158,
DiscreteStringKeyFrame = 159,
DiscreteThicknessKeyFrame = 160,
DiscreteVector3DKeyFrame = 161,
DiscreteVectorKeyFrame = 162,
DockPanel = 163,
DocumentPageView = 164,
DocumentReference = 165,
DocumentViewer = 166,
DocumentViewerBase = 167,
Double = 168,
DoubleAnimation = 169,
DoubleAnimationBase = 170,
DoubleAnimationUsingKeyFrames = 171,
DoubleAnimationUsingPath = 172,
DoubleCollection = 173,
DoubleCollectionConverter = 174,
DoubleConverter = 175,
DoubleIListConverter = 176,
DoubleKeyFrame = 177,
DoubleKeyFrameCollection = 178,
Drawing = 179,
DrawingBrush = 180,
DrawingCollection = 181,
DrawingContext = 182,
DrawingGroup = 183,
DrawingImage = 184,
DrawingVisual = 185,
DropShadowBitmapEffect = 186,
Duration = 187,
DurationConverter = 188,
DynamicResourceExtension = 189,
DynamicResourceExtensionConverter = 190,
Ellipse = 191,
EllipseGeometry = 192,
EmbossBitmapEffect = 193,
EmissiveMaterial = 194,
EnumConverter = 195,
EventManager = 196,
EventSetter = 197,
EventTrigger = 198,
Expander = 199,
Expression = 200,
ExpressionConverter = 201,
Figure = 202,
FigureLength = 203,
FigureLengthConverter = 204,
FixedDocument = 205,
FixedDocumentSequence = 206,
FixedPage = 207,
Floater = 208,
FlowDocument = 209,
FlowDocumentPageViewer = 210,
FlowDocumentReader = 211,
FlowDocumentScrollViewer = 212,
FocusManager = 213,
FontFamily = 214,
FontFamilyConverter = 215,
FontSizeConverter = 216,
FontStretch = 217,
FontStretchConverter = 218,
FontStyle = 219,
FontStyleConverter = 220,
FontWeight = 221,
FontWeightConverter = 222,
FormatConvertedBitmap = 223,
Frame = 224,
FrameworkContentElement = 225,
FrameworkElement = 226,
FrameworkElementFactory = 227,
FrameworkPropertyMetadata = 228,
FrameworkPropertyMetadataOptions = 229,
FrameworkRichTextComposition = 230,
FrameworkTemplate = 231,
FrameworkTextComposition = 232,
Freezable = 233,
GeneralTransform = 234,
GeneralTransformCollection = 235,
GeneralTransformGroup = 236,
Geometry = 237,
Geometry3D = 238,
GeometryCollection = 239,
GeometryConverter = 240,
GeometryDrawing = 241,
GeometryGroup = 242,
GeometryModel3D = 243,
GestureRecognizer = 244,
GifBitmapDecoder = 245,
GifBitmapEncoder = 246,
GlyphRun = 247,
GlyphRunDrawing = 248,
GlyphTypeface = 249,
Glyphs = 250,
GradientBrush = 251,
GradientStop = 252,
GradientStopCollection = 253,
Grid = 254,
GridLength = 255,
GridLengthConverter = 256,
GridSplitter = 257,
GridView = 258,
GridViewColumn = 259,
GridViewColumnHeader = 260,
GridViewHeaderRowPresenter = 261,
GridViewRowPresenter = 262,
GridViewRowPresenterBase = 263,
GroupBox = 264,
GroupItem = 265,
Guid = 266,
GuidConverter = 267,
GuidelineSet = 268,
HeaderedContentControl = 269,
HeaderedItemsControl = 270,
HierarchicalDataTemplate = 271,
HostVisual = 272,
Hyperlink = 273,
IAddChild = 274,
IAddChildInternal = 275,
ICommand = 276,
IComponentConnector = 277,
INameScope = 278,
IStyleConnector = 279,
IconBitmapDecoder = 280,
Image = 281,
ImageBrush = 282,
ImageDrawing = 283,
ImageMetadata = 284,
ImageSource = 285,
ImageSourceConverter = 286,
InPlaceBitmapMetadataWriter = 287,
InkCanvas = 288,
InkPresenter = 289,
Inline = 290,
InlineCollection = 291,
InlineUIContainer = 292,
InputBinding = 293,
InputDevice = 294,
InputLanguageManager = 295,
InputManager = 296,
InputMethod = 297,
InputScope = 298,
InputScopeConverter = 299,
InputScopeName = 300,
InputScopeNameConverter = 301,
Int16 = 302,
Int16Animation = 303,
Int16AnimationBase = 304,
Int16AnimationUsingKeyFrames = 305,
Int16Converter = 306,
Int16KeyFrame = 307,
Int16KeyFrameCollection = 308,
Int32 = 309,
Int32Animation = 310,
Int32AnimationBase = 311,
Int32AnimationUsingKeyFrames = 312,
Int32Collection = 313,
Int32CollectionConverter = 314,
Int32Converter = 315,
Int32KeyFrame = 316,
Int32KeyFrameCollection = 317,
Int32Rect = 318,
Int32RectConverter = 319,
Int64 = 320,
Int64Animation = 321,
Int64AnimationBase = 322,
Int64AnimationUsingKeyFrames = 323,
Int64Converter = 324,
Int64KeyFrame = 325,
Int64KeyFrameCollection = 326,
Italic = 327,
ItemCollection = 328,
ItemsControl = 329,
ItemsPanelTemplate = 330,
ItemsPresenter = 331,
JournalEntry = 332,
JournalEntryListConverter = 333,
JournalEntryUnifiedViewConverter = 334,
JpegBitmapDecoder = 335,
JpegBitmapEncoder = 336,
KeyBinding = 337,
KeyConverter = 338,
KeyGesture = 339,
KeyGestureConverter = 340,
KeySpline = 341,
KeySplineConverter = 342,
KeyTime = 343,
KeyTimeConverter = 344,
KeyboardDevice = 345,
Label = 346,
LateBoundBitmapDecoder = 347,
LengthConverter = 348,
Light = 349,
Line = 350,
LineBreak = 351,
LineGeometry = 352,
LineSegment = 353,
LinearByteKeyFrame = 354,
LinearColorKeyFrame = 355,
LinearDecimalKeyFrame = 356,
LinearDoubleKeyFrame = 357,
LinearGradientBrush = 358,
LinearInt16KeyFrame = 359,
LinearInt32KeyFrame = 360,
LinearInt64KeyFrame = 361,
LinearPoint3DKeyFrame = 362,
LinearPointKeyFrame = 363,
LinearQuaternionKeyFrame = 364,
LinearRectKeyFrame = 365,
LinearRotation3DKeyFrame = 366,
LinearSingleKeyFrame = 367,
LinearSizeKeyFrame = 368,
LinearThicknessKeyFrame = 369,
LinearVector3DKeyFrame = 370,
LinearVectorKeyFrame = 371,
List = 372,
ListBox = 373,
ListBoxItem = 374,
ListCollectionView = 375,
ListItem = 376,
ListView = 377,
ListViewItem = 378,
Localization = 379,
LostFocusEventManager = 380,
MarkupExtension = 381,
Material = 382,
MaterialCollection = 383,
MaterialGroup = 384,
Matrix = 385,
Matrix3D = 386,
Matrix3DConverter = 387,
MatrixAnimationBase = 388,
MatrixAnimationUsingKeyFrames = 389,
MatrixAnimationUsingPath = 390,
MatrixCamera = 391,
MatrixConverter = 392,
MatrixKeyFrame = 393,
MatrixKeyFrameCollection = 394,
MatrixTransform = 395,
MatrixTransform3D = 396,
MediaClock = 397,
MediaElement = 398,
MediaPlayer = 399,
MediaTimeline = 400,
Menu = 401,
MenuBase = 402,
MenuItem = 403,
MenuScrollingVisibilityConverter = 404,
MeshGeometry3D = 405,
Model3D = 406,
Model3DCollection = 407,
Model3DGroup = 408,
ModelVisual3D = 409,
ModifierKeysConverter = 410,
MouseActionConverter = 411,
MouseBinding = 412,
MouseDevice = 413,
MouseGesture = 414,
MouseGestureConverter = 415,
MultiBinding = 416,
MultiBindingExpression = 417,
MultiDataTrigger = 418,
MultiTrigger = 419,
NameScope = 420,
NavigationWindow = 421,
NullExtension = 422,
NullableBoolConverter = 423,
NullableConverter = 424,
NumberSubstitution = 425,
Object = 426,
ObjectAnimationBase = 427,
ObjectAnimationUsingKeyFrames = 428,
ObjectDataProvider = 429,
ObjectKeyFrame = 430,
ObjectKeyFrameCollection = 431,
OrthographicCamera = 432,
OuterGlowBitmapEffect = 433,
Page = 434,
PageContent = 435,
PageFunctionBase = 436,
Panel = 437,
Paragraph = 438,
ParallelTimeline = 439,
ParserContext = 440,
PasswordBox = 441,
Path = 442,
PathFigure = 443,
PathFigureCollection = 444,
PathFigureCollectionConverter = 445,
PathGeometry = 446,
PathSegment = 447,
PathSegmentCollection = 448,
PauseStoryboard = 449,
Pen = 450,
PerspectiveCamera = 451,
PixelFormat = 452,
PixelFormatConverter = 453,
PngBitmapDecoder = 454,
PngBitmapEncoder = 455,
Point = 456,
Point3D = 457,
Point3DAnimation = 458,
Point3DAnimationBase = 459,
Point3DAnimationUsingKeyFrames = 460,
Point3DCollection = 461,
Point3DCollectionConverter = 462,
Point3DConverter = 463,
Point3DKeyFrame = 464,
Point3DKeyFrameCollection = 465,
Point4D = 466,
Point4DConverter = 467,
PointAnimation = 468,
PointAnimationBase = 469,
PointAnimationUsingKeyFrames = 470,
PointAnimationUsingPath = 471,
PointCollection = 472,
PointCollectionConverter = 473,
PointConverter = 474,
PointIListConverter = 475,
PointKeyFrame = 476,
PointKeyFrameCollection = 477,
PointLight = 478,
PointLightBase = 479,
PolyBezierSegment = 480,
PolyLineSegment = 481,
PolyQuadraticBezierSegment = 482,
Polygon = 483,
Polyline = 484,
Popup = 485,
PresentationSource = 486,
PriorityBinding = 487,
PriorityBindingExpression = 488,
ProgressBar = 489,
ProjectionCamera = 490,
PropertyPath = 491,
PropertyPathConverter = 492,
QuadraticBezierSegment = 493,
Quaternion = 494,
QuaternionAnimation = 495,
QuaternionAnimationBase = 496,
QuaternionAnimationUsingKeyFrames = 497,
QuaternionConverter = 498,
QuaternionKeyFrame = 499,
QuaternionKeyFrameCollection = 500,
QuaternionRotation3D = 501,
RadialGradientBrush = 502,
RadioButton = 503,
RangeBase = 504,
Rect = 505,
Rect3D = 506,
Rect3DConverter = 507,
RectAnimation = 508,
RectAnimationBase = 509,
RectAnimationUsingKeyFrames = 510,
RectConverter = 511,
RectKeyFrame = 512,
RectKeyFrameCollection = 513,
Rectangle = 514,
RectangleGeometry = 515,
RelativeSource = 516,
RemoveStoryboard = 517,
RenderOptions = 518,
RenderTargetBitmap = 519,
RepeatBehavior = 520,
RepeatBehaviorConverter = 521,
RepeatButton = 522,
ResizeGrip = 523,
ResourceDictionary = 524,
ResourceKey = 525,
ResumeStoryboard = 526,
RichTextBox = 527,
RotateTransform = 528,
RotateTransform3D = 529,
Rotation3D = 530,
Rotation3DAnimation = 531,
Rotation3DAnimationBase = 532,
Rotation3DAnimationUsingKeyFrames = 533,
Rotation3DKeyFrame = 534,
Rotation3DKeyFrameCollection = 535,
RoutedCommand = 536,
RoutedEvent = 537,
RoutedEventConverter = 538,
RoutedUICommand = 539,
RoutingStrategy = 540,
RowDefinition = 541,
Run = 542,
RuntimeNamePropertyAttribute = 543,
SByte = 544,
SByteConverter = 545,
ScaleTransform = 546,
ScaleTransform3D = 547,
ScrollBar = 548,
ScrollContentPresenter = 549,
ScrollViewer = 550,
Section = 551,
SeekStoryboard = 552,
Selector = 553,
Separator = 554,
SetStoryboardSpeedRatio = 555,
Setter = 556,
SetterBase = 557,
Shape = 558,
Single = 559,
SingleAnimation = 560,
SingleAnimationBase = 561,
SingleAnimationUsingKeyFrames = 562,
SingleConverter = 563,
SingleKeyFrame = 564,
SingleKeyFrameCollection = 565,
Size = 566,
Size3D = 567,
Size3DConverter = 568,
SizeAnimation = 569,
SizeAnimationBase = 570,
SizeAnimationUsingKeyFrames = 571,
SizeConverter = 572,
SizeKeyFrame = 573,
SizeKeyFrameCollection = 574,
SkewTransform = 575,
SkipStoryboardToFill = 576,
Slider = 577,
SolidColorBrush = 578,
SoundPlayerAction = 579,
Span = 580,
SpecularMaterial = 581,
SpellCheck = 582,
SplineByteKeyFrame = 583,
SplineColorKeyFrame = 584,
SplineDecimalKeyFrame = 585,
SplineDoubleKeyFrame = 586,
SplineInt16KeyFrame = 587,
SplineInt32KeyFrame = 588,
SplineInt64KeyFrame = 589,
SplinePoint3DKeyFrame = 590,
SplinePointKeyFrame = 591,
SplineQuaternionKeyFrame = 592,
SplineRectKeyFrame = 593,
SplineRotation3DKeyFrame = 594,
SplineSingleKeyFrame = 595,
SplineSizeKeyFrame = 596,
SplineThicknessKeyFrame = 597,
SplineVector3DKeyFrame = 598,
SplineVectorKeyFrame = 599,
SpotLight = 600,
StackPanel = 601,
StaticExtension = 602,
StaticResourceExtension = 603,
StatusBar = 604,
StatusBarItem = 605,
StickyNoteControl = 606,
StopStoryboard = 607,
Storyboard = 608,
StreamGeometry = 609,
StreamGeometryContext = 610,
StreamResourceInfo = 611,
String = 612,
StringAnimationBase = 613,
StringAnimationUsingKeyFrames = 614,
StringConverter = 615,
StringKeyFrame = 616,
StringKeyFrameCollection = 617,
StrokeCollection = 618,
StrokeCollectionConverter = 619,
Style = 620,
Stylus = 621,
StylusDevice = 622,
TabControl = 623,
TabItem = 624,
TabPanel = 625,
Table = 626,
TableCell = 627,
TableColumn = 628,
TableRow = 629,
TableRowGroup = 630,
TabletDevice = 631,
TemplateBindingExpression = 632,
TemplateBindingExpressionConverter = 633,
TemplateBindingExtension = 634,
TemplateBindingExtensionConverter = 635,
TemplateKey = 636,
TemplateKeyConverter = 637,
TextBlock = 638,
TextBox = 639,
TextBoxBase = 640,
TextComposition = 641,
TextCompositionManager = 642,
TextDecoration = 643,
TextDecorationCollection = 644,
TextDecorationCollectionConverter = 645,
TextEffect = 646,
TextEffectCollection = 647,
TextElement = 648,
TextSearch = 649,
ThemeDictionaryExtension = 650,
Thickness = 651,
ThicknessAnimation = 652,
ThicknessAnimationBase = 653,
ThicknessAnimationUsingKeyFrames = 654,
ThicknessConverter = 655,
ThicknessKeyFrame = 656,
ThicknessKeyFrameCollection = 657,
Thumb = 658,
TickBar = 659,
TiffBitmapDecoder = 660,
TiffBitmapEncoder = 661,
TileBrush = 662,
TimeSpan = 663,
TimeSpanConverter = 664,
Timeline = 665,
TimelineCollection = 666,
TimelineGroup = 667,
ToggleButton = 668,
ToolBar = 669,
ToolBarOverflowPanel = 670,
ToolBarPanel = 671,
ToolBarTray = 672,
ToolTip = 673,
ToolTipService = 674,
Track = 675,
Transform = 676,
Transform3D = 677,
Transform3DCollection = 678,
Transform3DGroup = 679,
TransformCollection = 680,
TransformConverter = 681,
TransformGroup = 682,
TransformedBitmap = 683,
TranslateTransform = 684,
TranslateTransform3D = 685,
TreeView = 686,
TreeViewItem = 687,
Trigger = 688,
TriggerAction = 689,
TriggerBase = 690,
TypeExtension = 691,
TypeTypeConverter = 692,
Typography = 693,
UIElement = 694,
UInt16 = 695,
UInt16Converter = 696,
UInt32 = 697,
UInt32Converter = 698,
UInt64 = 699,
UInt64Converter = 700,
UShortIListConverter = 701,
Underline = 702,
UniformGrid = 703,
Uri = 704,
UriTypeConverter = 705,
UserControl = 706,
Validation = 707,
Vector = 708,
Vector3D = 709,
Vector3DAnimation = 710,
Vector3DAnimationBase = 711,
Vector3DAnimationUsingKeyFrames = 712,
Vector3DCollection = 713,
Vector3DCollectionConverter = 714,
Vector3DConverter = 715,
Vector3DKeyFrame = 716,
Vector3DKeyFrameCollection = 717,
VectorAnimation = 718,
VectorAnimationBase = 719,
VectorAnimationUsingKeyFrames = 720,
VectorCollection = 721,
VectorCollectionConverter = 722,
VectorConverter = 723,
VectorKeyFrame = 724,
VectorKeyFrameCollection = 725,
VideoDrawing = 726,
ViewBase = 727,
Viewbox = 728,
Viewport3D = 729,
Viewport3DVisual = 730,
VirtualizingPanel = 731,
VirtualizingStackPanel = 732,
Visual = 733,
Visual3D = 734,
VisualBrush = 735,
VisualTarget = 736,
WeakEventManager = 737,
WhitespaceSignificantCollectionAttribute = 738,
Window = 739,
WmpBitmapDecoder = 740,
WmpBitmapEncoder = 741,
WrapPanel = 742,
WriteableBitmap = 743,
XamlBrushSerializer = 744,
XamlInt32CollectionSerializer = 745,
XamlPathDataSerializer = 746,
XamlPoint3DCollectionSerializer = 747,
XamlPointCollectionSerializer = 748,
XamlReader = 749,
XamlStyleSerializer = 750,
XamlTemplateSerializer = 751,
XamlVector3DCollectionSerializer = 752,
XamlWriter = 753,
XmlDataProvider = 754,
XmlLangPropertyAttribute = 755,
XmlLanguage = 756,
XmlLanguageConverter = 757,
XmlNamespaceMapping = 758,
ZoomPercentageConverter = 759,
}
}

2325
ILSpy.BamlDecompiler/Baml/test.cs

File diff suppressed because it is too large Load Diff

39
ILSpy.BamlDecompiler/BamlConnectionId.cs

@ -0,0 +1,39 @@ @@ -0,0 +1,39 @@
/*
Copyright (c) 2019 Siegfried Pammer
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
namespace ILSpy.BamlDecompiler
{
/// <summary>
/// Represents an event registration of a XAML code-behind class.
/// </summary>
internal sealed class EventRegistration
{
public string EventName, MethodName;
}
internal class BamlConnectionId
{
public uint Id { get; }
public BamlConnectionId(uint id) => Id = id;
}
}

60
ILSpy.BamlDecompiler/BamlElement.cs

@ -0,0 +1,60 @@ @@ -0,0 +1,60 @@
/*
Copyright (c) 2015 Ki
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
using System.Collections.Generic;
using System.Xml.Linq;
using ILSpy.BamlDecompiler.Baml;
namespace ILSpy.BamlDecompiler {
internal readonly struct XamlNode {
XamlNode(XElement value) {
Element = value;
String = null;
}
XamlNode(string value) {
Element = null;
String = value;
}
public readonly XElement Element;
public readonly string String;
public static implicit operator XamlNode(XElement value) => new XamlNode(value);
public static implicit operator XamlNode(string value) => new XamlNode(value);
public static implicit operator XElement(XamlNode node) => node.Element;
public static implicit operator string(XamlNode node) => node.String;
}
internal class BamlElement {
public BamlNode Node { get; }
public XamlNode Xaml { get; set; }
public BamlElement Parent { get; set; }
public IList<BamlElement> Children { get; }
public BamlElement(BamlNode node) {
Node = node;
Children = new List<BamlElement>();
}
}
}

185
ILSpy.BamlDecompiler/BamlResourceEntryNode.cs

@ -5,17 +5,20 @@ using System; @@ -5,17 +5,20 @@ using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using SRM = System.Reflection.Metadata;
using System.Threading;
using System.Threading.Tasks;
using System.Xml.Linq;
using ICSharpCode.AvalonEdit.Highlighting;
using ICSharpCode.Decompiler.Metadata;
using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.Decompiler.TypeSystem.Implementation;
using ICSharpCode.Decompiler.Util;
using ICSharpCode.ILSpy;
using ICSharpCode.ILSpy.TextView;
using ICSharpCode.ILSpy.TreeNodes;
using Ricciolo.StylesExplorer.MarkupReflection;
using ILSpy.BamlDecompiler.Baml;
namespace ILSpy.BamlDecompiler
{
@ -59,105 +62,107 @@ namespace ILSpy.BamlDecompiler @@ -59,105 +62,107 @@ namespace ILSpy.BamlDecompiler
Stream stream, CancellationToken cancellationToken)
{
cancellationToken.ThrowIfCancellationRequested();
XDocument xamlDocument;
using (XmlBamlReader reader = new XmlBamlReader(stream, new NRTypeResolver(module, assemblyResolver))) {
xamlDocument = XDocument.Load(reader);
ConvertConnectionIds(xamlDocument, module, assemblyResolver, cancellationToken);
ConvertToEmptyElements(xamlDocument.Root);
MoveNamespacesToRoot(xamlDocument, reader.XmlnsDefinitions);
return xamlDocument;
}
}
static void ConvertConnectionIds(XDocument xamlDocument, PEFile asm, IAssemblyResolver assemblyResolver,
CancellationToken cancellationToken)
{
var attr = xamlDocument.Root.Attribute(XName.Get("Class", XmlBamlReader.XWPFNamespace));
if (attr != null) {
string fullTypeName = attr.Value;
var mappings = new ConnectMethodDecompiler().DecompileEventMappings(asm, assemblyResolver, fullTypeName, cancellationToken);
RemoveConnectionIds(xamlDocument.Root, mappings);
}
var document = BamlReader.ReadDocument(stream, cancellationToken);
var xaml = new XamlDecompiler().Decompile(new BamlDecompilerTypeSystem(module, assemblyResolver), document, cancellationToken, new BamlDecompilerOptions(), null);
return xaml;
}
class XAttributeComparer : IEqualityComparer<XAttribute>
class BamlDecompilerTypeSystem : SimpleCompilation, IDecompilerTypeSystem
{
public bool Equals(XAttribute x, XAttribute y)
{
if (ReferenceEquals(x, y))
return true;
if (x == null || y == null)
return false;
return x.ToString() == y.ToString();
}
public int GetHashCode(XAttribute obj)
{
return obj.ToString().GetHashCode();
}
}
static void MoveNamespacesToRoot(XDocument xamlDocument, IEnumerable<XmlNamespace> missingXmlns)
{
var additionalXmlns = new HashSet<XAttribute>(new XAttributeComparer()) {
new XAttribute("xmlns", XmlBamlReader.DefaultWPFNamespace),
new XAttribute(XName.Get("x", XNamespace.Xmlns.NamespaceName), XmlBamlReader.XWPFNamespace)
string[] defaultBamlReferences = new[] {
"mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089",
"System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089",
"WindowsBase, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35",
"PresentationCore, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35",
"PresentationFramework, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35",
"PresentationUI, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35",
"System.Xml, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
};
additionalXmlns.AddRange(
missingXmlns
.Where(ns => !string.IsNullOrWhiteSpace(ns.Prefix))
.Select(ns => new XAttribute(XName.Get(ns.Prefix, XNamespace.Xmlns.NamespaceName), ns.Namespace))
);
foreach (var element in xamlDocument.Root.DescendantsAndSelf()) {
if (element.Name.NamespaceName != XmlBamlReader.DefaultWPFNamespace && !additionalXmlns.Any(ka => ka.Value == element.Name.NamespaceName)) {
string newPrefix = new string(element.Name.LocalName.Where(c => char.IsUpper(c)).ToArray()).ToLowerInvariant();
int current = additionalXmlns.Count(ka => ka.Name.Namespace == XNamespace.Xmlns && ka.Name.LocalName.TrimEnd(ch => char.IsNumber(ch)) == newPrefix);
if (current > 0)
newPrefix += (current + 1).ToString();
XName defaultXmlns = XName.Get(newPrefix, XNamespace.Xmlns.NamespaceName);
if (element.Name.NamespaceName != XmlBamlReader.DefaultWPFNamespace)
additionalXmlns.Add(new XAttribute(defaultXmlns, element.Name.NamespaceName));
public BamlDecompilerTypeSystem(PEFile mainModule, IAssemblyResolver assemblyResolver)
{
if (mainModule == null)
throw new ArgumentNullException(nameof(mainModule));
if (assemblyResolver == null)
throw new ArgumentNullException(nameof(assemblyResolver));
// Load referenced assemblies and type-forwarder references.
// This is necessary to make .NET Core/PCL binaries work better.
var referencedAssemblies = new List<PEFile>();
var assemblyReferenceQueue = new Queue<(bool IsAssembly, PEFile MainModule, object Reference)>();
var mainMetadata = mainModule.Metadata;
foreach (var h in mainMetadata.GetModuleReferences()) {
var moduleRef = mainMetadata.GetModuleReference(h);
var moduleName = mainMetadata.GetString(moduleRef.Name);
foreach (var fileHandle in mainMetadata.AssemblyFiles) {
var file = mainMetadata.GetAssemblyFile(fileHandle);
if (mainMetadata.StringComparer.Equals(file.Name, moduleName) && file.ContainsMetadata) {
assemblyReferenceQueue.Enqueue((false, mainModule, moduleName));
break;
}
}
}
}
foreach (var xmlns in additionalXmlns.Except(xamlDocument.Root.Attributes())) {
xamlDocument.Root.Add(xmlns);
}
}
static void ConvertToEmptyElements(XElement element)
{
foreach (var el in element.Elements()) {
if (!el.IsEmpty && !el.HasElements && el.Value == "") {
el.RemoveNodes();
continue;
foreach (var refs in mainModule.AssemblyReferences) {
assemblyReferenceQueue.Enqueue((true, mainModule, refs));
}
ConvertToEmptyElements(el);
}
}
static void RemoveConnectionIds(XElement element, List<(LongSet key, EventRegistration[] value)> eventMappings)
{
foreach (var child in element.Elements())
RemoveConnectionIds(child, eventMappings);
var removableAttrs = new List<XAttribute>();
var addableAttrs = new List<XAttribute>();
foreach (var attr in element.Attributes(XName.Get("ConnectionId", XmlBamlReader.XWPFNamespace))) {
int id, index;
if (int.TryParse(attr.Value, out id) && (index = eventMappings.FindIndex(item => item.key.Contains(id))) > -1) {
foreach (var entry in eventMappings[index].value) {
string xmlns = ""; // TODO : implement xmlns resolver!
addableAttrs.Add(new XAttribute(xmlns + entry.EventName, entry.MethodName));
foreach (var bamlReference in defaultBamlReferences) {
assemblyReferenceQueue.Enqueue((true, mainModule, AssemblyNameReference.Parse(bamlReference)));
}
var comparer = KeyComparer.Create(((bool IsAssembly, PEFile MainModule, object Reference) reference) =>
reference.IsAssembly ? "A:" + ((IAssemblyReference)reference.Reference).FullName :
"M:" + reference.Reference);
var processedAssemblyReferences = new HashSet<(bool IsAssembly, PEFile Parent, object Reference)>(comparer);
while (assemblyReferenceQueue.Count > 0) {
var asmRef = assemblyReferenceQueue.Dequeue();
if (!processedAssemblyReferences.Add(asmRef))
continue;
PEFile asm;
if (asmRef.IsAssembly) {
asm = assemblyResolver.Resolve((IAssemblyReference)asmRef.Reference);
} else {
asm = assemblyResolver.ResolveModule(asmRef.MainModule, (string)asmRef.Reference);
}
if (asm != null) {
referencedAssemblies.Add(asm);
var metadata = asm.Metadata;
foreach (var h in metadata.ExportedTypes) {
var exportedType = metadata.GetExportedType(h);
switch (exportedType.Implementation.Kind) {
case SRM.HandleKind.AssemblyReference:
assemblyReferenceQueue.Enqueue((true, asm, new AssemblyReference(asm, (SRM.AssemblyReferenceHandle)exportedType.Implementation)));
break;
case SRM.HandleKind.AssemblyFile:
var file = metadata.GetAssemblyFile((SRM.AssemblyFileHandle)exportedType.Implementation);
assemblyReferenceQueue.Enqueue((false, asm, metadata.GetString(file.Name)));
break;
}
}
}
removableAttrs.Add(attr);
}
var mainModuleWithOptions = mainModule.WithOptions(TypeSystemOptions.Default);
var referencedAssembliesWithOptions = referencedAssemblies.Select(file => file.WithOptions(TypeSystemOptions.Default));
// Primitive types are necessary to avoid assertions in ILReader.
// Fallback to MinimalCorlib to provide the primitive types.
if (!HasType(KnownTypeCode.Void) || !HasType(KnownTypeCode.Int32)) {
Init(mainModule.WithOptions(TypeSystemOptions.Default), referencedAssembliesWithOptions.Concat(new[] { MinimalCorlib.Instance }));
} else {
Init(mainModuleWithOptions, referencedAssembliesWithOptions);
}
this.MainModule = (MetadataModule)base.MainModule;
bool HasType(KnownTypeCode code)
{
TopLevelTypeName name = KnownTypeReference.Get(code).TypeName;
if (mainModule.GetTypeDefinition(name) != null)
return true;
foreach (var file in referencedAssemblies) {
if (file.GetTypeDefinition(name) != null)
return true;
}
return false;
}
}
foreach (var attr in removableAttrs)
attr.Remove();
element.Add(addableAttrs);
public new MetadataModule MainModule { get; }
}
}
}

65
ILSpy.BamlDecompiler/CecilType.cs

@ -1,65 +0,0 @@ @@ -1,65 +0,0 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team
// This code is distributed under the MS-PL (for details please see \doc\MS-PL.txt)
using System;
using System.Linq;
using ICSharpCode.Decompiler.TypeSystem;
using Ricciolo.StylesExplorer.MarkupReflection;
namespace ILSpy.BamlDecompiler
{
public class NRType : IDotNetType
{
readonly ITypeDefinition type;
public ITypeDefinition Type => type;
public NRType(ITypeDefinition type)
{
this.type = type ?? throw new ArgumentNullException(nameof(type));
}
public string AssemblyQualifiedName {
get {
return type.FullName +
", " + type.ParentModule.FullAssemblyName;
}
}
public bool IsSubclassOf(IDotNetType type)
{
if (type == null)
throw new ArgumentNullException(nameof(type));
if (!(type is NRType baseType))
return false;
return this.type.GetAllBaseTypeDefinitions().Any(t => t.Equals(baseType.type));
}
public bool Equals(IDotNetType type)
{
if (type == null)
throw new ArgumentNullException("type");
if (!(type is NRType))
return false;
return this.type.Equals(((NRType)type).type);
}
public override string ToString()
{
return string.Format("[CecilType Type={0}]", type);
}
public IDotNetType BaseType {
get {
var t = type.DirectBaseTypes.First();
var td = t.GetDefinition();
if (td == null)
throw new Exception($"Could not resolve '{t.FullName}'!");
return new NRType(td);
}
}
}
}

78
ILSpy.BamlDecompiler/CecilTypeResolver.cs

@ -1,78 +0,0 @@ @@ -1,78 +0,0 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team
// This code is distributed under the MS-PL (for details please see \doc\MS-PL.txt)
using System;
using ICSharpCode.Decompiler.Metadata;
using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.ILSpy;
using Ricciolo.StylesExplorer.MarkupReflection;
namespace ILSpy.BamlDecompiler
{
/// <summary>
/// Description of CecilTypeResolver.
/// </summary>
public class NRTypeResolver : IDotNetTypeResolver
{
readonly PEFile module;
readonly DecompilerTypeSystem typeSystem;
public NRTypeResolver(PEFile module, IAssemblyResolver resolver)
{
this.module = module ?? throw new ArgumentNullException(nameof(module));
this.typeSystem = new DecompilerTypeSystem(module, resolver);
}
public bool IsLocalAssembly(string name)
{
return MakeShort(name) == typeSystem.MainModule.AssemblyName;
}
string MakeShort(string name)
{
int endOffset = name.IndexOf(',');
if (endOffset == -1)
return name;
return name.Substring(0, endOffset);
}
public IDotNetType GetTypeByAssemblyQualifiedName(string name)
{
int bracket = name.LastIndexOf(']');
int comma = bracket > -1 ? name.IndexOf(',', bracket) : name.IndexOf(',');
if (comma == -1)
throw new ArgumentException("invalid name");
string fullName = bracket > -1 ? name.Substring(0, name.IndexOf('[')) : name.Substring(0, comma);
string assemblyName = name.Substring(comma + 1).Trim();
var type = typeSystem.FindType(new FullTypeName(fullName)).GetDefinition();
if (type == null)
return new UnresolvableType(name);
return new NRType(type);
}
public IDependencyPropertyDescriptor GetDependencyPropertyDescriptor(string name, IDotNetType ownerType, IDotNetType targetType)
{
if (ownerType == null)
throw new ArgumentNullException("ownerType");
if (ownerType is NRType)
return new NRTypeDependencyPropertyDescriptor(((NRType)ownerType).Type, name);
if (ownerType is UnresolvableType)
return new UnresolvableDependencyPropertyDescriptor();
throw new ArgumentException("Invalid IType: " + ownerType.GetType());
}
public TargetRuntime RuntimeVersion {
get {
return module.GetRuntime();
}
}
}
}

39
ILSpy.BamlDecompiler/Handlers/Blocks/ConstructorParametersHandler.cs

@ -0,0 +1,39 @@ @@ -0,0 +1,39 @@
/*
Copyright (c) 2015 Ki
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
using System.Xml.Linq;
using ILSpy.BamlDecompiler.Baml;
namespace ILSpy.BamlDecompiler.Handlers {
internal class ConstructorParametersStartHandler : IHandler {
public BamlRecordType Type => BamlRecordType.ConstructorParametersStart;
public BamlElement Translate(XamlContext ctx, BamlNode node, BamlElement parent) {
var doc = new BamlElement(node);
doc.Xaml = new XElement(ctx.GetPseudoName("Ctor"));
parent.Xaml.Element.Add(doc.Xaml.Element);
HandlerMap.ProcessChildren(ctx, (BamlBlockNode)node, doc);
return doc;
}
}
}

38
ILSpy.BamlDecompiler/Handlers/Blocks/DocumentHandler.cs

@ -0,0 +1,38 @@ @@ -0,0 +1,38 @@
/*
Copyright (c) 2015 Ki
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
using System.Xml.Linq;
using ILSpy.BamlDecompiler.Baml;
namespace ILSpy.BamlDecompiler.Handlers {
internal class DocumentHandler : IHandler {
public BamlRecordType Type => BamlRecordType.DocumentStart;
public BamlElement Translate(XamlContext ctx, BamlNode node, BamlElement parent) {
var doc = new BamlElement(node);
doc.Xaml = new XElement(ctx.GetPseudoName("Document"));
HandlerMap.ProcessChildren(ctx, (BamlBlockNode)node, doc);
return doc;
}
}
}

56
ILSpy.BamlDecompiler/Handlers/Blocks/ElementHandler.cs

@ -0,0 +1,56 @@ @@ -0,0 +1,56 @@
/*
Copyright (c) 2015 Ki
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
using System.Xml.Linq;
using ILSpy.BamlDecompiler.Baml;
using ILSpy.BamlDecompiler.Xaml;
namespace ILSpy.BamlDecompiler.Handlers {
internal class ElementHandler : IHandler {
public BamlRecordType Type => BamlRecordType.ElementStart;
public BamlElement Translate(XamlContext ctx, BamlNode node, BamlElement parent) {
var record = (ElementStartRecord)((BamlBlockNode)node).Header;
var doc = new BamlElement(node);
var elemType = ctx.ResolveType(record.TypeId);
doc.Xaml = new XElement(elemType.ToXName(ctx));
doc.Xaml.Element.AddAnnotation(elemType);
parent.Xaml.Element.Add(doc.Xaml.Element);
HandlerMap.ProcessChildren(ctx, (BamlBlockNode)node, doc);
if (node.Annotation is XamlResourceKey key && key.KeyNode.Record != node.Record) {
var handler = (IDeferHandler)HandlerMap.LookupHandler(key.KeyNode.Record.Type);
var keyElem = handler.TranslateDefer(ctx, key.KeyNode, doc);
doc.Children.Add(keyElem);
keyElem.Parent = doc;
}
elemType.ResolveNamespace(doc.Xaml, ctx);
doc.Xaml.Element.Name = elemType.ToXName(ctx);
return doc;
}
}
}

49
ILSpy.BamlDecompiler/Handlers/Blocks/KeyElementStartHandler.cs

@ -0,0 +1,49 @@ @@ -0,0 +1,49 @@
/*
Copyright (c) 2015 Ki
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
using System.Xml.Linq;
using ILSpy.BamlDecompiler.Baml;
using ILSpy.BamlDecompiler.Xaml;
namespace ILSpy.BamlDecompiler.Handlers {
internal class KeyElementStartHandler : ElementHandler, IHandler, IDeferHandler {
BamlRecordType IHandler.Type => BamlRecordType.KeyElementStart;
BamlElement IHandler.Translate(XamlContext ctx, BamlNode node, BamlElement parent) {
XamlResourceKey.Create(node);
return null;
}
public BamlElement TranslateDefer(XamlContext ctx, BamlNode node, BamlElement parent) {
var record = (KeyElementStartRecord)((BamlBlockNode)node).Header;
var key = (XamlResourceKey)node.Annotation;
var bamlElem = new BamlElement(node);
bamlElem.Xaml = new XElement(ctx.GetXamlNsName("Key", parent.Xaml));
parent.Xaml.Element.Add(bamlElem.Xaml.Element);
key.KeyElement = bamlElem;
base.Translate(ctx, node, bamlElem);
return bamlElem;
}
}
}

47
ILSpy.BamlDecompiler/Handlers/Blocks/PropertyArrayHandler.cs

@ -0,0 +1,47 @@ @@ -0,0 +1,47 @@
/*
Copyright (c) 2015 Ki
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
using System.Xml.Linq;
using ILSpy.BamlDecompiler.Baml;
namespace ILSpy.BamlDecompiler.Handlers {
internal class PropertyArrayHandler : IHandler {
public BamlRecordType Type => BamlRecordType.PropertyArrayStart;
public BamlElement Translate(XamlContext ctx, BamlNode node, BamlElement parent) {
var record = (PropertyArrayStartRecord)((BamlBlockNode)node).Header;
var doc = new BamlElement(node);
var elemAttr = ctx.ResolveProperty(record.AttributeId);
doc.Xaml = new XElement(elemAttr.ToXName(ctx, null));
doc.Xaml.Element.AddAnnotation(elemAttr);
parent.Xaml.Element.Add(doc.Xaml.Element);
HandlerMap.ProcessChildren(ctx, (BamlBlockNode)node, doc);
elemAttr.DeclaringType.ResolveNamespace(doc.Xaml, ctx);
doc.Xaml.Element.Name = elemAttr.ToXName(ctx, null);
return doc;
}
}
}

47
ILSpy.BamlDecompiler/Handlers/Blocks/PropertyComplexHandler.cs

@ -0,0 +1,47 @@ @@ -0,0 +1,47 @@
/*
Copyright (c) 2015 Ki
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
using System.Xml.Linq;
using ILSpy.BamlDecompiler.Baml;
namespace ILSpy.BamlDecompiler.Handlers {
internal class PropertyComplexHandler : IHandler {
public BamlRecordType Type => BamlRecordType.PropertyComplexStart;
public BamlElement Translate(XamlContext ctx, BamlNode node, BamlElement parent) {
var record = (PropertyComplexStartRecord)((BamlBlockNode)node).Header;
var doc = new BamlElement(node);
var elemAttr = ctx.ResolveProperty(record.AttributeId);
doc.Xaml = new XElement(elemAttr.ToXName(ctx, null));
doc.Xaml.Element.AddAnnotation(elemAttr);
parent.Xaml.Element.Add(doc.Xaml.Element);
HandlerMap.ProcessChildren(ctx, (BamlBlockNode)node, doc);
elemAttr.DeclaringType.ResolveNamespace(doc.Xaml, ctx);
doc.Xaml.Element.Name = elemAttr.ToXName(ctx, null);
return doc;
}
}
}

47
ILSpy.BamlDecompiler/Handlers/Blocks/PropertyDictionaryHandler.cs

@ -0,0 +1,47 @@ @@ -0,0 +1,47 @@
/*
Copyright (c) 2015 Ki
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
using System.Xml.Linq;
using ILSpy.BamlDecompiler.Baml;
namespace ILSpy.BamlDecompiler.Handlers {
internal class PropertyDictionaryHandler : IHandler {
public BamlRecordType Type => BamlRecordType.PropertyDictionaryStart;
public BamlElement Translate(XamlContext ctx, BamlNode node, BamlElement parent) {
var record = (PropertyDictionaryStartRecord)((BamlBlockNode)node).Header;
var doc = new BamlElement(node);
var elemAttr = ctx.ResolveProperty(record.AttributeId);
doc.Xaml = new XElement(elemAttr.ToXName(ctx, null));
doc.Xaml.Element.AddAnnotation(elemAttr);
parent.Xaml.Element.Add(doc.Xaml.Element);
HandlerMap.ProcessChildren(ctx, (BamlBlockNode)node, doc);
elemAttr.DeclaringType.ResolveNamespace(doc.Xaml, ctx);
doc.Xaml.Element.Name = elemAttr.ToXName(ctx, null);
return doc;
}
}
}

47
ILSpy.BamlDecompiler/Handlers/Blocks/PropertyListHandler.cs

@ -0,0 +1,47 @@ @@ -0,0 +1,47 @@
/*
Copyright (c) 2015 Ki
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
using System.Xml.Linq;
using ILSpy.BamlDecompiler.Baml;
namespace ILSpy.BamlDecompiler.Handlers {
internal class PropertyListHandler : IHandler {
public BamlRecordType Type => BamlRecordType.PropertyListStart;
public BamlElement Translate(XamlContext ctx, BamlNode node, BamlElement parent) {
var record = (PropertyListStartRecord)((BamlBlockNode)node).Header;
var doc = new BamlElement(node);
var elemAttr = ctx.ResolveProperty(record.AttributeId);
doc.Xaml = new XElement(elemAttr.ToXName(ctx, null));
doc.Xaml.Element.AddAnnotation(elemAttr);
parent.Xaml.Element.Add(doc.Xaml.Element);
HandlerMap.ProcessChildren(ctx, (BamlBlockNode)node, doc);
elemAttr.DeclaringType.ResolveNamespace(doc.Xaml, ctx);
doc.Xaml.Element.Name = elemAttr.ToXName(ctx, null);
return doc;
}
}
}

31
ILSpy.BamlDecompiler/Handlers/Records/AssemblyInfoHandler.cs

@ -0,0 +1,31 @@ @@ -0,0 +1,31 @@
/*
Copyright (c) 2015 Ki
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
using ILSpy.BamlDecompiler.Baml;
namespace ILSpy.BamlDecompiler.Handlers {
internal class AssemblyInfoHandler : IHandler {
public BamlRecordType Type => BamlRecordType.AssemblyInfo;
public BamlElement Translate(XamlContext ctx, BamlNode node, BamlElement parent) => null;
}
}

31
ILSpy.BamlDecompiler/Handlers/Records/AttributeInfoHandler.cs

@ -0,0 +1,31 @@ @@ -0,0 +1,31 @@
/*
Copyright (c) 2015 Ki
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
using ILSpy.BamlDecompiler.Baml;
namespace ILSpy.BamlDecompiler.Handlers {
internal class AttributeInfoHandler : IHandler {
public BamlRecordType Type => BamlRecordType.AttributeInfo;
public BamlElement Translate(XamlContext ctx, BamlNode node, BamlElement parent) => null;
}
}

37
ILSpy.BamlDecompiler/Handlers/Records/ConnectionIdHandler.cs

@ -0,0 +1,37 @@ @@ -0,0 +1,37 @@
/*
Copyright (c) 2015 Ki
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
using ILSpy.BamlDecompiler.Baml;
namespace ILSpy.BamlDecompiler.Handlers {
internal class ConnectionIdHandler : IHandler {
public BamlRecordType Type => BamlRecordType.ConnectionId;
public BamlElement Translate(XamlContext ctx, BamlNode node, BamlElement parent) {
var record = (ConnectionIdRecord)((BamlRecordNode)node).Record;
parent.Xaml.Element.AddAnnotation(new BamlConnectionId(record.ConnectionId));
return null;
}
}
}

48
ILSpy.BamlDecompiler/Handlers/Records/ConstructorParameterTypeHandler.cs

@ -0,0 +1,48 @@ @@ -0,0 +1,48 @@
/*
Copyright (c) 2015 Ki
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
using System.Xml.Linq;
using ILSpy.BamlDecompiler.Baml;
using ILSpy.BamlDecompiler.Xaml;
namespace ILSpy.BamlDecompiler.Handlers {
internal class ConstructorParameterTypeHandler : IHandler {
public BamlRecordType Type => BamlRecordType.ConstructorParameterType;
public BamlElement Translate(XamlContext ctx, BamlNode node, BamlElement parent) {
var record = (ConstructorParameterTypeRecord)((BamlRecordNode)node).Record;
var elem = new XElement(ctx.GetXamlNsName("TypeExtension", parent.Xaml));
elem.AddAnnotation(ctx.ResolveType(0xfd4d)); // Known type - TypeExtension
var bamlElem = new BamlElement(node);
bamlElem.Xaml = elem;
parent.Xaml.Element.Add(elem);
var type = ctx.ResolveType(record.TypeId);
var typeName = ctx.ToString(parent.Xaml, type);
elem.Add(new XElement(ctx.GetPseudoName("Ctor"), typeName));
return bamlElem;
}
}
}

36
ILSpy.BamlDecompiler/Handlers/Records/ContentPropertyHandler.cs

@ -0,0 +1,36 @@ @@ -0,0 +1,36 @@
/*
Copyright (c) 2015 Ki
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
using ILSpy.BamlDecompiler.Baml;
namespace ILSpy.BamlDecompiler.Handlers {
internal class ContentPropertyHandler : IHandler {
public BamlRecordType Type => BamlRecordType.ContentProperty;
public BamlElement Translate(XamlContext ctx, BamlNode node, BamlElement parent) {
var record = (ContentPropertyRecord)((BamlRecordNode)node).Record;
// TODO: What to do here?
return null;
}
}
}

39
ILSpy.BamlDecompiler/Handlers/Records/DefAttributeHandler.cs

@ -0,0 +1,39 @@ @@ -0,0 +1,39 @@
/*
Copyright (c) 2015 Ki
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
using System.Xml.Linq;
using ILSpy.BamlDecompiler.Baml;
namespace ILSpy.BamlDecompiler.Handlers {
internal class DefAttributeHandler : IHandler {
public BamlRecordType Type => BamlRecordType.DefAttribute;
public BamlElement Translate(XamlContext ctx, BamlNode node, BamlElement parent) {
var record = (DefAttributeRecord)((BamlRecordNode)node).Record;
var attrName = ctx.ResolveString(record.NameId);
parent.Xaml.Element.Add(new XAttribute(ctx.GetXamlNsName(attrName), record.Value));
return null;
}
}
}

49
ILSpy.BamlDecompiler/Handlers/Records/DefAttributeKeyStringHandler.cs

@ -0,0 +1,49 @@ @@ -0,0 +1,49 @@
/*
Copyright (c) 2015 Ki
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
using System.Xml.Linq;
using ILSpy.BamlDecompiler.Baml;
using ILSpy.BamlDecompiler.Xaml;
namespace ILSpy.BamlDecompiler.Handlers {
internal class DefAttributeStringHandler : IHandler, IDeferHandler {
public BamlRecordType Type => BamlRecordType.DefAttributeKeyString;
public BamlElement Translate(XamlContext ctx, BamlNode node, BamlElement parent) {
XamlResourceKey.Create(node);
return null;
}
public BamlElement TranslateDefer(XamlContext ctx, BamlNode node, BamlElement parent) {
var record = (DefAttributeKeyStringRecord)((BamlRecordNode)node).Record;
var key = (XamlResourceKey)node.Annotation;
var bamlElem = new BamlElement(node);
bamlElem.Xaml = new XElement(ctx.GetXamlNsName("Key", parent.Xaml));
parent.Xaml.Element.Add(bamlElem.Xaml.Element);
bamlElem.Xaml.Element.Value = ctx.ResolveString(record.ValueId);
key.KeyElement = bamlElem;
return bamlElem;
}
}
}

56
ILSpy.BamlDecompiler/Handlers/Records/DefAttributeKeyTypeHandler.cs

@ -0,0 +1,56 @@ @@ -0,0 +1,56 @@
/*
Copyright (c) 2015 Ki
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
using System.Xml.Linq;
using ILSpy.BamlDecompiler.Baml;
using ILSpy.BamlDecompiler.Xaml;
namespace ILSpy.BamlDecompiler.Handlers {
internal class DefAttributeTypeHandler : IHandler, IDeferHandler {
public BamlRecordType Type => BamlRecordType.DefAttributeKeyType;
public BamlElement Translate(XamlContext ctx, BamlNode node, BamlElement parent) {
XamlResourceKey.Create(node);
return null;
}
public BamlElement TranslateDefer(XamlContext ctx, BamlNode node, BamlElement parent) {
var record = (DefAttributeKeyTypeRecord)((BamlRecordNode)node).Record;
var type = ctx.ResolveType(record.TypeId);
var typeName = ctx.ToString(parent.Xaml, type);
var key = (XamlResourceKey)node.Annotation;
var bamlElem = new BamlElement(node);
bamlElem.Xaml = new XElement(ctx.GetXamlNsName("Key", parent.Xaml));
parent.Xaml.Element.Add(bamlElem.Xaml.Element);
var typeElem = new XElement(ctx.GetXamlNsName("TypeExtension", parent.Xaml));
typeElem.AddAnnotation(ctx.ResolveType(0xfd4d)); // Known type - TypeExtension
typeElem.Add(new XElement(ctx.GetPseudoName("Ctor"), typeName));
bamlElem.Xaml.Element.Add(typeElem);
key.KeyElement = bamlElem;
return bamlElem;
}
}
}

38
ILSpy.BamlDecompiler/Handlers/Records/DeferableContentStartHandler.cs

@ -0,0 +1,38 @@ @@ -0,0 +1,38 @@
/*
Copyright (c) 2015 Ki
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
using System.Diagnostics;
using ILSpy.BamlDecompiler.Baml;
namespace ILSpy.BamlDecompiler.Handlers {
internal class DeferableContentStartHandler : IHandler {
public BamlRecordType Type => BamlRecordType.DeferableContentStart;
public BamlElement Translate(XamlContext ctx, BamlNode node, BamlElement parent) {
var record = (DeferableContentStartRecord)((BamlRecordNode)node).Record;
Debug.Assert(record.Record == ((BamlBlockNode)parent.Node).Footer);
return null;
}
}
}

31
ILSpy.BamlDecompiler/Handlers/Records/LineNumberAndPositionHandler.cs

@ -0,0 +1,31 @@ @@ -0,0 +1,31 @@
/*
Copyright (c) 2015 Ki
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
using ILSpy.BamlDecompiler.Baml;
namespace ILSpy.BamlDecompiler.Handlers {
internal class LineNumberAndPositionHandler : IHandler {
public BamlRecordType Type => BamlRecordType.LineNumberAndPosition;
public BamlElement Translate(XamlContext ctx, BamlNode node, BamlElement parent) => null;
}
}

31
ILSpy.BamlDecompiler/Handlers/Records/LinePositionHandler.cs

@ -0,0 +1,31 @@ @@ -0,0 +1,31 @@
/*
Copyright (c) 2015 Ki
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
using ILSpy.BamlDecompiler.Baml;
namespace ILSpy.BamlDecompiler.Handlers {
internal class LinePositionHandler : IHandler {
public BamlRecordType Type => BamlRecordType.LinePosition;
public BamlElement Translate(XamlContext ctx, BamlNode node, BamlElement parent) => null;
}
}

42
ILSpy.BamlDecompiler/Handlers/Records/LiteralContentHandler.cs

@ -0,0 +1,42 @@ @@ -0,0 +1,42 @@
/*
Copyright (c) 2015 Ki
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
using System.Xml.Linq;
using ILSpy.BamlDecompiler.Baml;
namespace ILSpy.BamlDecompiler.Handlers {
internal class LiteralContentHandler : IHandler {
public BamlRecordType Type => BamlRecordType.LiteralContent;
public BamlElement Translate(XamlContext ctx, BamlNode node, BamlElement parent) {
var record = (LiteralContentRecord)((BamlRecordNode)node).Record;
var elem = new XElement(ctx.GetXamlNsName("XData", parent.Xaml));
var content = XElement.Parse(record.Value);
elem.Add(content);
parent.Xaml.Element.Add(elem);
return null;
}
}
}

106
ILSpy.BamlDecompiler/Handlers/Records/OptimizedStaticResourceHandler.cs

@ -0,0 +1,106 @@ @@ -0,0 +1,106 @@
/*
Copyright (c) 2015 Ki
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
using System.Xml.Linq;
using ILSpy.BamlDecompiler.Baml;
using ILSpy.BamlDecompiler.Xaml;
namespace ILSpy.BamlDecompiler.Handlers {
internal class OptimizedStaticResourceHandler : IHandler, IDeferHandler {
public BamlRecordType Type => BamlRecordType.OptimizedStaticResource;
public BamlElement Translate(XamlContext ctx, BamlNode node, BamlElement parent) {
var record = (OptimizedStaticResourceRecord)((BamlRecordNode)node).Record;
var key = XamlResourceKey.FindKeyInSiblings(node);
key.StaticResources.Add(node);
return null;
}
public BamlElement TranslateDefer(XamlContext ctx, BamlNode node, BamlElement parent) {
var record = (OptimizedStaticResourceRecord)((BamlRecordNode)node).Record;
var bamlElem = new BamlElement(node);
object key;
if (record.IsType) {
var value = ctx.ResolveType(record.ValueId);
var typeElem = new XElement(ctx.GetXamlNsName("TypeExtension", parent.Xaml));
typeElem.AddAnnotation(ctx.ResolveType(0xfd4d)); // Known type - TypeExtension
typeElem.Add(new XElement(ctx.GetPseudoName("Ctor"), ctx.ToString(parent.Xaml, value)));
key = typeElem;
}
else if (record.IsStatic) {
string attrName;
if (record.ValueId > 0x7fff) {
bool isKey = true;
short bamlId = unchecked((short)-record.ValueId);
if (bamlId > 232 && bamlId < 464) {
bamlId -= 232;
isKey = false;
}
else if (bamlId > 464 && bamlId < 467) {
bamlId -= 231;
}
else if (bamlId > 467 && bamlId < 470) {
bamlId -= 234;
isKey = false;
}
var res = ctx.Baml.KnownThings.Resources(bamlId);
string name;
if (isKey)
name = res.Item1 + "." + res.Item2;
else
name = res.Item1 + "." + res.Item3;
var xmlns = ctx.GetXmlNamespace("http://schemas.microsoft.com/winfx/2006/xaml/presentation");
attrName = ctx.ToString(parent.Xaml, xmlns.GetName(name));
}
else {
var value = ctx.ResolveProperty(record.ValueId);
value.DeclaringType.ResolveNamespace(parent.Xaml, ctx);
var xName = value.ToXName(ctx, parent.Xaml);
attrName = ctx.ToString(parent.Xaml, xName);
}
var staticElem = new XElement(ctx.GetXamlNsName("StaticExtension", parent.Xaml));
staticElem.AddAnnotation(ctx.ResolveType(0xfda6)); // Known type - StaticExtension
staticElem.Add(new XElement(ctx.GetPseudoName("Ctor"), attrName));
key = staticElem;
}
else
key = ctx.ResolveString(record.ValueId);
var extType = ctx.ResolveType(0xfda5);
var resElem = new XElement(extType.ToXName(ctx));
resElem.AddAnnotation(extType); // Known type - StaticResourceExtension
bamlElem.Xaml = resElem;
parent.Xaml.Element.Add(resElem);
var attrElem = new XElement(ctx.GetPseudoName("Ctor"));
attrElem.Add(key);
resElem.Add(attrElem);
return bamlElem;
}
}
}

31
ILSpy.BamlDecompiler/Handlers/Records/PIMappingHandler.cs

@ -0,0 +1,31 @@ @@ -0,0 +1,31 @@
/*
Copyright (c) 2015 Ki
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
using ILSpy.BamlDecompiler.Baml;
namespace ILSpy.BamlDecompiler.Handlers {
internal class PIMappingHandler : IHandler {
public BamlRecordType Type => BamlRecordType.PIMapping;
public BamlElement Translate(XamlContext ctx, BamlNode node, BamlElement parent) => null;
}
}

40
ILSpy.BamlDecompiler/Handlers/Records/PresentationOptionsAttributeHandler.cs

@ -0,0 +1,40 @@ @@ -0,0 +1,40 @@
/*
Copyright (c) 2015 Ki
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
using System.Xml.Linq;
using ILSpy.BamlDecompiler.Baml;
namespace ILSpy.BamlDecompiler.Handlers {
internal class PresentationOptionsAttributeHandler : IHandler {
public BamlRecordType Type => BamlRecordType.PresentationOptionsAttribute;
public BamlElement Translate(XamlContext ctx, BamlNode node, BamlElement parent) {
var record = (PresentationOptionsAttributeRecord)((BamlRecordNode)node).Record;
var attrName = ctx.ResolveString(record.NameId);
var attr = new XAttribute(ctx.GetXamlNsName(attrName, parent.Xaml), record.Value);
parent.Xaml.Element.Add(attr);
return null;
}
}
}

160
ILSpy.BamlDecompiler/Handlers/Records/PropertyCustomHandler.cs

@ -0,0 +1,160 @@ @@ -0,0 +1,160 @@
/*
Copyright (c) 2015 Ki
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
using System;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Text;
using System.Xml.Linq;
using ILSpy.BamlDecompiler.Baml;
using ILSpy.BamlDecompiler.Xaml;
namespace ILSpy.BamlDecompiler.Handlers {
internal class PropertyCustomHandler : IHandler {
public BamlRecordType Type => BamlRecordType.PropertyCustom;
enum IntegerCollectionType : byte {
Unknown,
Consecutive,
U1,
U2,
I4
}
string Deserialize(XamlContext ctx, XElement elem, KnownTypes ser, byte[] value) {
using (BinaryReader reader = new BinaryReader(new MemoryStream(value))) {
switch (ser) {
case KnownTypes.DependencyPropertyConverter: {
if (value.Length == 2) {
var property = ctx.ResolveProperty(reader.ReadUInt16());
return ctx.ToString(elem, property.ToXName(ctx, elem, false));
}
else {
var type = ctx.ResolveType(reader.ReadUInt16());
var name = reader.ReadString();
var typeName = ctx.ToString(elem, type);
return typeName + "." + name;
}
}
case KnownTypes.EnumConverter: {
uint enumVal = reader.ReadUInt32();
// TODO: Convert to enum names
return enumVal.ToString("D", CultureInfo.InvariantCulture);
}
case KnownTypes.BooleanConverter: {
Debug.Assert(value.Length == 1);
return (reader.ReadByte() == 1).ToString(CultureInfo.InvariantCulture);
}
case KnownTypes.XamlBrushSerializer: {
switch (reader.ReadByte()) {
case 1: // KnownSolidColor
return string.Format(CultureInfo.InvariantCulture, "#{0:X8}", reader.ReadUInt32());
case 2: // OtherColor
return reader.ReadString();
}
break;
}
case KnownTypes.XamlPathDataSerializer:
return XamlPathDeserializer.Deserialize(reader);
case KnownTypes.XamlPoint3DCollectionSerializer:
case KnownTypes.XamlVector3DCollectionSerializer: {
var sb = new StringBuilder();
var count = reader.ReadUInt32();
for (uint i = 0; i < count; i++) {
sb.AppendFormat(CultureInfo.InvariantCulture, "{0:R},{1:R},{2:R} ",
reader.ReadXamlDouble(),
reader.ReadXamlDouble(),
reader.ReadXamlDouble());
}
return sb.ToString().Trim();
}
case KnownTypes.XamlPointCollectionSerializer: {
var sb = new StringBuilder();
var count = reader.ReadUInt32();
for (uint i = 0; i < count; i++) {
sb.AppendFormat(CultureInfo.InvariantCulture, "{0:R},{1:R} ",
reader.ReadXamlDouble(),
reader.ReadXamlDouble());
}
return sb.ToString().Trim();
}
case KnownTypes.XamlInt32CollectionSerializer: {
var sb = new StringBuilder();
var type = (IntegerCollectionType)reader.ReadByte();
var count = reader.ReadInt32();
switch (type) {
case IntegerCollectionType.Consecutive: {
var start = reader.ReadInt32();
for (int i = 0; i < count; i++)
sb.AppendFormat(CultureInfo.InvariantCulture, "{0:D}", start + i);
}
break;
case IntegerCollectionType.U1: {
for (int i = 0; i < count; i++)
sb.AppendFormat(CultureInfo.InvariantCulture, "{0:D}", reader.ReadByte());
}
break;
case IntegerCollectionType.U2: {
for (int i = 0; i < count; i++)
sb.AppendFormat(CultureInfo.InvariantCulture, "{0:D}", reader.ReadUInt16());
}
break;
case IntegerCollectionType.I4: {
for (int i = 0; i < count; i++)
sb.AppendFormat(CultureInfo.InvariantCulture, "{0:D}", reader.ReadInt32());
}
break;
default:
throw new NotSupportedException(type.ToString());
}
return sb.ToString().Trim();
}
}
}
throw new NotSupportedException(ser.ToString());
}
public BamlElement Translate(XamlContext ctx, BamlNode node, BamlElement parent) {
var record = (PropertyCustomRecord)((BamlRecordNode)node).Record;
var serTypeId = ((short)record.SerializerTypeId & 0xfff);
bool valueType = ((short)record.SerializerTypeId & 0x4000) == 0x4000;
var elemType = parent.Xaml.Element.Annotation<XamlType>();
var xamlProp = ctx.ResolveProperty(record.AttributeId);
string value = Deserialize(ctx, parent.Xaml, (KnownTypes)serTypeId, record.Data);
var attr = new XAttribute(xamlProp.ToXName(ctx, parent.Xaml, xamlProp.IsAttachedTo(elemType)), value);
parent.Xaml.Element.Add(attr);
return null;
}
}
}

49
ILSpy.BamlDecompiler/Handlers/Records/PropertyHandler.cs

@ -0,0 +1,49 @@ @@ -0,0 +1,49 @@
/*
Copyright (c) 2015 Ki
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
using System.Xml.Linq;
using ILSpy.BamlDecompiler.Baml;
using ILSpy.BamlDecompiler.Xaml;
namespace ILSpy.BamlDecompiler.Handlers {
internal class PropertyHandler : IHandler {
public virtual BamlRecordType Type => BamlRecordType.Property;
public BamlElement Translate(XamlContext ctx, BamlNode node, BamlElement parent) {
var record = (PropertyRecord)((BamlRecordNode)node).Record;
var elemType = parent.Xaml.Element.Annotation<XamlType>();
var xamlProp = ctx.ResolveProperty(record.AttributeId);
var value = XamlUtils.Escape(record.Value);
XAttribute attr;
if (xamlProp.PropertyName == "Name" && elemType.ResolvedType.GetDefinition()?.ParentModule.IsMainModule == true) {
attr = new XAttribute(ctx.GetXamlNsName("Name"), value);
} else {
attr = new XAttribute(xamlProp.ToXName(ctx, parent.Xaml, xamlProp.IsAttachedTo(elemType)), value);
}
parent.Xaml.Element.Add(attr);
return null;
}
}
}

56
ILSpy.BamlDecompiler/Handlers/Records/PropertyTypeReferenceHandler.cs

@ -0,0 +1,56 @@ @@ -0,0 +1,56 @@
/*
Copyright (c) 2015 Ki
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
using System.Xml.Linq;
using ILSpy.BamlDecompiler.Baml;
using ILSpy.BamlDecompiler.Xaml;
namespace ILSpy.BamlDecompiler.Handlers {
internal class PropertyTypeReferenceHandler : IHandler {
public BamlRecordType Type => BamlRecordType.PropertyTypeReference;
public BamlElement Translate(XamlContext ctx, BamlNode node, BamlElement parent) {
var record = (PropertyTypeReferenceRecord)((BamlRecordNode)node).Record;
var attr = ctx.ResolveProperty(record.AttributeId);
var type = ctx.ResolveType(record.TypeId);
var typeName = ctx.ToString(parent.Xaml, type);
var elem = new BamlElement(node);
var elemAttr = ctx.ResolveProperty(record.AttributeId);
elem.Xaml = new XElement(elemAttr.ToXName(ctx, null));
elem.Xaml.Element.AddAnnotation(elemAttr);
parent.Xaml.Element.Add(elem.Xaml.Element);
var typeElem = new XElement(ctx.GetXamlNsName("TypeExtension", parent.Xaml));
typeElem.AddAnnotation(ctx.ResolveType(0xfd4d)); // Known type - TypeExtension
typeElem.Add(new XElement(ctx.GetPseudoName("Ctor"), typeName));
elem.Xaml.Element.Add(typeElem);
elemAttr.DeclaringType.ResolveNamespace(elem.Xaml, ctx);
elem.Xaml.Element.Name = elemAttr.ToXName(ctx, null);
return elem;
}
}
}

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

Loading…
Cancel
Save