Browse Source

add ConnectMethodDecompiler

pull/252/head
Siegfried Pammer 14 years ago
parent
commit
a75e2a3c96
  1. 38
      ILSpy.BamlDecompiler/BamlResourceEntryNode.cs
  2. 78
      ILSpy.BamlDecompiler/ConnectMethodDecompiler.cs
  3. 1
      ILSpy.BamlDecompiler/ILSpy.BamlDecompiler.csproj
  4. 3
      ILSpy.BamlDecompiler/Tests/Cases/AttachedEvent.xaml
  5. 31
      ILSpy.BamlDecompiler/Tests/Cases/AttachedEvent.xaml.cs
  6. 5
      ILSpy.BamlDecompiler/Tests/ILSpy.BamlDecompiler.Tests.csproj
  7. 6
      ILSpy.BamlDecompiler/Tests/TestRunner.cs
  8. 1
      ILSpy/ILSpy.csproj
  9. 1
      ILSpy/Languages/CSharpLanguage.cs

38
ILSpy.BamlDecompiler/BamlResourceEntryNode.cs

@ -59,11 +59,22 @@ namespace ILSpy.BamlDecompiler @@ -59,11 +59,22 @@ namespace ILSpy.BamlDecompiler
XDocument xamlDocument;
using (XmlBamlReader reader = new XmlBamlReader(stream, new CecilTypeResolver(resolver, asm)))
xamlDocument = XDocument.Load(reader);
ConvertConnectionIds(xamlDocument, asm);
ConvertToEmptyElements(xamlDocument.Root);
MoveNamespacesToRoot(xamlDocument);
return xamlDocument;
}
static void ConvertConnectionIds(XDocument xamlDocument, AssemblyDefinition asm)
{
var attr = xamlDocument.Root.Attribute(XName.Get("Class", XmlBamlReader.XWPFNamespace));
if (attr != null) {
string fullTypeName = attr.Value;
var mappings = new ConnectMethodDecompiler(asm).DecompileEventMappings(fullTypeName);
RemoveConnectionIds(xamlDocument.Root, mappings);
}
}
static void MoveNamespacesToRoot(XDocument xamlDocument)
{
var additionalXmlns = new List<XAttribute> {
@ -98,5 +109,32 @@ namespace ILSpy.BamlDecompiler @@ -98,5 +109,32 @@ namespace ILSpy.BamlDecompiler
ConvertToEmptyElements(el);
}
}
static void RemoveConnectionIds(XElement element, Dictionary<int, EventRegistration[]> 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;
if (int.TryParse(attr.Value, out id) && eventMappings.ContainsKey(id)) {
var map = eventMappings[id];
foreach (var entry in map) {
string xmlns = ""; // TODO : implement xmlns resolver!
if (entry.IsAttached) {
addableAttrs.Add(new XAttribute(xmlns + entry.AttachSourceType.Name + "." + entry.EventName, entry.MethodName));
} else {
addableAttrs.Add(new XAttribute(xmlns + entry.EventName, entry.MethodName));
}
}
removableAttrs.Add(attr);
}
}
foreach (var attr in removableAttrs)
attr.Remove();
element.Add(addableAttrs);
}
}
}

78
ILSpy/ConnectMethodDecompiler.cs → ILSpy.BamlDecompiler/ConnectMethodDecompiler.cs

