Browse Source

implement detection of implicit elements and static resources

pull/252/head
Siegfried Pammer 14 years ago
parent
commit
e0932a6860
  1. 11
      ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/BamlBinaryReader.cs
  2. 39
      ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/XmlBamlElement.cs
  3. 129
      ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/XmlBamlReader.cs
  4. 6
      ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/XmlBamlSimpleProperty.cs
  5. 4
      ILSpy.BamlDecompiler/Tests/Cases/Resources.xaml
  6. 2
      ILSpy.BamlDecompiler/Tests/TestRunner.cs

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

@ -17,22 +17,15 @@ namespace Ricciolo.StylesExplorer.MarkupReflection
public virtual double ReadCompressedDouble() public virtual double ReadCompressedDouble()
{ {
switch (this.ReadByte()) switch (this.ReadByte()) {
{
case 1: case 1:
return 0; return 0;
case 2: case 2:
return 1; return 1;
case 3: case 3:
return -1; return -1;
case 4: case 4:
{ return ReadInt32() * 1E-06;
double num = this.ReadInt32();
return (num * 1E-06);
}
case 5: case 5:
return this.ReadDouble(); return this.ReadDouble();
} }

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

@ -9,19 +9,16 @@ using System.Xml;
namespace Ricciolo.StylesExplorer.MarkupReflection namespace Ricciolo.StylesExplorer.MarkupReflection
{ {
internal class XmlBamlElement : XmlBamlNode class XmlBamlElement : XmlBamlNode
{ {
private ArrayList _arguments = new ArrayList(); ArrayList _arguments = new ArrayList();
private XmlNamespaceCollection _namespaces = new XmlNamespaceCollection(); XmlNamespaceCollection _namespaces = new XmlNamespaceCollection();
private TypeDeclaration _typeDeclaration; KeysResourcesCollection _keysResources = new KeysResourcesCollection();
private KeysResourcesCollection _keysResources = new KeysResourcesCollection();
private long _position;
public XmlBamlElement() public XmlBamlElement()
{ {
} }
public XmlBamlElement(XmlBamlElement parent) public XmlBamlElement(XmlBamlElement parent)
{ {
this.Namespaces.AddRange(parent.Namespaces); this.Namespaces.AddRange(parent.Namespaces);
@ -32,31 +29,15 @@ namespace Ricciolo.StylesExplorer.MarkupReflection
get { return _namespaces; } get { return _namespaces; }
} }
public TypeDeclaration TypeDeclaration public TypeDeclaration TypeDeclaration { get; set; }
{
get
{
return this._typeDeclaration;
}
set
{
this._typeDeclaration = value;
}
}
public override XmlNodeType NodeType public override XmlNodeType NodeType {
{ get { return XmlNodeType.Element; }
get
{
return XmlNodeType.Element;
}
} }
public long Position public long Position { get; set; }
{
get { return _position; } public bool IsImplicit { get; set; }
set { _position = value; }
}
public override string ToString() public override string ToString()
{ {

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

@ -26,6 +26,7 @@ namespace Ricciolo.StylesExplorer.MarkupReflection
Dictionary<short, string> stringTable = new Dictionary<short, string>(); Dictionary<short, string> stringTable = new Dictionary<short, string>();
Dictionary<short, TypeDeclaration> typeTable = new Dictionary<short, TypeDeclaration>(); Dictionary<short, TypeDeclaration> typeTable = new Dictionary<short, TypeDeclaration>();
Dictionary<short, PropertyDeclaration> propertyTable = new Dictionary<short, PropertyDeclaration>(); Dictionary<short, PropertyDeclaration> propertyTable = new Dictionary<short, PropertyDeclaration>();
List<TypeDeclaration> staticResources = new List<TypeDeclaration>();
readonly ITypeResolver _resolver; readonly ITypeResolver _resolver;
@ -48,6 +49,8 @@ namespace Ricciolo.StylesExplorer.MarkupReflection
bool isPartialDefKeysClosed = true; bool isPartialDefKeysClosed = true;
bool isDefKeysClosed = true; bool isDefKeysClosed = true;
int currentKey;
int bytesToSkip; int bytesToSkip;
@ -950,8 +953,10 @@ namespace Ricciolo.StylesExplorer.MarkupReflection
{ {
// Guardo se la dichiarazione delle chiavi risulta chiusa // Guardo se la dichiarazione delle chiavi risulta chiusa
// Se è aperta c'è un sotto ResourceDictionary oppure è il root ResourceDictionary // Se è aperta c'è un sotto ResourceDictionary oppure è il root ResourceDictionary
if (isDefKeysClosed) if (isDefKeysClosed) {
currentKey = 0;
keysResources.Push(new KeysResourcesCollection()); keysResources.Push(new KeysResourcesCollection());
}
// Guardo se è stata chiusa la dichiarazione parziale (mediante dichiarazione OptimizedStaticResource) // Guardo se è stata chiusa la dichiarazione parziale (mediante dichiarazione OptimizedStaticResource)
// Si chiude il ciclo di chiavi // Si chiude il ciclo di chiavi
@ -1061,30 +1066,30 @@ namespace Ricciolo.StylesExplorer.MarkupReflection
CloseElement(); CloseElement();
complexPropertyOpened--; complexPropertyOpened--;
// Valuto se contiene tutte extension // // Valuto se contiene tutte extension
int start = nodes.IndexOf(propertyElement) + 1; // int start = nodes.IndexOf(propertyElement) + 1;
IEnumerator enumerator = nodes.GetEnumerator(); // IEnumerator enumerator = nodes.GetEnumerator();
//
int c = 0; // int c = 0;
while (c < start && enumerator.MoveNext()) // while (c < start && enumerator.MoveNext())
c++; // c++;
//
if (IsExtension(enumerator)) // if (IsExtension(enumerator))
{ // {
start--; // start--;
nodes.RemoveAt(start); // nodes.RemoveAt(start);
nodes.RemoveLast(); // nodes.RemoveLast();
//
StringBuilder sb = new StringBuilder(); // StringBuilder sb = new StringBuilder();
FormatElementExtension((XmlBamlElement) nodes[start], sb); // FormatElementExtension((XmlBamlElement) nodes[start], sb);
//
XmlBamlProperty property = // XmlBamlProperty property =
new XmlBamlProperty(PropertyType.Complex, propertyElement.PropertyDeclaration); // new XmlBamlProperty(PropertyType.Complex, propertyElement.PropertyDeclaration);
property.Value = sb.ToString(); // property.Value = sb.ToString();
nodes.Add(property); // nodes.Add(property);
//
return; // return;
} // }
} }
void FormatElementExtension(XmlBamlElement element, StringBuilder sb) void FormatElementExtension(XmlBamlElement element, StringBuilder sb)
@ -1145,24 +1150,22 @@ namespace Ricciolo.StylesExplorer.MarkupReflection
} }
} }
static bool IsExtension(IEnumerator enumerator) bool IsExtension(IEnumerator enumerator)
{ {
bool r = true; while (enumerator.MoveNext()) {
while (enumerator.MoveNext() && r)
{
object node = enumerator.Current; object node = enumerator.Current;
if (node is XmlBamlElement && !(node is XmlBamlEndElement) && !((XmlBamlElement)node).TypeDeclaration.IsExtension) if (node is XmlBamlElement && !(node is XmlBamlEndElement) && !((XmlBamlElement)node).TypeDeclaration.IsExtension)
{ return false;
r = false;
}
} }
return r; return true;
} }
void CloseElement() void CloseElement()
{ {
nodes.Enqueue(new XmlBamlEndElement(elements.Pop())); var e = elements.Pop();
if (!e.IsImplicit)
nodes.Enqueue(new XmlBamlEndElement(e));
} }
void ReadElementStart() void ReadElementStart()
@ -1171,6 +1174,8 @@ namespace Ricciolo.StylesExplorer.MarkupReflection
sbyte flags = reader.ReadSByte(); sbyte flags = reader.ReadSByte();
if (flags < 0 || flags > 3) if (flags < 0 || flags > 3)
throw new NotImplementedException(); throw new NotImplementedException();
Debug.Print("ElementFlags: " + flags);
TypeDeclaration declaration = GetTypeDeclaration(identifier); TypeDeclaration declaration = GetTypeDeclaration(identifier);
XmlBamlElement element; XmlBamlElement element;
@ -1195,10 +1200,11 @@ namespace Ricciolo.StylesExplorer.MarkupReflection
oldDeclaration = declaration; oldDeclaration = declaration;
declaration = GetKnownTypeDeclarationByName(declaration.Type.BaseType.AssemblyQualifiedName); declaration = GetKnownTypeDeclarationByName(declaration.Type.BaseType.AssemblyQualifiedName);
} }
element.TypeDeclaration = declaration; element.TypeDeclaration = declaration;
element.IsImplicit = (flags & 2) == 2;
elements.Push(element); elements.Push(element);
nodes.Enqueue(element); if (!element.IsImplicit)
nodes.Enqueue(element);
if (oldDeclaration != null) { if (oldDeclaration != null) {
nodes.Enqueue(new XmlBamlSimpleProperty(XWPFNamespace, "Class", string.Format("{0}.{1}", oldDeclaration.Namespace, oldDeclaration.Name))); nodes.Enqueue(new XmlBamlSimpleProperty(XWPFNamespace, "Class", string.Format("{0}.{1}", oldDeclaration.Namespace, oldDeclaration.Name)));
@ -1207,15 +1213,15 @@ namespace Ricciolo.StylesExplorer.MarkupReflection
if (parentElement != null && complexPropertyOpened == 0) if (parentElement != null && complexPropertyOpened == 0)
{ {
// Calcolo la posizione dell'elemento rispetto al padre // Calcolo la posizione dell'elemento rispetto al padre
long position = element.Position - parentElement.Position;
KeysResource keysResource = (keysResources.Count > 0) ? keysResources.Peek().First : null; KeysResource keysResource = (keysResources.Count > 0) ? keysResources.Peek().First : null;
if (keysResource != null && keysResource.Keys.HasKey(position)) if (keysResource != null && keysResource.Keys.HasKey(currentKey))
{ {
string key = keysResource.Keys[position]; string key = keysResource.Keys[currentKey];
// Rimuovo la chiave perché è stata usata // Rimuovo la chiave perché è stata usata
keysResource.Keys.Remove(position); // keysResource.Keys.Remove(currentKey);
AddKeyToElement(key); AddKeyToElement(key);
currentKey++;
} }
} }
} }
@ -1330,28 +1336,32 @@ namespace Ricciolo.StylesExplorer.MarkupReflection
} }
} }
static void ReadStaticResourceStart() void ReadStaticResourceStart()
{ {
//short identifier = reader.ReadInt16(); short identifier = reader.ReadInt16();
//byte n = reader.ReadByte(); byte flags = reader.ReadByte();
//TypeDeclaration declaration = this.GetTypeDeclaration(identifier); TypeDeclaration declaration = GetTypeDeclaration(identifier);
//this.staticResourceTable.Add(declaration); staticResources.Add(declaration);
throw new NotImplementedException("StaticResourceStart"); XmlBamlElement element;
if (elements.Any())
element = new XmlBamlElement(elements.Peek());
else
element = new XmlBamlElement();
element.TypeDeclaration = declaration;
elements.Push(element);
nodes.Enqueue(element);
} }
static void ReadStaticResourceEnd() void ReadStaticResourceEnd()
{ {
throw new NotImplementedException("ReadStaticResourceEnd"); CloseElement();
} }
static void ReadStaticResourceId() void ReadStaticResourceId()
{ {
//short identifier = reader.ReadInt16(); short identifier = reader.ReadInt16();
//object staticResource = this.GetStaticResource(identifier); object staticResource = GetStaticResource(identifier);
//TypeDeclaration declaration = this.GetTypeDeclaration(-603);
throw new NotImplementedException("StaticResourceId");
} }
void ReadPresentationOptionsAttribute() void ReadPresentationOptionsAttribute()
@ -1490,7 +1500,7 @@ namespace Ricciolo.StylesExplorer.MarkupReflection
short staticIdentifier = reader.ReadInt16(); short staticIdentifier = reader.ReadInt16();
PropertyDeclaration pd = this.GetPropertyDeclaration(identifier); PropertyDeclaration pd = this.GetPropertyDeclaration(identifier);
object staticResource = this.GetStaticResource(staticIdentifier); object staticResource = GetStaticResource(staticIdentifier);
string prefix = this.LookupPrefix(XmlPIMapping.PresentationNamespace, false); string prefix = this.LookupPrefix(XmlPIMapping.PresentationNamespace, false);
string value = String.Format("{{{0}{1}StaticResource {2}}}", prefix, (String.IsNullOrEmpty(prefix)) ? String.Empty : ":", staticResource); string value = String.Format("{{{0}{1}StaticResource {2}}}", prefix, (String.IsNullOrEmpty(prefix)) ? String.Empty : ":", staticResource);
@ -1518,9 +1528,12 @@ namespace Ricciolo.StylesExplorer.MarkupReflection
return resourceGroup.StaticResources[identifier]; return resourceGroup.StaticResources[identifier];
} }
} }
if (identifier < staticResources.Count)
return staticResources[identifier];
//return "???"; return "???" + identifier +"???";
throw new ArgumentException("Cannot find StaticResource", "identifier"); // throw new ArgumentException("Cannot find StaticResource", "identifier");
} }
void ReadTextWithConverter() void ReadTextWithConverter()

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

