Browse Source

Add BAML decompiler engine from dnSpy.

pull/1419/head
Siegfried Pammer 6 years ago
parent
commit
c23522dca1
  1. 5
      ICSharpCode.Decompiler/Metadata/AssemblyReferences.cs
  2. 2
      ILSpy.BamlDecompiler.Tests/Cases/AttachedEvent.xaml
  3. 38
      ILSpy.BamlDecompiler.Tests/Cases/AvalonDockBrushes.xaml
  4. 24
      ILSpy.BamlDecompiler.Tests/Cases/AvalonDockCommon.xaml
  5. 26
      ILSpy.BamlDecompiler.Tests/Cases/EscapeSequence.xaml
  6. 22
      ILSpy.BamlDecompiler.Tests/Cases/Issue445.xaml
  7. 11
      ILSpy.BamlDecompiler.Tests/Cases/MarkupExtension.xaml
  8. 8
      ILSpy.BamlDecompiler.Tests/Cases/MyControl.xaml
  9. 17
      ILSpy.BamlDecompiler.Tests/Cases/NamespacePrefix.xaml
  10. 14
      ILSpy.BamlDecompiler.Tests/Cases/Resources.xaml
  11. 2
      ILSpy.BamlDecompiler.Tests/Cases/Simple.xaml
  12. 2
      ILSpy.BamlDecompiler.Tests/Cases/SimpleDictionary.xaml
  13. 2
      ILSpy.BamlDecompiler.Tests/Cases/SimpleNames.xaml
  14. 7
      ILSpy.BamlDecompiler.Tests/Cases/SimplePropertyElement.xaml
  15. 97
      ILSpy.BamlDecompiler/Baml/BamlContext.cs
  16. 39
      ILSpy.BamlDecompiler/Baml/BamlDocument.cs
  17. 164
      ILSpy.BamlDecompiler/Baml/BamlNode.cs
  18. 259
      ILSpy.BamlDecompiler/Baml/BamlReader.cs
  19. 992
      ILSpy.BamlDecompiler/Baml/BamlRecords.cs
  20. 65
      ILSpy.BamlDecompiler/Baml/BamlWriter.cs
  21. 297
      ILSpy.BamlDecompiler/Baml/KnownMembers.cs
  22. 80
      ILSpy.BamlDecompiler/Baml/KnownThings.cs
  23. 1321
      ILSpy.BamlDecompiler/Baml/KnownThings.g.cs
  24. 278
      ILSpy.BamlDecompiler/Baml/KnownThings.gen.cs
  25. 788
      ILSpy.BamlDecompiler/Baml/KnownTypes.cs
  26. 2325
      ILSpy.BamlDecompiler/Baml/test.cs
  27. 39
      ILSpy.BamlDecompiler/BamlConnectionId.cs
  28. 60
      ILSpy.BamlDecompiler/BamlElement.cs
  29. 185
      ILSpy.BamlDecompiler/BamlResourceEntryNode.cs
  30. 65
      ILSpy.BamlDecompiler/CecilType.cs
  31. 78
      ILSpy.BamlDecompiler/CecilTypeResolver.cs
  32. 39
      ILSpy.BamlDecompiler/Handlers/Blocks/ConstructorParametersHandler.cs
  33. 38
      ILSpy.BamlDecompiler/Handlers/Blocks/DocumentHandler.cs
  34. 56
      ILSpy.BamlDecompiler/Handlers/Blocks/ElementHandler.cs
  35. 49
      ILSpy.BamlDecompiler/Handlers/Blocks/KeyElementStartHandler.cs
  36. 47
      ILSpy.BamlDecompiler/Handlers/Blocks/PropertyArrayHandler.cs
  37. 47
      ILSpy.BamlDecompiler/Handlers/Blocks/PropertyComplexHandler.cs
  38. 47
      ILSpy.BamlDecompiler/Handlers/Blocks/PropertyDictionaryHandler.cs
  39. 47
      ILSpy.BamlDecompiler/Handlers/Blocks/PropertyListHandler.cs
  40. 31
      ILSpy.BamlDecompiler/Handlers/Records/AssemblyInfoHandler.cs
  41. 31
      ILSpy.BamlDecompiler/Handlers/Records/AttributeInfoHandler.cs
  42. 37
      ILSpy.BamlDecompiler/Handlers/Records/ConnectionIdHandler.cs
  43. 48
      ILSpy.BamlDecompiler/Handlers/Records/ConstructorParameterTypeHandler.cs
  44. 36
      ILSpy.BamlDecompiler/Handlers/Records/ContentPropertyHandler.cs
  45. 39
      ILSpy.BamlDecompiler/Handlers/Records/DefAttributeHandler.cs
  46. 49
      ILSpy.BamlDecompiler/Handlers/Records/DefAttributeKeyStringHandler.cs
  47. 56
      ILSpy.BamlDecompiler/Handlers/Records/DefAttributeKeyTypeHandler.cs
  48. 38
      ILSpy.BamlDecompiler/Handlers/Records/DeferableContentStartHandler.cs
  49. 31
      ILSpy.BamlDecompiler/Handlers/Records/LineNumberAndPositionHandler.cs
  50. 31
      ILSpy.BamlDecompiler/Handlers/Records/LinePositionHandler.cs
  51. 42
      ILSpy.BamlDecompiler/Handlers/Records/LiteralContentHandler.cs
  52. 106
      ILSpy.BamlDecompiler/Handlers/Records/OptimizedStaticResourceHandler.cs
  53. 31
      ILSpy.BamlDecompiler/Handlers/Records/PIMappingHandler.cs
  54. 40
      ILSpy.BamlDecompiler/Handlers/Records/PresentationOptionsAttributeHandler.cs
  55. 160
      ILSpy.BamlDecompiler/Handlers/Records/PropertyCustomHandler.cs
  56. 49
      ILSpy.BamlDecompiler/Handlers/Records/PropertyHandler.cs
  57. 56
      ILSpy.BamlDecompiler/Handlers/Records/PropertyTypeReferenceHandler.cs
  58. 29
      ILSpy.BamlDecompiler/Handlers/Records/PropertyWithConverterHandler.cs
  59. 101
      ILSpy.BamlDecompiler/Handlers/Records/PropertyWithExtensionHandler.cs
  60. 65
      ILSpy.BamlDecompiler/Handlers/Records/PropertyWithStaticResourceIdHandler.cs
  61. 49
      ILSpy.BamlDecompiler/Handlers/Records/TextHandler.cs
  62. 29
      ILSpy.BamlDecompiler/Handlers/Records/TextWithConverterHandler.cs
  63. 37
      ILSpy.BamlDecompiler/Handlers/Records/TypeInfoHandler.cs
  64. 71
      ILSpy.BamlDecompiler/Handlers/Records/XmlnsPropertyHandler.cs
  65. 91
      ILSpy.BamlDecompiler/IHandlers.cs
  66. 90
      ILSpy.BamlDecompiler/ILSpy.BamlDecompiler.csproj
  67. 29
      ILSpy.BamlDecompiler/IRewritePass.cs
  68. 79
      ILSpy.BamlDecompiler/Rewrite/AttributeRewritePass.cs
  69. 127
      ILSpy.BamlDecompiler/Rewrite/ConnectionIdRewritePass.cs
  70. 44
      ILSpy.BamlDecompiler/Rewrite/DocumentRewritePass.cs
  71. 180
      ILSpy.BamlDecompiler/Rewrite/MarkupExtensionRewritePass.cs
  72. 62
      ILSpy.BamlDecompiler/Rewrite/XClassRewritePass.cs
  73. 22
      ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/BAML format.txt
  74. 40
      ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/BamlBinaryReader.cs
  75. 68
      ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/BamlRecordType.cs
  76. 20
      ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/IDependencyPropertyDescriptor.cs
  77. 39
      ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/IType.cs
  78. 14
      ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/ITypeResolver.cs
  79. 46
      ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/KeyMapping.cs
  80. 1345
      ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/KnownInfo.cs
  81. 57
      ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/NodesCollection.cs
  82. 55
      ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/PropertyDeclaration.cs
  83. 29
      ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/ResourceName.cs
  84. 167
      ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/TypeDeclaration.cs
  85. 58
      ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/XmlBamlElement.cs
  86. 19
      ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/XmlBamlNode.cs
  87. 59
      ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/XmlBamlProperty.cs
  88. 45
      ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/XmlBamlPropertyElement.cs
  89. 1738
      ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/XmlBamlReader.cs
  90. 38
      ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/XmlBamlSimpleProperty.cs
  91. 30
      ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/XmlBamlText.cs
  92. 41
      ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/XmlNamespace.cs
  93. 31
      ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/XmlToClrNamespaceMapping.cs
  94. 33
      ILSpy.BamlDecompiler/SRMDependencyPropertyDescriptor.cs
  95. 46
      ILSpy.BamlDecompiler/Xaml/NamespaceMap.cs
  96. 83
      ILSpy.BamlDecompiler/Xaml/XamlExtension.cs
  97. 187
      ILSpy.BamlDecompiler/Xaml/XamlPathDeserializer.cs
  98. 95
      ILSpy.BamlDecompiler/Xaml/XamlProperty.cs
  99. 98
      ILSpy.BamlDecompiler/Xaml/XamlResourceKey.cs
  100. 102
      ILSpy.BamlDecompiler/Xaml/XamlType.cs
  101. Some files were not shown because too many files have changed in this diff Show More

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

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>

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;
}
}
}

29
ILSpy.BamlDecompiler/Handlers/Records/PropertyWithConverterHandler.cs