@ -1,47 +1,34 @@ @@ -1,47 +1,34 @@
// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team
//
// 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.
// 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.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.ILAst;
using Mono.Cecil;
using Mono.Cecil.Cil;
namespace ICSharpCode.ILSpy.Baml
namespace ILSpy.BamlDecompiler
{
[Serializable]
/// <summary>
/// Represents an event registration of a XAML code-behind class.
/// </summary>
sealed class EventRegistration
{
public string EventName, MethodName, AttachSourceType;
public string EventName, MethodName;
public TypeDefinition AttachSourceType;
public bool IsAttached;
}
/// <summary>
/// Description of ConnectMethodDecompiler.
/// Decompiles event and name mappings of XAML code-behind classes.
/// </summary>
sealed class ConnectMethodDecompiler : MarshalByRefObject
sealed class ConnectMethodDecompiler
{
LoadedAssembly assembly;
AssemblyDefinition assembly;
public ConnectMethodDecompiler(LoadedAssembly assembly)
public ConnectMethodDecompiler(AssemblyDefinition assembly)
{
this.assembly = assembly;
}
@ -49,7 +36,7 @@ namespace ICSharpCode.ILSpy.Baml @@ -49,7 +36,7 @@ namespace ICSharpCode.ILSpy.Baml
public Dictionary<int, EventRegistration[]> DecompileEventMappings(string fullTypeName)
{
var result = new Dictionary<int, EventRegistration[]>();
TypeDefinition type = this.assembly.AssemblyDefinition.MainModule.GetType(fullTypeName);
TypeDefinition type = this.assembly.MainModule.GetType(fullTypeName);
if (type == null)
return result;
@ -98,7 +85,8 @@ namespace ICSharpCode.ILSpy.Baml @@ -98,7 +85,8 @@ namespace ICSharpCode.ILSpy.Baml
foreach (var node in block.Body) {
var expr = node as ILExpression;
string eventName, handlerName, attachSource;
string eventName, handlerName;
TypeDefinition attachSource;
if (IsAddEvent(expr, out eventName, out handlerName))
events.Add(new EventRegistration {
EventName = eventName,
@ -116,11 +104,11 @@ namespace ICSharpCode.ILSpy.Baml @@ -116,11 +104,11 @@ namespace ICSharpCode.ILSpy.Baml
return events.ToArray();
}
bool IsAddAttachedEvent(ILExpression expr, out string eventName, out string handlerName, out string attachSource)
bool IsAddAttachedEvent(ILExpression expr, out string eventName, out string handlerName, out TypeDefinition attachSource)
{
eventName = "";
handlerName = "";
attachSource = "";
attachSource = null;
if (expr == null || !(expr.Code == ILCode.Callvirt || expr.Code == ILCode.Call))
return false;
@ -133,7 +121,7 @@ namespace ICSharpCode.ILSpy.Baml @@ -133,7 +121,7 @@ namespace ICSharpCode.ILSpy.Baml
if (arg.Code != ILCode.Ldsfld || arg.Arguments.Any() || !(arg.Operand is FieldReference))
return false;
FieldReference fldRef = (FieldReference)arg.Operand;
attachSource = GetAssemblyQualifiedName(fldRef.DeclaringType);
attachSource = fldRef.DeclaringType.Resolve();
eventName = fldRef.Name;
if (eventName.EndsWith("Event") && eventName.Length > "Event".Length)
eventName = eventName.Remove(eventName.Length - "Event".Length);
@ -153,18 +141,6 @@ namespace ICSharpCode.ILSpy.Baml @@ -153,18 +141,6 @@ namespace ICSharpCode.ILSpy.Baml
return false;
}
string GetAssemblyQualifiedName(TypeReference declaringType)
{
string fullName = declaringType.FullName;
if (declaringType.Scope is AssemblyNameReference)
fullName += ", " + ((AssemblyNameReference)declaringType.Scope).FullName;
else if (declaringType.Scope is ModuleDefinition)
fullName += ", " + ((ModuleDefinition)declaringType.Scope).Assembly.FullName;
return fullName;
}
bool IsAddEvent(ILExpression expr, out string eventName, out string handlerName)
{
eventName = "";
@ -193,20 +169,4 @@ namespace ICSharpCode.ILSpy.Baml @@ -193,20 +169,4 @@ namespace ICSharpCode.ILSpy.Baml
return false;
}
}
sealed class AssemblyResolver : MarshalByRefObject
{
LoadedAssembly assembly;
public AssemblyResolver(LoadedAssembly assembly)
{
this.assembly = assembly;
}
public string FindAssembly(string name)
{
var asm = assembly.LookupReferencedAssembly(name);
return asm == null ? null : asm.FileName;
}
}
}

1
ILSpy.BamlDecompiler/ILSpy.BamlDecompiler.csproj

@ -77,6 +77,7 @@ @@ -77,6 +77,7 @@
<Compile Include="CecilDependencyPropertyDescriptor.cs" />
<Compile Include="CecilType.cs" />
<Compile Include="CecilTypeResolver.cs" />
<Compile Include="ConnectMethodDecompiler.cs" />
<Compile Include="Extensions.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Ricciolo.StylesExplorer.MarkupReflection\AppDomainTypeResolver.cs" />

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

@ -0,0 +1,3 @@ @@ -0,0 +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">
<Grid AccessKeyManager.AccessKeyPressed="GridAccessKeyPressed" />
</Window>

31
ILSpy.BamlDecompiler/Tests/Cases/AttachedEvent.xaml.cs

@ -0,0 +1,31 @@ @@ -0,0 +1,31 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
namespace ILSpy.BamlDecompiler.Tests.Cases
{
/// <summary>
/// Interaction logic for AttachedEvent.xaml
/// </summary>
public partial class AttachedEvent : Window
{
public AttachedEvent()
{
InitializeComponent();
}
void GridAccessKeyPressed(object sender, AccessKeyPressedEventArgs e)
{
throw new NotImplementedException();
}
}
}

5
ILSpy.BamlDecompiler/Tests/ILSpy.BamlDecompiler.Tests.csproj

@ -66,6 +66,10 @@ @@ -66,6 +66,10 @@
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="Cases\AttachedEvent.xaml.cs">
<DependentUpon>AttachedEvent.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
<Compile Include="Cases\Resources.xaml.cs">
<DependentUpon>Resources.xaml</DependentUpon>
<SubType>Code</SubType>
@ -110,6 +114,7 @@ @@ -110,6 +114,7 @@
<Folder Include="Properties" />
</ItemGroup>
<ItemGroup>
<Page Include="Cases\AttachedEvent.xaml" />
<Page Include="Cases\AvalonDockBrushes.xaml" />
<Page Include="Cases\AvalonDockCommon.xaml" />
<Page Include="Cases\Resources.xaml" />

6
ILSpy.BamlDecompiler/Tests/TestRunner.cs

@ -55,6 +55,12 @@ namespace ILSpy.BamlDecompiler.Tests @@ -55,6 +55,12 @@ namespace ILSpy.BamlDecompiler.Tests
RunTest("cases/avalondockcommon");
}
[Test]
public void AttachedEvent()
{
RunTest("cases/attachedevent");
}
#region RunTest
void RunTest(string name)
{

1
ILSpy/ILSpy.csproj

@ -98,7 +98,6 @@ @@ -98,7 +98,6 @@
<Compile Include="CommandLineArguments.cs" />
<Compile Include="Commands\ExitCommand.cs" />
<Compile Include="Commands\CommandWrapper.cs" />
<Compile Include="ConnectMethodDecompiler.cs" />
<Compile Include="Controls\DockedPane.cs" />
<Compile Include="Commands\DecompileAllCommand.cs" />
<Compile Include="DecompilerSettingsPanel.xaml.cs">

1
ILSpy/Languages/CSharpLanguage.cs

@ -31,7 +31,6 @@ using System.Xml; @@ -31,7 +31,6 @@ using System.Xml;
using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.Ast;
using ICSharpCode.Decompiler.Ast.Transforms;
using ICSharpCode.ILSpy.Baml;
using ICSharpCode.ILSpy.XmlDoc;
using ICSharpCode.NRefactory.CSharp;
using Mono.Cecil;

Loading…
Cancel
Save