@ -30,5 +30,11 @@ namespace Ricciolo.StylesExplorer.MarkupReflection
public override XmlNodeType NodeType { public override XmlNodeType NodeType {
get { return XmlNodeType.Attribute; } get { return XmlNodeType.Attribute; }
} }
public override string ToString()
{
return string.Format("{{{0}}}{1}=\"{2}\"", NamespaceName, LocalName, Value);
}
} }
} }

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

@ -3,13 +3,13 @@
<Canvas> <Canvas>
<FrameworkElement.Resources> <FrameworkElement.Resources>
<ResourceDictionary> <ResourceDictionary>
<BooleanToVisibilityConverter x:Key="b"/> <BooleanToVisibilityConverter x:Key="b" />
</ResourceDictionary> </ResourceDictionary>
</FrameworkElement.Resources> </FrameworkElement.Resources>
</Canvas> </Canvas>
<Canvas> <Canvas>
<FrameworkElement.Resources> <FrameworkElement.Resources>
<BooleanToVisibilityConverter x:Key="b"/> <BooleanToVisibilityConverter x:Key="b" />
</FrameworkElement.Resources> </FrameworkElement.Resources>
</Canvas> </Canvas>
</Grid> </Grid>

2
ILSpy.BamlDecompiler/Tests/TestRunner.cs

@ -31,7 +31,7 @@ namespace ILSpy.BamlDecompiler.Tests
RunTest("cases/simpledictionary"); RunTest("cases/simpledictionary");
} }
[Test, Ignore] [Test]
public void Resources() public void Resources()
{ {
RunTest("cases/resources"); RunTest("cases/resources");

Loading…
Cancel
Save