@ -0,0 +1,29 @@ @@ -0,0 +1,29 @@
/*
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 PropertyWithConverterHandler : PropertyHandler, IHandler {
BamlRecordType IHandler.Type => BamlRecordType.PropertyWithConverter;
}
}

101
ILSpy.BamlDecompiler/Handlers/Records/PropertyWithExtensionHandler.cs

@ -0,0 +1,101 @@ @@ -0,0 +1,101 @@
/*
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 PropertyWithExtensionHandler : IHandler {
public BamlRecordType Type => BamlRecordType.PropertyWithExtension;
public BamlElement Translate(XamlContext ctx, BamlNode node, BamlElement parent) {
var record = (PropertyWithExtensionRecord)((BamlRecordNode)node).Record;
var extTypeId = ((short)record.Flags & 0xfff);
bool valTypeExt = ((short)record.Flags & 0x4000) == 0x4000;
bool valStaticExt = ((short)record.Flags & 0x2000) == 0x2000;
var elemType = parent.Xaml.Element.Annotation<XamlType>();
var xamlProp = ctx.ResolveProperty(record.AttributeId);
var extType = ctx.ResolveType(unchecked((ushort)-extTypeId));
extType.ResolveNamespace(parent.Xaml, ctx);
var ext = new XamlExtension(extType);
if (valTypeExt || extTypeId == (short)KnownTypes.TypeExtension) {
var value = ctx.ResolveType(record.ValueId);
ext.Initializer = new object[] { ctx.ToString(parent.Xaml, value) };
}
else if (extTypeId == (short)KnownTypes.TemplateBindingExtension) {
var value = ctx.ResolveProperty(record.ValueId);
value.DeclaringType.ResolveNamespace(parent.Xaml, ctx);
var xName = value.ToXName(ctx, parent.Xaml, false);
ext.Initializer = new object[] { ctx.ToString(parent.Xaml, xName) };
}
else if (valStaticExt || extTypeId == (short)KnownTypes.StaticExtension) {
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);
}
ext.Initializer = new object[] { attrName };
}
else {
ext.Initializer = new object[] { XamlUtils.Escape(ctx.ResolveString(record.ValueId)) };
}
var extValue = ext.ToString(ctx, parent.Xaml);
var attr = new XAttribute(xamlProp.ToXName(ctx, parent.Xaml, xamlProp.IsAttachedTo(elemType)), extValue);
parent.Xaml.Element.Add(attr);
return null;
}
}
}

65
ILSpy.BamlDecompiler/Handlers/Records/PropertyWithStaticResourceIdHandler.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;
using System.Xml.Linq;
using ILSpy.BamlDecompiler.Baml;
using ILSpy.BamlDecompiler.Xaml;
namespace ILSpy.BamlDecompiler.Handlers {
internal class PropertyWithStaticResourceIdHandler : IHandler {
public BamlRecordType Type => BamlRecordType.PropertyWithStaticResourceId;
public BamlElement Translate(XamlContext ctx, BamlNode node, BamlElement parent) {
var record = (PropertyWithStaticResourceIdRecord)((BamlRecordNode)node).Record;
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);
BamlNode found = node;
XamlResourceKey key;
do {
key = XamlResourceKey.FindKeyInAncestors(found.Parent, out found);
} while (key != null && record.StaticResourceId >= key.StaticResources.Count);
if (key == null)
throw new Exception("Cannot find StaticResource @" + node.Record.Position);
var resNode = key.StaticResources[record.StaticResourceId];
var handler = (IDeferHandler)HandlerMap.LookupHandler(resNode.Type);
var resElem = handler.TranslateDefer(ctx, resNode, doc);
doc.Children.Add(resElem);
resElem.Parent = doc;
elemAttr.DeclaringType.ResolveNamespace(doc.Xaml, ctx);
doc.Xaml.Element.Name = elemAttr.ToXName(ctx, null);
return doc;
}
}
}

49
ILSpy.BamlDecompiler/Handlers/Records/TextHandler.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 ILSpy.BamlDecompiler.Baml;
namespace ILSpy.BamlDecompiler.Handlers {
internal class TextHandler : IHandler {
public BamlRecordType Type => BamlRecordType.Text;
public BamlElement Translate(XamlContext ctx, BamlNode node, BamlElement parent) {
var record = (TextRecord)((BamlRecordNode)node).Record;
parent.Xaml.Element.Add(record.Value);
return null;
}
}
internal class TextWithIdHandler : IHandler {
public BamlRecordType Type => BamlRecordType.TextWithId;
public BamlElement Translate(XamlContext ctx, BamlNode node, BamlElement parent) {
var record = (TextWithIdRecord)((BamlRecordNode)node).Record;
parent.Xaml.Element.Add(ctx.ResolveString(record.ValueId));
return null;
}
}
}

29
ILSpy.BamlDecompiler/Handlers/Records/TextWithConverterHandler.cs

@ -0,0 +1,29 @@ @@ -0,0 +1,29 @@
/*
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 TextWithConverterHandler : TextHandler, IHandler {
BamlRecordType IHandler.Type => BamlRecordType.TextWithConverter;
}
}

37
ILSpy.BamlDecompiler/Handlers/Records/TypeInfoHandler.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 TypeInfoHandler : IHandler {
public BamlRecordType Type => BamlRecordType.TypeInfo;
public BamlElement Translate(XamlContext ctx, BamlNode node, BamlElement parent) => null;
}
internal class TypeSerializerInfoHandler : IHandler {
public BamlRecordType Type => BamlRecordType.TypeSerializerInfo;
public BamlElement Translate(XamlContext ctx, BamlNode node, BamlElement parent) => null;
}
}

71
ILSpy.BamlDecompiler/Handlers/Records/XmlnsPropertyHandler.cs

@ -0,0 +1,71 @@ @@ -0,0 +1,71 @@
/*
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.Diagnostics;
using System.Linq;
using System.Xml;
using System.Xml.Linq;
using ICSharpCode.Decompiler.TypeSystem;
using ILSpy.BamlDecompiler.Baml;
using ILSpy.BamlDecompiler.Xaml;
namespace ILSpy.BamlDecompiler.Handlers {
internal class XmlnsPropertyHandler : IHandler {
public BamlRecordType Type => BamlRecordType.XmlnsProperty;
IEnumerable<string> ResolveCLRNamespaces(IModule assembly, string ns) {
foreach (var attr in assembly.GetAssemblyAttributes().Where(a => a.AttributeType.FullName == "System.Windows.Markup.XmlnsDefinitionAttribute")) {
Debug.Assert(attr.FixedArguments.Length == 2);
var xmlNs = attr.FixedArguments[0].Value;
var clrNs = attr.FixedArguments[1].Value;
Debug.Assert(xmlNs is string && clrNs is string);
if ((string)xmlNs == ns)
yield return (string)clrNs;
}
}
public BamlElement Translate(XamlContext ctx, BamlNode node, BamlElement parent) {
var record = (XmlnsPropertyRecord)((BamlRecordNode)node).Record;
foreach (var asmId in record.AssemblyIds) {
var assembly = ctx.Baml.ResolveAssembly(asmId);
ctx.XmlNs.Add(new NamespaceMap(record.Prefix, assembly, record.XmlNamespace));
if (assembly.IsMainModule) {
foreach (var clrNs in ResolveCLRNamespaces(assembly, record.XmlNamespace))
ctx.XmlNs.Add(new NamespaceMap(record.Prefix, assembly, record.XmlNamespace, clrNs));
}
}
XName xmlnsDef;
if (string.IsNullOrEmpty(record.Prefix))
xmlnsDef = "xmlns";
else
xmlnsDef = XNamespace.Xmlns + XmlConvert.EncodeLocalName(record.Prefix);
parent.Xaml.Element.Add(new XAttribute(xmlnsDef, ctx.GetXmlNamespace(record.XmlNamespace)));
return null;
}
}
}

91
ILSpy.BamlDecompiler/IHandlers.cs

@ -0,0 +1,91 @@ @@ -0,0 +1,91 @@
/*
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 ILSpy.BamlDecompiler.Baml;
namespace ILSpy.BamlDecompiler {
internal interface IHandler {
BamlRecordType Type { get; }
BamlElement Translate(XamlContext ctx, BamlNode node, BamlElement parent);
}
internal interface IDeferHandler {
BamlElement TranslateDefer(XamlContext ctx, BamlNode node, BamlElement parent);
}
internal static class HandlerMap {
static readonly Dictionary<BamlRecordType, IHandler> handlers;
static HandlerMap() {
handlers = new Dictionary<BamlRecordType, IHandler>();
foreach (var type in typeof(IHandler).Assembly.GetTypes()) {
if (typeof(IHandler).IsAssignableFrom(type) &&
!type.IsInterface && !type.IsAbstract) {
var handler = (IHandler)Activator.CreateInstance(type);
handlers.Add(handler.Type, handler);
}
}
}
public static IHandler LookupHandler(BamlRecordType type) {
#if DEBUG
switch (type) {
case BamlRecordType.AssemblyInfo:
case BamlRecordType.TypeInfo:
case BamlRecordType.AttributeInfo:
case BamlRecordType.StringInfo:
break;
default:
if (!handlers.ContainsKey(type))
throw new NotSupportedException(type.ToString());
break;
}
#endif
return handlers.ContainsKey(type) ? handlers[type] : null;
}
public static void ProcessChildren(XamlContext ctx, BamlBlockNode node, BamlElement nodeElem) {
ctx.XmlNs.PushScope(nodeElem);
if (nodeElem.Xaml.Element != null)
nodeElem.Xaml.Element.AddAnnotation(ctx.XmlNs.CurrentScope);
foreach (var child in node.Children) {
var handler = LookupHandler(child.Type);
if (handler == null) {
Debug.WriteLine("BAML Handler {0} not implemented.", child.Type);
continue;
}
var elem = handler.Translate(ctx, (BamlNode)child, nodeElem);
if (elem != null) {
nodeElem.Children.Add(elem);
elem.Parent = nodeElem;
}
ctx.CancellationToken.ThrowIfCancellationRequested();
}
ctx.XmlNs.PopScope();
}
}
}

90
ILSpy.BamlDecompiler/ILSpy.BamlDecompiler.csproj

@ -53,38 +53,72 @@ @@ -53,38 +53,72 @@
</ItemGroup>
<ItemGroup>
<Compile Include="BamlElement.cs" />
<Compile Include="BamlResourceNodeFactory.cs" />
<Compile Include="BamlResourceEntryNode.cs" />
<Compile Include="SRMDependencyPropertyDescriptor.cs" />
<Compile Include="CecilType.cs" />
<Compile Include="CecilTypeResolver.cs" />
<Compile Include="ConnectMethodDecompiler.cs" />
<Compile Include="Baml\BamlContext.cs" />
<Compile Include="Baml\BamlDocument.cs" />
<Compile Include="Baml\BamlNode.cs" />
<Compile Include="Baml\BamlReader.cs" />
<Compile Include="Baml\BamlRecords.cs" />
<Compile Include="Baml\BamlWriter.cs" />
<Compile Include="Baml\KnownMembers.cs" />
<Compile Include="Baml\KnownThings.cs" />
<Compile Include="Baml\KnownThings.g.cs" />
<Compile Include="Baml\KnownTypes.cs" />
<Compile Include="BamlConnectionId.cs" />
<Compile Include="Extensions.cs" />
<Compile Include="Handlers\Blocks\ConstructorParametersHandler.cs" />
<Compile Include="Handlers\Blocks\DocumentHandler.cs" />
<Compile Include="Handlers\Blocks\ElementHandler.cs" />
<Compile Include="Handlers\Blocks\KeyElementStartHandler.cs" />
<Compile Include="Handlers\Blocks\PropertyArrayHandler.cs" />
<Compile Include="Handlers\Blocks\PropertyComplexHandler.cs" />
<Compile Include="Handlers\Blocks\PropertyDictionaryHandler.cs" />
<Compile Include="Handlers\Blocks\PropertyListHandler.cs" />
<Compile Include="Handlers\Records\AssemblyInfoHandler.cs" />
<Compile Include="Handlers\Records\AttributeInfoHandler.cs" />
<Compile Include="Handlers\Records\ConnectionIdHandler.cs" />
<Compile Include="Handlers\Records\ConstructorParameterTypeHandler.cs" />
<Compile Include="Handlers\Records\ContentPropertyHandler.cs" />
<Compile Include="Handlers\Records\DefAttributeHandler.cs" />
<Compile Include="Handlers\Records\DefAttributeKeyStringHandler.cs" />
<Compile Include="Handlers\Records\DefAttributeKeyTypeHandler.cs" />
<Compile Include="Handlers\Records\DeferableContentStartHandler.cs" />
<Compile Include="Handlers\Records\LineNumberAndPositionHandler.cs" />
<Compile Include="Handlers\Records\LinePositionHandler.cs" />
<Compile Include="Handlers\Records\LiteralContentHandler.cs" />
<Compile Include="Handlers\Records\OptimizedStaticResourceHandler.cs" />
<Compile Include="Handlers\Records\PIMappingHandler.cs" />
<Compile Include="Handlers\Records\PresentationOptionsAttributeHandler.cs" />
<Compile Include="Handlers\Records\PropertyCustomHandler.cs" />
<Compile Include="Handlers\Records\PropertyHandler.cs" />
<Compile Include="Handlers\Records\PropertyTypeReferenceHandler.cs" />
<Compile Include="Handlers\Records\PropertyWithConverterHandler.cs" />
<Compile Include="Handlers\Records\PropertyWithExtensionHandler.cs" />
<Compile Include="Handlers\Records\PropertyWithStaticResourceIdHandler.cs" />
<Compile Include="Handlers\Records\TextHandler.cs" />
<Compile Include="Handlers\Records\TextWithConverterHandler.cs" />
<Compile Include="Handlers\Records\TypeInfoHandler.cs" />
<Compile Include="Handlers\Records\XmlnsPropertyHandler.cs" />
<Compile Include="IHandlers.cs" />
<Compile Include="IRewritePass.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Ricciolo.StylesExplorer.MarkupReflection\BamlBinaryReader.cs" />
<Compile Include="Ricciolo.StylesExplorer.MarkupReflection\BamlRecordType.cs" />
<Compile Include="Ricciolo.StylesExplorer.MarkupReflection\IDependencyPropertyDescriptor.cs" />
<Compile Include="Ricciolo.StylesExplorer.MarkupReflection\IType.cs" />
<Compile Include="Ricciolo.StylesExplorer.MarkupReflection\ITypeResolver.cs" />
<Compile Include="Ricciolo.StylesExplorer.MarkupReflection\KeyMapping.cs" />
<Compile Include="Ricciolo.StylesExplorer.MarkupReflection\KnownInfo.cs" />
<Compile Include="Ricciolo.StylesExplorer.MarkupReflection\NodesCollection.cs" />
<Compile Include="Ricciolo.StylesExplorer.MarkupReflection\PropertyDeclaration.cs" />
<Compile Include="Ricciolo.StylesExplorer.MarkupReflection\ResourceName.cs" />
<Compile Include="Ricciolo.StylesExplorer.MarkupReflection\TypeDeclaration.cs" />
<Compile Include="Ricciolo.StylesExplorer.MarkupReflection\XmlBamlElement.cs" />
<Compile Include="Ricciolo.StylesExplorer.MarkupReflection\XmlBamlNode.cs" />
<Compile Include="Ricciolo.StylesExplorer.MarkupReflection\XmlBamlProperty.cs" />
<Compile Include="Ricciolo.StylesExplorer.MarkupReflection\XmlBamlPropertyElement.cs" />
<Compile Include="Ricciolo.StylesExplorer.MarkupReflection\XmlBamlReader.cs" />
<Compile Include="Ricciolo.StylesExplorer.MarkupReflection\XmlBamlSimpleProperty.cs" />
<Compile Include="Ricciolo.StylesExplorer.MarkupReflection\XmlBamlText.cs" />
<Compile Include="Ricciolo.StylesExplorer.MarkupReflection\XmlNamespace.cs" />
<Compile Include="Ricciolo.StylesExplorer.MarkupReflection\XmlToClrNamespaceMapping.cs" />
</ItemGroup>
<ItemGroup>
<None Include="Ricciolo.StylesExplorer.MarkupReflection\BAML format.txt" />
<Compile Include="Rewrite\AttributeRewritePass.cs" />
<Compile Include="Rewrite\ConnectionIdRewritePass.cs" />
<Compile Include="Rewrite\DocumentRewritePass.cs" />
<Compile Include="Rewrite\MarkupExtensionRewritePass.cs" />
<Compile Include="Rewrite\XClassRewritePass.cs" />
<Compile Include="XamlContext.cs" />
<Compile Include="XamlDecompiler.cs" />
<Compile Include="Xaml\NamespaceMap.cs" />
<Compile Include="Xaml\XamlExtension.cs" />
<Compile Include="Xaml\XamlPathDeserializer.cs" />
<Compile Include="Xaml\XamlProperty.cs" />
<Compile Include="Xaml\XamlResourceKey.cs" />
<Compile Include="Xaml\XamlType.cs" />
<Compile Include="Xaml\XamlUtils.cs" />
<Compile Include="XmlnsDictionary.cs" />
</ItemGroup>
<Import Sdk="Microsoft.NET.Sdk" Project="Sdk.targets" />

29
ILSpy.BamlDecompiler/IRewritePass.cs

@ -0,0 +1,29 @@ @@ -0,0 +1,29 @@
/*
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;
namespace ILSpy.BamlDecompiler {
internal interface IRewritePass {
void Run(XamlContext ctx, XDocument document);
}
}

79
ILSpy.BamlDecompiler/Rewrite/AttributeRewritePass.cs

@ -0,0 +1,79 @@ @@ -0,0 +1,79 @@
/*
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.Xaml;
namespace ILSpy.BamlDecompiler.Rewrite {
internal class AttributeRewritePass : IRewritePass {
XName key;
public void Run(XamlContext ctx, XDocument document) {
key = ctx.GetXamlNsName("Key");
bool doWork;
do {
doWork = false;
foreach (var elem in document.Elements()) {
doWork |= ProcessElement(ctx, elem);
}
} while (doWork);
}
bool ProcessElement(XamlContext ctx, XElement elem) {
bool doWork = false;
foreach (var child in elem.Elements()) {
doWork |= RewriteElement(ctx, elem, child);
doWork |= ProcessElement(ctx, child);
}
return doWork;
}
bool RewriteElement(XamlContext ctx, XElement parent, XElement elem) {
var property = elem.Annotation<XamlProperty>();
if (property == null && elem.Name != key)
return false;
if (elem.HasAttributes || elem.HasElements)
return false;
ctx.CancellationToken.ThrowIfCancellationRequested();
var value = elem.Value;
var attrName = elem.Name;
if (attrName != key)
attrName = property.ToXName(ctx, parent, property.IsAttachedTo(parent.Annotation<XamlType>()));
var attr = new XAttribute(attrName, value);
var list = new List<XAttribute>(parent.Attributes());
if (attrName == key)
list.Insert(0, attr);
else
list.Add(attr);
parent.RemoveAttributes();
parent.ReplaceAttributes(list);
elem.Remove();
return true;
}
}
}

127
ILSpy.BamlDecompiler/ConnectMethodDecompiler.cs → ILSpy.BamlDecompiler/Rewrite/ConnectionIdRewritePass.cs

@ -1,76 +1,109 @@ @@ -1,76 +1,109 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team
// This code is distributed under the MS-PL (for details please see \doc\MS-PL.txt)
// 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.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection.Metadata;
using System.Threading;
using System.Xml.Linq;
using ICSharpCode.Decompiler.CSharp;
using ICSharpCode.Decompiler.IL;
using ICSharpCode.Decompiler.IL.Transforms;
using ICSharpCode.Decompiler.Metadata;
using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.Decompiler.TypeSystem.Implementation;
using ICSharpCode.Decompiler.Util;
using ICSharpCode.ILSpy;
using Metadata = ICSharpCode.Decompiler.Metadata;
namespace ILSpy.BamlDecompiler
namespace ILSpy.BamlDecompiler.Rewrite
{
/// <summary>
/// Represents an event registration of a XAML code-behind class.
/// </summary>
sealed class EventRegistration
internal class ConnectionIdRewritePass : IRewritePass
{
public string EventName, MethodName;
}
/// <summary>
/// Decompiles event and name mappings of XAML code-behind classes.
/// </summary>
sealed class ConnectMethodDecompiler
{
public List<(LongSet, EventRegistration[])> DecompileEventMappings(Metadata.PEFile module, IAssemblyResolver assemblyResolver,
string fullTypeName, CancellationToken cancellationToken)
static readonly TopLevelTypeName componentConnectorTypeName = new TopLevelTypeName("System.Windows.Markup", "IComponentConnector");
public void Run(XamlContext ctx, XDocument document)
{
var mappings = DecompileEventMappings(ctx, document);
ProcessConnectionIds(document.Root, mappings);
}
static void ProcessConnectionIds(XElement element, List<(LongSet key, EventRegistration[] value)> eventMappings)
{
foreach (var child in element.Elements())
ProcessConnectionIds(child, eventMappings);
foreach (var annotation in element.Annotations<BamlConnectionId>()) {
int index;
if ((index = eventMappings.FindIndex(item => item.key.Contains(annotation.Id))) > -1) {
foreach (var entry in eventMappings[index].value) {
string xmlns = ""; // TODO : implement xmlns resolver!
element.Add(new XAttribute(xmlns + entry.EventName, entry.MethodName));
}
}
}
}
List<(LongSet, EventRegistration[])> DecompileEventMappings(XamlContext ctx, XDocument document)
{
var result = new List<(LongSet, EventRegistration[])>();
var typeSystem = new DecompilerTypeSystem(module, assemblyResolver);
var typeDefinition = typeSystem.FindType(new FullTypeName(fullTypeName)).GetDefinition();
if (typeDefinition == null)
var xClass = document.Root.Elements().First().Attribute(ctx.GetXamlNsName("Class"));
if (xClass == null)
return result;
var type = ctx.TypeSystem.FindType(new FullTypeName(xClass.Value)).GetDefinition();
if (type == null)
return result;
var connectorInterface = ctx.TypeSystem.FindType(componentConnectorTypeName).GetDefinition();
if (connectorInterface == null)
return result;
var connect = connectorInterface.GetMethods(m => m.Name == "Connect").SingleOrDefault();
IMethod method = null;
MethodDefinition metadataEntry = default;
foreach (var m in typeDefinition.GetMethods()) {
if (m.Name == "System.Windows.Markup.IComponentConnector.Connect") {
var module = ctx.TypeSystem.MainModule.PEFile;
foreach (IMethod m in type.Methods) {
if (m.ExplicitlyImplementedInterfaceMembers.Any(md => md.MemberDefinition.Equals(connect))) {
method = m;
metadataEntry = module.Metadata.GetMethodDefinition((MethodDefinitionHandle)method.MetadataToken);
break;
}
}
if (method == null || metadataEntry.RelativeVirtualAddress <= 0)
return result;
var body = module.Reader.GetMethodBody(metadataEntry.RelativeVirtualAddress);
var genericContext = new ICSharpCode.Decompiler.TypeSystem.GenericContext(
var genericContext = new GenericContext(
classTypeParameters: method.DeclaringType?.TypeParameters,
methodTypeParameters: method.TypeParameters);
// decompile method and optimize the switch
var ilReader = new ILReader(typeSystem.MainModule);
var function = ilReader.ReadIL((MethodDefinitionHandle)method.MetadataToken, body, genericContext, cancellationToken);
var ilReader = new ILReader(ctx.TypeSystem.MainModule);
var function = ilReader.ReadIL((MethodDefinitionHandle)method.MetadataToken, body, genericContext, ctx.CancellationToken);
var context = new ILTransformContext(function, typeSystem, null) {
CancellationToken = cancellationToken
var context = new ILTransformContext(function, ctx.TypeSystem, null) {
CancellationToken = ctx.CancellationToken
};
function.RunTransforms(CSharpDecompiler.GetILTransforms(), context);
var block = function.Body.Children.OfType<Block>().First();
var ilSwitch = block.Descendants.OfType<SwitchInstruction>().FirstOrDefault();
if (ilSwitch != null) {
foreach (var section in ilSwitch.Sections) {
var events = FindEvents(section.Body);
@ -90,11 +123,11 @@ namespace ILSpy.BamlDecompiler @@ -90,11 +123,11 @@ namespace ILSpy.BamlDecompiler
}
return result;
}
EventRegistration[] FindEvents(ILInstruction inst)
{
var events = new List<EventRegistration>();
switch (inst) {
case Block b:
foreach (var node in ((Block)inst).Instructions) {
@ -110,23 +143,23 @@ namespace ILSpy.BamlDecompiler @@ -110,23 +143,23 @@ namespace ILSpy.BamlDecompiler
}
return events.ToArray();
}
void FindEvents(ILInstruction inst, List<EventRegistration> events)
{
CallInstruction call = inst as CallInstruction;
if (call == null || call.OpCode == OpCode.NewObj)
return;
string eventName, handlerName;
if (IsAddEvent(call, out eventName, out handlerName) || IsAddAttachedEvent(call, out eventName, out handlerName))
events.Add(new EventRegistration { EventName = eventName, MethodName = handlerName });
}
bool IsAddAttachedEvent(CallInstruction call, out string eventName, out string handlerName)
{
eventName = "";
handlerName = "";
if (call.Arguments.Count == 3) {
var addMethod = call.Method;
if (addMethod.Name != "AddHandler" || addMethod.Parameters.Count != 2)
@ -146,15 +179,15 @@ namespace ILSpy.BamlDecompiler @@ -146,15 +179,15 @@ namespace ILSpy.BamlDecompiler
handlerName = ((IInstructionWithMethodOperand)ldftn).Method.Name;
return true;
}
return false;
}
bool IsAddEvent(CallInstruction call, out string eventName, out string handlerName)
{
eventName = "";
handlerName = "";
if (call.Arguments.Count == 2) {
var addMethod = call.Method;
if (!addMethod.Name.StartsWith("add_", StringComparison.Ordinal) || addMethod.Parameters.Count != 1)
@ -169,7 +202,7 @@ namespace ILSpy.BamlDecompiler @@ -169,7 +202,7 @@ namespace ILSpy.BamlDecompiler
handlerName = ((IInstructionWithMethodOperand)ldftn).Method.Name;
return true;
}
return false;
}
}

44
ILSpy.BamlDecompiler/Rewrite/DocumentRewritePass.cs

@ -0,0 +1,44 @@ @@ -0,0 +1,44 @@
/*
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 System.Linq;
using System.Xml.Linq;
namespace ILSpy.BamlDecompiler.Rewrite {
internal class DocumentRewritePass : IRewritePass {
public void Run(XamlContext ctx, XDocument document) {
foreach (var elem in document.Elements(ctx.GetPseudoName("Document")).ToList()) {
if (elem.Elements().Count() != 1)
continue;
var docElem = elem.Elements().Single();
foreach (var attr in elem.Attributes()) {
Debug.Assert(attr.IsNamespaceDeclaration);
attr.Remove();
docElem.Add(attr);
}
elem.ReplaceWith(docElem);
}
}
}
}

180
ILSpy.BamlDecompiler/Rewrite/MarkupExtensionRewritePass.cs

@ -0,0 +1,180 @@ @@ -0,0 +1,180 @@
/*
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.Linq;
using System.Xml.Linq;
using ILSpy.BamlDecompiler.Xaml;
namespace ILSpy.BamlDecompiler.Rewrite {
internal class MarkupExtensionRewritePass : IRewritePass {
XName key;
XName ctor;
public void Run(XamlContext ctx, XDocument document) {
key = ctx.GetXamlNsName("Key");
ctor = ctx.GetPseudoName("Ctor");
bool doWork;
do {
doWork = false;
foreach (var elem in document.Elements()) {
doWork |= ProcessElement(ctx, elem);
}
} while (doWork);
}
bool ProcessElement(XamlContext ctx, XElement elem) {
bool doWork = false;
foreach (var child in elem.Elements()) {
doWork |= RewriteElement(ctx, elem, child);
doWork |= ProcessElement(ctx, child);
}
return doWork;
}
bool RewriteElement(XamlContext ctx, XElement parent, XElement elem) {
var type = parent.Annotation<XamlType>();
var property = elem.Annotation<XamlProperty>();
if ((property == null || type == null) && elem.Name != key)
return false;
if (elem.Elements().Count() != 1 || elem.Attributes().Any(t => t.Name.Namespace != XNamespace.Xmlns))
return false;
var value = elem.Elements().Single();
if (!CanInlineExt(ctx, value))
return false;
var ext = InlineExtension(ctx, value);
if (ext == null)
return false;
ctx.CancellationToken.ThrowIfCancellationRequested();
var extValue = ext.ToString(ctx, parent);
var attrName = elem.Name;
if (attrName != key)
attrName = property.ToXName(ctx, parent, property.IsAttachedTo(type));
var attr = new XAttribute(attrName, extValue);
var list = new List<XAttribute>(parent.Attributes());
if (attrName == key)
list.Insert(0, attr);
else
list.Add(attr);
parent.RemoveAttributes();
parent.ReplaceAttributes(list);
elem.Remove();
return true;
}
bool CanInlineExt(XamlContext ctx, XElement ctxElement) {
var type = ctxElement.Annotation<XamlType>();
if (type != null && type.ResolvedType != null) {
var typeDef = type.ResolvedType.GetDefinition()?.DirectBaseTypes.FirstOrDefault();
bool isExt = false;
while (typeDef != null) {
if (typeDef.FullName == "System.Windows.Markup.MarkupExtension") {
isExt = true;
break;
}
typeDef = typeDef.DirectBaseTypes.FirstOrDefault();
}
if (!isExt)
return false;
}
else if (ctxElement.Annotation<XamlProperty>() == null &&
ctxElement.Name != ctor)
return false;
foreach (var child in ctxElement.Elements()) {
if (!CanInlineExt(ctx, child))
return false;
}
return true;
}
object InlineObject(XamlContext ctx, XNode obj) {
if (obj is XText)
return ((XText)obj).Value;
else if (obj is XElement)
return InlineExtension(ctx, (XElement)obj);
else
return null;
}
object[] InlineCtor(XamlContext ctx, XElement ctor) {
if (ctor.HasAttributes)
return null;
var args = new List<object>();
foreach (var child in ctor.Nodes()) {
var arg = InlineObject(ctx, child);
if (arg == null)
return null;
args.Add(arg);
}
return args.ToArray();
}
XamlExtension InlineExtension(XamlContext ctx, XElement ctxElement) {
var type = ctxElement.Annotation<XamlType>();
if (type == null)
return null;
var ext = new XamlExtension(type);
foreach (var attr in ctxElement.Attributes().Where(attr => attr.Name.Namespace != XNamespace.Xmlns))
ext.NamedArguments[attr.Name.LocalName] = attr.Value;
foreach (var child in ctxElement.Nodes()) {
var elem = child as XElement;
if (elem == null)
return null;
if (elem.Name == ctor) {
if (ext.Initializer != null)
return null;
var args = InlineCtor(ctx, elem);
if (args == null)
return null;
ext.Initializer = args;
continue;
}
var property = elem.Annotation<XamlProperty>();
if (property == null || elem.Nodes().Count() != 1 ||
elem.Attributes().Any(attr => attr.Name.Namespace != XNamespace.Xmlns))
return null;
var name = property.PropertyName;
var value = InlineObject(ctx, elem.Nodes().Single());
ext.NamedArguments[name] = value;
}
return ext;
}
}
}

62
ILSpy.BamlDecompiler/Rewrite/XClassRewritePass.cs

@ -0,0 +1,62 @@ @@ -0,0 +1,62 @@
/*
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.Linq;
using System.Xml.Linq;
using ILSpy.BamlDecompiler.Xaml;
namespace ILSpy.BamlDecompiler.Rewrite {
internal class XClassRewritePass : IRewritePass {
public void Run(XamlContext ctx, XDocument document) {
foreach (var elem in document.Elements(ctx.GetPseudoName("Document")).Elements())
RewriteClass(ctx, elem);
}
void RewriteClass(XamlContext ctx, XElement elem) {
var type = elem.Annotation<XamlType>();
if (type == null || type.ResolvedType == null)
return;
var typeDef = type.ResolvedType.GetDefinition();
if (typeDef == null || !typeDef.ParentModule.IsMainModule)
return;
var newType = typeDef.DirectBaseTypes.First().GetDefinition();
if (newType == null)
return;
var xamlType = new XamlType(newType.ParentModule, newType.Namespace, newType.Name);
xamlType.ResolveNamespace(elem, ctx);
elem.Name = xamlType.ToXName(ctx);
var attrName = ctx.GetXamlNsName("Class", elem);
var attrs = elem.Attributes().ToList();
if (typeDef.Accessibility != ICSharpCode.Decompiler.TypeSystem.Accessibility.Public) {
var classModifierName = ctx.GetXamlNsName("ClassModifier", elem);
attrs.Insert(0, new XAttribute(classModifierName, "internal"));
}
attrs.Insert(0, new XAttribute(attrName, type.ResolvedType.FullName));
elem.ReplaceAttributes(attrs);
}
}
}

22
ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/BAML format.txt

@ -1,22 +0,0 @@ @@ -1,22 +0,0 @@
BAML format description
A BAML stream consists of a header and sequential records that contain the data.
The Header
The header is 28 bytes long. The first four bytes are a little endian integer containing the length of the preamble in bytes. The preamble is the UTF-16 string "MSBAML", followed by three integers with the value 0x60000.
Record format:
In general a record consists of a type byte and its content. Some records also have a field, following the type byte, containing the remaining length of the record, encoded as 7-bit encoded integer.
Record Types:
DocumentStart (= 0x01):
The document start (after the type byte) is 6 Bytes long. Usually 00 FF FF FF FF 00. These bytes can be safely ignored.
AssemblyInfo (= 0xC1):
The length field is followed by a 2 byte long ID. The ID is followed by a string containing the assembly name.

40
ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/BamlBinaryReader.cs

@ -1,40 +0,0 @@ @@ -1,40 +0,0 @@
// Copyright (c) Cristian Civera (cristian@aspitalia.com)
// This code is distributed under the MS-PL (for details please see \doc\MS-PL.txt)
using System;
using System.IO;
namespace Ricciolo.StylesExplorer.MarkupReflection
{
internal class BamlBinaryReader : BinaryReader
{
public BamlBinaryReader(Stream stream)
: base(stream)
{
}
public virtual double ReadCompressedDouble()
{
byte b = this.ReadByte();
switch (b) {
case 1:
return 0;
case 2:
return 1;
case 3:
return -1;
case 4:
return ReadInt32() * 1E-06;
case 5:
return this.ReadDouble();
default:
throw new BadImageFormatException($"Unexpected byte sequence in ReadCompressedDouble: 0x{b:x}");
}
}
public int ReadCompressedInt32()
{
return base.Read7BitEncodedInt();
}
}
}

68
ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/BamlRecordType.cs

@ -1,68 +0,0 @@ @@ -1,68 +0,0 @@
// Copyright (c) Cristian Civera (cristian@aspitalia.com)
// This code is distributed under the MS-PL (for details please see \doc\MS-PL.txt)
namespace Ricciolo.StylesExplorer.MarkupReflection
{
internal enum BamlRecordType : byte
{
Unknown,
DocumentStart,
DocumentEnd,
ElementStart,
ElementEnd,
Property,
PropertyCustom,
PropertyComplexStart,
PropertyComplexEnd,
PropertyArrayStart,
PropertyArrayEnd,
PropertyListStart,
PropertyListEnd,
PropertyDictionaryStart,
PropertyDictionaryEnd,
LiteralContent,
Text,
TextWithConverter,
RoutedEvent,
ClrEvent,
XmlnsProperty,
XmlAttribute,
ProcessingInstruction,
Comment,
DefTag,
DefAttribute,
EndAttributes,
PIMapping,
AssemblyInfo,
TypeInfo,
TypeSerializerInfo,
AttributeInfo,
StringInfo,
PropertyStringReference,
PropertyTypeReference,
PropertyWithExtension,
PropertyWithConverter,
DeferableContentStart,
DefAttributeKeyString,
DefAttributeKeyType,
KeyElementStart,
KeyElementEnd,
ConstructorParametersStart,
ConstructorParametersEnd,
ConstructorParameterType,
ConnectionId,
ContentProperty,
NamedElementStart,
StaticResourceStart,
StaticResourceEnd,
StaticResourceId,
TextWithId,
PresentationOptionsAttribute,
LineNumberAndPosition,
LinePosition,
OptimizedStaticResource,
PropertyWithStaticResourceId,
LastRecordType
}
}

20
ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/IDependencyPropertyDescriptor.cs

@ -1,20 +0,0 @@ @@ -1,20 +0,0 @@
// Copyright (c) Cristian Civera (cristian@aspitalia.com)
// This code is distributed under the MS-PL (for details please see \doc\MS-PL.txt)
namespace Ricciolo.StylesExplorer.MarkupReflection
{
public interface IDependencyPropertyDescriptor
{
bool IsAttached { get; }
}
public class UnresolvableDependencyPropertyDescriptor : IDependencyPropertyDescriptor
{
public bool IsAttached {
get {
return false;
}
}
}
}

39
ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/IType.cs

@ -1,39 +0,0 @@ @@ -1,39 +0,0 @@
// Copyright (c) Cristian Civera (cristian@aspitalia.com)
// This code is distributed under the MS-PL (for details please see \doc\MS-PL.txt)
namespace Ricciolo.StylesExplorer.MarkupReflection
{
/// <summary>
/// Interface representing a DotNet type
/// </summary>
public interface IDotNetType
{
IDotNetType BaseType { get; }
string AssemblyQualifiedName { get; }
bool IsSubclassOf(IDotNetType type);
bool Equals(IDotNetType type);
}
public class UnresolvableType : IDotNetType
{
public UnresolvableType(string assemblyQualifiedName)
{
this.AssemblyQualifiedName = assemblyQualifiedName;
}
public IDotNetType BaseType => null;
public string AssemblyQualifiedName { get; }
public bool IsSubclassOf(IDotNetType type)
{
return Equals(type);
}
public bool Equals(IDotNetType type)
{
return type is UnresolvableType && type.AssemblyQualifiedName == AssemblyQualifiedName;
}
}
}

14
ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/ITypeResolver.cs

@ -1,14 +0,0 @@ @@ -1,14 +0,0 @@
// Copyright (c) Cristian Civera (cristian@aspitalia.com)
// This code is distributed under the MS-PL (for details please see \doc\MS-PL.txt)
namespace Ricciolo.StylesExplorer.MarkupReflection
{
public interface IDotNetTypeResolver
{
ICSharpCode.Decompiler.Metadata.TargetRuntime RuntimeVersion { get; }
bool IsLocalAssembly(string name);
IDotNetType GetTypeByAssemblyQualifiedName(string name);
IDependencyPropertyDescriptor GetDependencyPropertyDescriptor(string name, IDotNetType ownerType, IDotNetType targetType);
}
}

46
ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/KeyMapping.cs

@ -1,46 +0,0 @@ @@ -1,46 +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.Collections.Generic;
namespace Ricciolo.StylesExplorer.MarkupReflection
{
public class KeyMapping
{
List<object> staticResources;
public List<object> StaticResources {
get { return staticResources; }
}
public bool HasStaticResource(int identifier)
{
return staticResources != null && staticResources.Count > identifier;
}
public string KeyString { get; set; }
public bool Shared { get; set; }
public bool SharedSet { get; set; }
public int Position { get; set; }
public KeyMapping()
{
this.staticResources = new List<object>();
this.Position = -1;
}
public KeyMapping(string key)
{
this.KeyString = key;
this.staticResources = new List<object>();
this.Position = -1;
}
public override string ToString()
{
return '"' + KeyString + '"';
}
}
}

1345
ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/KnownInfo.cs

File diff suppressed because it is too large Load Diff

57
ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/NodesCollection.cs

@ -1,57 +0,0 @@ @@ -1,57 +0,0 @@
// Copyright (c) Cristian Civera (cristian@aspitalia.com)
// This code is distributed under the MS-PL (for details please see \doc\MS-PL.txt)
using System.Collections.Generic;
namespace Ricciolo.StylesExplorer.MarkupReflection
{
class NodesCollection : List<XmlBamlNode>
{
public XmlBamlNode Last
{
get
{
if (this.Count > 0)
{
int i = this.Count - 1;
return this[i];
}
return null;
}
}
public void RemoveLast()
{
if (this.Count > 0)
this.Remove(this.Last);
}
public XmlBamlNode Dequeue()
{
return DequeueInternal(true);
}
public XmlBamlNode Peek()
{
return DequeueInternal(false);
}
XmlBamlNode DequeueInternal(bool remove)
{
if (this.Count > 0)
{
XmlBamlNode node = this[0];
if (remove)
this.RemoveAt(0);
return node;
}
else
return null;
}
public void Enqueue(XmlBamlNode node)
{
this.Add(node);
}
}
}

55
ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/PropertyDeclaration.cs

@ -1,55 +0,0 @@ @@ -1,55 +0,0 @@
// Copyright (c) Cristian Civera (cristian@aspitalia.com)
// This code is distributed under the MS-PL (for details please see \doc\MS-PL.txt)
namespace Ricciolo.StylesExplorer.MarkupReflection
{
internal class PropertyDeclaration
{
private TypeDeclaration declaringType;
private string name;
// Methods
public PropertyDeclaration(string name)
{
this.name = name;
this.declaringType = null;
}
public PropertyDeclaration(string name, TypeDeclaration declaringType)
{
this.name = name;
this.declaringType = declaringType;
}
public override string ToString()
{
if (((this.DeclaringType != null) && (this.DeclaringType.Name == "XmlNamespace")) && ((this.DeclaringType.Namespace == null) && (this.DeclaringType.Assembly == null)))
{
if ((this.Name == null) || (this.Name.Length == 0))
{
return "xmlns";
}
return ("xmlns:" + this.Name);
}
return this.Name;
}
// Properties
public TypeDeclaration DeclaringType
{
get
{
return this.declaringType;
}
}
public string Name
{
get
{
return this.name;
}
}
}
}

29
ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/ResourceName.cs

@ -1,29 +0,0 @@ @@ -1,29 +0,0 @@
// Copyright (c) Cristian Civera (cristian@aspitalia.com)
// This code is distributed under the MS-PL (for details please see \doc\MS-PL.txt)
namespace Ricciolo.StylesExplorer.MarkupReflection
{
public class ResourceName
{
private string name;
public ResourceName(string name)
{
this.name = name;
}
public override string ToString()
{
return this.Name;
}
public string Name
{
get
{
return this.name;
}
}
}
}

167
ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/TypeDeclaration.cs

@ -1,167 +0,0 @@ @@ -1,167 +0,0 @@
// Copyright (c) Cristian Civera (cristian@aspitalia.com)
// This code is distributed under the MS-PL (for details please see \doc\MS-PL.txt)
using System;
namespace Ricciolo.StylesExplorer.MarkupReflection
{
class TypeDeclaration
{
readonly XmlBamlReader reader;
readonly bool _isExtension;
IDotNetType _type;
bool _typeLoaded;
readonly IDotNetTypeResolver resolver;
protected TypeDeclaration(IDotNetTypeResolver resolver)
{
this.resolver = resolver;
}
public TypeDeclaration(IDotNetTypeResolver resolver, string name, string namespaceName, short assemblyId)
: this(null, resolver, name, namespaceName, assemblyId)
{
}
public TypeDeclaration(IDotNetTypeResolver resolver, string name, string enclosingTypeName, string namespaceName, short assemblyId)
: this(null, resolver, name, namespaceName, assemblyId)
{
this.EnclosingTypeName = enclosingTypeName;
}
public TypeDeclaration(IDotNetTypeResolver resolver, string name, string namespaceName, short assemblyId, bool isExtension)
: this(null, resolver, name, namespaceName, assemblyId)
{
_isExtension = isExtension;
}
public TypeDeclaration(XmlBamlReader reader, IDotNetTypeResolver resolver, string name, string namespaceName, short assemblyId)
{
this.reader = reader;
this.resolver = resolver;
this.Name = name;
this.Namespace = namespaceName;
this.AssemblyId = assemblyId;
if (!_isExtension)
_isExtension = name.EndsWith("Extension");
}
public override string ToString()
{
return this.Name;
}
protected virtual string EnclosingTypeName { get; set; }
public bool IsExtension
{
get { return _isExtension; }
}
public virtual string Assembly
{
get {
if (reader != null)
return this.reader.GetAssembly(this.AssemblyId);
else
return KnownInfo.KnownAssemblyTable[this.AssemblyId];
}
}
public virtual short AssemblyId { get; protected set; }
public virtual string Name { get; protected set; }
public IDotNetType Type {
get {
if (!_typeLoaded) {
if (this.Name.Length > 0)
_type = resolver.GetTypeByAssemblyQualifiedName(AssemblyQualifiedName);
_typeLoaded = true;
}
return _type;
}
}
public virtual string Namespace { get; protected set; }
public string FullyQualifiedName {
get { return EnclosingTypeName == null ? string.Format("{0}.{1}", Namespace, Name) : string.Format("{0}.{1}+{2}", Namespace, EnclosingTypeName, Name); }
}
public string AssemblyQualifiedName {
get { return string.Format("{0}, {1}", FullyQualifiedName, Assembly); }
}
public override bool Equals(object obj)
{
TypeDeclaration td = obj as TypeDeclaration;
if (td != null && !(obj is ResolverTypeDeclaration))
return (this.Name == td.Name && this.EnclosingTypeName == td.EnclosingTypeName && this.Namespace == td.Namespace && this.AssemblyId == td.AssemblyId);
return false;
}
public override int GetHashCode()
{
return this.AssemblyId ^ this.Name.GetHashCode() ^ this.EnclosingTypeName.GetHashCode() ^ this.Namespace.GetHashCode();
}
}
class ResolverTypeDeclaration : TypeDeclaration
{
string assembly;
public override short AssemblyId {
get { throw new NotSupportedException(); }
protected set { throw new NotSupportedException(); }
}
public ResolverTypeDeclaration(IDotNetTypeResolver resolver, string assemblyQualifiedName)
: base(resolver)
{
string name, @namespace, assembly;
ParseName(assemblyQualifiedName, out name, out @namespace, out assembly);
Name = name;
Namespace = @namespace;
this.assembly = assembly;
}
void ParseName(string assemblyQualifiedName, out string name, out string @namespace, out string assembly)
{
int bracket = assemblyQualifiedName.LastIndexOf(']');
int commaSeparator = bracket > -1 ? assemblyQualifiedName.IndexOf(", ", bracket) : assemblyQualifiedName.IndexOf(", ");
assembly = "";
if (commaSeparator >= 0) {
assembly = assemblyQualifiedName.Substring(commaSeparator + 2);
assemblyQualifiedName = assemblyQualifiedName.Remove(commaSeparator);
}
int namespaceSeparator = assemblyQualifiedName.LastIndexOf('.');
@namespace = "";
if (namespaceSeparator >= 0) {
@namespace = assemblyQualifiedName.Substring(0, namespaceSeparator);
}
name = assemblyQualifiedName.Substring(namespaceSeparator + 1);
}
public override string Assembly {
get { return assembly; }
}
public override bool Equals(object obj)
{
ResolverTypeDeclaration td = obj as ResolverTypeDeclaration;
if (td != null)
return (this.Name == td.Name && this.EnclosingTypeName == td.EnclosingTypeName && this.Namespace == td.Namespace);
return false;
}
public override int GetHashCode()
{
return this.Name.GetHashCode() ^ this.EnclosingTypeName.GetHashCode() ^ this.Namespace.GetHashCode();
}
}
}

58
ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/XmlBamlElement.cs

@ -1,58 +0,0 @@ @@ -1,58 +0,0 @@
// Copyright (c) Cristian Civera (cristian@aspitalia.com)
// This code is distributed under the MS-PL (for details please see \doc\MS-PL.txt)
using System.Collections.Generic;
using System.Xml;
namespace Ricciolo.StylesExplorer.MarkupReflection
{
class XmlBamlElement : XmlBamlNode
{
public XmlBamlElement()
{
}
public XmlBamlElement(XmlBamlElement parent)
{
this.Parent = parent;
this.Namespaces.AddRange(parent.Namespaces);
}
public List<XmlNamespace> Namespaces { get; } = new List<XmlNamespace>();
public XmlBamlElement Parent { get; }
public TypeDeclaration TypeDeclaration { get; set; }
public override XmlNodeType NodeType {
get { return XmlNodeType.Element; }
}
public long Position { get; set; }
public bool IsImplicit { get; set; }
public override string ToString()
{
return string.Format("Element: {0}", TypeDeclaration.Name);
}
}
class XmlBamlEndElement : XmlBamlElement
{
public XmlBamlEndElement(XmlBamlElement start)
{
this.TypeDeclaration = start.TypeDeclaration;
this.Namespaces.AddRange(start.Namespaces);
}
public override XmlNodeType NodeType {
get { return XmlNodeType.EndElement; }
}
public override string ToString()
{
return string.Format("EndElement: {0}", TypeDeclaration.Name);
}
}
}

19
ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/XmlBamlNode.cs

@ -1,19 +0,0 @@ @@ -1,19 +0,0 @@
// Copyright (c) Cristian Civera (cristian@aspitalia.com)
// This code is distributed under the MS-PL (for details please see \doc\MS-PL.txt)
using System.Collections.Generic;
using System.Xml;
namespace Ricciolo.StylesExplorer.MarkupReflection
{
internal class XmlBamlNode
{
public virtual XmlNodeType NodeType
{
get { return XmlNodeType.None;}
}
}
internal class XmlBamlNodeCollection : List<XmlBamlNode>
{}
}

59
ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/XmlBamlProperty.cs

@ -1,59 +0,0 @@ @@ -1,59 +0,0 @@
// Copyright (c) Cristian Civera (cristian@aspitalia.com)
// This code is distributed under the MS-PL (for details please see \doc\MS-PL.txt)
using System.Collections.Generic;
using System.Xml;
namespace Ricciolo.StylesExplorer.MarkupReflection
{
internal class XmlBamlProperty : XmlBamlNode
{
PropertyType propertyType;
public XmlBamlProperty(XmlBamlElement parent, PropertyType propertyType)
{
this.Parent = parent;
this.propertyType = propertyType;
}
public XmlBamlProperty(XmlBamlElement parent, PropertyType propertyType, PropertyDeclaration propertyDeclaration)
{
this.Parent = parent;
this.PropertyDeclaration = propertyDeclaration;
this.propertyType = propertyType;
}
public override string ToString()
{
return this.PropertyDeclaration.Name;
}
public XmlBamlElement Parent { get; set; }
public PropertyDeclaration PropertyDeclaration { get; set; }
public PropertyType PropertyType {
get { return this.propertyType; }
}
public object Value { get; set; }
public override XmlNodeType NodeType {
get { return XmlNodeType.Attribute; }
}
}
internal enum PropertyType
{
Key,
Value,
Content,
Array,
List,
Dictionary,
Complex
}
internal class XmlBamlPropertyCollection : List<XmlBamlNode>
{ }
}

45
ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/XmlBamlPropertyElement.cs

@ -1,45 +0,0 @@ @@ -1,45 +0,0 @@
// Copyright (c) Cristian Civera (cristian@aspitalia.com)
// This code is distributed under the MS-PL (for details please see \doc\MS-PL.txt)
using System;
namespace Ricciolo.StylesExplorer.MarkupReflection
{
internal class XmlBamlPropertyElement : XmlBamlElement
{
private readonly PropertyType _propertyType;
private PropertyDeclaration propertyDeclaration;
public XmlBamlPropertyElement(PropertyType propertyType, PropertyDeclaration propertyDeclaration)
{
_propertyType = propertyType;
this.propertyDeclaration = propertyDeclaration;
}
public XmlBamlPropertyElement(XmlBamlElement parent, PropertyType propertyType, PropertyDeclaration propertyDeclaration)
: base(parent)
{
_propertyType = propertyType;
this.propertyDeclaration = propertyDeclaration;
this.TypeDeclaration = propertyDeclaration.DeclaringType;
}
public PropertyDeclaration PropertyDeclaration
{
get
{
return this.propertyDeclaration;
}
}
public PropertyType PropertyType
{
get { return _propertyType; }
}
public override string ToString()
{
return String.Format("PropertyElement: {0}.{1}", TypeDeclaration.Name.Replace('+', '.'), PropertyDeclaration.Name);
}
}
}

1738
ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/XmlBamlReader.cs

File diff suppressed because it is too large Load Diff

38
ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/XmlBamlSimpleProperty.cs

@ -1,38 +0,0 @@ @@ -1,38 +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.Xml;
namespace Ricciolo.StylesExplorer.MarkupReflection
{
class XmlBamlSimpleProperty : XmlBamlNode
{
public string NamespaceName { get; private set; }
public string LocalName { get; private set; }
public string Value { get; private set; }
public XmlBamlSimpleProperty(string namespaceName, string localName, string value)
{
if (string.IsNullOrWhiteSpace(namespaceName))
throw new ArgumentException("namespaceName");
if (string.IsNullOrWhiteSpace(localName))
throw new ArgumentException("localName");
if (value == null)
throw new ArgumentNullException("value");
this.NamespaceName = namespaceName;
this.LocalName = localName;
this.Value = value;
}
public override XmlNodeType NodeType {
get { return XmlNodeType.Attribute; }
}
public override string ToString()
{
return string.Format("{{{0}}}{1}=\"{2}\"", NamespaceName, LocalName, Value);
}
}
}

30
ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/XmlBamlText.cs

@ -1,30 +0,0 @@ @@ -1,30 +0,0 @@
// Copyright (c) Cristian Civera (cristian@aspitalia.com)
// This code is distributed under the MS-PL (for details please see \doc\MS-PL.txt)
using System.Xml;
namespace Ricciolo.StylesExplorer.MarkupReflection
{
internal class XmlBamlText : XmlBamlNode
{
private string _text;
public XmlBamlText(string text)
{
_text = text;
}
public string Text
{
get { return _text; }
}
public override System.Xml.XmlNodeType NodeType
{
get
{
return XmlNodeType.Text;
}
}
}
}

41
ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/XmlNamespace.cs

@ -1,41 +0,0 @@ @@ -1,41 +0,0 @@
// Copyright (c) Cristian Civera (cristian@aspitalia.com)
// This code is distributed under the MS-PL (for details please see \doc\MS-PL.txt)
using System;
namespace Ricciolo.StylesExplorer.MarkupReflection
{
public class XmlNamespace
{
public XmlNamespace(string prefix, string ns)
{
Prefix = prefix;
Namespace = ns;
}
public string Prefix { get; }
public string Namespace { get; }
public override bool Equals(object obj)
{
XmlNamespace o = obj as XmlNamespace;
if (o == null)
return false;
return o.Prefix.Equals(Prefix) && o.Namespace.Equals(Namespace);
}
public override int GetHashCode()
{
int hashCode = 0;
unchecked
{
if (Namespace != null)
hashCode += 1000000007 * Namespace.GetHashCode();
if (Prefix != null)
hashCode += 1000000009 * Prefix.GetHashCode();
}
return hashCode;
}
}
}

31
ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/XmlToClrNamespaceMapping.cs

@ -1,31 +0,0 @@ @@ -1,31 +0,0 @@
// Copyright (c) Cristian Civera (cristian@aspitalia.com)
// This code is distributed under the MS-PL (for details please see \doc\MS-PL.txt)
using System;
namespace Ricciolo.StylesExplorer.MarkupReflection
{
/// <summary>
/// Represents a mapping between an XML namespace and a CLR namespace and assembly.
/// </summary>
public class XmlToClrNamespaceMapping
{
public const string XamlNamespace = "http://schemas.microsoft.com/winfx/2006/xaml";
public const string PresentationNamespace = "http://schemas.microsoft.com/winfx/2006/xaml/presentation";
public const string PresentationOptionsNamespace = "http://schemas.microsoft.com/winfx/2006/xaml/presentation/options";
public const string McNamespace = "http://schemas.openxmlformats.org/markup-compatibility/2006";
public XmlToClrNamespaceMapping(string xmlNamespace, short assemblyId, string assemblyName, string clrNamespace)
{
XmlNamespace = xmlNamespace;
AssemblyId = assemblyId;
AssemblyName = assemblyName;
ClrNamespace = clrNamespace;
}
public short AssemblyId { get; }
public string XmlNamespace { get; set; }
public string AssemblyName { get; }
public string ClrNamespace { get; }
}
}

33
ILSpy.BamlDecompiler/SRMDependencyPropertyDescriptor.cs

@ -1,33 +0,0 @@ @@ -1,33 +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 NRTypeDependencyPropertyDescriptor : IDependencyPropertyDescriptor
{
readonly ITypeDefinition typeDefinition;
readonly string member;
public NRTypeDependencyPropertyDescriptor(ITypeDefinition type, string name)
{
this.typeDefinition = type;
this.member = name;
}
public bool IsAttached {
get {
return typeDefinition.GetMethods(m => m.Name == "Get" + member, GetMemberOptions.IgnoreInheritedMembers).Any();
}
}
public override string ToString()
{
return string.Format("[CecilDependencyPropertyDescriptor Member={0}, Type={1}]", member, typeDefinition);
}
}
}

46
ILSpy.BamlDecompiler/Xaml/NamespaceMap.cs

@ -0,0 +1,46 @@ @@ -0,0 +1,46 @@
/*
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 ICSharpCode.Decompiler.TypeSystem;
namespace ILSpy.BamlDecompiler.Xaml {
internal class NamespaceMap {
public string XmlnsPrefix { get; set; }
public IModule Assembly { get; set; }
public string XMLNamespace { get; set; }
public string CLRNamespace { get; set; }
public NamespaceMap(string prefix, IModule asm, string xmlNs)
: this(prefix, asm, xmlNs, null) {
}
public NamespaceMap(string prefix, IModule asm, string xmlNs, string clrNs) {
XmlnsPrefix = prefix;
Assembly = asm ?? throw new ArgumentNullException(nameof(asm));
XMLNamespace = xmlNs;
CLRNamespace = clrNs;
}
public override string ToString() => $"{XmlnsPrefix}:[{Assembly.Name}|{CLRNamespace ?? XMLNamespace}]";
}
}

83
ILSpy.BamlDecompiler/Xaml/XamlExtension.cs

@ -0,0 +1,83 @@ @@ -0,0 +1,83 @@
/*
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.Text;
using System.Xml.Linq;
namespace ILSpy.BamlDecompiler.Xaml {
internal class XamlExtension {
public XamlType ExtensionType { get; }
public object[] Initializer { get; set; }
public IDictionary<string, object> NamedArguments { get; }
public XamlExtension(XamlType type) {
ExtensionType = type;
NamedArguments = new Dictionary<string, object>();
}
static void WriteObject(StringBuilder sb, XamlContext ctx, XElement ctxElement, object value) {
if (value is XamlExtension)
sb.Append(((XamlExtension)value).ToString(ctx, ctxElement));
else
sb.Append(value.ToString());
}
public string ToString(XamlContext ctx, XElement ctxElement) {
var sb = new StringBuilder();
sb.Append('{');
var typeName = ctx.ToString(ctxElement, ExtensionType);
if (typeName.EndsWith("Extension"))
sb.Append(typeName.Substring(0, typeName.Length - 9));
else
sb.Append(typeName);
bool comma = false;
if (Initializer != null && Initializer.Length > 0) {
sb.Append(' ');
for (int i = 0; i < Initializer.Length; i++) {
if (comma)
sb.Append(", ");
WriteObject(sb, ctx, ctxElement, Initializer[i]);
comma = true;
}
}
if (NamedArguments.Count > 0) {
foreach (var kvp in NamedArguments) {
if (comma)
sb.Append(", ");
else {
sb.Append(' ');
comma = true;
}
sb.AppendFormat("{0}=", kvp.Key);
WriteObject(sb, ctx, ctxElement, kvp.Value);
}
}
sb.Append('}');
return sb.ToString();
}
}
}

187
ILSpy.BamlDecompiler/Xaml/XamlPathDeserializer.cs

@ -0,0 +1,187 @@ @@ -0,0 +1,187 @@
/*
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.Globalization;
using System.IO;
using System.Text;
namespace ILSpy.BamlDecompiler.Xaml
{
class XamlPathDeserializer
{
enum PathOpCodes
{
BeginFigure,
LineTo,
QuadraticBezierTo,
BezierTo,
PolyLineTo,
PolyQuadraticBezierTo,
PolyBezierTo,
ArcTo,
Closed,
FillRule
}
readonly struct Point
{
public readonly double X;
public readonly double Y;
public Point(double x, double y)
{
X = x;
Y = y;
}
public override string ToString() => string.Format(CultureInfo.InvariantCulture, "{0:R},{1:R}", X, Y);
}
static void UnpackBools(byte b, out bool b1, out bool b2, out bool b3, out bool b4)
{
b1 = (b & 0x10) != 0;
b2 = (b & 0x20) != 0;
b3 = (b & 0x40) != 0;
b4 = (b & 0x80) != 0;
}
static Point ReadPoint(BinaryReader reader) => new Point(reader.ReadXamlDouble(), reader.ReadXamlDouble());
static void ReadPointBoolBool(BinaryReader reader, byte b, out Point pt, out bool b1, out bool b2)
{
UnpackBools(b, out b1, out b2, out bool sx, out bool sy);
pt = new Point(reader.ReadXamlDouble(sx), reader.ReadXamlDouble(sy));
}
static IList<Point> ReadPointsBoolBool(BinaryReader reader, byte b, out bool b1, out bool b2)
{
UnpackBools(b, out b1, out b2, out bool b3, out bool b4);
var count = reader.ReadInt32();
var pts = new List<Point>();
for (int i = 0; i < count; i++)
pts.Add(ReadPoint(reader));
return pts;
}
public static string Deserialize(BinaryReader reader)
{
bool end = false;
var sb = new StringBuilder();
Point pt1, pt2, pt3;
IList<Point> pts;
while (!end) {
var b = reader.ReadByte();
switch ((PathOpCodes)(b & 0xf)) {
case PathOpCodes.BeginFigure: {
ReadPointBoolBool(reader, b, out pt1, out bool filled, out bool closed);
sb.AppendFormat("M{0} ", pt1);
break;
}
case PathOpCodes.LineTo: {
ReadPointBoolBool(reader, b, out pt1, out bool stroked, out bool smoothJoin);
sb.AppendFormat("L{0} ", pt1);
break;
}
case PathOpCodes.QuadraticBezierTo: {
ReadPointBoolBool(reader, b, out pt1, out bool stroked, out bool smoothJoin);
pt2 = ReadPoint(reader);
sb.AppendFormat("Q{0} {1} ", pt1, pt2);
break;
}
case PathOpCodes.BezierTo: {
ReadPointBoolBool(reader, b, out pt1, out bool stroked, out bool smoothJoin);
pt2 = ReadPoint(reader);
pt3 = ReadPoint(reader);
sb.AppendFormat("C{0} {1} {2} ", pt1, pt2, pt3);
break;
}
case PathOpCodes.PolyLineTo: {
pts = ReadPointsBoolBool(reader, b, out bool stroked, out bool smoothJoin);
sb.Append('L');
foreach (var pt in pts)
sb.AppendFormat("{0} ", pt);
break;
}
case PathOpCodes.PolyQuadraticBezierTo: {
pts = ReadPointsBoolBool(reader, b, out bool stroked, out bool smoothJoin);
sb.Append('Q');
foreach (var pt in pts)
sb.AppendFormat("{0} ", pt);
break;
}
case PathOpCodes.PolyBezierTo: {
pts = ReadPointsBoolBool(reader, b, out bool stroked, out bool smoothJoin);
sb.Append('C');
foreach (var pt in pts)
sb.AppendFormat("{0} ", pt);
break;
}
case PathOpCodes.ArcTo: {
ReadPointBoolBool(reader, b, out pt1, out bool stroked, out bool smoothJoin);
byte b2 = reader.ReadByte();
bool largeArc = (b2 & 0x0f) != 0;
bool sweepDirection = (b2 & 0xf0) != 0;
var size = ReadPoint(reader);
double angle = reader.ReadXamlDouble();
sb.AppendFormat(CultureInfo.InvariantCulture, "A{0} {2:R} {2} {3} {4}",
size, angle, largeArc ? '1' : '0', sweepDirection ? '1' : '0', pt1);
break;
}
case PathOpCodes.Closed:
end = true;
break;
case PathOpCodes.FillRule: {
UnpackBools(b, out bool fillRule, out bool b2, out bool b3, out bool b4);
if (fillRule)
sb.Insert(0, "F1 ");
break;
}
}
}
return sb.ToString().Trim();
}
}
}

95
ILSpy.BamlDecompiler/Xaml/XamlProperty.cs

@ -0,0 +1,95 @@ @@ -0,0 +1,95 @@
/*
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.Linq;
using System.Xml;
using System.Xml.Linq;
using ICSharpCode.Decompiler.TypeSystem;
namespace ILSpy.BamlDecompiler.Xaml {
internal class XamlProperty {
public XamlType DeclaringType { get; }
public string PropertyName { get; }
public IMember ResolvedMember { get; set; }
public XamlProperty(XamlType type, string name) {
DeclaringType = type;
PropertyName = name;
}
public void TryResolve() {
if (ResolvedMember != null)
return;
var typeDef = DeclaringType.ResolvedType.GetDefinition();
if (typeDef == null)
return;
ResolvedMember = typeDef.GetProperties(p => p.Name == PropertyName).FirstOrDefault();
if (ResolvedMember != null)
return;
ResolvedMember = typeDef.GetFields(f => f.Name == PropertyName + "Property").FirstOrDefault();
if (ResolvedMember != null)
return;
ResolvedMember = typeDef.GetEvents(e => e.Name == PropertyName).FirstOrDefault();
if (ResolvedMember != null)
return;
ResolvedMember = typeDef.GetFields(f => f.Name == PropertyName + "Event").FirstOrDefault();
}
public bool IsAttachedTo(XamlType type) {
if (type == null || ResolvedMember == null || type.ResolvedType == null)
return true;
var declType = ResolvedMember.DeclaringType;
var t = type.ResolvedType;
do {
if (t.FullName == declType.FullName && t.TypeParameterCount == declType.TypeParameterCount)
return false;
t = t.DirectBaseTypes.FirstOrDefault();
} while (t != null);
return true;
}
public XName ToXName(XamlContext ctx, XElement parent, bool isFullName = true) {
var typeName = DeclaringType.ToXName(ctx);
XName name;
if (!isFullName)
name = XmlConvert.EncodeLocalName(PropertyName);
else
name = typeName.LocalName + "." + XmlConvert.EncodeLocalName(PropertyName);
if (parent == null || (parent.GetDefaultNamespace() != typeName.Namespace &&
parent.Name.Namespace != typeName.Namespace))
name = typeName.Namespace + name.LocalName;
return name;
}
public override string ToString() => PropertyName;
}
}

98
ILSpy.BamlDecompiler/Xaml/XamlResourceKey.cs

@ -0,0 +1,98 @@ @@ -0,0 +1,98 @@
/*
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.Diagnostics;
using ILSpy.BamlDecompiler.Baml;
namespace ILSpy.BamlDecompiler.Xaml {
internal class XamlResourceKey {
XamlResourceKey(BamlNode node) {
KeyNode = node;
StaticResources = new List<BamlNode>();
IBamlDeferRecord keyRecord;
if (node is BamlBlockNode)
keyRecord = (IBamlDeferRecord)((BamlBlockNode)node).Header;
else
keyRecord = (IBamlDeferRecord)((BamlRecordNode)node).Record;
if (keyRecord.Record.Type == BamlRecordType.ElementEnd) {
Debug.Assert(node.Parent.Footer == keyRecord.Record);
node.Parent.Annotation = this;
node.Annotation = this;
return;
}
if (keyRecord.Record.Type != BamlRecordType.ElementStart && node.Parent.Type == BamlRecordType.ElementStart) {
node.Parent.Annotation = this;
node.Annotation = this;
return;
}
if (keyRecord.Record.Type != BamlRecordType.ElementStart) {
Debug.WriteLine($"Key record @{keyRecord.Position} must be attached to ElementStart (actual {keyRecord.Record.Type})");
}
foreach (var child in node.Parent.Children) {
if (child.Record != keyRecord.Record)
continue;
child.Annotation = this;
node.Annotation = this;
return;
}
Debug.WriteLine("Cannot find corresponding value element of key record @" + keyRecord.Position);
}
public static XamlResourceKey Create(BamlNode node) => new XamlResourceKey(node);
public BamlNode KeyNode { get; set; }
public BamlElement KeyElement { get; set; }
public IList<BamlNode> StaticResources { get; }
public static XamlResourceKey FindKeyInSiblings(BamlNode node) {
var children = node.Parent.Children;
var index = children.IndexOf(node);
for (int i = index; i >= 0; i--) {
if (children[i].Annotation is XamlResourceKey)
return (XamlResourceKey)children[i].Annotation;
}
return null;
}
public static XamlResourceKey FindKeyInAncestors(BamlNode node) => FindKeyInAncestors(node, out var found);
public static XamlResourceKey FindKeyInAncestors(BamlNode node, out BamlNode found) {
BamlNode n = node;
do {
if (n.Annotation is XamlResourceKey) {
found = n;
return (XamlResourceKey)n.Annotation;
}
n = n.Parent;
} while (n != null);
found = null;
return null;
}
}
}

102
ILSpy.BamlDecompiler/Xaml/XamlType.cs

@ -0,0 +1,102 @@ @@ -0,0 +1,102 @@
/*
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;
using System.Xml.Linq;
using ICSharpCode.Decompiler.TypeSystem;
namespace ILSpy.BamlDecompiler.Xaml {
internal class XamlType {
public IModule Assembly { get; }
public string TypeNamespace { get; }
public string TypeName { get; }
public XNamespace Namespace { get; private set; }
public IType ResolvedType { get; set; }
public XamlType(IModule assembly, string ns, string name)
: this(assembly, ns, name, null) {
}
public XamlType(IModule assembly, string ns, string name, XNamespace xmlns) {
Assembly = assembly;
TypeNamespace = ns;
TypeName = name;
Namespace = xmlns;
}
public void ResolveNamespace(XElement elem, XamlContext ctx) {
if (Namespace != null)
return;
// Since XmlnsProperty records are inside the element,
// the namespace is resolved after processing the element body.
string xmlNs = null;
if (elem.Annotation<XmlnsScope>() != null)
xmlNs = elem.Annotation<XmlnsScope>().LookupXmlns(Assembly, TypeNamespace);
if (xmlNs == null)
xmlNs = ctx.XmlNs.LookupXmlns(Assembly, TypeNamespace);
// Sometimes there's no reference to System.Xaml even if x:Type is used
if (xmlNs == null)
xmlNs = ctx.TryGetXmlNamespace(Assembly, TypeNamespace);
if (xmlNs == null) {
if (Assembly.FullAssemblyName == ctx.TypeSystem.MainModule.FullAssemblyName)
xmlNs = $"clr-namespace:{TypeNamespace}";
else
xmlNs = $"clr-namespace:{TypeNamespace};assembly={Assembly.Name}";
var nsSeg = TypeNamespace.Split('.');
var prefix = nsSeg[nsSeg.Length - 1].ToLowerInvariant();
if (string.IsNullOrEmpty(prefix)) {
if (string.IsNullOrEmpty(TypeNamespace))
prefix = "global";
else
prefix = "empty";
}
int count = 0;
var truePrefix = prefix;
XNamespace prefixNs, ns = ctx.GetXmlNamespace(xmlNs);
while ((prefixNs = elem.GetNamespaceOfPrefix(truePrefix)) != null && prefixNs != ns) {
count++;
truePrefix = prefix + count;
}
if (prefixNs == null) {
elem.Add(new XAttribute(XNamespace.Xmlns + XmlConvert.EncodeLocalName(truePrefix), ns));
if (string.IsNullOrEmpty(TypeNamespace))
elem.AddBeforeSelf(new XComment(string.Format("'{0}' is prefix for the global namespace", truePrefix)));
}
}
Namespace = ctx.GetXmlNamespace(xmlNs);
}
public XName ToXName(XamlContext ctx) {
if (Namespace == null)
return XmlConvert.EncodeLocalName(TypeName);
return Namespace + XmlConvert.EncodeLocalName(TypeName);
}
public override string ToString() => TypeName;
}
}

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

Loading…
Cancel
Save