mirror of https://github.com/icsharpcode/ILSpy.git
118 changed files with 7923 additions and 1135 deletions
@ -0,0 +1,58 @@ |
|||||||
|
// 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.
|
||||||
|
|
||||||
|
using System; |
||||||
|
using ICSharpCode.NRefactory.CSharp; |
||||||
|
using ICSharpCode.NRefactory.PatternMatching; |
||||||
|
using Mono.Cecil; |
||||||
|
|
||||||
|
namespace ICSharpCode.Decompiler.Ast.Transforms |
||||||
|
{ |
||||||
|
/// <summary>
|
||||||
|
/// Transforms decimal constant fields.
|
||||||
|
/// </summary>
|
||||||
|
public class DecimalConstantTransform : DepthFirstAstVisitor<object, object>, IAstTransform |
||||||
|
{ |
||||||
|
static readonly PrimitiveType decimalType = new PrimitiveType("decimal"); |
||||||
|
|
||||||
|
public override object VisitFieldDeclaration(FieldDeclaration fieldDeclaration, object data) |
||||||
|
{ |
||||||
|
const Modifiers staticReadOnly = Modifiers.Static | Modifiers.Readonly; |
||||||
|
if ((fieldDeclaration.Modifiers & staticReadOnly) == staticReadOnly && decimalType.IsMatch(fieldDeclaration.ReturnType)) { |
||||||
|
foreach (var attributeSection in fieldDeclaration.Attributes) { |
||||||
|
foreach (var attribute in attributeSection.Attributes) { |
||||||
|
TypeReference tr = attribute.Type.Annotation<TypeReference>(); |
||||||
|
if (tr != null && tr.Name == "DecimalConstantAttribute" && tr.Namespace == "System.Runtime.CompilerServices") { |
||||||
|
attribute.Remove(); |
||||||
|
if (attributeSection.Attributes.Count == 0) |
||||||
|
attributeSection.Remove(); |
||||||
|
fieldDeclaration.Modifiers = (fieldDeclaration.Modifiers & ~staticReadOnly) | Modifiers.Const; |
||||||
|
return null; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
return null; |
||||||
|
} |
||||||
|
|
||||||
|
public void Run(AstNode compilationUnit) |
||||||
|
{ |
||||||
|
compilationUnit.AcceptVisitor(this, null); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,75 @@ |
|||||||
|
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||||
|
// This code is distributed under MIT X11 license (for details please see \doc\license.txt)
|
||||||
|
|
||||||
|
using System; |
||||||
|
|
||||||
|
public static class CustomShortCircuitOperators |
||||||
|
{ |
||||||
|
private class B |
||||||
|
{ |
||||||
|
public static bool operator true(CustomShortCircuitOperators.B x) |
||||||
|
{ |
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
public static bool operator false(CustomShortCircuitOperators.B x) |
||||||
|
{ |
||||||
|
return false; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private class C : CustomShortCircuitOperators.B |
||||||
|
{ |
||||||
|
public static CustomShortCircuitOperators.C operator &(CustomShortCircuitOperators.C x, CustomShortCircuitOperators.C y) |
||||||
|
{ |
||||||
|
return null; |
||||||
|
} |
||||||
|
|
||||||
|
public static CustomShortCircuitOperators.C operator |(CustomShortCircuitOperators.C x, CustomShortCircuitOperators.C y) |
||||||
|
{ |
||||||
|
return null; |
||||||
|
} |
||||||
|
|
||||||
|
public static bool operator !(CustomShortCircuitOperators.C x) |
||||||
|
{ |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
private static void Main() |
||||||
|
{ |
||||||
|
CustomShortCircuitOperators.C c = new CustomShortCircuitOperators.C(); |
||||||
|
CustomShortCircuitOperators.C c2 = new CustomShortCircuitOperators.C(); |
||||||
|
CustomShortCircuitOperators.C c3 = c && c2; |
||||||
|
CustomShortCircuitOperators.C c4 = c || c2; |
||||||
|
Console.WriteLine(c3.ToString()); |
||||||
|
Console.WriteLine(c4.ToString()); |
||||||
|
} |
||||||
|
|
||||||
|
private static void Test2() |
||||||
|
{ |
||||||
|
CustomShortCircuitOperators.C c = new CustomShortCircuitOperators.C(); |
||||||
|
if (c && c) |
||||||
|
{ |
||||||
|
Console.WriteLine(c.ToString()); |
||||||
|
} |
||||||
|
|
||||||
|
if (!(c && c)) |
||||||
|
{ |
||||||
|
Console.WriteLine(c.ToString()); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private static void Test3() |
||||||
|
{ |
||||||
|
CustomShortCircuitOperators.C c = new CustomShortCircuitOperators.C(); |
||||||
|
if (c) |
||||||
|
{ |
||||||
|
Console.WriteLine(c.ToString()); |
||||||
|
} |
||||||
|
if (!c) |
||||||
|
{ |
||||||
|
Console.WriteLine(c.ToString()); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,87 @@ |
|||||||
|
// 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.
|
||||||
|
|
||||||
|
using System; |
||||||
|
using System.Runtime.InteropServices; |
||||||
|
|
||||||
|
// P/Invoke and marshalling attribute tests
|
||||||
|
public class PInvoke |
||||||
|
{ |
||||||
|
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode, Pack = 2)] |
||||||
|
public struct MarshalAsTest |
||||||
|
{ |
||||||
|
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)] |
||||||
|
public uint[] FixedArray; |
||||||
|
|
||||||
|
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4, ArraySubType = UnmanagedType.Bool)] |
||||||
|
public int[] FixedBoolArray; |
||||||
|
|
||||||
|
[MarshalAs(UnmanagedType.SafeArray, SafeArraySubType = VarEnum.VT_BSTR)] |
||||||
|
public string[] SafeBStrArray; |
||||||
|
|
||||||
|
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 8)] |
||||||
|
public string FixedString; |
||||||
|
} |
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Explicit)] |
||||||
|
public struct Rect |
||||||
|
{ |
||||||
|
[FieldOffset(0)] |
||||||
|
public int left; |
||||||
|
[FieldOffset(4)] |
||||||
|
public int top; |
||||||
|
[FieldOffset(8)] |
||||||
|
public int right; |
||||||
|
[FieldOffset(12)] |
||||||
|
public int bottom; |
||||||
|
} |
||||||
|
|
||||||
|
public static decimal MarshalAttributesOnPropertyAccessors |
||||||
|
{ |
||||||
|
[return: MarshalAs(UnmanagedType.Currency)] |
||||||
|
get |
||||||
|
{ |
||||||
|
return 0m; |
||||||
|
} |
||||||
|
[param: MarshalAs(UnmanagedType.Currency)] |
||||||
|
set |
||||||
|
{ |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
[DllImport("xyz.dll", CharSet = CharSet.Auto)] |
||||||
|
[return: MarshalAs(UnmanagedType.Bool)] |
||||||
|
public static extern bool Method([MarshalAs(UnmanagedType.LPStr)] string input); |
||||||
|
|
||||||
|
[DllImport("xyz.dll")] |
||||||
|
private static extern void New1(int ElemCnt, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] int[] ar); |
||||||
|
|
||||||
|
[DllImport("xyz.dll")] |
||||||
|
private static extern void New2([MarshalAs(UnmanagedType.LPArray, SizeConst = 128)] int[] ar); |
||||||
|
|
||||||
|
[DllImport("xyz.dll")] |
||||||
|
private static extern void New3([MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.Bool, SizeConst = 64, SizeParamIndex = 1)] int[] ar); |
||||||
|
|
||||||
|
public void CustomMarshal1([MarshalAs(UnmanagedType.CustomMarshaler, MarshalType = "MyCompany.MyMarshaler")] object o) |
||||||
|
{ |
||||||
|
} |
||||||
|
|
||||||
|
public void CustomMarshal2([MarshalAs(UnmanagedType.CustomMarshaler, MarshalType = "MyCompany.MyMarshaler", MarshalCookie = "Cookie")] object o) |
||||||
|
{ |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,61 @@ |
|||||||
|
// 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.IO; |
||||||
|
using System.Linq; |
||||||
|
using System.Threading.Tasks; |
||||||
|
using System.Xml.Linq; |
||||||
|
|
||||||
|
using ICSharpCode.AvalonEdit.Highlighting; |
||||||
|
using ICSharpCode.ILSpy.TextView; |
||||||
|
using ICSharpCode.ILSpy.TreeNodes; |
||||||
|
using Ricciolo.StylesExplorer.MarkupReflection; |
||||||
|
|
||||||
|
namespace ILSpy.BamlDecompiler |
||||||
|
{ |
||||||
|
public sealed class BamlResourceEntryNode : ResourceEntryNode |
||||||
|
{ |
||||||
|
public BamlResourceEntryNode(string key, Stream data) : base(key, data) |
||||||
|
{ |
||||||
|
} |
||||||
|
|
||||||
|
public override bool View(DecompilerTextView textView) |
||||||
|
{ |
||||||
|
AvalonEditTextOutput output = new AvalonEditTextOutput(); |
||||||
|
IHighlightingDefinition highlighting = null; |
||||||
|
|
||||||
|
textView.RunWithCancellation( |
||||||
|
token => Task.Factory.StartNew( |
||||||
|
() => { |
||||||
|
try { |
||||||
|
if (LoadBaml(output)) |
||||||
|
highlighting = HighlightingManager.Instance.GetDefinitionByExtension(".xml"); |
||||||
|
} catch (Exception ex) { |
||||||
|
output.Write(ex.ToString()); |
||||||
|
} |
||||||
|
return output; |
||||||
|
}), |
||||||
|
t => textView.ShowNode(t.Result, this, highlighting) |
||||||
|
); |
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
bool LoadBaml(AvalonEditTextOutput output) |
||||||
|
{ |
||||||
|
var asm = this.Ancestors().OfType<AssemblyTreeNode>().FirstOrDefault().LoadedAssembly; |
||||||
|
MemoryStream bamlStream = new MemoryStream(); |
||||||
|
Data.Position = 0; |
||||||
|
Data.CopyTo(bamlStream); |
||||||
|
bamlStream.Position = 0; |
||||||
|
|
||||||
|
XDocument xamlDocument; |
||||||
|
using (XmlBamlReader reader = new XmlBamlReader(bamlStream)) |
||||||
|
xamlDocument = XDocument.Load(reader); |
||||||
|
|
||||||
|
output.Write(xamlDocument.ToString()); |
||||||
|
return true; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,29 @@ |
|||||||
|
// 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.ComponentModel.Composition; |
||||||
|
using System.IO; |
||||||
|
|
||||||
|
using ICSharpCode.ILSpy.TreeNodes; |
||||||
|
|
||||||
|
namespace ILSpy.BamlDecompiler |
||||||
|
{ |
||||||
|
[Export(typeof(IResourceNodeFactory))] |
||||||
|
public sealed class BamlResourceNodeFactory : IResourceNodeFactory |
||||||
|
{ |
||||||
|
public ILSpyTreeNode CreateNode(Mono.Cecil.Resource resource) |
||||||
|
{ |
||||||
|
return null; |
||||||
|
} |
||||||
|
|
||||||
|
public ILSpyTreeNode CreateNode(string key, Stream data) |
||||||
|
{ |
||||||
|
if (key.EndsWith(".baml", StringComparison.OrdinalIgnoreCase)) |
||||||
|
return new BamlResourceEntryNode(key, data); |
||||||
|
else |
||||||
|
return null; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,124 @@ |
|||||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||||
|
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" DefaultTargets="Build"> |
||||||
|
<PropertyGroup> |
||||||
|
<ProjectGuid>{A6BAD2BA-76BA-461C-8B6D-418607591247}</ProjectGuid> |
||||||
|
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> |
||||||
|
<Platform Condition=" '$(Platform)' == '' ">x86</Platform> |
||||||
|
<OutputType>Library</OutputType> |
||||||
|
<RootNamespace>ILSpy.BamlDecompiler</RootNamespace> |
||||||
|
<AssemblyName>ILSpy.BamlDecompiler.Plugin</AssemblyName> |
||||||
|
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion> |
||||||
|
<TargetFrameworkProfile>Client</TargetFrameworkProfile> |
||||||
|
<AppDesignerFolder>Properties</AppDesignerFolder> |
||||||
|
<AllowUnsafeBlocks>False</AllowUnsafeBlocks> |
||||||
|
<NoStdLib>False</NoStdLib> |
||||||
|
<WarningLevel>4</WarningLevel> |
||||||
|
<TreatWarningsAsErrors>false</TreatWarningsAsErrors> |
||||||
|
</PropertyGroup> |
||||||
|
<PropertyGroup Condition=" '$(Platform)' == 'x86' "> |
||||||
|
<PlatformTarget>x86</PlatformTarget> |
||||||
|
<RegisterForComInterop>False</RegisterForComInterop> |
||||||
|
<GenerateSerializationAssemblies>Auto</GenerateSerializationAssemblies> |
||||||
|
<BaseAddress>4194304</BaseAddress> |
||||||
|
<FileAlignment>4096</FileAlignment> |
||||||
|
</PropertyGroup> |
||||||
|
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' "> |
||||||
|
<OutputPath>..\ILSpy\bin\Debug\</OutputPath> |
||||||
|
<DebugSymbols>true</DebugSymbols> |
||||||
|
<DebugType>Full</DebugType> |
||||||
|
<Optimize>False</Optimize> |
||||||
|
<CheckForOverflowUnderflow>True</CheckForOverflowUnderflow> |
||||||
|
<DefineConstants>DEBUG;TRACE</DefineConstants> |
||||||
|
</PropertyGroup> |
||||||
|
<PropertyGroup Condition=" '$(Configuration)' == 'Release' "> |
||||||
|
<OutputPath>..\ILSpy\bin\Release\</OutputPath> |
||||||
|
<DebugSymbols>false</DebugSymbols> |
||||||
|
<DebugType>None</DebugType> |
||||||
|
<Optimize>True</Optimize> |
||||||
|
<CheckForOverflowUnderflow>False</CheckForOverflowUnderflow> |
||||||
|
<DefineConstants>TRACE</DefineConstants> |
||||||
|
</PropertyGroup> |
||||||
|
<ItemGroup> |
||||||
|
<Reference Include="PresentationCore"> |
||||||
|
<RequiredTargetFramework>3.0</RequiredTargetFramework> |
||||||
|
</Reference> |
||||||
|
<Reference Include="PresentationFramework"> |
||||||
|
<RequiredTargetFramework>3.0</RequiredTargetFramework> |
||||||
|
</Reference> |
||||||
|
<Reference Include="System" /> |
||||||
|
<Reference Include="System.ComponentModel.Composition"> |
||||||
|
<RequiredTargetFramework>4.0</RequiredTargetFramework> |
||||||
|
</Reference> |
||||||
|
<Reference Include="System.Core"> |
||||||
|
<RequiredTargetFramework>3.5</RequiredTargetFramework> |
||||||
|
</Reference> |
||||||
|
<Reference Include="System.Xaml"> |
||||||
|
<RequiredTargetFramework>4.0</RequiredTargetFramework> |
||||||
|
</Reference> |
||||||
|
<Reference Include="System.Xml" /> |
||||||
|
<Reference Include="System.Xml.Linq"> |
||||||
|
<RequiredTargetFramework>3.5</RequiredTargetFramework> |
||||||
|
</Reference> |
||||||
|
<Reference Include="WindowsBase"> |
||||||
|
<RequiredTargetFramework>3.0</RequiredTargetFramework> |
||||||
|
</Reference> |
||||||
|
</ItemGroup> |
||||||
|
<ItemGroup> |
||||||
|
<Compile Include="BamlResourceNodeFactory.cs" /> |
||||||
|
<Compile Include="BamlResourceEntryNode.cs" /> |
||||||
|
<Compile Include="Properties\AssemblyInfo.cs" /> |
||||||
|
<Compile Include="Ricciolo.StylesExplorer.MarkupReflection\AppDomainTypeResolver.cs" /> |
||||||
|
<Compile Include="Ricciolo.StylesExplorer.MarkupReflection\BamlAssembly.cs" /> |
||||||
|
<Compile Include="Ricciolo.StylesExplorer.MarkupReflection\BamlBinaryReader.cs" /> |
||||||
|
<Compile Include="Ricciolo.StylesExplorer.MarkupReflection\BamlFile.cs" /> |
||||||
|
<Compile Include="Ricciolo.StylesExplorer.MarkupReflection\BamlRecordType.cs" /> |
||||||
|
<Compile Include="Ricciolo.StylesExplorer.MarkupReflection\DotNetType.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\KnownInfo.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\WpfDependencyPropertyDescriptor.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\XmlBamlText.cs" /> |
||||||
|
<Compile Include="Ricciolo.StylesExplorer.MarkupReflection\XmlNamespace.cs" /> |
||||||
|
<Compile Include="Ricciolo.StylesExplorer.MarkupReflection\XmlPIMapping.cs" /> |
||||||
|
</ItemGroup> |
||||||
|
<ItemGroup> |
||||||
|
<Folder Include="Ricciolo.StylesExplorer.MarkupReflection" /> |
||||||
|
</ItemGroup> |
||||||
|
<ItemGroup> |
||||||
|
<ProjectReference Include="..\AvalonEdit\ICSharpCode.AvalonEdit\ICSharpCode.AvalonEdit.csproj"> |
||||||
|
<Project>{6C55B776-26D4-4DB3-A6AB-87E783B2F3D1}</Project> |
||||||
|
<Name>ICSharpCode.AvalonEdit</Name> |
||||||
|
<Private>False</Private> |
||||||
|
</ProjectReference> |
||||||
|
<ProjectReference Include="..\ICSharpCode.Decompiler\ICSharpCode.Decompiler.csproj"> |
||||||
|
<Project>{984CC812-9470-4A13-AFF9-CC44068D666C}</Project> |
||||||
|
<Name>ICSharpCode.Decompiler</Name> |
||||||
|
<Private>False</Private> |
||||||
|
</ProjectReference> |
||||||
|
<ProjectReference Include="..\ILSpy\ILSpy.csproj"> |
||||||
|
<Project>{1E85EFF9-E370-4683-83E4-8A3D063FF791}</Project> |
||||||
|
<Name>ILSpy</Name> |
||||||
|
<Private>False</Private> |
||||||
|
</ProjectReference> |
||||||
|
<ProjectReference Include="..\Mono.Cecil\Mono.Cecil.csproj"> |
||||||
|
<Project>{D68133BD-1E63-496E-9EDE-4FBDBF77B486}</Project> |
||||||
|
<Name>Mono.Cecil</Name> |
||||||
|
<Private>False</Private> |
||||||
|
</ProjectReference> |
||||||
|
<ProjectReference Include="..\SharpTreeView\ICSharpCode.TreeView.csproj"> |
||||||
|
<Project>{DDE2A481-8271-4EAC-A330-8FA6A38D13D1}</Project> |
||||||
|
<Name>ICSharpCode.TreeView</Name> |
||||||
|
<Private>False</Private> |
||||||
|
</ProjectReference> |
||||||
|
</ItemGroup> |
||||||
|
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.Targets" /> |
||||||
|
</Project> |
@ -0,0 +1,31 @@ |
|||||||
|
#region Using directives
|
||||||
|
|
||||||
|
using System; |
||||||
|
using System.Reflection; |
||||||
|
using System.Runtime.InteropServices; |
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
// General Information about an assembly is controlled through the following
|
||||||
|
// set of attributes. Change these attribute values to modify the information
|
||||||
|
// associated with an assembly.
|
||||||
|
[assembly: AssemblyTitle("ILSpy.BamlDecompiler.Plugin")] |
||||||
|
[assembly: AssemblyDescription("")] |
||||||
|
[assembly: AssemblyConfiguration("")] |
||||||
|
[assembly: AssemblyCompany("")] |
||||||
|
[assembly: AssemblyProduct("ILSpy.BamlDecompiler.Plugin")] |
||||||
|
[assembly: AssemblyCopyright("Copyright 2011")] |
||||||
|
[assembly: AssemblyTrademark("")] |
||||||
|
[assembly: AssemblyCulture("")] |
||||||
|
|
||||||
|
// This sets the default COM visibility of types in the assembly to invisible.
|
||||||
|
// If you need to expose a type to COM, use [ComVisible(true)] on that type.
|
||||||
|
[assembly: ComVisible(false)] |
||||||
|
|
||||||
|
// The assembly version has following format :
|
||||||
|
//
|
||||||
|
// Major.Minor.Build.Revision
|
||||||
|
//
|
||||||
|
// You can specify all the values or you can use the default the Revision and
|
||||||
|
// Build Numbers by using the '*' as shown below:
|
||||||
|
[assembly: AssemblyVersion("1.0.*")] |
@ -0,0 +1,172 @@ |
|||||||
|
// 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.Collections.Generic; |
||||||
|
using System.ComponentModel; |
||||||
|
using System.Reflection; |
||||||
|
using System.Text; |
||||||
|
using System.IO; |
||||||
|
using System.Linq; |
||||||
|
using Microsoft.Win32; |
||||||
|
using System.Threading; |
||||||
|
using System.Security.Permissions; |
||||||
|
using System.Security; |
||||||
|
|
||||||
|
namespace Ricciolo.StylesExplorer.MarkupReflection |
||||||
|
{ |
||||||
|
public delegate void AssemblyResolveEventHandler(object s, AssemblyResolveEventArgs e); |
||||||
|
|
||||||
|
public class AppDomainTypeResolver : MarshalByRefObject, ITypeResolver |
||||||
|
{ |
||||||
|
private readonly AppDomain _domain; |
||||||
|
private string baseDir; |
||||||
|
|
||||||
|
public event AssemblyResolveEventHandler AssemblyResolve; |
||||||
|
|
||||||
|
public static AppDomainTypeResolver GetIntoNewAppDomain(string baseDir) |
||||||
|
{ |
||||||
|
AppDomainSetup info = new AppDomainSetup(); |
||||||
|
info.ApplicationBase = Environment.CurrentDirectory; |
||||||
|
AppDomain domain = AppDomain.CreateDomain("AppDomainTypeResolver", null, info, new PermissionSet(PermissionState.Unrestricted)); |
||||||
|
AppDomainTypeResolver resolver = (AppDomainTypeResolver)domain.CreateInstanceAndUnwrap(typeof(AppDomainTypeResolver).Assembly.FullName, |
||||||
|
typeof(AppDomainTypeResolver).FullName, false, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.CreateInstance, null, new object[] { domain, baseDir }, null, null, null); |
||||||
|
|
||||||
|
return resolver; |
||||||
|
} |
||||||
|
|
||||||
|
Assembly domain_AssemblyResolve(object sender, ResolveEventArgs args) |
||||||
|
{ |
||||||
|
// Cerco di risolvere automaticamente
|
||||||
|
AssemblyName name = new AssemblyName(args.Name); |
||||||
|
string fileName = Path.Combine(this.baseDir, name.Name + ".exe"); |
||||||
|
if (!File.Exists(fileName)) |
||||||
|
fileName = Path.Combine(this.baseDir, name.Name + ".dll"); |
||||||
|
|
||||||
|
// Carico il percorso autocalcolato
|
||||||
|
if (File.Exists(fileName)) |
||||||
|
return Assembly.LoadFile(fileName); |
||||||
|
|
||||||
|
if (AssemblyResolve != null) |
||||||
|
{ |
||||||
|
AssemblyResolveEventArgs e = new AssemblyResolveEventArgs(args.Name, this.baseDir); |
||||||
|
AssemblyResolve(this, e); |
||||||
|
if (!String.IsNullOrEmpty(e.Location) && File.Exists(e.Location)) |
||||||
|
return Assembly.LoadFile(e.Location); |
||||||
|
} |
||||||
|
|
||||||
|
return null; |
||||||
|
} |
||||||
|
|
||||||
|
public static void DestroyResolver(AppDomainTypeResolver resolver) |
||||||
|
{ |
||||||
|
if (resolver == null) throw new ArgumentNullException("resolver"); |
||||||
|
|
||||||
|
ThreadPool.QueueUserWorkItem(delegate |
||||||
|
{ |
||||||
|
AppDomain.Unload(resolver.Domain); |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
protected AppDomainTypeResolver(AppDomain domain, string baseDir) |
||||||
|
{ |
||||||
|
_domain = domain; |
||||||
|
this.baseDir = baseDir; |
||||||
|
|
||||||
|
domain.AssemblyResolve += new ResolveEventHandler(domain_AssemblyResolve); |
||||||
|
} |
||||||
|
|
||||||
|
public BamlAssembly LoadAssembly(AssemblyName asm) |
||||||
|
{ |
||||||
|
//return new BamlAssembly(Assembly.Load(asm));
|
||||||
|
return new BamlAssembly(_domain.Load(asm)); |
||||||
|
} |
||||||
|
|
||||||
|
public BamlAssembly LoadAssembly(string location) |
||||||
|
{ |
||||||
|
Assembly asm = Assembly.LoadFile(location); |
||||||
|
return new BamlAssembly(asm); |
||||||
|
//return _domain.Load(System.IO.File.ReadAllBytes(location));
|
||||||
|
//return Assembly.LoadFrom(location);
|
||||||
|
} |
||||||
|
|
||||||
|
public BamlAssembly[] GetReferencedAssemblies(BamlAssembly asm) |
||||||
|
{ |
||||||
|
AssemblyName[] list = asm.Assembly.GetReferencedAssemblies(); |
||||||
|
|
||||||
|
return (from an in list |
||||||
|
select this.LoadAssembly(an)).ToArray(); |
||||||
|
} |
||||||
|
|
||||||
|
public AppDomain Domain |
||||||
|
{ |
||||||
|
get { return _domain; } |
||||||
|
} |
||||||
|
|
||||||
|
#region ITypeResolver Members
|
||||||
|
|
||||||
|
public IType GetTypeByAssemblyQualifiedName(string name) |
||||||
|
{ |
||||||
|
return new DotNetType(name); |
||||||
|
} |
||||||
|
|
||||||
|
public IDependencyPropertyDescriptor GetDependencyPropertyDescriptor(string name, IType ownerType, IType targetType) |
||||||
|
{ |
||||||
|
if (name == null) throw new ArgumentNullException("name"); |
||||||
|
if (ownerType == null) throw new ArgumentNullException("ownerType"); |
||||||
|
if (targetType == null) throw new ArgumentNullException("targetType"); |
||||||
|
|
||||||
|
Type dOwnerType = ((DotNetType)ownerType).Type; |
||||||
|
Type dTargetType = ((DotNetType)targetType).Type; |
||||||
|
|
||||||
|
try |
||||||
|
{ |
||||||
|
DependencyPropertyDescriptor propertyDescriptor = DependencyPropertyDescriptor.FromName(name, dOwnerType, dTargetType); |
||||||
|
if (propertyDescriptor != null) |
||||||
|
return new WpfDependencyPropertyDescriptor(propertyDescriptor); |
||||||
|
return null; |
||||||
|
} |
||||||
|
catch (Exception) |
||||||
|
{ |
||||||
|
return null; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
public override object InitializeLifetimeService() |
||||||
|
{ |
||||||
|
return null; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public class AssemblyResolveEventArgs : MarshalByRefObject |
||||||
|
{ |
||||||
|
|
||||||
|
private string _location; |
||||||
|
private string _name; |
||||||
|
private string _baseDir; |
||||||
|
|
||||||
|
public AssemblyResolveEventArgs(string name, string baseDir) |
||||||
|
{ |
||||||
|
_name = name; |
||||||
|
_baseDir = baseDir; |
||||||
|
} |
||||||
|
|
||||||
|
public string Location |
||||||
|
{ |
||||||
|
get { return _location; } |
||||||
|
set { _location = value; } |
||||||
|
} |
||||||
|
|
||||||
|
public string Name |
||||||
|
{ |
||||||
|
get { return _name; } |
||||||
|
} |
||||||
|
|
||||||
|
public string BaseDir |
||||||
|
{ |
||||||
|
get { return _baseDir; } |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,112 @@ |
|||||||
|
// 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.Collections; |
||||||
|
using System.Collections.Generic; |
||||||
|
using System.Collections.ObjectModel; |
||||||
|
using System.IO; |
||||||
|
using System.Reflection; |
||||||
|
using System.Resources; |
||||||
|
using System.Text; |
||||||
|
|
||||||
|
namespace Ricciolo.StylesExplorer.MarkupReflection |
||||||
|
{ |
||||||
|
public class BamlAssembly : MarshalByRefObject |
||||||
|
{ |
||||||
|
private readonly string _filePath; |
||||||
|
private Assembly _assembly; |
||||||
|
private BamlFileList _bamlFile; |
||||||
|
|
||||||
|
public BamlAssembly(Assembly assembly) |
||||||
|
{ |
||||||
|
_assembly = assembly; |
||||||
|
_filePath = assembly.CodeBase; |
||||||
|
|
||||||
|
ReadBaml(); |
||||||
|
} |
||||||
|
|
||||||
|
public BamlAssembly(string filePath) |
||||||
|
{ |
||||||
|
this._filePath = Path.GetFullPath(filePath); |
||||||
|
this._assembly = Assembly.LoadFile(this.FilePath); |
||||||
|
if (String.Compare(this.Assembly.CodeBase, this.FilePath, true) != 0) |
||||||
|
throw new ArgumentException("Cannot load filePath because Assembly is already loaded", "filePath"); |
||||||
|
|
||||||
|
ReadBaml(); |
||||||
|
} |
||||||
|
|
||||||
|
private void ReadBaml() |
||||||
|
{ |
||||||
|
// Get available names
|
||||||
|
string[] resources = this.Assembly.GetManifestResourceNames(); |
||||||
|
foreach (string res in resources) |
||||||
|
{ |
||||||
|
// Solo le risorse
|
||||||
|
if (String.Compare(Path.GetExtension(res), ".resources", true) != 0) continue; |
||||||
|
|
||||||
|
// Get stream
|
||||||
|
using (Stream stream = this.Assembly.GetManifestResourceStream(res)) |
||||||
|
{ |
||||||
|
try |
||||||
|
{ |
||||||
|
ResourceReader reader = new ResourceReader(stream); |
||||||
|
foreach (DictionaryEntry entry in reader) |
||||||
|
{ |
||||||
|
if (String.Compare(Path.GetExtension(entry.Key.ToString()), ".baml", true) == 0 && entry.Value is Stream) |
||||||
|
{ |
||||||
|
BamlFile bm = new BamlFile(GetAssemblyResourceUri(entry.Key.ToString()), (Stream)entry.Value); |
||||||
|
this.BamlFiles.Add(bm); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
catch (ArgumentException) |
||||||
|
{} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private Uri GetAssemblyResourceUri(string resourceName) |
||||||
|
{ |
||||||
|
AssemblyName asm = this.Assembly.GetName(); |
||||||
|
byte[] data = asm.GetPublicKeyToken(); |
||||||
|
StringBuilder token = new StringBuilder(data.Length * 2); |
||||||
|
for (int x = 0; x < data.Length; x++) |
||||||
|
{ |
||||||
|
token.Append(data[x].ToString("x", System.Globalization.CultureInfo.InvariantCulture)); |
||||||
|
} |
||||||
|
|
||||||
|
return new Uri(String.Format(@"{0};V{1};{2};component\{3}", asm.Name, asm.Version, token, Path.ChangeExtension(resourceName, ".xaml")), UriKind.RelativeOrAbsolute); |
||||||
|
} |
||||||
|
|
||||||
|
public string FilePath |
||||||
|
{ |
||||||
|
get { return _filePath; } |
||||||
|
} |
||||||
|
|
||||||
|
public Assembly Assembly |
||||||
|
{ |
||||||
|
get { return _assembly; } |
||||||
|
} |
||||||
|
|
||||||
|
public BamlFileList BamlFiles |
||||||
|
{ |
||||||
|
get |
||||||
|
{ |
||||||
|
if (_bamlFile == null) |
||||||
|
_bamlFile = new BamlFileList(); |
||||||
|
return _bamlFile; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public override object InitializeLifetimeService() |
||||||
|
{ |
||||||
|
return null; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
[Serializable()] |
||||||
|
public class BamlFileList : Collection<BamlFile> |
||||||
|
{} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,47 @@ |
|||||||
|
// 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; |
||||||
|
using System.Text; |
||||||
|
|
||||||
|
namespace Ricciolo.StylesExplorer.MarkupReflection |
||||||
|
{ |
||||||
|
internal class BamlBinaryReader : BinaryReader |
||||||
|
{ |
||||||
|
// Methods
|
||||||
|
public BamlBinaryReader(Stream stream) |
||||||
|
: base(stream) |
||||||
|
{ |
||||||
|
} |
||||||
|
|
||||||
|
public virtual double ReadCompressedDouble() |
||||||
|
{ |
||||||
|
switch (this.ReadByte()) |
||||||
|
{ |
||||||
|
case 1: |
||||||
|
return 0; |
||||||
|
|
||||||
|
case 2: |
||||||
|
return 1; |
||||||
|
|
||||||
|
case 3: |
||||||
|
return -1; |
||||||
|
|
||||||
|
case 4: |
||||||
|
{ |
||||||
|
double num = this.ReadInt32(); |
||||||
|
return (num * 1E-06); |
||||||
|
} |
||||||
|
case 5: |
||||||
|
return this.ReadDouble(); |
||||||
|
} |
||||||
|
throw new NotSupportedException(); |
||||||
|
} |
||||||
|
|
||||||
|
public int ReadCompressedInt32() |
||||||
|
{ |
||||||
|
return base.Read7BitEncodedInt(); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,80 @@ |
|||||||
|
// 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.Collections; |
||||||
|
using System.Collections.Generic; |
||||||
|
using System.ComponentModel; |
||||||
|
using System.IO; |
||||||
|
using System.Resources; |
||||||
|
using System.Text; |
||||||
|
using System.Windows; |
||||||
|
|
||||||
|
namespace Ricciolo.StylesExplorer.MarkupReflection |
||||||
|
{ |
||||||
|
/// <summary>
|
||||||
|
/// Rappresenta un singole file Baml all'interno di un assembly
|
||||||
|
/// </summary>
|
||||||
|
public class BamlFile : Component |
||||||
|
{ |
||||||
|
private Uri _uri; |
||||||
|
private readonly Stream _stream; |
||||||
|
|
||||||
|
public BamlFile(Uri uri, Stream stream) |
||||||
|
{ |
||||||
|
if (uri == null) |
||||||
|
new ArgumentNullException("uri"); |
||||||
|
if (stream == null) |
||||||
|
throw new ArgumentNullException("stream"); |
||||||
|
|
||||||
|
_uri = uri; |
||||||
|
_stream = stream; |
||||||
|
} |
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Carica il Baml attraverso il motore di WPF con Application.LoadComponent
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
public object LoadContent() |
||||||
|
{ |
||||||
|
try |
||||||
|
{ |
||||||
|
return Application.LoadComponent(this.Uri); |
||||||
|
} |
||||||
|
catch (Exception e) |
||||||
|
{ |
||||||
|
throw new InvalidOperationException("Invalid baml file.", e); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
protected override void Dispose(bool disposing) |
||||||
|
{ |
||||||
|
base.Dispose(disposing); |
||||||
|
|
||||||
|
if (disposing) |
||||||
|
this.Stream.Dispose(); |
||||||
|
} |
||||||
|
|
||||||
|
public override object InitializeLifetimeService() |
||||||
|
{ |
||||||
|
return null; |
||||||
|
} |
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Restituisce lo stream originale contenente il Baml
|
||||||
|
/// </summary>
|
||||||
|
public Stream Stream |
||||||
|
{ |
||||||
|
get { return _stream; } |
||||||
|
} |
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Restituisce l'indirizzo secondo lo schema pack://
|
||||||
|
/// </summary>
|
||||||
|
public Uri Uri |
||||||
|
{ |
||||||
|
get { return _uri; } |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
} |
@ -0,0 +1,72 @@ |
|||||||
|
// 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.Collections.Generic; |
||||||
|
using System.Text; |
||||||
|
|
||||||
|
namespace Ricciolo.StylesExplorer.MarkupReflection |
||||||
|
{ |
||||||
|
internal enum BamlRecordType : byte |
||||||
|
{ |
||||||
|
AssemblyInfo = 0x1c, |
||||||
|
AttributeInfo = 0x1f, |
||||||
|
ClrEvent = 0x13, |
||||||
|
Comment = 0x17, |
||||||
|
ConnectionId = 0x2d, |
||||||
|
ConstructorParametersEnd = 0x2b, |
||||||
|
ConstructorParametersStart = 0x2a, |
||||||
|
ConstructorParameterType = 0x2c, |
||||||
|
ContentProperty = 0x2e, |
||||||
|
DefAttribute = 0x19, |
||||||
|
DefAttributeKeyString = 0x26, |
||||||
|
DefAttributeKeyType = 0x27, |
||||||
|
DeferableContentStart = 0x25, |
||||||
|
DefTag = 0x18, |
||||||
|
DocumentEnd = 2, |
||||||
|
DocumentStart = 1, |
||||||
|
ElementEnd = 4, |
||||||
|
ElementStart = 3, |
||||||
|
EndAttributes = 0x1a, |
||||||
|
KeyElementEnd = 0x29, |
||||||
|
KeyElementStart = 40, |
||||||
|
LastRecordType = 0x39, |
||||||
|
LineNumberAndPosition = 0x35, |
||||||
|
LinePosition = 0x36, |
||||||
|
LiteralContent = 15, |
||||||
|
NamedElementStart = 0x2f, |
||||||
|
OptimizedStaticResource = 0x37, |
||||||
|
PIMapping = 0x1b, |
||||||
|
PresentationOptionsAttribute = 0x34, |
||||||
|
ProcessingInstruction = 0x16, |
||||||
|
Property = 5, |
||||||
|
PropertyArrayEnd = 10, |
||||||
|
PropertyArrayStart = 9, |
||||||
|
PropertyComplexEnd = 8, |
||||||
|
PropertyComplexStart = 7, |
||||||
|
PropertyCustom = 6, |
||||||
|
PropertyDictionaryEnd = 14, |
||||||
|
PropertyDictionaryStart = 13, |
||||||
|
PropertyListEnd = 12, |
||||||
|
PropertyListStart = 11, |
||||||
|
PropertyStringReference = 0x21, |
||||||
|
PropertyTypeReference = 0x22, |
||||||
|
PropertyWithConverter = 0x24, |
||||||
|
PropertyWithExtension = 0x23, |
||||||
|
PropertyWithStaticResourceId = 0x38, |
||||||
|
RoutedEvent = 0x12, |
||||||
|
StaticResourceEnd = 0x31, |
||||||
|
StaticResourceId = 50, |
||||||
|
StaticResourceStart = 0x30, |
||||||
|
StringInfo = 0x20, |
||||||
|
Text = 0x10, |
||||||
|
TextWithConverter = 0x11, |
||||||
|
TextWithId = 0x33, |
||||||
|
TypeInfo = 0x1d, |
||||||
|
TypeSerializerInfo = 30, |
||||||
|
Unknown = 0, |
||||||
|
XmlAttribute = 0x15, |
||||||
|
XmlnsProperty = 20 |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,58 @@ |
|||||||
|
// 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.Collections.Generic; |
||||||
|
using System.Text; |
||||||
|
|
||||||
|
namespace Ricciolo.StylesExplorer.MarkupReflection |
||||||
|
{ |
||||||
|
public class DotNetType : MarshalByRefObject, IType |
||||||
|
{ |
||||||
|
private readonly string _assemblyQualifiedName; |
||||||
|
private Type _type; |
||||||
|
|
||||||
|
public DotNetType(string assemblyQualifiedName) |
||||||
|
{ |
||||||
|
if (assemblyQualifiedName == null) throw new ArgumentNullException("assemblyQualifiedName"); |
||||||
|
|
||||||
|
_assemblyQualifiedName = assemblyQualifiedName; |
||||||
|
_type = Type.GetType(assemblyQualifiedName, false, true); |
||||||
|
} |
||||||
|
|
||||||
|
#region IType Members
|
||||||
|
|
||||||
|
public string AssemblyQualifiedName |
||||||
|
{ |
||||||
|
get { return _assemblyQualifiedName; } |
||||||
|
} |
||||||
|
|
||||||
|
public bool IsSubclassOf(IType type) |
||||||
|
{ |
||||||
|
if (type == null) throw new ArgumentNullException("type"); |
||||||
|
if (!(type is DotNetType)) throw new ArgumentException("type"); |
||||||
|
if (_type == null) return false; |
||||||
|
return this._type.IsSubclassOf(((DotNetType)type).Type); |
||||||
|
} |
||||||
|
|
||||||
|
public bool Equals(IType type) |
||||||
|
{ |
||||||
|
if (type == null) throw new ArgumentNullException("type"); |
||||||
|
if (!(type is DotNetType)) throw new ArgumentException("type"); |
||||||
|
if (_type == null) return false; |
||||||
|
return this._type.Equals(((DotNetType)type).Type); |
||||||
|
} |
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
public Type Type |
||||||
|
{ |
||||||
|
get { return _type; } |
||||||
|
} |
||||||
|
|
||||||
|
public override object InitializeLifetimeService() |
||||||
|
{ |
||||||
|
return null; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,14 @@ |
|||||||
|
// 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.Collections.Generic; |
||||||
|
using System.Text; |
||||||
|
|
||||||
|
namespace Ricciolo.StylesExplorer.MarkupReflection |
||||||
|
{ |
||||||
|
public interface IDependencyPropertyDescriptor |
||||||
|
{ |
||||||
|
bool IsAttached { get; } |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,19 @@ |
|||||||
|
// 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.Collections.Generic; |
||||||
|
using System.Text; |
||||||
|
|
||||||
|
namespace Ricciolo.StylesExplorer.MarkupReflection |
||||||
|
{ |
||||||
|
/// <summary>
|
||||||
|
/// Interface rappresenting a DotNet type
|
||||||
|
/// </summary>
|
||||||
|
public interface IType |
||||||
|
{ |
||||||
|
string AssemblyQualifiedName { get; } |
||||||
|
bool IsSubclassOf(IType type); |
||||||
|
bool Equals(IType type); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,15 @@ |
|||||||
|
// 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.Collections.Generic; |
||||||
|
using System.Text; |
||||||
|
|
||||||
|
namespace Ricciolo.StylesExplorer.MarkupReflection |
||||||
|
{ |
||||||
|
public interface ITypeResolver |
||||||
|
{ |
||||||
|
IType GetTypeByAssemblyQualifiedName(string name); |
||||||
|
IDependencyPropertyDescriptor GetDependencyPropertyDescriptor(string name, IType ownerType, IType targetType); |
||||||
|
} |
||||||
|
} |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,58 @@ |
|||||||
|
// 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.Collections.Generic; |
||||||
|
using System.Text; |
||||||
|
|
||||||
|
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; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,32 @@ |
|||||||
|
// 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.Collections.Generic; |
||||||
|
using System.Text; |
||||||
|
|
||||||
|
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; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,137 @@ |
|||||||
|
// 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 TypeDeclaration |
||||||
|
{ |
||||||
|
private readonly XmlBamlReader reader; |
||||||
|
|
||||||
|
private readonly short _assemblyId; |
||||||
|
private readonly bool _isKnown; |
||||||
|
private readonly string _name; |
||||||
|
private readonly string _namespaceName; |
||||||
|
private readonly bool _isExtension; |
||||||
|
private IType _type; |
||||||
|
private bool _typeLoaded; |
||||||
|
private readonly ITypeResolver resolver; |
||||||
|
|
||||||
|
public TypeDeclaration(ITypeResolver resolver, string name, string namespaceName, short assemblyId) |
||||||
|
: this(null, resolver, name, namespaceName, assemblyId, true) |
||||||
|
{ |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
public TypeDeclaration(ITypeResolver resolver, string name, string namespaceName, short assemblyId, bool isExtension) |
||||||
|
: this(null, resolver, name, namespaceName, assemblyId, true) |
||||||
|
{ |
||||||
|
_isExtension = isExtension; |
||||||
|
} |
||||||
|
|
||||||
|
public TypeDeclaration(XmlBamlReader reader, ITypeResolver resolver, string name, string namespaceName, short assemblyId) |
||||||
|
: this(reader, resolver, name, namespaceName, assemblyId, true) |
||||||
|
{ |
||||||
|
} |
||||||
|
|
||||||
|
public TypeDeclaration(XmlBamlReader reader, ITypeResolver resolver, string name, string namespaceName, short assemblyId, bool isKnown) |
||||||
|
{ |
||||||
|
this.reader = reader; |
||||||
|
this.resolver = resolver; |
||||||
|
this._name = name; |
||||||
|
this._namespaceName = namespaceName; |
||||||
|
this._assemblyId = assemblyId; |
||||||
|
this._isKnown = isKnown; |
||||||
|
|
||||||
|
if (!_isExtension) |
||||||
|
_isExtension = name.EndsWith("Extension"); |
||||||
|
} |
||||||
|
|
||||||
|
public override string ToString() |
||||||
|
{ |
||||||
|
return this._name; |
||||||
|
} |
||||||
|
|
||||||
|
public bool IsExtension |
||||||
|
{ |
||||||
|
get { return _isExtension; } |
||||||
|
} |
||||||
|
|
||||||
|
public string Assembly |
||||||
|
{ |
||||||
|
get |
||||||
|
{ |
||||||
|
if (reader != null) |
||||||
|
return this.reader.GetAssembly(this.AssemblyId); |
||||||
|
else |
||||||
|
return KnownInfo.KnownAssemblyTable[this.AssemblyId]; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public short AssemblyId |
||||||
|
{ |
||||||
|
get { return _assemblyId; } |
||||||
|
} |
||||||
|
|
||||||
|
public string Name |
||||||
|
{ |
||||||
|
get |
||||||
|
{ |
||||||
|
return this._name; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public bool IsKnown |
||||||
|
{ |
||||||
|
get { return _isKnown; } |
||||||
|
} |
||||||
|
|
||||||
|
//public Type DotNetType
|
||||||
|
//{
|
||||||
|
// get
|
||||||
|
// {
|
||||||
|
// if (!_typeLoaded)
|
||||||
|
// {
|
||||||
|
// _type = Type.GetType(String.Format("{0}.{1}, {2}", this.Namespace, this.Name, this.Assembly), false, true);
|
||||||
|
// _typeLoaded = true;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// return _type;
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
|
public IType Type |
||||||
|
{ |
||||||
|
get |
||||||
|
{ |
||||||
|
if (!_typeLoaded) |
||||||
|
{ |
||||||
|
if (this.Name.Length > 0) |
||||||
|
_type = resolver.GetTypeByAssemblyQualifiedName(String.Format("{0}.{1}, {2}", this.Namespace, this.Name, this.Assembly)); |
||||||
|
_typeLoaded = true; |
||||||
|
} |
||||||
|
|
||||||
|
return _type; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public string Namespace |
||||||
|
{ |
||||||
|
get |
||||||
|
{ |
||||||
|
return this._namespaceName; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public override bool Equals(object obj) |
||||||
|
{ |
||||||
|
TypeDeclaration td = obj as TypeDeclaration; |
||||||
|
if (td != null) |
||||||
|
return (this.Name == td.Name && this.Namespace == td.Namespace && this.AssemblyId == td.AssemblyId); |
||||||
|
else |
||||||
|
return false; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,35 @@ |
|||||||
|
// 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.Collections.Generic; |
||||||
|
using System.ComponentModel; |
||||||
|
using System.Text; |
||||||
|
|
||||||
|
namespace Ricciolo.StylesExplorer.MarkupReflection |
||||||
|
{ |
||||||
|
public class WpfDependencyPropertyDescriptor : MarshalByRefObject, IDependencyPropertyDescriptor |
||||||
|
{ |
||||||
|
private readonly DependencyPropertyDescriptor _propertyDescriptor; |
||||||
|
|
||||||
|
public WpfDependencyPropertyDescriptor(DependencyPropertyDescriptor propertyDescriptor) |
||||||
|
{ |
||||||
|
if (propertyDescriptor == null) throw new ArgumentNullException("propertyDescriptor"); |
||||||
|
_propertyDescriptor = propertyDescriptor; |
||||||
|
} |
||||||
|
|
||||||
|
#region IDependencyPropertyDescriptor Members
|
||||||
|
|
||||||
|
public bool IsAttached |
||||||
|
{ |
||||||
|
get { return _propertyDescriptor.IsAttached; } |
||||||
|
} |
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
public override object InitializeLifetimeService() |
||||||
|
{ |
||||||
|
return null; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,193 @@ |
|||||||
|
// 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.Collections; |
||||||
|
using System.Collections.Generic; |
||||||
|
using System.Text; |
||||||
|
using System.Xml; |
||||||
|
|
||||||
|
namespace Ricciolo.StylesExplorer.MarkupReflection |
||||||
|
{ |
||||||
|
internal class XmlBamlElement : XmlBamlNode |
||||||
|
{ |
||||||
|
private ArrayList _arguments = new ArrayList(); |
||||||
|
private XmlNamespaceCollection _namespaces = new XmlNamespaceCollection(); |
||||||
|
private TypeDeclaration _typeDeclaration; |
||||||
|
private KeysResourcesCollection _keysResources = new KeysResourcesCollection(); |
||||||
|
private long _position; |
||||||
|
|
||||||
|
public XmlBamlElement() |
||||||
|
{ |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
public XmlBamlElement(XmlBamlElement parent) |
||||||
|
{ |
||||||
|
this.Namespaces.AddRange(parent.Namespaces); |
||||||
|
} |
||||||
|
|
||||||
|
public XmlNamespaceCollection Namespaces |
||||||
|
{ |
||||||
|
get { return _namespaces; } |
||||||
|
} |
||||||
|
|
||||||
|
public TypeDeclaration TypeDeclaration |
||||||
|
{ |
||||||
|
get |
||||||
|
{ |
||||||
|
return this._typeDeclaration; |
||||||
|
} |
||||||
|
set |
||||||
|
{ |
||||||
|
this._typeDeclaration = value; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public override XmlNodeType NodeType |
||||||
|
{ |
||||||
|
get |
||||||
|
{ |
||||||
|
return XmlNodeType.Element; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public long Position |
||||||
|
{ |
||||||
|
get { return _position; } |
||||||
|
set { _position = value; } |
||||||
|
} |
||||||
|
|
||||||
|
public override string ToString() |
||||||
|
{ |
||||||
|
return String.Format("Element: {0}", TypeDeclaration.Name); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
internal 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); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
internal class KeyMapping |
||||||
|
{ |
||||||
|
private string _key; |
||||||
|
private TypeDeclaration _declaration; |
||||||
|
private string _trueKey; |
||||||
|
|
||||||
|
public KeyMapping(string key, TypeDeclaration declaration, string trueKey) |
||||||
|
{ |
||||||
|
_key = key; |
||||||
|
_declaration = declaration; |
||||||
|
_trueKey = trueKey; |
||||||
|
} |
||||||
|
|
||||||
|
public string Key |
||||||
|
{ |
||||||
|
get { return _key; } |
||||||
|
} |
||||||
|
|
||||||
|
public TypeDeclaration Declaration |
||||||
|
{ |
||||||
|
get { return _declaration; } |
||||||
|
} |
||||||
|
|
||||||
|
public string TrueKey |
||||||
|
{ |
||||||
|
get { return _trueKey; } |
||||||
|
} |
||||||
|
|
||||||
|
public override string ToString() |
||||||
|
{ |
||||||
|
return String.Format("{0} - {1} - {2}", Key, Declaration, TrueKey); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
internal class KeysResourcesCollection : List<KeysResource> |
||||||
|
{ |
||||||
|
public KeysResource Last |
||||||
|
{ |
||||||
|
get |
||||||
|
{ |
||||||
|
if (this.Count == 0) |
||||||
|
return null; |
||||||
|
return this[this.Count - 1]; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public KeysResource First |
||||||
|
{ |
||||||
|
get |
||||||
|
{ |
||||||
|
if (this.Count == 0) |
||||||
|
return null; |
||||||
|
return this[0]; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
internal class KeysResource |
||||||
|
{ |
||||||
|
private KeysTable _keys = new KeysTable(); |
||||||
|
private ArrayList _staticResources = new ArrayList(); |
||||||
|
|
||||||
|
public KeysTable Keys |
||||||
|
{ |
||||||
|
get { return _keys; } |
||||||
|
} |
||||||
|
|
||||||
|
public ArrayList StaticResources |
||||||
|
{ |
||||||
|
get { return _staticResources; } |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
internal class KeysTable |
||||||
|
{ |
||||||
|
private Hashtable table = new Hashtable(); |
||||||
|
|
||||||
|
public String this[long position] |
||||||
|
{ |
||||||
|
get |
||||||
|
{ |
||||||
|
return (string)this.table[position]; |
||||||
|
} |
||||||
|
set |
||||||
|
{ |
||||||
|
this.table[position] = value; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public int Count |
||||||
|
{ |
||||||
|
get { return this.table.Count; } |
||||||
|
} |
||||||
|
|
||||||
|
public void Remove(long position) |
||||||
|
{ |
||||||
|
this.table.Remove(position); |
||||||
|
} |
||||||
|
|
||||||
|
public bool HasKey(long position) |
||||||
|
{ |
||||||
|
return this.table.ContainsKey(position); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,21 @@ |
|||||||
|
// 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.Collections.Generic; |
||||||
|
using System.Text; |
||||||
|
using System.Xml; |
||||||
|
|
||||||
|
namespace Ricciolo.StylesExplorer.MarkupReflection |
||||||
|
{ |
||||||
|
internal class XmlBamlNode |
||||||
|
{ |
||||||
|
public virtual XmlNodeType NodeType |
||||||
|
{ |
||||||
|
get { return XmlNodeType.None;} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
internal class XmlBamlNodeCollection : List<XmlBamlNode> |
||||||
|
{} |
||||||
|
} |
@ -0,0 +1,86 @@ |
|||||||
|
// 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.Collections.Generic; |
||||||
|
using System.Text; |
||||||
|
using System.Xml; |
||||||
|
|
||||||
|
namespace Ricciolo.StylesExplorer.MarkupReflection |
||||||
|
{ |
||||||
|
internal class XmlBamlProperty : XmlBamlNode |
||||||
|
{ |
||||||
|
private PropertyDeclaration propertyDeclaration; |
||||||
|
private PropertyType propertyType; |
||||||
|
private object value; |
||||||
|
|
||||||
|
public XmlBamlProperty(PropertyType propertyType) |
||||||
|
{ |
||||||
|
this.propertyType = propertyType; |
||||||
|
} |
||||||
|
|
||||||
|
public XmlBamlProperty(PropertyType propertyType, PropertyDeclaration propertyDeclaration) |
||||||
|
{ |
||||||
|
this.propertyDeclaration = propertyDeclaration; |
||||||
|
this.propertyType = propertyType; |
||||||
|
} |
||||||
|
|
||||||
|
public override string ToString() |
||||||
|
{ |
||||||
|
return this.PropertyDeclaration.Name; |
||||||
|
} |
||||||
|
|
||||||
|
public PropertyDeclaration PropertyDeclaration |
||||||
|
{ |
||||||
|
get |
||||||
|
{ |
||||||
|
return this.propertyDeclaration; |
||||||
|
} |
||||||
|
set |
||||||
|
{ |
||||||
|
this.propertyDeclaration = value; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public PropertyType PropertyType |
||||||
|
{ |
||||||
|
get |
||||||
|
{ |
||||||
|
return this.propertyType; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public object Value |
||||||
|
{ |
||||||
|
get |
||||||
|
{ |
||||||
|
return this.value; |
||||||
|
} |
||||||
|
set |
||||||
|
{ |
||||||
|
this.value = value; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public override XmlNodeType NodeType |
||||||
|
{ |
||||||
|
get |
||||||
|
{ |
||||||
|
return XmlNodeType.Attribute; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
internal enum PropertyType |
||||||
|
{ |
||||||
|
Key, |
||||||
|
Value, |
||||||
|
Content, |
||||||
|
List, |
||||||
|
Dictionary, |
||||||
|
Complex |
||||||
|
} |
||||||
|
|
||||||
|
internal class XmlBamlPropertyCollection : List<XmlBamlNode> |
||||||
|
{ } |
||||||
|
} |
@ -0,0 +1,48 @@ |
|||||||
|
// 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.Collections.Generic; |
||||||
|
using System.Text; |
||||||
|
|
||||||
|
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, PropertyDeclaration.Name); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,33 @@ |
|||||||
|
// 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.Collections.Generic; |
||||||
|
using System.Text; |
||||||
|
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; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,47 @@ |
|||||||
|
// 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 |
||||||
|
{ |
||||||
|
internal class XmlNamespace |
||||||
|
{ |
||||||
|
private string _prefix; |
||||||
|
private string _namespace; |
||||||
|
|
||||||
|
public XmlNamespace(string prefix, string ns) |
||||||
|
{ |
||||||
|
_prefix = prefix; |
||||||
|
_namespace = ns; |
||||||
|
} |
||||||
|
|
||||||
|
public string Prefix |
||||||
|
{ |
||||||
|
get { return _prefix; } |
||||||
|
} |
||||||
|
|
||||||
|
public string Namespace |
||||||
|
{ |
||||||
|
get { return _namespace; } |
||||||
|
} |
||||||
|
|
||||||
|
public override bool Equals(object obj) |
||||||
|
{ |
||||||
|
if (obj is XmlNamespace) |
||||||
|
{ |
||||||
|
XmlNamespace o = (XmlNamespace)obj; |
||||||
|
return (o.Prefix.Equals(this.Prefix) && o.Namespace.Equals(this.Namespace)); |
||||||
|
} |
||||||
|
return base.Equals(obj); |
||||||
|
} |
||||||
|
|
||||||
|
public override int GetHashCode() |
||||||
|
{ |
||||||
|
return _prefix.GetHashCode() + _namespace.GetHashCode() >> 20; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
internal class XmlNamespaceCollection : List<XmlNamespace> |
||||||
|
{} |
||||||
|
} |
@ -0,0 +1,63 @@ |
|||||||
|
// 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>
|
||||||
|
/// Rappresenta la mappatura tra namespace XML e namespace CLR con relativo assembly
|
||||||
|
/// </summary>
|
||||||
|
public class XmlPIMapping |
||||||
|
{ |
||||||
|
private string _xmlNamespace; |
||||||
|
private short _assemblyId; |
||||||
|
private string _clrNamespace; |
||||||
|
private static XmlPIMapping _default = new XmlPIMapping(PresentationNamespace, 0, String.Empty); |
||||||
|
|
||||||
|
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 XmlPIMapping(string xmlNamespace, short assemblyId, string clrNamespace) |
||||||
|
{ |
||||||
|
_xmlNamespace = xmlNamespace; |
||||||
|
_assemblyId = assemblyId; |
||||||
|
_clrNamespace = clrNamespace; |
||||||
|
} |
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Restituisce o imposta il namespace XML
|
||||||
|
/// </summary>
|
||||||
|
public string XmlNamespace |
||||||
|
{ |
||||||
|
get { return _xmlNamespace; } |
||||||
|
set { _xmlNamespace = value;} |
||||||
|
} |
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Restituisce l'id dell'assembly
|
||||||
|
/// </summary>
|
||||||
|
public short AssemblyId |
||||||
|
{ |
||||||
|
get { return _assemblyId; } |
||||||
|
} |
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Restituisce il namespace clr
|
||||||
|
/// </summary>
|
||||||
|
public string ClrNamespace |
||||||
|
{ |
||||||
|
get { return _clrNamespace; } |
||||||
|
} |
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Restituisce il mapping di default di WPF
|
||||||
|
/// </summary>
|
||||||
|
public static XmlPIMapping Presentation |
||||||
|
{ |
||||||
|
get { return _default; } |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -1,445 +0,0 @@ |
|||||||
// 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.
|
|
||||||
|
|
||||||
using System; |
|
||||||
using System.ComponentModel.Composition; |
|
||||||
using System.IO; |
|
||||||
using System.Linq; |
|
||||||
using System.Reflection; |
|
||||||
using System.Threading.Tasks; |
|
||||||
using System.Windows.Baml2006; |
|
||||||
using System.Xaml; |
|
||||||
using System.Xaml.Schema; |
|
||||||
using System.Xml; |
|
||||||
using System.Xml.Linq; |
|
||||||
using ICSharpCode.AvalonEdit.Highlighting; |
|
||||||
using ICSharpCode.ILSpy.TextView; |
|
||||||
using ICSharpCode.ILSpy.TreeNodes; |
|
||||||
using System.Diagnostics; |
|
||||||
using System.Collections; |
|
||||||
using System.Collections.Generic; |
|
||||||
|
|
||||||
namespace ICSharpCode.ILSpy.Baml |
|
||||||
{ |
|
||||||
/// <remarks>Caution: use in separate AppDomain only!</remarks>
|
|
||||||
sealed class BamlDecompiler : MarshalByRefObject |
|
||||||
{ |
|
||||||
public BamlDecompiler() |
|
||||||
{ |
|
||||||
} |
|
||||||
|
|
||||||
abstract class XamlNode |
|
||||||
{ |
|
||||||
public readonly List<XamlNode> Children = new List<XamlNode>(); |
|
||||||
|
|
||||||
public abstract void WriteTo(XamlWriter writer); |
|
||||||
} |
|
||||||
|
|
||||||
[Conditional("DEBUG")] |
|
||||||
static void Log(string format, params object[] args) |
|
||||||
{ |
|
||||||
Debug.WriteLine(format, args); |
|
||||||
} |
|
||||||
|
|
||||||
sealed class XamlObjectNode : XamlNode |
|
||||||
{ |
|
||||||
public readonly XamlType Type; |
|
||||||
|
|
||||||
public XamlObjectNode(XamlType type) |
|
||||||
{ |
|
||||||
this.Type = type; |
|
||||||
} |
|
||||||
|
|
||||||
public override void WriteTo(XamlWriter writer) |
|
||||||
{ |
|
||||||
Log("StartObject {0}", this.Type); |
|
||||||
writer.WriteStartObject(this.Type); |
|
||||||
Debug.Indent(); |
|
||||||
foreach (XamlNode node in this.Children) |
|
||||||
node.WriteTo(writer); |
|
||||||
Debug.Unindent(); |
|
||||||
Log("EndObject"); |
|
||||||
writer.WriteEndObject(); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
sealed class XamlGetObjectNode : XamlNode |
|
||||||
{ |
|
||||||
public override void WriteTo(XamlWriter writer) |
|
||||||
{ |
|
||||||
Log("GetObject"); |
|
||||||
writer.WriteGetObject(); |
|
||||||
Debug.Indent(); |
|
||||||
foreach (XamlNode node in this.Children) |
|
||||||
node.WriteTo(writer); |
|
||||||
Debug.Unindent(); |
|
||||||
Log("EndObject"); |
|
||||||
writer.WriteEndObject(); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
sealed class XamlMemberNode : XamlNode |
|
||||||
{ |
|
||||||
public XamlMember Member; |
|
||||||
|
|
||||||
public XamlMemberNode(XamlMember member) |
|
||||||
{ |
|
||||||
this.Member = member; |
|
||||||
} |
|
||||||
|
|
||||||
public override void WriteTo(XamlWriter writer) |
|
||||||
{ |
|
||||||
Log("StartMember {0}", this.Member); |
|
||||||
writer.WriteStartMember(this.Member); |
|
||||||
Debug.Indent(); |
|
||||||
foreach (XamlNode node in this.Children) |
|
||||||
node.WriteTo(writer); |
|
||||||
Debug.Unindent(); |
|
||||||
Log("EndMember"); |
|
||||||
writer.WriteEndMember(); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
sealed class XamlValueNode : XamlNode |
|
||||||
{ |
|
||||||
public readonly object Value; |
|
||||||
|
|
||||||
public XamlValueNode(object value) |
|
||||||
{ |
|
||||||
this.Value = value; |
|
||||||
} |
|
||||||
|
|
||||||
public override void WriteTo(XamlWriter writer) |
|
||||||
{ |
|
||||||
Log("Value {0}", this.Value); |
|
||||||
Debug.Assert(this.Children.Count == 0); |
|
||||||
// requires XamlReaderSettings.ValuesMustBeString = true to work properly
|
|
||||||
writer.WriteValue(this.Value); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
sealed class XamlNamespaceDeclarationNode : XamlNode |
|
||||||
{ |
|
||||||
public readonly NamespaceDeclaration Namespace; |
|
||||||
|
|
||||||
public XamlNamespaceDeclarationNode(NamespaceDeclaration @namespace) |
|
||||||
{ |
|
||||||
this.Namespace = @namespace; |
|
||||||
} |
|
||||||
|
|
||||||
public override void WriteTo(XamlWriter writer) |
|
||||||
{ |
|
||||||
Log("NamespaceDeclaration {0}", this.Namespace); |
|
||||||
Debug.Assert(this.Children.Count == 0); |
|
||||||
writer.WriteNamespace(this.Namespace); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
static List<XamlNode> Parse(XamlReader reader) |
|
||||||
{ |
|
||||||
List<XamlNode> currentList = new List<XamlNode>(); |
|
||||||
Stack<List<XamlNode>> stack = new Stack<List<XamlNode>>(); |
|
||||||
while (reader.Read()) { |
|
||||||
switch (reader.NodeType) { |
|
||||||
case XamlNodeType.None: |
|
||||||
break; |
|
||||||
case XamlNodeType.StartObject: |
|
||||||
XamlObjectNode obj = new XamlObjectNode(reader.Type); |
|
||||||
currentList.Add(obj); |
|
||||||
stack.Push(currentList); |
|
||||||
currentList = obj.Children; |
|
||||||
break; |
|
||||||
case XamlNodeType.GetObject: |
|
||||||
XamlGetObjectNode getObject = new XamlGetObjectNode(); |
|
||||||
currentList.Add(getObject); |
|
||||||
stack.Push(currentList); |
|
||||||
currentList = getObject.Children; |
|
||||||
break; |
|
||||||
case XamlNodeType.StartMember: |
|
||||||
XamlMemberNode member = new XamlMemberNode(reader.Member); |
|
||||||
currentList.Add(member); |
|
||||||
stack.Push(currentList); |
|
||||||
currentList = member.Children; |
|
||||||
break; |
|
||||||
case XamlNodeType.Value: |
|
||||||
currentList.Add(new XamlValueNode(reader.Value)); |
|
||||||
break; |
|
||||||
case XamlNodeType.NamespaceDeclaration: |
|
||||||
currentList.Add(new XamlNamespaceDeclarationNode(reader.Namespace)); |
|
||||||
break; |
|
||||||
case XamlNodeType.EndObject: |
|
||||||
case XamlNodeType.EndMember: |
|
||||||
currentList = stack.Pop(); |
|
||||||
break; |
|
||||||
default: |
|
||||||
throw new InvalidOperationException("Invalid value for XamlNodeType"); |
|
||||||
} |
|
||||||
} |
|
||||||
if (stack.Count != 0) |
|
||||||
throw new InvalidOperationException("Imbalanced stack"); |
|
||||||
return currentList; |
|
||||||
} |
|
||||||
|
|
||||||
void AvoidContentProperties(XamlNode node) |
|
||||||
{ |
|
||||||
foreach (XamlNode child in node.Children) |
|
||||||
AvoidContentProperties(child); |
|
||||||
|
|
||||||
|
|
||||||
XamlObjectNode obj = node as XamlObjectNode; |
|
||||||
if (obj != null) { |
|
||||||
// Visit all except for the last child:
|
|
||||||
for (int i = 0; i < obj.Children.Count - 1; i++) { |
|
||||||
// Avoids using content property syntax for simple string values, if the content property is not the last member.
|
|
||||||
// Without this, we cannot decompile <GridViewColumn Header="Culture" DisplayMemberBinding="{Binding Culture}" />,
|
|
||||||
// because the Header property is the content property, but there is no way to represent the Binding as an element.
|
|
||||||
XamlMemberNode memberNode = obj.Children[i] as XamlMemberNode; |
|
||||||
if (memberNode != null && memberNode.Member == obj.Type.ContentProperty) { |
|
||||||
if (memberNode.Children.Count == 1 && memberNode.Children[0] is XamlValueNode) { |
|
||||||
// By creating a clone of the XamlMember, we prevent WPF from knowing that it's the content property.
|
|
||||||
XamlMember member = memberNode.Member; |
|
||||||
memberNode.Member = new XamlMember(member.Name, member.DeclaringType, member.IsAttachable); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
// We also need to avoid using content properties that have a markup extension as value, as the XamlXmlWriter would always expand those:
|
|
||||||
for (int i = 0; i < obj.Children.Count; i++) { |
|
||||||
XamlMemberNode memberNode = obj.Children[i] as XamlMemberNode; |
|
||||||
if (memberNode != null && memberNode.Member == obj.Type.ContentProperty && memberNode.Children.Count == 1) { |
|
||||||
XamlObjectNode me = memberNode.Children[0] as XamlObjectNode; |
|
||||||
if (me != null && me.Type.IsMarkupExtension) { |
|
||||||
// By creating a clone of the XamlMember, we prevent WPF from knowing that it's the content property.
|
|
||||||
XamlMember member = memberNode.Member; |
|
||||||
memberNode.Member = new XamlMember(member.Name, member.DeclaringType, member.IsAttachable); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// It seems like BamlReader will always output 'x:Key' as last property. However, it must be specified as attribute in valid .xaml, so we move it to the front
|
|
||||||
/// of the attribute list.
|
|
||||||
/// </summary>
|
|
||||||
void MoveXKeyToFront(XamlNode node) |
|
||||||
{ |
|
||||||
foreach (XamlNode child in node.Children) |
|
||||||
MoveXKeyToFront(child); |
|
||||||
|
|
||||||
XamlObjectNode obj = node as XamlObjectNode; |
|
||||||
if (obj != null && obj.Children.Count > 0) { |
|
||||||
XamlMemberNode memberNode = obj.Children[obj.Children.Count - 1] as XamlMemberNode; |
|
||||||
if (memberNode != null && memberNode.Member == XamlLanguage.Key) { |
|
||||||
// move memberNode in front of the first member node:
|
|
||||||
for (int i = 0; i < obj.Children.Count; i++) { |
|
||||||
if (obj.Children[i] is XamlMemberNode) { |
|
||||||
obj.Children.Insert(i, memberNode); |
|
||||||
obj.Children.RemoveAt(obj.Children.Count - 1); |
|
||||||
break; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
AssemblyResolver asmResolver; |
|
||||||
|
|
||||||
Assembly AssemblyResolve(object sender, ResolveEventArgs args) |
|
||||||
{ |
|
||||||
string path = asmResolver.FindAssembly(args.Name); |
|
||||||
|
|
||||||
if (path == null) |
|
||||||
return null; |
|
||||||
|
|
||||||
return Assembly.LoadFile(path); |
|
||||||
} |
|
||||||
|
|
||||||
public string DecompileBaml(MemoryStream bamlCode, string containingAssemblyFile, ConnectMethodDecompiler connectMethodDecompiler, AssemblyResolver asmResolver) |
|
||||||
{ |
|
||||||
this.asmResolver = asmResolver; |
|
||||||
AppDomain.CurrentDomain.AssemblyResolve += AssemblyResolve; |
|
||||||
|
|
||||||
bamlCode.Position = 0; |
|
||||||
TextWriter w = new StringWriter(); |
|
||||||
|
|
||||||
Assembly assembly = Assembly.LoadFile(containingAssemblyFile); |
|
||||||
|
|
||||||
Baml2006Reader reader = new Baml2006Reader(bamlCode, new XamlReaderSettings() { ValuesMustBeString = true, LocalAssembly = assembly }); |
|
||||||
var xamlDocument = Parse(reader); |
|
||||||
|
|
||||||
string bamlTypeName = xamlDocument.OfType<XamlObjectNode>().First().Type.UnderlyingType.FullName; |
|
||||||
|
|
||||||
var eventMappings = connectMethodDecompiler.DecompileEventMappings(bamlTypeName); |
|
||||||
|
|
||||||
foreach (var xamlNode in xamlDocument) { |
|
||||||
RemoveConnectionIds(xamlNode, eventMappings, reader.SchemaContext); |
|
||||||
AvoidContentProperties(xamlNode); |
|
||||||
MoveXKeyToFront(xamlNode); |
|
||||||
} |
|
||||||
|
|
||||||
XDocument doc = new XDocument(); |
|
||||||
XamlXmlWriter writer = new XamlXmlWriter(doc.CreateWriter(), reader.SchemaContext, new XamlXmlWriterSettings { AssumeValidInput = true }); |
|
||||||
foreach (var xamlNode in xamlDocument) |
|
||||||
xamlNode.WriteTo(writer); |
|
||||||
writer.Close(); |
|
||||||
|
|
||||||
// Fix namespace references
|
|
||||||
string suffixToRemove = ";assembly=" + assembly.GetName().Name; |
|
||||||
foreach (XAttribute attrib in doc.Root.Attributes()) { |
|
||||||
if (attrib.Name.Namespace == XNamespace.Xmlns) { |
|
||||||
if (attrib.Value.EndsWith(suffixToRemove, StringComparison.Ordinal)) { |
|
||||||
string newNamespace = attrib.Value.Substring(0, attrib.Value.Length - suffixToRemove.Length); |
|
||||||
ChangeXmlNamespace(doc, attrib.Value, newNamespace); |
|
||||||
attrib.Value = newNamespace; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
return doc.ToString(); |
|
||||||
} |
|
||||||
|
|
||||||
void RemoveConnectionIds(XamlNode node, Dictionary<int, EventRegistration[]> eventMappings, XamlSchemaContext context) |
|
||||||
{ |
|
||||||
foreach (XamlNode child in node.Children) |
|
||||||
RemoveConnectionIds(child, eventMappings, context); |
|
||||||
|
|
||||||
XamlObjectNode obj = node as XamlObjectNode; |
|
||||||
if (obj != null && obj.Children.Count > 0) { |
|
||||||
var removableNodes = new List<XamlMemberNode>(); |
|
||||||
var addableNodes = new List<XamlMemberNode>(); |
|
||||||
foreach (XamlMemberNode memberNode in obj.Children.OfType<XamlMemberNode>()) { |
|
||||||
if (memberNode.Member == XamlLanguage.ConnectionId && memberNode.Children.Single() is XamlValueNode) { |
|
||||||
var value = memberNode.Children.Single() as XamlValueNode; |
|
||||||
int id; |
|
||||||
if (value.Value is string && int.TryParse(value.Value as string, out id) && eventMappings.ContainsKey(id)) { |
|
||||||
var map = eventMappings[id]; |
|
||||||
foreach (var entry in map) { |
|
||||||
if (entry.IsAttached) { |
|
||||||
var type = context.GetXamlType(Type.GetType(entry.AttachSourceType)); |
|
||||||
var member = new XamlMemberNode(new XamlMember(entry.EventName, type, true)); |
|
||||||
member.Children.Add(new XamlValueNode(entry.MethodName)); |
|
||||||
addableNodes.Add(member); |
|
||||||
} else { |
|
||||||
var member = new XamlMemberNode(obj.Type.GetMember(entry.EventName)); |
|
||||||
member.Children.Add(new XamlValueNode(entry.MethodName)); |
|
||||||
addableNodes.Add(member); |
|
||||||
} |
|
||||||
} |
|
||||||
removableNodes.Add(memberNode); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
foreach (var rnode in removableNodes) |
|
||||||
node.Children.Remove(rnode); |
|
||||||
node.Children.InsertRange(node.Children.Count > 1 ? node.Children.Count - 1 : 0, addableNodes); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Changes all references from oldNamespace to newNamespace in the document.
|
|
||||||
/// </summary>
|
|
||||||
void ChangeXmlNamespace(XDocument doc, XNamespace oldNamespace, XNamespace newNamespace) |
|
||||||
{ |
|
||||||
foreach (XElement e in doc.Descendants()) { |
|
||||||
if (e.Name.Namespace == oldNamespace) |
|
||||||
e.Name = newNamespace + e.Name.LocalName; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
[Export(typeof(IResourceNodeFactory))] |
|
||||||
sealed class BamlResourceNodeFactory : IResourceNodeFactory |
|
||||||
{ |
|
||||||
public ILSpyTreeNode CreateNode(Mono.Cecil.Resource resource) |
|
||||||
{ |
|
||||||
return null; |
|
||||||
} |
|
||||||
|
|
||||||
public ILSpyTreeNode CreateNode(string key, Stream data) |
|
||||||
{ |
|
||||||
if (key.EndsWith(".baml", StringComparison.OrdinalIgnoreCase)) |
|
||||||
return new BamlResourceEntryNode(key, data); |
|
||||||
else |
|
||||||
return null; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
sealed class BamlResourceEntryNode : ResourceEntryNode |
|
||||||
{ |
|
||||||
public BamlResourceEntryNode(string key, Stream data) : base(key, data) |
|
||||||
{ |
|
||||||
} |
|
||||||
|
|
||||||
internal override bool View(DecompilerTextView textView) |
|
||||||
{ |
|
||||||
AvalonEditTextOutput output = new AvalonEditTextOutput(); |
|
||||||
IHighlightingDefinition highlighting = null; |
|
||||||
|
|
||||||
textView.RunWithCancellation( |
|
||||||
token => Task.Factory.StartNew( |
|
||||||
() => { |
|
||||||
try { |
|
||||||
if (LoadBaml(output)) |
|
||||||
highlighting = HighlightingManager.Instance.GetDefinitionByExtension(".xml"); |
|
||||||
} catch (Exception ex) { |
|
||||||
output.Write(ex.ToString()); |
|
||||||
} |
|
||||||
return output; |
|
||||||
}), |
|
||||||
t => textView.Show(t.Result, highlighting) |
|
||||||
); |
|
||||||
return true; |
|
||||||
} |
|
||||||
|
|
||||||
bool LoadBaml(AvalonEditTextOutput output) |
|
||||||
{ |
|
||||||
var asm = this.Ancestors().OfType<AssemblyTreeNode>().FirstOrDefault().LoadedAssembly; |
|
||||||
|
|
||||||
AppDomain bamlDecompilerAppDomain = null; |
|
||||||
try { |
|
||||||
BamlDecompiler decompiler = CreateBamlDecompilerInAppDomain(ref bamlDecompilerAppDomain, asm.FileName); |
|
||||||
|
|
||||||
MemoryStream bamlStream = new MemoryStream(); |
|
||||||
Data.Position = 0; |
|
||||||
Data.CopyTo(bamlStream); |
|
||||||
|
|
||||||
output.Write(decompiler.DecompileBaml(bamlStream, asm.FileName, new ConnectMethodDecompiler(asm), new AssemblyResolver(asm))); |
|
||||||
return true; |
|
||||||
} finally { |
|
||||||
if (bamlDecompilerAppDomain != null) |
|
||||||
AppDomain.Unload(bamlDecompilerAppDomain); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public static BamlDecompiler CreateBamlDecompilerInAppDomain(ref AppDomain appDomain, string assemblyFileName) |
|
||||||
{ |
|
||||||
if (appDomain == null) { |
|
||||||
// Construct and initialize settings for a second AppDomain.
|
|
||||||
AppDomainSetup bamlDecompilerAppDomainSetup = new AppDomainSetup(); |
|
||||||
// bamlDecompilerAppDomainSetup.ApplicationBase = "file:///" + Path.GetDirectoryName(assemblyFileName);
|
|
||||||
bamlDecompilerAppDomainSetup.DisallowBindingRedirects = false; |
|
||||||
bamlDecompilerAppDomainSetup.DisallowCodeDownload = true; |
|
||||||
bamlDecompilerAppDomainSetup.ConfigurationFile = AppDomain.CurrentDomain.SetupInformation.ConfigurationFile; |
|
||||||
|
|
||||||
// Create the second AppDomain.
|
|
||||||
appDomain = AppDomain.CreateDomain("BamlDecompiler AD", null, bamlDecompilerAppDomainSetup); |
|
||||||
} |
|
||||||
return (BamlDecompiler)appDomain.CreateInstanceAndUnwrap(typeof(BamlDecompiler).Assembly.FullName, typeof(BamlDecompiler).FullName); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
@ -0,0 +1,93 @@ |
|||||||
|
// 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.
|
||||||
|
|
||||||
|
using System; |
||||||
|
using System.ComponentModel; |
||||||
|
using System.Windows.Media; |
||||||
|
|
||||||
|
namespace ICSharpCode.ILSpy |
||||||
|
{ |
||||||
|
/// <summary>
|
||||||
|
/// Description of DisplaySettings.
|
||||||
|
/// </summary>
|
||||||
|
public class DisplaySettings : INotifyPropertyChanged |
||||||
|
{ |
||||||
|
public DisplaySettings() |
||||||
|
{ |
||||||
|
} |
||||||
|
|
||||||
|
#region INotifyPropertyChanged implementation
|
||||||
|
public event PropertyChangedEventHandler PropertyChanged; |
||||||
|
|
||||||
|
protected virtual void OnPropertyChanged(PropertyChangedEventArgs e) |
||||||
|
{ |
||||||
|
if (PropertyChanged != null) { |
||||||
|
PropertyChanged(this, e); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
protected void OnPropertyChanged(string propertyName) |
||||||
|
{ |
||||||
|
OnPropertyChanged(new PropertyChangedEventArgs(propertyName)); |
||||||
|
} |
||||||
|
#endregion
|
||||||
|
|
||||||
|
FontFamily selectedFont; |
||||||
|
|
||||||
|
public FontFamily SelectedFont { |
||||||
|
get { return selectedFont; } |
||||||
|
set { |
||||||
|
if (selectedFont != value) { |
||||||
|
selectedFont = value; |
||||||
|
OnPropertyChanged("SelectedFont"); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
double selectedFontSize; |
||||||
|
|
||||||
|
public double SelectedFontSize { |
||||||
|
get { return selectedFontSize; } |
||||||
|
set { |
||||||
|
if (selectedFontSize != value) { |
||||||
|
selectedFontSize = value; |
||||||
|
OnPropertyChanged("SelectedFontSize"); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
bool showLineNumbers; |
||||||
|
|
||||||
|
public bool ShowLineNumbers { |
||||||
|
get { return showLineNumbers; } |
||||||
|
set { |
||||||
|
if (showLineNumbers != value) { |
||||||
|
showLineNumbers = value; |
||||||
|
OnPropertyChanged("ShowLineNumbers"); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public void CopyValues(DisplaySettings s) |
||||||
|
{ |
||||||
|
this.SelectedFont = s.selectedFont; |
||||||
|
this.SelectedFontSize = s.selectedFontSize; |
||||||
|
this.ShowLineNumbers = s.showLineNumbers; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,64 @@ |
|||||||
|
<UserControl x:Class="ICSharpCode.ILSpy.DisplaySettingsPanel" |
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" |
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" |
||||||
|
xmlns:local="clr-namespace:ICSharpCode.ILSpy"> |
||||||
|
<UserControl.Resources> |
||||||
|
<local:FontSizeConverter x:Key="fontSizeConv" /> |
||||||
|
</UserControl.Resources> |
||||||
|
<Grid> |
||||||
|
<Grid.RowDefinitions> |
||||||
|
<RowDefinition Height="Auto"/> |
||||||
|
<RowDefinition/> |
||||||
|
</Grid.RowDefinitions> |
||||||
|
<GroupBox Header="Font"> |
||||||
|
<Grid> |
||||||
|
<Grid.ColumnDefinitions> |
||||||
|
<ColumnDefinition Width="Auto" /> |
||||||
|
<ColumnDefinition Width="*" /> |
||||||
|
<ColumnDefinition Width="Auto" /> |
||||||
|
<ColumnDefinition Width="Auto" /> |
||||||
|
</Grid.ColumnDefinitions> |
||||||
|
<Grid.RowDefinitions> |
||||||
|
<RowDefinition Height="Auto" /> |
||||||
|
<RowDefinition Height="50" /> |
||||||
|
</Grid.RowDefinitions> |
||||||
|
<Label Margin="3,0">Font:</Label> |
||||||
|
<ComboBox x:Name="fontSelector" VerticalContentAlignment="Center" SelectedItem="{Binding SelectedFont}" Grid.Column="1"> |
||||||
|
<ComboBox.ItemTemplate> |
||||||
|
<DataTemplate> |
||||||
|
<TextBlock Text="{Binding Source}" /> |
||||||
|
</DataTemplate> |
||||||
|
</ComboBox.ItemTemplate> |
||||||
|
</ComboBox> |
||||||
|
<Label Grid.Column="2" Margin="3,0">Size:</Label> |
||||||
|
<ComboBox Grid.Column="3" Text="{Binding SelectedFontSize, Converter={StaticResource fontSizeConv}}" IsEditable="True" Margin="3,0"> |
||||||
|
<ComboBoxItem>6</ComboBoxItem> |
||||||
|
<ComboBoxItem>7</ComboBoxItem> |
||||||
|
<ComboBoxItem>8</ComboBoxItem> |
||||||
|
<ComboBoxItem>9</ComboBoxItem> |
||||||
|
<ComboBoxItem>10</ComboBoxItem> |
||||||
|
<ComboBoxItem>11</ComboBoxItem> |
||||||
|
<ComboBoxItem>12</ComboBoxItem> |
||||||
|
<ComboBoxItem>13</ComboBoxItem> |
||||||
|
<ComboBoxItem>14</ComboBoxItem> |
||||||
|
<ComboBoxItem>15</ComboBoxItem> |
||||||
|
<ComboBoxItem>16</ComboBoxItem> |
||||||
|
<ComboBoxItem>17</ComboBoxItem> |
||||||
|
<ComboBoxItem>18</ComboBoxItem> |
||||||
|
<ComboBoxItem>19</ComboBoxItem> |
||||||
|
<ComboBoxItem>20</ComboBoxItem> |
||||||
|
<ComboBoxItem>21</ComboBoxItem> |
||||||
|
<ComboBoxItem>22</ComboBoxItem> |
||||||
|
<ComboBoxItem>23</ComboBoxItem> |
||||||
|
<ComboBoxItem>24</ComboBoxItem> |
||||||
|
</ComboBox> |
||||||
|
<Border Grid.Row="1" Grid.ColumnSpan="4" BorderBrush="Black" BorderThickness="1" Background="White" Margin="3,5"> |
||||||
|
<TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" Text="AaBbCcXxYyZz" FontFamily="{Binding SelectedFont}" FontSize="{Binding SelectedFontSize}" /> |
||||||
|
</Border> |
||||||
|
</Grid> |
||||||
|
</GroupBox> |
||||||
|
<GroupBox Header="Other options" Grid.Row="1"> |
||||||
|
<CheckBox Margin="3,3" IsChecked="{Binding ShowLineNumbers}">Show line numbers</CheckBox> |
||||||
|
</GroupBox> |
||||||
|
</Grid> |
||||||
|
</UserControl> |
@ -0,0 +1,154 @@ |
|||||||
|
// 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.
|
||||||
|
|
||||||
|
using System; |
||||||
|
using System.Collections.Generic; |
||||||
|
using System.Linq; |
||||||
|
using System.Text; |
||||||
|
using System.Threading.Tasks; |
||||||
|
using System.Windows; |
||||||
|
using System.Windows.Controls; |
||||||
|
using System.Windows.Data; |
||||||
|
using System.Windows.Documents; |
||||||
|
using System.Windows.Input; |
||||||
|
using System.Windows.Media; |
||||||
|
using System.Windows.Threading; |
||||||
|
using System.Xml.Linq; |
||||||
|
using ICSharpCode.Decompiler; |
||||||
|
|
||||||
|
namespace ICSharpCode.ILSpy |
||||||
|
{ |
||||||
|
/// <summary>
|
||||||
|
/// Interaction logic for DisplaySettingsPanel.xaml
|
||||||
|
/// </summary>
|
||||||
|
[ExportOptionPage("Display")] |
||||||
|
public partial class DisplaySettingsPanel : UserControl, IOptionPage |
||||||
|
{ |
||||||
|
public DisplaySettingsPanel() |
||||||
|
{ |
||||||
|
InitializeComponent(); |
||||||
|
|
||||||
|
Task<FontFamily[]> task = new Task<FontFamily[]>(FontLoader); |
||||||
|
task.Start(); |
||||||
|
task.ContinueWith( |
||||||
|
delegate(Task continuation) { |
||||||
|
App.Current.Dispatcher.Invoke( |
||||||
|
DispatcherPriority.Normal, |
||||||
|
(Action)( |
||||||
|
() => { |
||||||
|
fontSelector.ItemsSource = task.Result; |
||||||
|
if (continuation.Exception != null) { |
||||||
|
foreach (var ex in continuation.Exception.InnerExceptions) { |
||||||
|
MessageBox.Show(ex.ToString()); |
||||||
|
} |
||||||
|
} |
||||||
|
}) |
||||||
|
); |
||||||
|
} |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
public void Load(ILSpySettings settings) |
||||||
|
{ |
||||||
|
this.DataContext = LoadDisplaySettings(settings); |
||||||
|
} |
||||||
|
|
||||||
|
static DisplaySettings currentDisplaySettings; |
||||||
|
|
||||||
|
public static DisplaySettings CurrentDisplaySettings { |
||||||
|
get { |
||||||
|
return currentDisplaySettings ?? (currentDisplaySettings = LoadDisplaySettings(ILSpySettings.Load())); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
static bool IsSymbolFont(FontFamily fontFamily) |
||||||
|
{ |
||||||
|
foreach (var tf in fontFamily.GetTypefaces()) { |
||||||
|
GlyphTypeface glyph; |
||||||
|
try { |
||||||
|
if (tf.TryGetGlyphTypeface(out glyph)) |
||||||
|
return glyph.Symbol; |
||||||
|
} catch (Exception) { |
||||||
|
return true; |
||||||
|
} |
||||||
|
} |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
static FontFamily[] FontLoader() |
||||||
|
{ |
||||||
|
return Fonts.SystemFontFamilies |
||||||
|
.Where(ff => !IsSymbolFont(ff)) |
||||||
|
.OrderBy(ff => ff.Source) |
||||||
|
.ToArray(); |
||||||
|
} |
||||||
|
|
||||||
|
public static DisplaySettings LoadDisplaySettings(ILSpySettings settings) |
||||||
|
{ |
||||||
|
XElement e = settings["DisplaySettings"]; |
||||||
|
DisplaySettings s = new DisplaySettings(); |
||||||
|
s.SelectedFont = new FontFamily((string)e.Attribute("Font") ?? "Consolas"); |
||||||
|
s.SelectedFontSize = (double?)e.Attribute("FontSize") ?? 10.0 * 4 / 3; |
||||||
|
s.ShowLineNumbers = (bool?)e.Attribute("ShowLineNumbers") ?? false; |
||||||
|
|
||||||
|
return s; |
||||||
|
} |
||||||
|
|
||||||
|
public void Save(XElement root) |
||||||
|
{ |
||||||
|
DisplaySettings s = (DisplaySettings)this.DataContext; |
||||||
|
|
||||||
|
currentDisplaySettings.CopyValues(s); |
||||||
|
|
||||||
|
XElement section = new XElement("DisplaySettings"); |
||||||
|
section.SetAttributeValue("Font", s.SelectedFont.Source); |
||||||
|
section.SetAttributeValue("FontSize", s.SelectedFontSize); |
||||||
|
section.SetAttributeValue("ShowLineNumbers", s.ShowLineNumbers); |
||||||
|
|
||||||
|
XElement existingElement = root.Element("DisplaySettings"); |
||||||
|
if (existingElement != null) |
||||||
|
existingElement.ReplaceWith(section); |
||||||
|
else |
||||||
|
root.Add(section); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public class FontSizeConverter : IValueConverter |
||||||
|
{ |
||||||
|
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) |
||||||
|
{ |
||||||
|
if (value is double) { |
||||||
|
return Math.Round((double)value / 4 * 3); |
||||||
|
} |
||||||
|
|
||||||
|
throw new NotImplementedException(); |
||||||
|
} |
||||||
|
|
||||||
|
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) |
||||||
|
{ |
||||||
|
if (value is string) { |
||||||
|
double d; |
||||||
|
if (double.TryParse((string)value, out d)) |
||||||
|
return d * 4 / 3; |
||||||
|
return 11 * 4 / 3; |
||||||
|
} |
||||||
|
|
||||||
|
throw new NotImplementedException(); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
After Width: | Height: | Size: 569 B |
@ -0,0 +1,151 @@ |
|||||||
|
// 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.
|
||||||
|
|
||||||
|
using System; |
||||||
|
using System.Collections.Concurrent; |
||||||
|
using System.Collections.Generic; |
||||||
|
using System.Linq; |
||||||
|
using System.Threading; |
||||||
|
using ICSharpCode.TreeView; |
||||||
|
using Mono.Cecil; |
||||||
|
using Mono.Cecil.Cil; |
||||||
|
using ICSharpCode.Decompiler.Ast; |
||||||
|
|
||||||
|
namespace ICSharpCode.ILSpy.TreeNodes.Analyzer |
||||||
|
{ |
||||||
|
internal sealed class AnalyzedVirtualMethodUsedByTreeNode : AnalyzerTreeNode |
||||||
|
{ |
||||||
|
private readonly MethodDefinition analyzedMethod; |
||||||
|
private readonly ThreadingSupport threading; |
||||||
|
private ConcurrentDictionary<MethodDefinition, int> foundMethods; |
||||||
|
private MethodDefinition baseMethod; |
||||||
|
private List<TypeReference> possibleTypes; |
||||||
|
|
||||||
|
public AnalyzedVirtualMethodUsedByTreeNode(MethodDefinition analyzedMethod) |
||||||
|
{ |
||||||
|
if (analyzedMethod == null) |
||||||
|
throw new ArgumentNullException("analyzedMethod"); |
||||||
|
|
||||||
|
this.analyzedMethod = analyzedMethod; |
||||||
|
this.threading = new ThreadingSupport(); |
||||||
|
this.LazyLoading = true; |
||||||
|
} |
||||||
|
|
||||||
|
public override object Text |
||||||
|
{ |
||||||
|
get { return "Used By"; } |
||||||
|
} |
||||||
|
|
||||||
|
public override object Icon |
||||||
|
{ |
||||||
|
get { return Images.Search; } |
||||||
|
} |
||||||
|
|
||||||
|
protected override void LoadChildren() |
||||||
|
{ |
||||||
|
threading.LoadChildren(this, FetchChildren); |
||||||
|
} |
||||||
|
|
||||||
|
protected override void OnCollapsing() |
||||||
|
{ |
||||||
|
if (threading.IsRunning) { |
||||||
|
this.LazyLoading = true; |
||||||
|
threading.Cancel(); |
||||||
|
this.Children.Clear(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private IEnumerable<SharpTreeNode> FetchChildren(CancellationToken ct) |
||||||
|
{ |
||||||
|
InitializeAnalyzer(); |
||||||
|
|
||||||
|
var analyzer = new ScopedWhereUsedAnalyzer<SharpTreeNode>(analyzedMethod, FindReferencesInType); |
||||||
|
foreach (var child in analyzer.PerformAnalysis(ct)) { |
||||||
|
yield return child; |
||||||
|
} |
||||||
|
|
||||||
|
ReleaseAnalyzer(); |
||||||
|
} |
||||||
|
|
||||||
|
private void InitializeAnalyzer() |
||||||
|
{ |
||||||
|
foundMethods = new ConcurrentDictionary<MethodDefinition, int>(); |
||||||
|
|
||||||
|
var BaseMethods = TypesHierarchyHelpers.FindBaseMethods(analyzedMethod).ToArray(); |
||||||
|
if (BaseMethods.Length > 0) { |
||||||
|
baseMethod = BaseMethods[BaseMethods.Length - 1]; |
||||||
|
} |
||||||
|
|
||||||
|
possibleTypes = new List<TypeReference>(); |
||||||
|
|
||||||
|
TypeReference type = analyzedMethod.DeclaringType.BaseType; |
||||||
|
while (type !=null) |
||||||
|
{ |
||||||
|
possibleTypes.Add(type); |
||||||
|
type = type.Resolve().BaseType; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private void ReleaseAnalyzer() |
||||||
|
{ |
||||||
|
foundMethods = null; |
||||||
|
baseMethod = null; |
||||||
|
} |
||||||
|
|
||||||
|
private IEnumerable<SharpTreeNode> FindReferencesInType(TypeDefinition type) |
||||||
|
{ |
||||||
|
string name = analyzedMethod.Name; |
||||||
|
foreach (MethodDefinition method in type.Methods) { |
||||||
|
bool found = false; |
||||||
|
string prefix = string.Empty; |
||||||
|
if (!method.HasBody) |
||||||
|
continue; |
||||||
|
foreach (Instruction instr in method.Body.Instructions) { |
||||||
|
MethodReference mr = instr.Operand as MethodReference; |
||||||
|
if (mr != null && mr.Name == name) { |
||||||
|
// explicit call to the requested method
|
||||||
|
if (Helpers.IsReferencedBy(analyzedMethod.DeclaringType, mr.DeclaringType) && mr.Resolve() == analyzedMethod) { |
||||||
|
found = true; |
||||||
|
prefix = "(as base) "; |
||||||
|
break; |
||||||
|
} |
||||||
|
// virtual call to base method
|
||||||
|
if (instr.OpCode.Code == Code.Callvirt && Helpers.IsReferencedBy(baseMethod.DeclaringType, mr.DeclaringType) && mr.Resolve() == baseMethod) { |
||||||
|
found = true; |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
method.Body = null; |
||||||
|
|
||||||
|
if (found) { |
||||||
|
MethodDefinition codeLocation = this.Language.GetOriginalCodeLocation(method) as MethodDefinition; |
||||||
|
if (codeLocation != null && !HasAlreadyBeenFound(codeLocation)) { |
||||||
|
yield return new AnalyzedMethodTreeNode(codeLocation, prefix); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private bool HasAlreadyBeenFound(MethodDefinition method) |
||||||
|
{ |
||||||
|
return !foundMethods.TryAdd(method, 0); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue