Browse Source

Merge branch '1.0'

pull/219/merge
Daniel Grunwald 15 years ago
parent
commit
ffc7e031f3
  1. 1
      ICSharpCode.Decompiler/Ast/AstBuilder.cs
  2. 37
      ICSharpCode.Decompiler/Ast/AstMethodBodyBuilder.cs
  3. 19
      ICSharpCode.Decompiler/ILAst/ILAstOptimizer.cs
  4. 144
      ICSharpCode.Decompiler/ILAst/InitializerPeepholeTransforms.cs
  5. 27
      ICSharpCode.Decompiler/ILAst/TypeAnalysis.cs
  6. 2
      ICSharpCode.Decompiler/Tests/Helpers/CodeAssert.cs
  7. 742
      ICSharpCode.Decompiler/Tests/InitializerTests.cs
  8. 2
      ICSharpCode.Decompiler/Tests/TestRunner.cs
  9. 38
      ILSpy.BamlDecompiler/BamlResourceEntryNode.cs
  10. 11
      ILSpy.BamlDecompiler/CecilTypeResolver.cs
  11. 78
      ILSpy.BamlDecompiler/ConnectMethodDecompiler.cs
  12. 2
      ILSpy.BamlDecompiler/ILSpy.BamlDecompiler.csproj
  13. 11
      ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/BamlBinaryReader.cs
  14. 40
      ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/KeyMapping.cs
  15. 145
      ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/XmlBamlElement.cs
  16. 56
      ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/XmlBamlProperty.cs
  17. 3
      ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/XmlBamlPropertyElement.cs
  18. 467
      ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/XmlBamlReader.cs
  19. 6
      ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/XmlBamlSimpleProperty.cs
  20. 3
      ILSpy.BamlDecompiler/Tests/Cases/AttachedEvent.xaml
  21. 31
      ILSpy.BamlDecompiler/Tests/Cases/AttachedEvent.xaml.cs
  22. 53
      ILSpy.BamlDecompiler/Tests/Cases/AvalonDockBrushes.xaml
  23. 58
      ILSpy.BamlDecompiler/Tests/Cases/AvalonDockCommon.xaml
  24. 7
      ILSpy.BamlDecompiler/Tests/Cases/MyControl.xaml
  25. 26
      ILSpy.BamlDecompiler/Tests/Cases/MyControl.xaml.cs
  26. 16
      ILSpy.BamlDecompiler/Tests/Cases/Resources.xaml
  27. 26
      ILSpy.BamlDecompiler/Tests/Cases/Resources.xaml.cs
  28. 6
      ILSpy.BamlDecompiler/Tests/Cases/SimpleNames.xaml
  29. 26
      ILSpy.BamlDecompiler/Tests/Cases/SimpleNames.xaml.cs
  30. 24
      ILSpy.BamlDecompiler/Tests/ILSpy.BamlDecompiler.Tests.csproj
  31. 70
      ILSpy.BamlDecompiler/Tests/Mocks/AvalonDock.cs
  32. 34
      ILSpy.BamlDecompiler/Tests/TestRunner.cs
  33. 31
      ILSpy/Commands/ShowAnalyzerCommand.cs
  34. 2
      ILSpy/ILSpy.csproj
  35. 1
      ILSpy/Languages/CSharpLanguage.cs
  36. 4
      ILSpy/LoadedAssembly.cs
  37. 12
      ILSpy/TreeNodes/AssemblyTreeNode.cs
  38. 25
      ILSpy/TreeNodes/FieldTreeNode.cs
  39. 1
      NRefactory/ICSharpCode.NRefactory/CSharp/OutputVisitor/OutputVisitor.cs
  40. 2
      SharpTreeView/SharpTreeNodeView.cs
  41. 43
      SharpTreeView/SharpTreeView.cs
  42. 2
      TestPlugin/TestPlugin.csproj

1
ICSharpCode.Decompiler/Ast/AstBuilder.cs

@ -301,6 +301,7 @@ namespace ICSharpCode.Decompiler.Ast @@ -301,6 +301,7 @@ namespace ICSharpCode.Decompiler.Ast
}
} else {
EnumMemberDeclaration enumMember = new EnumMemberDeclaration();
enumMember.AddAnnotation(field);
enumMember.Name = CleanName(field.Name);
long memberValue = (long)CSharpPrimitiveCast.Cast(TypeCode.Int64, field.Constant, false);
if (forcePrintingInitializers || memberValue != expectedEnumMemberValue) {

37
ICSharpCode.Decompiler/Ast/AstMethodBodyBuilder.cs

@ -349,8 +349,7 @@ namespace ICSharpCode.Decompiler.Ast @@ -349,8 +349,7 @@ namespace ICSharpCode.Decompiler.Ast
}
#endregion
#region Arrays
case ILCode.Newarr:
case ILCode.InitArray: {
case ILCode.Newarr: {
var ace = new Ast.ArrayCreateExpression();
ace.Type = operandAsTypeRef;
ComposedType ct = operandAsTypeRef as ComposedType;
@ -366,7 +365,39 @@ namespace ICSharpCode.Decompiler.Ast @@ -366,7 +365,39 @@ namespace ICSharpCode.Decompiler.Ast
}
return ace;
}
case ILCode.Ldlen: return arg1.Member("Length");
case ILCode.InitArray: {
var ace = new Ast.ArrayCreateExpression();
ace.Type = operandAsTypeRef;
ComposedType ct = operandAsTypeRef as ComposedType;
var arrayType = (ArrayType) operand;
if (ct != null)
{
// change "new (int[,])[10] to new int[10][,]"
ct.ArraySpecifiers.MoveTo(ace.AdditionalArraySpecifiers);
ace.Initializer = new ArrayInitializerExpression();
var first = ace.AdditionalArraySpecifiers.First();
first.Remove();
ace.Arguments.AddRange(Enumerable.Repeat(0, first.Dimensions).Select(i => new EmptyExpression()));
}
var newArgs = new List<Expression>();
foreach (var arrayDimension in arrayType.Dimensions.Skip(1).Reverse())
{
int length = (int)arrayDimension.UpperBound - (int)arrayDimension.LowerBound;
for (int j = 0; j < args.Count; j += length)
{
var child = new ArrayInitializerExpression();
child.Elements.AddRange(args.GetRange(j, length));
newArgs.Add(child);
}
var temp = args;
args = newArgs;
newArgs = temp;
newArgs.Clear();
}
ace.Initializer.Elements.AddRange(args);
return ace;
}
case ILCode.Ldlen: return arg1.Member("Length");
case ILCode.Ldelem_I:
case ILCode.Ldelem_I1:
case ILCode.Ldelem_I2:

19
ICSharpCode.Decompiler/ILAst/ILAstOptimizer.cs

@ -46,6 +46,7 @@ namespace ICSharpCode.Decompiler.ILAst @@ -46,6 +46,7 @@ namespace ICSharpCode.Decompiler.ILAst
SimplifyLdObjAndStObj,
SimplifyCustomShortCircuit,
TransformArrayInitializers,
TransformMultidimensionalArrayInitializers,
TransformObjectInitializers,
MakeAssignmentExpression,
IntroducePostIncrement,
@ -143,6 +144,9 @@ namespace ICSharpCode.Decompiler.ILAst @@ -143,6 +144,9 @@ namespace ICSharpCode.Decompiler.ILAst
if (abortBeforeStep == ILAstOptimizationStep.TransformArrayInitializers) return;
modified |= block.RunOptimization(TransformArrayInitializers);
if (abortBeforeStep == ILAstOptimizationStep.TransformMultidimensionalArrayInitializers) return;
modified |= block.RunOptimization(TransformMultidimensionalArrayInitializers);
if (abortBeforeStep == ILAstOptimizationStep.TransformObjectInitializers) return;
modified |= block.RunOptimization(TransformObjectInitializers);
@ -738,9 +742,24 @@ namespace ICSharpCode.Decompiler.ILAst @@ -738,9 +742,24 @@ namespace ICSharpCode.Decompiler.ILAst
// property getters can't be expression statements, but all other method calls can be
MethodReference mr = (MethodReference)expr.Operand;
return !mr.Name.StartsWith("get_", StringComparison.Ordinal);
case ILCode.CallSetter:
case ILCode.CallvirtSetter:
case ILCode.Newobj:
case ILCode.Newarr:
case ILCode.Stloc:
case ILCode.Stobj:
case ILCode.Stsfld:
case ILCode.Stfld:
case ILCode.Stind_Ref:
case ILCode.Stelem_Any:
case ILCode.Stelem_I:
case ILCode.Stelem_I1:
case ILCode.Stelem_I2:
case ILCode.Stelem_I4:
case ILCode.Stelem_I8:
case ILCode.Stelem_R4:
case ILCode.Stelem_R8:
case ILCode.Stelem_Ref:
return true;
default:
return false;

144
ICSharpCode.Decompiler/ILAst/InitializerPeepholeTransforms.cs

@ -32,37 +32,23 @@ namespace ICSharpCode.Decompiler.ILAst @@ -32,37 +32,23 @@ namespace ICSharpCode.Decompiler.ILAst
#region Array Initializers
bool TransformArrayInitializers(List<ILNode> body, ILExpression expr, int pos)
{
ILVariable v, v2, v3;
ILVariable v, v3;
ILExpression newarrExpr;
TypeReference arrayType;
TypeReference elementType;
ILExpression lengthExpr;
int arrayLength;
if (expr.Match(ILCode.Stloc, out v, out newarrExpr) &&
newarrExpr.Match(ILCode.Newarr, out arrayType, out lengthExpr) &&
newarrExpr.Match(ILCode.Newarr, out elementType, out lengthExpr) &&
lengthExpr.Match(ILCode.Ldc_I4, out arrayLength) &&
arrayLength > 0)
{
MethodReference methodRef;
ILExpression methodArg1;
ILExpression methodArg2;
FieldDefinition field;
if (body.ElementAtOrDefault(pos + 1).Match(ILCode.Call, out methodRef, out methodArg1, out methodArg2) &&
methodRef.DeclaringType.FullName == "System.Runtime.CompilerServices.RuntimeHelpers" &&
methodRef.Name == "InitializeArray" &&
methodArg1.Match(ILCode.Ldloc, out v2) &&
v == v2 &&
methodArg2.Match(ILCode.Ldtoken, out field) &&
field != null && field.InitialValue != null)
{
ILExpression[] newArr = new ILExpression[arrayLength];
if (DecodeArrayInitializer(TypeAnalysis.GetTypeCode(arrayType), field.InitialValue, newArr)) {
body[pos] = new ILExpression(ILCode.Stloc, v, new ILExpression(ILCode.InitArray, arrayType, newArr));
body.RemoveAt(pos + 1);
new ILInlining(method).InlineIfPossible(body, ref pos);
return true;
}
arrayLength > 0) {
ILExpression[] newArr;
int initArrayPos;
if (ForwardScanInitializeArrayRuntimeHelper(body, pos + 1, v, elementType, arrayLength, out newArr, out initArrayPos)) {
var arrayType = new ArrayType(elementType, 1);
arrayType.Dimensions[0] = new ArrayDimension(0, arrayLength);
body[pos] = new ILExpression(ILCode.Stloc, v, new ILExpression(ILCode.InitArray, arrayType, newArr));
body.RemoveAt(initArrayPos);
}
// Put in a limit so that we don't consume too much memory if the code allocates a huge array
// and populates it extremely sparsly. However, 255 "null" elements in a row actually occur in the Mono C# compiler!
const int maxConsecutiveDefaultValueExpressions = 300;
@ -77,10 +63,9 @@ namespace ICSharpCode.Decompiler.ILAst @@ -77,10 +63,9 @@ namespace ICSharpCode.Decompiler.ILAst
v == v3 &&
nextExpr.Arguments[1].Match(ILCode.Ldc_I4, out arrayPos) &&
arrayPos >= operands.Count &&
arrayPos <= operands.Count + maxConsecutiveDefaultValueExpressions)
{
arrayPos <= operands.Count + maxConsecutiveDefaultValueExpressions) {
while (operands.Count < arrayPos)
operands.Add(new ILExpression(ILCode.DefaultValue, arrayType));
operands.Add(new ILExpression(ILCode.DefaultValue, elementType));
operands.Add(nextExpr.Arguments[2]);
numberOfInstructionsToRemove++;
} else {
@ -88,16 +73,77 @@ namespace ICSharpCode.Decompiler.ILAst @@ -88,16 +73,77 @@ namespace ICSharpCode.Decompiler.ILAst
}
}
if (operands.Count == arrayLength) {
var arrayType = new ArrayType(elementType, 1);
arrayType.Dimensions[0] = new ArrayDimension(0, arrayLength);
expr.Arguments[0] = new ILExpression(ILCode.InitArray, arrayType, operands);
body.RemoveRange(pos + 1, numberOfInstructionsToRemove);
new ILInlining(method).InlineIfPossible(body, ref pos);
return true;
}
}
return false;
}
bool TransformMultidimensionalArrayInitializers(List<ILNode> body, ILExpression expr, int pos)
{
ILVariable v;
ILExpression newarrExpr;
MethodReference ctor;
List<ILExpression> ctorArgs;
ArrayType arrayType;
if (expr.Match(ILCode.Stloc, out v, out newarrExpr) &&
newarrExpr.Match(ILCode.Newobj, out ctor, out ctorArgs) &&
(arrayType = (ctor.DeclaringType as ArrayType)) != null &&
arrayType.Rank == ctorArgs.Count) {
// Clone the type, so we can muck about with the Dimensions
arrayType = new ArrayType(arrayType.ElementType, arrayType.Rank);
var arrayLengths = new int[arrayType.Rank];
for (int i = 0; i < arrayType.Rank; i++) {
if (!ctorArgs[i].Match(ILCode.Ldc_I4, out arrayLengths[i])) return false;
if (arrayLengths[i] <= 0) return false;
arrayType.Dimensions[i] = new ArrayDimension(0, arrayLengths[i]);
}
var totalElements = arrayLengths.Aggregate(1, (t, l) => t * l);
ILExpression[] newArr;
int initArrayPos;
if (ForwardScanInitializeArrayRuntimeHelper(body, pos + 1, v, arrayType, totalElements, out newArr, out initArrayPos)) {
var mdArr = Array.CreateInstance(typeof(ILExpression), arrayLengths);
body[pos] = new ILExpression(ILCode.Stloc, v, new ILExpression(ILCode.InitArray, arrayType, newArr));
body.RemoveAt(initArrayPos);
return true;
}
}
return false;
}
bool ForwardScanInitializeArrayRuntimeHelper(List<ILNode> body, int pos, ILVariable array, TypeReference arrayType, int arrayLength, out ILExpression[] values, out int foundPos)
{
ILVariable v2;
MethodReference methodRef;
ILExpression methodArg1;
ILExpression methodArg2;
FieldDefinition field;
if (body.ElementAtOrDefault(pos).Match(ILCode.Call, out methodRef, out methodArg1, out methodArg2) &&
methodRef.DeclaringType.FullName == "System.Runtime.CompilerServices.RuntimeHelpers" &&
methodRef.Name == "InitializeArray" &&
methodArg1.Match(ILCode.Ldloc, out v2) &&
array == v2 &&
methodArg2.Match(ILCode.Ldtoken, out field) &&
field != null && field.InitialValue != null) {
ILExpression[] newArr = new ILExpression[arrayLength];
if (DecodeArrayInitializer(TypeAnalysis.GetTypeCode(arrayType.GetElementType()), field.InitialValue, newArr)) {
values = newArr;
foundPos = pos;
return true;
}
}
values = null;
foundPos = -1;
return false;
}
static bool DecodeArrayInitializer(TypeCode elementType, byte[] initialValue, ILExpression[] output)
{
switch (elementType) {
@ -160,7 +206,7 @@ namespace ICSharpCode.Decompiler.ILAst @@ -160,7 +206,7 @@ namespace ICSharpCode.Decompiler.ILAst
}
}
#endregion
/// <summary>
/// Handles both object and collection initializers.
/// </summary>
@ -168,7 +214,7 @@ namespace ICSharpCode.Decompiler.ILAst @@ -168,7 +214,7 @@ namespace ICSharpCode.Decompiler.ILAst
{
if (!context.Settings.ObjectOrCollectionInitializers)
return false;
Debug.Assert(body[pos] == expr); // should be called for top-level expressions only
ILVariable v;
ILExpression newObjExpr;
@ -182,19 +228,19 @@ namespace ICSharpCode.Decompiler.ILAst @@ -182,19 +228,19 @@ namespace ICSharpCode.Decompiler.ILAst
// don't use object initializer syntax for closures
if (Ast.Transforms.DelegateConstruction.IsPotentialClosure(context, ctor.DeclaringType.ResolveWithinSameModule()))
return false;
ILExpression initializer = ParseObjectInitializer(body, ref pos, v, newObjExpr, IsCollectionType(ctor.DeclaringType));
if (initializer.Arguments.Count == 1) // only newobj argument, no initializer elements
return false;
int totalElementCount = pos - originalPos - 1; // totalElementCount: includes elements from nested collections
Debug.Assert(totalElementCount >= initializer.Arguments.Count - 1);
// Verify that we can inline 'v' into the next instruction:
if (pos >= body.Count)
return false; // reached end of block, but there should be another instruction which consumes the initialized object
ILInlining inlining = new ILInlining(method);
// one ldloc for each initializer argument, and another ldloc for the use of the initialized object
if (inlining.numLdloc.GetOrDefault(v) != totalElementCount + 1)
@ -204,20 +250,20 @@ namespace ICSharpCode.Decompiler.ILAst @@ -204,20 +250,20 @@ namespace ICSharpCode.Decompiler.ILAst
ILExpression nextExpr = body[pos] as ILExpression;
if (!inlining.CanInlineInto(nextExpr, v, initializer))
return false;
expr.Arguments[0] = initializer;
// remove all the instructions that were pulled into the initializer
body.RemoveRange(originalPos + 1, pos - originalPos - 1);
// now that we know that it's an object initializer, change all the first arguments to 'InitializedObject'
ChangeFirstArgumentToInitializedObject(initializer);
inlining = new ILInlining(method);
inlining.InlineIfPossible(body, ref originalPos);
return true;
}
/// <summary>
/// Gets whether the type supports collection initializers.
/// </summary>
@ -233,7 +279,7 @@ namespace ICSharpCode.Decompiler.ILAst @@ -233,7 +279,7 @@ namespace ICSharpCode.Decompiler.ILAst
}
return false;
}
/// <summary>
/// Gets whether 'expr' represents a setter in an object initializer.
/// ('CallvirtSetter(Property, v, value)')
@ -247,7 +293,7 @@ namespace ICSharpCode.Decompiler.ILAst @@ -247,7 +293,7 @@ namespace ICSharpCode.Decompiler.ILAst
}
return false;
}
/// <summary>
/// Gets whether 'expr' represents the invocation of an 'Add' method in a collection initializer.
/// </summary>
@ -262,7 +308,7 @@ namespace ICSharpCode.Decompiler.ILAst @@ -262,7 +308,7 @@ namespace ICSharpCode.Decompiler.ILAst
}
return false;
}
/// <summary>
/// Parses an object initializer.
/// </summary>
@ -304,7 +350,7 @@ namespace ICSharpCode.Decompiler.ILAst @@ -304,7 +350,7 @@ namespace ICSharpCode.Decompiler.ILAst
}
return objectInitializer;
}
static bool AdjustInitializerStack(List<ILExpression> initializerStack, ILExpression argument, ILVariable v, bool isCollection)
{
// Argument is of the form 'getter(getter(...(v)))'
@ -340,7 +386,7 @@ namespace ICSharpCode.Decompiler.ILAst @@ -340,7 +386,7 @@ namespace ICSharpCode.Decompiler.ILAst
returnType = TypeAnalysis.GetFieldType((FieldReference)mr);
else
returnType = TypeAnalysis.SubstituteTypeArgs(((MethodReference)mr).ReturnType, mr);
ILExpression nestedInitializer = new ILExpression(
IsCollectionType(returnType) ? ILCode.InitCollection : ILCode.InitObject,
null, g);
@ -375,7 +421,7 @@ namespace ICSharpCode.Decompiler.ILAst @@ -375,7 +421,7 @@ namespace ICSharpCode.Decompiler.ILAst
}
}
}
static void CleanupInitializerStackAfterFailedAdjustment(List<ILExpression> initializerStack)
{
// There might be empty nested initializers left over; so we'll remove those:
@ -386,7 +432,7 @@ namespace ICSharpCode.Decompiler.ILAst @@ -386,7 +432,7 @@ namespace ICSharpCode.Decompiler.ILAst
initializerStack.RemoveAt(initializerStack.Count - 1);
}
}
static void ChangeFirstArgumentToInitializedObject(ILExpression initializer)
{
// Go through all elements in the initializer (so skip the newobj-instr. at the start)

27
ICSharpCode.Decompiler/ILAst/TypeAnalysis.cs

@ -568,11 +568,13 @@ namespace ICSharpCode.Decompiler.ILAst @@ -568,11 +568,13 @@ namespace ICSharpCode.Decompiler.ILAst
InferTypeForExpression(expr.Arguments.Single(), typeSystem.Int32);
return new ArrayType((TypeReference)expr.Operand);
case ILCode.InitArray:
if (forceInferChildren) {
var operandAsArrayType = (ArrayType)expr.Operand;
if (forceInferChildren)
{
foreach (ILExpression arg in expr.Arguments)
InferTypeForExpression(arg, (TypeReference)expr.Operand);
InferTypeForExpression(arg, operandAsArrayType.ElementType);
}
return new ArrayType((TypeReference)expr.Operand);
return operandAsArrayType;
case ILCode.Ldlen:
return typeSystem.Int32;
case ILCode.Ldelem_U1:
@ -955,7 +957,7 @@ namespace ICSharpCode.Decompiler.ILAst @@ -955,7 +957,7 @@ namespace ICSharpCode.Decompiler.ILAst
{
if (type == null)
return 0;
if (type.IsValueType) {
if (type.IsValueType && !IsArrayPointerOrReference(type)) {
// value type might be an enum
TypeDefinition typeDef = type.Resolve() as TypeDefinition;
if (typeDef != null && typeDef.IsEnum) {
@ -1003,7 +1005,9 @@ namespace ICSharpCode.Decompiler.ILAst @@ -1003,7 +1005,9 @@ namespace ICSharpCode.Decompiler.ILAst
public static bool IsEnum(TypeReference type)
{
if (type == null)
// Arrays/Pointers/ByReference resolve to their element type, but we don't want to consider those to be enums
// However, GenericInstanceTypes, ModOpts etc. should be considered enums.
if (type == null || IsArrayPointerOrReference(type))
return false;
// unfortunately we cannot rely on type.IsValueType here - it's not set when the instruction operand is a typeref (as opposed to a typespec)
TypeDefinition typeDef = type.Resolve() as TypeDefinition;
@ -1012,7 +1016,7 @@ namespace ICSharpCode.Decompiler.ILAst @@ -1012,7 +1016,7 @@ namespace ICSharpCode.Decompiler.ILAst
static bool? IsSigned(TypeReference type)
{
if (type == null)
if (type == null || IsArrayPointerOrReference(type))
return null;
// unfortunately we cannot rely on type.IsValueType here - it's not set when the instruction operand is a typeref (as opposed to a typespec)
TypeDefinition typeDef = type.Resolve() as TypeDefinition;
@ -1039,6 +1043,17 @@ namespace ICSharpCode.Decompiler.ILAst @@ -1039,6 +1043,17 @@ namespace ICSharpCode.Decompiler.ILAst
}
}
static bool IsArrayPointerOrReference(TypeReference type)
{
TypeSpecification typeSpec = type as TypeSpecification;
while (typeSpec != null) {
if (typeSpec is ArrayType || typeSpec is PointerType || typeSpec is ByReferenceType)
return true;
typeSpec = typeSpec.ElementType as TypeSpecification;
}
return false;
}
public static TypeCode GetTypeCode(TypeReference type)
{
if (type == null)

2
ICSharpCode.Decompiler/Tests/Helpers/CodeAssert.cs

@ -89,6 +89,8 @@ namespace ICSharpCode.Decompiler.Tests.Helpers @@ -89,6 +89,8 @@ namespace ICSharpCode.Decompiler.Tests.Helpers
var index = line.IndexOf("//");
if (index >= 0) {
return line.Substring(0, index);
} else if (line.StartsWith("#")) {
return string.Empty;
} else {
return line;
}

742
ICSharpCode.Decompiler/Tests/InitializerTests.cs

@ -21,20 +21,21 @@ using System.Collections.Generic; @@ -21,20 +21,21 @@ using System.Collections.Generic;
public class InitializerTests
{
enum MyEnum
private enum MyEnum
{
a,
b
}
enum MyEnum2
private enum MyEnum2
{
c,
d
}
class Data
private class Data
{
public List<InitializerTests.MyEnum2> FieldList = new List<InitializerTests.MyEnum2>();
public InitializerTests.MyEnum a
{
get;
@ -45,218 +46,749 @@ public class InitializerTests @@ -45,218 +46,749 @@ public class InitializerTests
get;
set;
}
public List<InitializerTests.MyEnum2> FieldList = new List<InitializerTests.MyEnum2>();
public InitializerTests.Data MoreData { get; set; }
public InitializerTests.Data MoreData
{
get;
set;
}
}
// Helper methods used to ensure initializers used within expressions work correctly
static void X(object a, object b)
private static void X(object a, object b)
{
}
static object Y()
private static object Y()
{
return null;
}
#region Array Initializers
public static void Array1()
{
X(Y(), new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 });
InitializerTests.X(InitializerTests.Y(), new int[]
{
1,
2,
3,
4,
5,
6,
7,
8,
9,
10
});
}
public static void Array2(int a, int b, int c)
{
X(Y(), new int[] { a, 0, b, 0, c });
InitializerTests.X(InitializerTests.Y(), new int[]
{
a,
0,
b,
0,
c
});
}
public static void NestedArray(int a, int b, int c)
{
X(Y(), new int[][] {
new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 },
new int[] { a, b, c },
new int[] { 1, 2, 3, 4, 5, 6 }
InitializerTests.X(InitializerTests.Y(), new int[][]
{
new int[]
{
1,
2,
3,
4,
5,
6,
7,
8,
9,
10
},
new int[]
{
a,
b,
c
},
new int[]
{
1,
2,
3,
4,
5,
6
}
});
}
public static void ArrayBoolean()
{
X(Y(), new bool[] { true, false, true, false, false, false, true, true });
InitializerTests.X(InitializerTests.Y(), new bool[]
{
true,
false,
true,
false,
false,
false,
true,
true
});
}
public static void ArrayByte()
{
X(Y(), new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 254, 255 });
InitializerTests.X(InitializerTests.Y(), new byte[]
{
1,
2,
3,
4,
5,
6,
7,
8,
254,
255
});
}
public static void ArraySByte()
{
X(Y(), new sbyte[] { -128, -127, 0, 1, 2, 3, 4, 127 });
InitializerTests.X(InitializerTests.Y(), new sbyte[]
{
-128,
-127,
0,
1,
2,
3,
4,
127
});
}
public static void ArrayShort()
{
X(Y(), new short[] { -32768, -1, 0, 1, 32767 });
InitializerTests.X(InitializerTests.Y(), new short[]
{
-32768,
-1,
0,
1,
32767
});
}
public static void ArrayUShort()
{
X(Y(), new ushort[] { 0, 1, 32767, 32768, 65534, 65535 });
InitializerTests.X(InitializerTests.Y(), new ushort[]
{
0,
1,
32767,
32768,
65534,
65535
});
}
public static void ArrayInt()
{
X(Y(), new int[] { 1, -2, 2000000000, 4, 5, -6, 7, 8, 9, 10 });
InitializerTests.X(InitializerTests.Y(), new int[]
{
1,
-2,
2000000000,
4,
5,
-6,
7,
8,
9,
10
});
}
public static void ArrayUInt()
{
X(Y(), new uint[] { 1, 2000000000, 3000000000, 4, 5, 6, 7, 8, 9, 10 });
InitializerTests.X(InitializerTests.Y(), new uint[]
{
1u,
2000000000u,
3000000000u,
4u,
5u,
6u,
7u,
8u,
9u,
10u
});
}
public static void ArrayLong()
{
X(Y(), new long[] { -4999999999999999999, -1, 0, 1, 4999999999999999999 });
InitializerTests.X(InitializerTests.Y(), new long[]
{
-4999999999999999999L,
-1L,
0L,
1L,
4999999999999999999L
});
}
public static void ArrayULong()
{
X(Y(), new ulong[] { 1, 2000000000, 3000000000, 4, 5, 6, 7, 8, 4999999999999999999, 9999999999999999999 });
InitializerTests.X(InitializerTests.Y(), new ulong[]
{
1uL,
2000000000uL,
3000000000uL,
4uL,
5uL,
6uL,
7uL,
8uL,
4999999999999999999uL,
9999999999999999999uL
});
}
public static void ArrayFloat()
{
X(Y(), new float[] { -1.5f, 0f, 1.5f, float.NegativeInfinity, float.PositiveInfinity, float.NaN });
InitializerTests.X(InitializerTests.Y(), new float[]
{
-1.5f,
0f,
1.5f,
float.NegativeInfinity,
float.PositiveInfinity,
float.NaN
});
}
public static void ArrayDouble()
{
X(Y(), new double[] { -1.5, 0.0, 1.5, double.NegativeInfinity, double.PositiveInfinity, double.NaN });
InitializerTests.X(InitializerTests.Y(), new double[]
{
-1.5,
0.0,
1.5,
double.NegativeInfinity,
double.PositiveInfinity,
double.NaN
});
}
public static void ArrayDecimal()
{
X(Y(), new decimal[] { -100m, 0m, 100m, decimal.MinValue, decimal.MaxValue, 0.0000001m });
InitializerTests.X(InitializerTests.Y(), new decimal[]
{
-100m,
0m,
100m,
-79228162514264337593543950335m,
79228162514264337593543950335m,
0.0000001m
});
}
public static void ArrayString()
{
X(Y(), new string[] { "", null, "Hello", "World" });
InitializerTests.X(InitializerTests.Y(), new string[]
{
"",
null,
"Hello",
"World"
});
}
public static void ArrayEnum()
{
X(Y(), new InitializerTests.MyEnum[] { InitializerTests.MyEnum.a, InitializerTests.MyEnum.b, InitializerTests.MyEnum.a, InitializerTests.MyEnum.b });
InitializerTests.X(InitializerTests.Y(), new InitializerTests.MyEnum[]
{
InitializerTests.MyEnum.a,
InitializerTests.MyEnum.b,
InitializerTests.MyEnum.a,
InitializerTests.MyEnum.b
});
}
#endregion
public static void CollectionInitializerList()
{
X(Y(), new List<int> { 1, 2, 3 });
InitializerTests.X(InitializerTests.Y(), new List<int>
{
1,
2,
3
});
}
public static void CollectionInitializerDictionary()
{
X(Y(), new Dictionary<string, int> {
{ "First", 1 },
{ "Second", 2 },
{ "Third" , 3 }
InitializerTests.X(InitializerTests.Y(), new Dictionary<string, int>
{
{
"First",
1
},
{
"Second",
2
},
{
"Third",
3
}
});
}
public static void CollectionInitializerDictionaryWithEnumTypes()
{
X(Y(), new Dictionary<InitializerTests.MyEnum, InitializerTests.MyEnum2> {
{ InitializerTests.MyEnum.a, InitializerTests.MyEnum2.c },
{ InitializerTests.MyEnum.b, InitializerTests.MyEnum2.d }
InitializerTests.X(InitializerTests.Y(), new Dictionary<InitializerTests.MyEnum, InitializerTests.MyEnum2>
{
{
InitializerTests.MyEnum.a,
InitializerTests.MyEnum2.c
},
{
InitializerTests.MyEnum.b,
InitializerTests.MyEnum2.d
}
});
}
public static void NotACollectionInitializer()
{
List<int> list = new List<int>();
list.Add(1);
list.Add(2);
list.Add(3);
X(Y(), list);
InitializerTests.X(InitializerTests.Y(), list);
}
public static void ObjectInitializer()
{
X(Y(), new Data
InitializerTests.X(InitializerTests.Y(), new InitializerTests.Data
{
a = InitializerTests.MyEnum.a
a = InitializerTests.MyEnum.a
});
}
public static void NotAObjectInitializer()
{
Data data = new InitializerTests.Data();
InitializerTests.Data data = new InitializerTests.Data();
data.a = InitializerTests.MyEnum.a;
X(Y(), data);
InitializerTests.X(InitializerTests.Y(), data);
}
public static void ObjectInitializerAssignCollectionToField()
{
X(Y(), new InitializerTests.Data
InitializerTests.X(InitializerTests.Y(), new InitializerTests.Data
{
a = InitializerTests.MyEnum.a,
FieldList = new List<InitializerTests.MyEnum2>
{
InitializerTests.MyEnum2.c,
InitializerTests.MyEnum2.d
}
a = InitializerTests.MyEnum.a,
FieldList = new List<InitializerTests.MyEnum2>
{
InitializerTests.MyEnum2.c,
InitializerTests.MyEnum2.d
}
});
}
public static void ObjectInitializerAddToCollectionInField()
{
X(Y(), new InitializerTests.Data
InitializerTests.X(InitializerTests.Y(), new InitializerTests.Data
{
a = InitializerTests.MyEnum.a,
FieldList =
{
InitializerTests.MyEnum2.c,
InitializerTests.MyEnum2.d
}
a = InitializerTests.MyEnum.a,
FieldList =
{
InitializerTests.MyEnum2.c,
InitializerTests.MyEnum2.d
}
});
}
public static void ObjectInitializerAssignCollectionToProperty()
{
X(Y(), new InitializerTests.Data
InitializerTests.X(InitializerTests.Y(), new InitializerTests.Data
{
a = InitializerTests.MyEnum.a,
PropertyList = new List<InitializerTests.MyEnum2>
{
InitializerTests.MyEnum2.c,
InitializerTests.MyEnum2.d
}
a = InitializerTests.MyEnum.a,
PropertyList = new List<InitializerTests.MyEnum2>
{
InitializerTests.MyEnum2.c,
InitializerTests.MyEnum2.d
}
});
}
public static void ObjectInitializerAddToCollectionInProperty()
{
X(Y(), new InitializerTests.Data
InitializerTests.X(InitializerTests.Y(), new InitializerTests.Data
{
a = InitializerTests.MyEnum.a,
PropertyList =
{
InitializerTests.MyEnum2.c,
InitializerTests.MyEnum2.d
}
a = InitializerTests.MyEnum.a,
PropertyList =
{
InitializerTests.MyEnum2.c,
InitializerTests.MyEnum2.d
}
});
}
public static void ObjectInitializerWithInitializationOfNestedObjects()
{
X(Y(), new InitializerTests.Data
InitializerTests.X(InitializerTests.Y(), new InitializerTests.Data
{
MoreData =
{
a = InitializerTests.MyEnum.a
}
MoreData =
{
a = InitializerTests.MyEnum.a
}
});
}
public void MultidimensionalInit()
{
int[,] expr_09 = new int[, ]
{
{
0,
0,
0,
0
},
{
1,
1,
1,
1
},
{
0,
0,
0,
0
},
{
0,
0,
0,
0
},
{
0,
0,
1,
0
},
{
0,
0,
1,
0
},
{
0,
0,
1,
0
},
{
0,
0,
1,
0
},
{
0,
0,
0,
0
},
{
1,
1,
1,
1
},
{
0,
0,
0,
0
},
{
0,
0,
0,
0
},
{
0,
0,
1,
0
},
{
0,
0,
1,
0
},
{
0,
0,
1,
0
},
{
0,
0,
1,
0
}
};
}
public void MultidimensionalInit2()
{
int[][,] array = new int[][,]
{
new int[, ]
{
{
0,
0,
0,
0
},
{
1,
1,
1,
1
},
{
0,
0,
0,
0
},
{
0,
0,
0,
0
}
},
new int[, ]
{
{
0,
0,
1,
0
},
{
0,
0,
1,
0
},
{
0,
0,
1,
0
},
{
0,
0,
1,
0
}
},
new int[, ]
{
{
0,
0,
0,
0
},
{
1,
1,
1,
1
},
{
0,
0,
0,
0
},
{
0,
0,
0,
0
}
},
new int[, ]
{
{
0,
0,
1,
0
},
{
0,
0,
1,
0
},
{
0,
0,
1,
0
},
{
0,
0,
1,
0
}
}
};
}
public void ArrayOfArrayOfArrayInit()
{
int[][,,] array = new int[][,,]
{
new int[, , ]
{
{
{
1,
2,
3
},
{
4,
5,
6
},
{
7,
8,
9
}
},
{
{
11,
12,
13
},
{
14,
15,
16
},
{
17,
18,
19
}
}
},
new int[, , ]
{
{
{
21,
22,
23
},
{
24,
25,
26
},
{
27,
28,
29
}
},
{
{
31,
32,
33
},
{
34,
35,
36
},
{
37,
38,
39
}
}
}
};
}
}

2
ICSharpCode.Decompiler/Tests/TestRunner.cs

@ -76,7 +76,7 @@ namespace ICSharpCode.Decompiler.Tests @@ -76,7 +76,7 @@ namespace ICSharpCode.Decompiler.Tests
TestFile(@"..\..\Tests\IncrementDecrement.cs");
}
[Test, Ignore("Formatting issues (array initializers not on single line)")]
[Test]
public void InitializerTests()
{
TestFile(@"..\..\Tests\InitializerTests.cs");

38
ILSpy.BamlDecompiler/BamlResourceEntryNode.cs

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

11
ILSpy.BamlDecompiler/CecilTypeResolver.cs

@ -25,7 +25,16 @@ namespace ILSpy.BamlDecompiler @@ -25,7 +25,16 @@ namespace ILSpy.BamlDecompiler
public bool IsLocalAssembly(string name)
{
return name == this.thisAssembly.Name.Name;
return MakeShort(name) == this.thisAssembly.Name.Name;
}
string MakeShort(string name)
{
int endOffset = name.IndexOf(',');
if (endOffset == -1)
return name;
return name.Substring(0, endOffset);
}
public IType GetTypeByAssemblyQualifiedName(string name)

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

@ -1,47 +1,34 @@ @@ -1,47 +1,34 @@
// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software
// without restriction, including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
// to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or
// substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team
// This code is distributed under the MS-PL (for details please see \doc\MS-PL.txt)
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.ILAst;
using Mono.Cecil;
using Mono.Cecil.Cil;
namespace ICSharpCode.ILSpy.Baml
namespace ILSpy.BamlDecompiler
{
[Serializable]
/// <summary>
/// Represents an event registration of a XAML code-behind class.
/// </summary>
sealed class EventRegistration
{
public string EventName, MethodName, AttachSourceType;
public string EventName, MethodName;
public TypeDefinition AttachSourceType;
public bool IsAttached;
}
/// <summary>
/// Description of ConnectMethodDecompiler.
/// Decompiles event and name mappings of XAML code-behind classes.
/// </summary>
sealed class ConnectMethodDecompiler : MarshalByRefObject
sealed class ConnectMethodDecompiler
{
LoadedAssembly assembly;
AssemblyDefinition assembly;
public ConnectMethodDecompiler(LoadedAssembly assembly)
public ConnectMethodDecompiler(AssemblyDefinition assembly)
{
this.assembly = assembly;
}
@ -49,7 +36,7 @@ namespace ICSharpCode.ILSpy.Baml @@ -49,7 +36,7 @@ namespace ICSharpCode.ILSpy.Baml
public Dictionary<int, EventRegistration[]> DecompileEventMappings(string fullTypeName)
{
var result = new Dictionary<int, EventRegistration[]>();
TypeDefinition type = this.assembly.AssemblyDefinition.MainModule.GetType(fullTypeName);
TypeDefinition type = this.assembly.MainModule.GetType(fullTypeName);
if (type == null)
return result;
@ -98,7 +85,8 @@ namespace ICSharpCode.ILSpy.Baml @@ -98,7 +85,8 @@ namespace ICSharpCode.ILSpy.Baml
foreach (var node in block.Body) {
var expr = node as ILExpression;
string eventName, handlerName, attachSource;
string eventName, handlerName;
TypeDefinition attachSource;
if (IsAddEvent(expr, out eventName, out handlerName))
events.Add(new EventRegistration {
EventName = eventName,
@ -116,11 +104,11 @@ namespace ICSharpCode.ILSpy.Baml @@ -116,11 +104,11 @@ namespace ICSharpCode.ILSpy.Baml
return events.ToArray();
}
bool IsAddAttachedEvent(ILExpression expr, out string eventName, out string handlerName, out string attachSource)
bool IsAddAttachedEvent(ILExpression expr, out string eventName, out string handlerName, out TypeDefinition attachSource)
{
eventName = "";
handlerName = "";
attachSource = "";
attachSource = null;
if (expr == null || !(expr.Code == ILCode.Callvirt || expr.Code == ILCode.Call))
return false;
@ -133,7 +121,7 @@ namespace ICSharpCode.ILSpy.Baml @@ -133,7 +121,7 @@ namespace ICSharpCode.ILSpy.Baml
if (arg.Code != ILCode.Ldsfld || arg.Arguments.Any() || !(arg.Operand is FieldReference))
return false;
FieldReference fldRef = (FieldReference)arg.Operand;
attachSource = GetAssemblyQualifiedName(fldRef.DeclaringType);
attachSource = fldRef.DeclaringType.Resolve();
eventName = fldRef.Name;
if (eventName.EndsWith("Event") && eventName.Length > "Event".Length)
eventName = eventName.Remove(eventName.Length - "Event".Length);
@ -153,18 +141,6 @@ namespace ICSharpCode.ILSpy.Baml @@ -153,18 +141,6 @@ namespace ICSharpCode.ILSpy.Baml
return false;
}
string GetAssemblyQualifiedName(TypeReference declaringType)
{
string fullName = declaringType.FullName;
if (declaringType.Scope is AssemblyNameReference)
fullName += ", " + ((AssemblyNameReference)declaringType.Scope).FullName;
else if (declaringType.Scope is ModuleDefinition)
fullName += ", " + ((ModuleDefinition)declaringType.Scope).Assembly.FullName;
return fullName;
}
bool IsAddEvent(ILExpression expr, out string eventName, out string handlerName)
{
eventName = "";
@ -193,20 +169,4 @@ namespace ICSharpCode.ILSpy.Baml @@ -193,20 +169,4 @@ namespace ICSharpCode.ILSpy.Baml
return false;
}
}
sealed class AssemblyResolver : MarshalByRefObject
{
LoadedAssembly assembly;
public AssemblyResolver(LoadedAssembly assembly)
{
this.assembly = assembly;
}
public string FindAssembly(string name)
{
var asm = assembly.LookupReferencedAssembly(name);
return asm == null ? null : asm.FileName;
}
}
}

2
ILSpy.BamlDecompiler/ILSpy.BamlDecompiler.csproj

@ -77,6 +77,7 @@ @@ -77,6 +77,7 @@
<Compile Include="CecilDependencyPropertyDescriptor.cs" />
<Compile Include="CecilType.cs" />
<Compile Include="CecilTypeResolver.cs" />
<Compile Include="ConnectMethodDecompiler.cs" />
<Compile Include="Extensions.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Ricciolo.StylesExplorer.MarkupReflection\AppDomainTypeResolver.cs" />
@ -90,6 +91,7 @@ @@ -90,6 +91,7 @@
<Compile Include="Ricciolo.StylesExplorer.MarkupReflection\IDependencyPropertyDescriptor.cs" />
<Compile Include="Ricciolo.StylesExplorer.MarkupReflection\IType.cs" />
<Compile Include="Ricciolo.StylesExplorer.MarkupReflection\ITypeResolver.cs" />
<Compile Include="Ricciolo.StylesExplorer.MarkupReflection\KeyMapping.cs" />
<Compile Include="Ricciolo.StylesExplorer.MarkupReflection\KnownInfo.cs" />
<Compile Include="Ricciolo.StylesExplorer.MarkupReflection\PropertyDeclaration.cs" />
<Compile Include="Ricciolo.StylesExplorer.MarkupReflection\ResourceName.cs" />

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

@ -17,22 +17,15 @@ namespace Ricciolo.StylesExplorer.MarkupReflection @@ -17,22 +17,15 @@ namespace Ricciolo.StylesExplorer.MarkupReflection
public virtual double ReadCompressedDouble()
{
switch (this.ReadByte())
{
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);
}
return ReadInt32() * 1E-06;
case 5:
return this.ReadDouble();
}

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

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

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

@ -9,21 +9,17 @@ using System.Xml; @@ -9,21 +9,17 @@ using System.Xml;
namespace Ricciolo.StylesExplorer.MarkupReflection
{
internal class XmlBamlElement : XmlBamlNode
class XmlBamlElement : XmlBamlNode
{
private ArrayList _arguments = new ArrayList();
private XmlNamespaceCollection _namespaces = new XmlNamespaceCollection();
private TypeDeclaration _typeDeclaration;
private KeysResourcesCollection _keysResources = new KeysResourcesCollection();
private long _position;
XmlNamespaceCollection _namespaces = new XmlNamespaceCollection();
public XmlBamlElement()
{
}
public XmlBamlElement(XmlBamlElement parent)
{
this.Parent = parent;
this.Namespaces.AddRange(parent.Namespaces);
}
@ -31,32 +27,18 @@ namespace Ricciolo.StylesExplorer.MarkupReflection @@ -31,32 +27,18 @@ namespace Ricciolo.StylesExplorer.MarkupReflection
{
get { return _namespaces; }
}
public XmlBamlElement Parent { get; private set; }
public TypeDeclaration TypeDeclaration { get; set; }
public TypeDeclaration TypeDeclaration
{
get
{
return this._typeDeclaration;
}
set
{
this._typeDeclaration = value;
}
public override XmlNodeType NodeType {
get { return XmlNodeType.Element; }
}
public override XmlNodeType NodeType
{
get
{
return XmlNodeType.Element;
}
}
public long Position
{
get { return _position; }
set { _position = value; }
}
public long Position { get; set; }
public bool IsImplicit { get; set; }
public override string ToString()
{
@ -86,108 +68,5 @@ namespace Ricciolo.StylesExplorer.MarkupReflection @@ -86,108 +68,5 @@ namespace Ricciolo.StylesExplorer.MarkupReflection
}
}
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);
}
}
}

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

@ -10,18 +10,18 @@ namespace Ricciolo.StylesExplorer.MarkupReflection @@ -10,18 +10,18 @@ namespace Ricciolo.StylesExplorer.MarkupReflection
{
internal class XmlBamlProperty : XmlBamlNode
{
private PropertyDeclaration propertyDeclaration;
private PropertyType propertyType;
private object value;
PropertyType propertyType;
public XmlBamlProperty(PropertyType propertyType)
public XmlBamlProperty(XmlBamlElement parent, PropertyType propertyType)
{
this.Parent = parent;
this.propertyType = propertyType;
}
public XmlBamlProperty(PropertyType propertyType, PropertyDeclaration propertyDeclaration)
public XmlBamlProperty(XmlBamlElement parent, PropertyType propertyType, PropertyDeclaration propertyDeclaration)
{
this.propertyDeclaration = propertyDeclaration;
this.Parent = parent;
this.PropertyDeclaration = propertyDeclaration;
this.propertyType = propertyType;
}
@ -29,45 +29,19 @@ namespace Ricciolo.StylesExplorer.MarkupReflection @@ -29,45 +29,19 @@ namespace Ricciolo.StylesExplorer.MarkupReflection
{
return this.PropertyDeclaration.Name;
}
public XmlBamlElement Parent { get; set; }
public PropertyDeclaration PropertyDeclaration { get; set; }
public PropertyDeclaration PropertyDeclaration
{
get
{
return this.propertyDeclaration;
}
set
{
this.propertyDeclaration = value;
}
public PropertyType PropertyType {
get { return this.propertyType; }
}
public PropertyType PropertyType
{
get
{
return this.propertyType;
}
}
public object Value { get; set; }
public object Value
{
get
{
return this.value;
}
set
{
this.value = value;
}
}
public override XmlNodeType NodeType
{
get
{
return XmlNodeType.Attribute;
}
public override XmlNodeType NodeType {
get { return XmlNodeType.Attribute; }
}
}

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

@ -11,8 +11,7 @@ namespace Ricciolo.StylesExplorer.MarkupReflection @@ -11,8 +11,7 @@ namespace Ricciolo.StylesExplorer.MarkupReflection
{
private readonly PropertyType _propertyType;
private PropertyDeclaration propertyDeclaration;
public XmlBamlPropertyElement(PropertyType propertyType, PropertyDeclaration propertyDeclaration)
{
_propertyType = propertyType;

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

@ -18,49 +18,100 @@ namespace Ricciolo.StylesExplorer.MarkupReflection @@ -18,49 +18,100 @@ namespace Ricciolo.StylesExplorer.MarkupReflection
{
public class XmlBamlReader : XmlReader, IXmlNamespaceResolver
{
BamlBinaryReader reader;
Dictionary<short, string> assemblyTable = new Dictionary<short, string>();
Dictionary<short, string> stringTable = new Dictionary<short, string>();
Dictionary<short, TypeDeclaration> typeTable = new Dictionary<short, TypeDeclaration>();
Dictionary<short, PropertyDeclaration> propertyTable = new Dictionary<short, PropertyDeclaration>();
#region Variables
readonly ITypeResolver _resolver;
private BamlBinaryReader reader;
private Dictionary<short, string> assemblyTable = new Dictionary<short, string>();
private Dictionary<short, string> stringTable = new Dictionary<short, string>();
private Dictionary<short, TypeDeclaration> typeTable = new Dictionary<short, TypeDeclaration>();
private Dictionary<short, PropertyDeclaration> propertyTable = new Dictionary<short, PropertyDeclaration>();
BamlRecordType currentType;
private readonly ITypeResolver _resolver;
Stack<XmlBamlElement> elements = new Stack<XmlBamlElement>();
Stack<XmlBamlElement> readingElements = new Stack<XmlBamlElement>();
NodesCollection nodes = new NodesCollection();
List<XmlPIMapping> _mappings = new List<XmlPIMapping>();
XmlBamlNode _currentNode;
private BamlRecordType currentType;
readonly KnownInfo KnownInfo;
private Stack<XmlBamlElement> elements = new Stack<XmlBamlElement>();
private Stack<XmlBamlElement> readingElements = new Stack<XmlBamlElement>();
private Stack<KeysResourcesCollection> keysResources = new Stack<KeysResourcesCollection>();
private NodesCollection nodes = new NodesCollection();
private List<XmlPIMapping> _mappings = new List<XmlPIMapping>();
private XmlBamlNode _currentNode;
int complexPropertyOpened = 0;
private readonly KnownInfo KnownInfo;
bool intoAttribute = false;
bool initialized;
bool _eof;
private int complexPropertyOpened = 0;
private bool intoAttribute = false;
private bool initialized;
private bool _eof;
bool isPartialDefKeysClosed = true;
bool isDefKeysClosed = true;
#region Context
Stack<ReaderContext> layer = new Stack<ReaderContext>();
class ReaderContext
{
public bool IsDeferred { get; set; }
public bool IsInStaticResource { get; set; }
private bool isPartialDefKeysClosed = true;
private bool isDefKeysClosed = true;
public ReaderContext Previous { get; private set; }
public ReaderContext()
{
this.Previous = this;
}
public ReaderContext(ReaderContext previous)
{
this.Previous = previous;
}
}
ReaderContext Current {
get {
if (!layer.Any())
layer.Push(new ReaderContext());
return layer.Peek();
}
}
int currentKey;
List<KeyMapping> keys = new List<KeyMapping>();
KeyMapping LastKey {
get {
KeyMapping last = keys.LastOrDefault();
if (last == null)
keys.Add(last = new KeyMapping());
return last;
}
}
void LayerPop()
{
layer.Pop();
}
void LayerPush()
{
if (layer.Any())
layer.Push(new ReaderContext(layer.Peek()));
else
layer.Push(new ReaderContext());
}
#endregion
private int bytesToSkip;
int bytesToSkip;
private static readonly MethodInfo staticConvertCustomBinaryToObjectMethod = Type.GetType("System.Windows.Markup.XamlPathDataSerializer,PresentationFramework, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35").GetMethod("StaticConvertCustomBinaryToObject", BindingFlags.Static | BindingFlags.Public);
private readonly TypeDeclaration XamlTypeDeclaration;
private readonly XmlNameTable _nameTable = new NameTable();
private IDictionary<string, string> _rootNamespaces;
static readonly MethodInfo staticConvertCustomBinaryToObjectMethod = Type.GetType("System.Windows.Markup.XamlPathDataSerializer,PresentationFramework, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35").GetMethod("StaticConvertCustomBinaryToObject", BindingFlags.Static | BindingFlags.Public);
readonly TypeDeclaration XamlTypeDeclaration;
readonly XmlNameTable _nameTable = new NameTable();
IDictionary<string, string> _rootNamespaces;
public const string XWPFNamespace = "http://schemas.microsoft.com/winfx/2006/xaml";
public const string DefaultWPFNamespace = "http://schemas.microsoft.com/winfx/2006/xaml/presentation";
#endregion
public XmlBamlReader(Stream stream) : this (stream, AppDomainTypeResolver.GetIntoNewAppDomain(Environment.CurrentDirectory))
{
@ -240,7 +291,7 @@ namespace Ricciolo.StylesExplorer.MarkupReflection @@ -240,7 +291,7 @@ namespace Ricciolo.StylesExplorer.MarkupReflection
return ReadInternal();
}
private bool ReadInternal()
bool ReadInternal()
{
EnsureInit();
@ -288,10 +339,10 @@ namespace Ricciolo.StylesExplorer.MarkupReflection @@ -288,10 +339,10 @@ namespace Ricciolo.StylesExplorer.MarkupReflection
else
currentType = (BamlRecordType)type;
// Debug.WriteLine(currentType);
Debug.WriteLine(string.Format("{0} (0x{0:x})", currentType));
}
private bool SetNextNode()
bool SetNextNode()
{
while (nodes.Count > 0)
{
@ -315,7 +366,7 @@ namespace Ricciolo.StylesExplorer.MarkupReflection @@ -315,7 +366,7 @@ namespace Ricciolo.StylesExplorer.MarkupReflection
return false;
}
private void ProcessNext()
void ProcessNext()
{
switch (currentType)
{
@ -347,9 +398,10 @@ namespace Ricciolo.StylesExplorer.MarkupReflection @@ -347,9 +398,10 @@ namespace Ricciolo.StylesExplorer.MarkupReflection
this.ReadXmlnsProperty();
break;
case BamlRecordType.ConnectionId:
reader.ReadInt32();
this.ReadConnectionId();
break;
case BamlRecordType.DeferableContentStart:
Current.IsDeferred = true;
reader.ReadInt32();
break;
case BamlRecordType.DefAttribute:
@ -453,6 +505,12 @@ namespace Ricciolo.StylesExplorer.MarkupReflection @@ -453,6 +505,12 @@ namespace Ricciolo.StylesExplorer.MarkupReflection
}
}
void ReadConnectionId()
{
int id = reader.ReadInt32();
nodes.Enqueue(new XmlBamlSimpleProperty(XWPFNamespace, "ConnectionId", id.ToString()));
}
void ReadTextWithId()
{
short textId = reader.ReadInt16();
@ -460,7 +518,7 @@ namespace Ricciolo.StylesExplorer.MarkupReflection @@ -460,7 +518,7 @@ namespace Ricciolo.StylesExplorer.MarkupReflection
nodes.Enqueue(new XmlBamlText(text));
}
private void ComputeBytesToSkip()
void ComputeBytesToSkip()
{
bytesToSkip = 0;
switch (currentType)
@ -485,7 +543,7 @@ namespace Ricciolo.StylesExplorer.MarkupReflection @@ -485,7 +543,7 @@ namespace Ricciolo.StylesExplorer.MarkupReflection
}
}
private void EnsureInit()
void EnsureInit()
{
if (!initialized)
{
@ -595,7 +653,12 @@ namespace Ricciolo.StylesExplorer.MarkupReflection @@ -595,7 +653,12 @@ namespace Ricciolo.StylesExplorer.MarkupReflection
else if (node is XmlBamlPropertyElement)
{
XmlBamlPropertyElement property = (XmlBamlPropertyElement)node;
localName = String.Format("{0}.{1}", property.TypeDeclaration.Name, property.PropertyDeclaration.Name);
string typeName = property.TypeDeclaration.Name;
if (property.Parent.TypeDeclaration.Type.IsSubclassOf(property.PropertyDeclaration.DeclaringType.Type))
typeName = property.Parent.TypeDeclaration.Name;
localName = String.Format("{0}.{1}", typeName, property.PropertyDeclaration.Name);
}
else if (node is XmlBamlElement)
localName = ((XmlBamlElement)node).TypeDeclaration.Name;
@ -606,7 +669,7 @@ namespace Ricciolo.StylesExplorer.MarkupReflection @@ -606,7 +669,7 @@ namespace Ricciolo.StylesExplorer.MarkupReflection
}
}
private PropertyDeclaration GetPropertyDeclaration(short identifier)
PropertyDeclaration GetPropertyDeclaration(short identifier)
{
PropertyDeclaration declaration;
if (identifier >= 0)
@ -624,7 +687,7 @@ namespace Ricciolo.StylesExplorer.MarkupReflection @@ -624,7 +687,7 @@ namespace Ricciolo.StylesExplorer.MarkupReflection
return declaration;
}
private object GetResourceName(short identifier)
object GetResourceName(short identifier)
{
if (identifier >= 0)
{
@ -644,7 +707,7 @@ namespace Ricciolo.StylesExplorer.MarkupReflection @@ -644,7 +707,7 @@ namespace Ricciolo.StylesExplorer.MarkupReflection
}
}
private void ReadPropertyDictionaryStart()
void ReadPropertyDictionaryStart()
{
short identifier = reader.ReadInt16();
@ -653,19 +716,14 @@ namespace Ricciolo.StylesExplorer.MarkupReflection @@ -653,19 +716,14 @@ namespace Ricciolo.StylesExplorer.MarkupReflection
XmlBamlPropertyElement property = new XmlBamlPropertyElement(element, PropertyType.Dictionary, pd);
elements.Push(property);
nodes.Enqueue(property);
isDefKeysClosed = true;
isPartialDefKeysClosed = true;
}
private void ReadPropertyDictionaryEnd()
void ReadPropertyDictionaryEnd()
{
keysResources.Pop();
CloseElement();
}
private void ReadPropertyCustom()
void ReadPropertyCustom()
{
short identifier = reader.ReadInt16();
short serializerTypeId = reader.ReadInt16();
@ -719,13 +777,13 @@ namespace Ricciolo.StylesExplorer.MarkupReflection @@ -719,13 +777,13 @@ namespace Ricciolo.StylesExplorer.MarkupReflection
return;
}
XmlBamlProperty property = new XmlBamlProperty(PropertyType.Value, pd);
XmlBamlProperty property = new XmlBamlProperty(elements.Peek(), PropertyType.Value, pd);
property.Value = value;
nodes.Enqueue(property);
}
private string DeserializePoints()
string DeserializePoints()
{
using (StringWriter writer = new StringWriter())
{
@ -745,7 +803,7 @@ namespace Ricciolo.StylesExplorer.MarkupReflection @@ -745,7 +803,7 @@ namespace Ricciolo.StylesExplorer.MarkupReflection
}
}
private String Deserialize3DPoints()
String Deserialize3DPoints()
{
using (StringWriter writer = new StringWriter())
{
@ -769,7 +827,7 @@ namespace Ricciolo.StylesExplorer.MarkupReflection @@ -769,7 +827,7 @@ namespace Ricciolo.StylesExplorer.MarkupReflection
}
}
private static Int32Collection DeserializeInt32CollectionFrom(BinaryReader reader)
static Int32Collection DeserializeInt32CollectionFrom(BinaryReader reader)
{
IntegerCollectionType type = (IntegerCollectionType)reader.ReadByte();
int capacity = reader.ReadInt32();
@ -799,7 +857,7 @@ namespace Ricciolo.StylesExplorer.MarkupReflection @@ -799,7 +857,7 @@ namespace Ricciolo.StylesExplorer.MarkupReflection
throw new ArgumentException();
}
private void ReadPropertyWithExtension()
void ReadPropertyWithExtension()
{
short identifier = reader.ReadInt16();
short x = reader.ReadInt16();
@ -812,8 +870,7 @@ namespace Ricciolo.StylesExplorer.MarkupReflection @@ -812,8 +870,7 @@ namespace Ricciolo.StylesExplorer.MarkupReflection
short extensionIdentifier = (short)-(x & 0xfff);
string value = String.Empty;
switch (x)
{
switch (x) {
case 0x25a:
// StaticExtension
object resource = this.GetResourceName(valueIdentifier);
@ -849,62 +906,62 @@ namespace Ricciolo.StylesExplorer.MarkupReflection @@ -849,62 +906,62 @@ namespace Ricciolo.StylesExplorer.MarkupReflection
throw new NotSupportedException("Unknown property with extension");
}
XmlBamlProperty property = new XmlBamlProperty(PropertyType.Value, pd);
XmlBamlProperty property = new XmlBamlProperty(elements.Peek(), PropertyType.Value, pd);
property.Value = value;
nodes.Enqueue(property);
}
private void ReadProperty()
void ReadProperty()
{
short identifier = reader.ReadInt16();
string text = reader.ReadString();
PropertyDeclaration pd = this.GetPropertyDeclaration(identifier);
XmlBamlProperty property = new XmlBamlProperty(PropertyType.Value, pd);
XmlBamlProperty property = new XmlBamlProperty(elements.Peek(), PropertyType.Value, pd);
property.Value = text;
nodes.Enqueue(property);
}
private void ReadPropertyWithConverter()
void ReadPropertyWithConverter()
{
short identifier = reader.ReadInt16();
string text = reader.ReadString();
reader.ReadInt16();
PropertyDeclaration pd = this.GetPropertyDeclaration(identifier);
XmlBamlProperty property = new XmlBamlProperty(PropertyType.Value, pd);
XmlBamlProperty property = new XmlBamlProperty(elements.Peek(), PropertyType.Value, pd);
property.Value = text;
nodes.Enqueue(property);
}
private void ReadAttributeInfo()
void ReadAttributeInfo()
{
short key = reader.ReadInt16();
short identifier = reader.ReadInt16();
reader.ReadByte();
string name = reader.ReadString();
TypeDeclaration declaringType = this.GetTypeDeclaration(identifier);
PropertyDeclaration declaration2 = new PropertyDeclaration(name, declaringType);
this.propertyTable.Add(key, declaration2);
PropertyDeclaration property = new PropertyDeclaration(name, declaringType);
this.propertyTable.Add(key, property);
}
private void ReadDefAttributeKeyType()
void ReadDefAttributeKeyType()
{
short typeIdentifier = reader.ReadInt16();
reader.ReadByte();
int position = reader.ReadInt32();
// TODO: shared
bool shared = reader.ReadBoolean();
bool sharedSet = reader.ReadBoolean();
// TODO: handle shared
AddDefKey(position, this.GetTypeExtension(typeIdentifier));
string extension = GetTypeExtension(typeIdentifier);
keys.Add(new KeyMapping(extension) { Shared = shared, SharedSet = sharedSet, Position = position });
}
private void ReadDefAttribute()
void ReadDefAttribute()
{
string text = reader.ReadString();
short identifier = reader.ReadInt16();
@ -923,53 +980,31 @@ namespace Ricciolo.StylesExplorer.MarkupReflection @@ -923,53 +980,31 @@ namespace Ricciolo.StylesExplorer.MarkupReflection
if (recordName != "Key") throw new NotSupportedException(recordName);
pd = new PropertyDeclaration(recordName, XamlTypeDeclaration);
AddDefKey(-1, text);
keys.Add(new KeyMapping(text) { Position = -1 });
break;
}
XmlBamlProperty property = new XmlBamlProperty(PropertyType.Key, pd);
XmlBamlProperty property = new XmlBamlProperty(elements.Peek(), PropertyType.Key, pd);
property.Value = text;
nodes.Enqueue(property);
}
private void ReadDefAttributeKeyString()
void ReadDefAttributeKeyString()
{
short num = reader.ReadInt16();
short stringId = reader.ReadInt16();
int position = reader.ReadInt32();
//bool shared = reader.ReadBoolean();
//bool sharedSet = reader.ReadBoolean();
string text = this.stringTable[num];
bool shared = reader.ReadBoolean();
bool sharedSet = reader.ReadBoolean();
string text = this.stringTable[stringId];
if (text == null)
throw new NotSupportedException();
AddDefKey(position, text);
keys.Add(new KeyMapping(text) { Position = position });
}
private void AddDefKey(long position, string text)
{
// Guardo se la dichiarazione delle chiavi risulta chiusa
// Se è aperta c'è un sotto ResourceDictionary oppure è il root ResourceDictionary
if (isDefKeysClosed)
{
keysResources.Push(new KeysResourcesCollection());
}
// Guardo se è stata chiusa la dichiarazione parziale (mediante dichiarazione OptimizedStaticResource)
// Si chiude il ciclo di chiavi
if (isPartialDefKeysClosed)
{
keysResources.Peek().Add(new KeysResource());
}
isDefKeysClosed = false;
isPartialDefKeysClosed = false;
// TODO: handle shared
if (position >= 0)
keysResources.Peek().Last.Keys[position] = text;
}
private void ReadXmlnsProperty()
void ReadXmlnsProperty()
{
string prefix = reader.ReadString();
string @namespace = reader.ReadString();
@ -1001,19 +1036,13 @@ namespace Ricciolo.StylesExplorer.MarkupReflection @@ -1001,19 +1036,13 @@ namespace Ricciolo.StylesExplorer.MarkupReflection
namespaces.Add(new XmlNamespace(prefix, @namespace));
}
private void ReadElementEnd()
void ReadElementEnd()
{
CloseElement();
// Provvedo all'eliminazione del gruppo di chiavi se sono sul root ResourceDictionary
// e si è chiuso uno degli elementi di primo livello e tutte le chiavi sono state usate
// Passo alla prossima lista
KeysResource keysResource = (elements.Count == 1 && keysResources.Count > 0) ? keysResources.Peek().First : null;
if (keysResource != null && keysResource.Keys.Count == 0)
keysResources.Peek().RemoveAt(0);
LayerPop();
}
private void ReadPropertyComplexStart()
void ReadPropertyComplexStart()
{
short identifier = reader.ReadInt16();
@ -1026,7 +1055,7 @@ namespace Ricciolo.StylesExplorer.MarkupReflection @@ -1026,7 +1055,7 @@ namespace Ricciolo.StylesExplorer.MarkupReflection
complexPropertyOpened++;
}
private XmlBamlElement FindXmlBamlElement()
XmlBamlElement FindXmlBamlElement()
{
return elements.Peek();
@ -1040,7 +1069,7 @@ namespace Ricciolo.StylesExplorer.MarkupReflection @@ -1040,7 +1069,7 @@ namespace Ricciolo.StylesExplorer.MarkupReflection
//return element;
}
private void ReadPropertyListStart()
void ReadPropertyListStart()
{
short identifier = reader.ReadInt16();
@ -1051,28 +1080,27 @@ namespace Ricciolo.StylesExplorer.MarkupReflection @@ -1051,28 +1080,27 @@ namespace Ricciolo.StylesExplorer.MarkupReflection
nodes.Enqueue(property);
}
private void ReadPropertyListEnd()
void ReadPropertyListEnd()
{
CloseElement();
}
private void ReadPropertyComplexEnd()
void ReadPropertyComplexEnd()
{
XmlBamlPropertyElement propertyElement = (XmlBamlPropertyElement) elements.Peek();
CloseElement();
complexPropertyOpened--;
// Valuto se contiene tutte extension
// this property could be a markup extension
// try to convert it
int start = nodes.IndexOf(propertyElement) + 1;
IEnumerator enumerator = nodes.GetEnumerator();
// move enumerator to the start of this property value
for (int i = 0; i < start && enumerator.MoveNext(); i++) ;
int c = 0;
while (c < start && enumerator.MoveNext())
c++;
if (IsExtension(enumerator))
{
if (IsExtension(enumerator)) {
start--;
nodes.RemoveAt(start);
nodes.RemoveLast();
@ -1081,15 +1109,13 @@ namespace Ricciolo.StylesExplorer.MarkupReflection @@ -1081,15 +1109,13 @@ namespace Ricciolo.StylesExplorer.MarkupReflection
FormatElementExtension((XmlBamlElement) nodes[start], sb);
XmlBamlProperty property =
new XmlBamlProperty(PropertyType.Complex, propertyElement.PropertyDeclaration);
new XmlBamlProperty(elements.Peek(), PropertyType.Complex, propertyElement.PropertyDeclaration);
property.Value = sb.ToString();
nodes.Add(property);
return;
}
}
private void FormatElementExtension(XmlBamlElement element, StringBuilder sb)
void FormatElementExtension(XmlBamlElement element, StringBuilder sb)
{
sb.Append("{");
sb.Append(FormatTypeDeclaration(element.TypeDeclaration));
@ -1143,36 +1169,37 @@ namespace Ricciolo.StylesExplorer.MarkupReflection @@ -1143,36 +1169,37 @@ namespace Ricciolo.StylesExplorer.MarkupReflection
sb.Append(sep);
sb.Append(((XmlBamlText)node).Text);
}
sep = ",";
sep = ", ";
}
}
private static bool IsExtension(IEnumerator enumerator)
bool IsExtension(IEnumerator enumerator)
{
bool r = true;
while (enumerator.MoveNext() && r)
{
while (enumerator.MoveNext()) {
object node = enumerator.Current;
if (node is XmlBamlElement && !(node is XmlBamlEndElement) && !((XmlBamlElement)node).TypeDeclaration.IsExtension)
{
r = false;
}
return false;
}
return r;
return true;
}
private void CloseElement()
void CloseElement()
{
nodes.Enqueue(new XmlBamlEndElement(elements.Pop()));
var e = elements.Pop();
if (!e.IsImplicit)
nodes.Enqueue(new XmlBamlEndElement(e));
}
private void ReadElementStart()
void ReadElementStart()
{
LayerPush();
short identifier = reader.ReadInt16();
sbyte flags = reader.ReadSByte();
if (flags < 0 || flags > 3)
throw new NotImplementedException();
Debug.Print("ElementFlags: " + flags);
TypeDeclaration declaration = GetTypeDeclaration(identifier);
XmlBamlElement element;
@ -1197,47 +1224,41 @@ namespace Ricciolo.StylesExplorer.MarkupReflection @@ -1197,47 +1224,41 @@ namespace Ricciolo.StylesExplorer.MarkupReflection
oldDeclaration = declaration;
declaration = GetKnownTypeDeclarationByName(declaration.Type.BaseType.AssemblyQualifiedName);
}
element.TypeDeclaration = declaration;
element.IsImplicit = (flags & 2) == 2;
elements.Push(element);
nodes.Enqueue(element);
if (!element.IsImplicit)
nodes.Enqueue(element);
if (oldDeclaration != null) {
nodes.Enqueue(new XmlBamlSimpleProperty(XWPFNamespace, "Class", string.Format("{0}.{1}", oldDeclaration.Namespace, oldDeclaration.Name)));
}
if (parentElement != null && complexPropertyOpened == 0)
{
// Calcolo la posizione dell'elemento rispetto al padre
long position = element.Position - parentElement.Position;
KeysResource keysResource = (keysResources.Count > 0) ? keysResources.Peek().First : null;
if (keysResource != null && keysResource.Keys.HasKey(position))
{
string key = keysResource.Keys[position];
// Rimuovo la chiave perché è stata usata
keysResource.Keys.Remove(position);
if (parentElement != null && complexPropertyOpened == 0 && !Current.IsInStaticResource && Current.Previous.IsDeferred) {
if (keys != null && keys.Count > currentKey) {
string key = keys[currentKey].KeyString;
AddKeyToElement(key);
currentKey++;
}
}
}
private void AddKeyToElement(string key)
void AddKeyToElement(string key)
{
PropertyDeclaration pd = new PropertyDeclaration("Key", XamlTypeDeclaration);
XmlBamlProperty property = new XmlBamlProperty(PropertyType.Key, pd);
XmlBamlProperty property = new XmlBamlProperty(elements.Peek(), PropertyType.Key, pd);
property.Value = key;
nodes.Enqueue(property);
}
private XmlPIMapping FindByClrNamespaceAndAssemblyId(TypeDeclaration declaration)
XmlPIMapping FindByClrNamespaceAndAssemblyId(TypeDeclaration declaration)
{
return FindByClrNamespaceAndAssemblyId(declaration.Namespace, declaration.AssemblyId);
}
private XmlPIMapping FindByClrNamespaceAndAssemblyId(string clrNamespace, int assemblyId)
XmlPIMapping FindByClrNamespaceAndAssemblyId(string clrNamespace, int assemblyId)
{
if (clrNamespace == XamlTypeDeclaration.Namespace && assemblyId == XamlTypeDeclaration.AssemblyId)
return new XmlPIMapping(XmlPIMapping.XamlNamespace, 0, clrNamespace);
@ -1252,7 +1273,7 @@ namespace Ricciolo.StylesExplorer.MarkupReflection @@ -1252,7 +1273,7 @@ namespace Ricciolo.StylesExplorer.MarkupReflection
return null;
}
private void ReadPIMapping()
void ReadPIMapping()
{
string xmlNamespace = reader.ReadString();
string clrNamespace = reader.ReadString();
@ -1261,26 +1282,26 @@ namespace Ricciolo.StylesExplorer.MarkupReflection @@ -1261,26 +1282,26 @@ namespace Ricciolo.StylesExplorer.MarkupReflection
Mappings.Add(new XmlPIMapping(xmlNamespace, assemblyId, clrNamespace));
}
private void ReadContentProperty()
void ReadContentProperty()
{
reader.ReadInt16();
// Non serve aprire niente, è il default
}
private static void ReadConstructorParametersStart()
static void ReadConstructorParametersStart()
{
//this.constructorParameterTable.Add(this.elements.Peek());
//PromoteDataToComplexProperty();
}
private static void ReadConstructorParametersEnd()
static void ReadConstructorParametersEnd()
{
//this.constructorParameterTable.Remove(this.elements.Peek());
//properties.Pop();
}
private void ReadConstructorParameterType()
void ReadConstructorParameterType()
{
short identifier = reader.ReadInt16();
@ -1288,14 +1309,14 @@ namespace Ricciolo.StylesExplorer.MarkupReflection @@ -1288,14 +1309,14 @@ namespace Ricciolo.StylesExplorer.MarkupReflection
nodes.Enqueue(new XmlBamlText(GetTypeExtension(identifier)));
}
private void ReadText()
void ReadText()
{
string text = reader.ReadString();
nodes.Enqueue(new XmlBamlText(text));
}
private void ReadKeyElementStart()
void ReadKeyElementStart()
{
short typeIdentifier = reader.ReadInt16();
byte valueIdentifier = reader.ReadByte();
@ -1315,7 +1336,7 @@ namespace Ricciolo.StylesExplorer.MarkupReflection @@ -1315,7 +1336,7 @@ namespace Ricciolo.StylesExplorer.MarkupReflection
complexPropertyOpened++;
}
private void ReadKeyElementEnd()
void ReadKeyElementEnd()
{
XmlBamlPropertyElement propertyElement = (XmlBamlPropertyElement)elements.Peek();
@ -1328,46 +1349,51 @@ namespace Ricciolo.StylesExplorer.MarkupReflection @@ -1328,46 +1349,51 @@ namespace Ricciolo.StylesExplorer.MarkupReflection
StringBuilder sb = new StringBuilder();
FormatElementExtension((XmlBamlElement)nodes[start], sb);
AddDefKey(propertyElement.Position, sb.ToString());
keys.Add(new KeyMapping(sb.ToString()) { Position = -1 });
}
}
private static void ReadStaticResourceStart()
void ReadStaticResourceStart()
{
//short identifier = reader.ReadInt16();
//byte n = reader.ReadByte();
//TypeDeclaration declaration = this.GetTypeDeclaration(identifier);
//this.staticResourceTable.Add(declaration);
throw new NotImplementedException("StaticResourceStart");
Current.IsInStaticResource = true;
short identifier = reader.ReadInt16();
byte flags = reader.ReadByte();
TypeDeclaration declaration = GetTypeDeclaration(identifier);
LastKey.StaticResources.Add(declaration);
XmlBamlElement element;
if (elements.Any())
element = new XmlBamlElement(elements.Peek());
else
element = new XmlBamlElement();
element.TypeDeclaration = declaration;
elements.Push(element);
nodes.Enqueue(element);
}
private static void ReadStaticResourceEnd()
void ReadStaticResourceEnd()
{
throw new NotImplementedException("ReadStaticResourceEnd");
CloseElement();
Current.IsInStaticResource = false;
}
private static void ReadStaticResourceId()
void ReadStaticResourceId()
{
//short identifier = reader.ReadInt16();
//object staticResource = this.GetStaticResource(identifier);
//TypeDeclaration declaration = this.GetTypeDeclaration(-603);
throw new NotImplementedException("StaticResourceId");
short identifier = reader.ReadInt16();
object staticResource = GetStaticResource(identifier);
}
private void ReadPresentationOptionsAttribute()
void ReadPresentationOptionsAttribute()
{
string text = reader.ReadString();
short valueIdentifier = reader.ReadInt16();
PropertyDeclaration pd = new PropertyDeclaration(this.stringTable[valueIdentifier].ToString());
XmlBamlProperty property = new XmlBamlProperty(PropertyType.Value, pd);
XmlBamlProperty property = new XmlBamlProperty(elements.Peek(), PropertyType.Value, pd);
property.Value = text;
}
private void ReadPropertyTypeReference()
void ReadPropertyTypeReference()
{
short identifier = reader.ReadInt16();
short typeIdentifier = reader.ReadInt16();
@ -1375,13 +1401,13 @@ namespace Ricciolo.StylesExplorer.MarkupReflection @@ -1375,13 +1401,13 @@ namespace Ricciolo.StylesExplorer.MarkupReflection
PropertyDeclaration pd = this.GetPropertyDeclaration(identifier);
string value = this.GetTypeExtension(typeIdentifier);
XmlBamlProperty property = new XmlBamlProperty(PropertyType.Value, pd);
XmlBamlProperty property = new XmlBamlProperty(elements.Peek(), PropertyType.Value, pd);
property.Value = value;
nodes.Enqueue(property);
}
private void ReadOptimizedStaticResource()
void ReadOptimizedStaticResource()
{
byte num = reader.ReadByte();
short typeIdentifier = reader.ReadInt16();
@ -1404,15 +1430,15 @@ namespace Ricciolo.StylesExplorer.MarkupReflection @@ -1404,15 +1430,15 @@ namespace Ricciolo.StylesExplorer.MarkupReflection
//this.staticResourceTable.Add(resource);
isPartialDefKeysClosed = true;
// Aggiungo la risorsa nell'ultimo gruppo
keysResources.Peek().Last.StaticResources.Add(resource);
LastKey.StaticResources.Add(resource);
}
private string GetTemplateBindingExtension(PropertyDeclaration propertyDeclaration)
string GetTemplateBindingExtension(PropertyDeclaration propertyDeclaration)
{
return String.Format("{{TemplateBinding {0}}}", FormatPropertyDeclaration(propertyDeclaration, true, false, false));
}
private string GetStaticExtension(string name)
string GetStaticExtension(string name)
{
string prefix = this.LookupPrefix(XmlPIMapping.XamlNamespace, false);
if (String.IsNullOrEmpty(prefix))
@ -1421,12 +1447,12 @@ namespace Ricciolo.StylesExplorer.MarkupReflection @@ -1421,12 +1447,12 @@ namespace Ricciolo.StylesExplorer.MarkupReflection
return String.Format("{{{0}:Static {1}}}", prefix, name);
}
private string GetExtension(TypeDeclaration declaration, string value)
string GetExtension(TypeDeclaration declaration, string value)
{
return String.Format("{{{0} {1}}}", FormatTypeDeclaration(declaration), value);
}
private string GetTypeExtension(short typeIdentifier)
string GetTypeExtension(short typeIdentifier)
{
string prefix = this.LookupPrefix(XmlPIMapping.XamlNamespace, false);
if (String.IsNullOrEmpty(prefix))
@ -1435,7 +1461,7 @@ namespace Ricciolo.StylesExplorer.MarkupReflection @@ -1435,7 +1461,7 @@ namespace Ricciolo.StylesExplorer.MarkupReflection
return String.Format("{{{0}:Type {1}}}", prefix, FormatTypeDeclaration(GetTypeDeclaration(typeIdentifier)));
}
private string FormatTypeDeclaration(TypeDeclaration typeDeclaration)
string FormatTypeDeclaration(TypeDeclaration typeDeclaration)
{
XmlPIMapping mapping = FindByClrNamespaceAndAssemblyId(typeDeclaration.Namespace, typeDeclaration.AssemblyId);
string prefix = (mapping != null) ? this.LookupPrefix(mapping.XmlNamespace, false) : null;
@ -1450,7 +1476,7 @@ namespace Ricciolo.StylesExplorer.MarkupReflection @@ -1450,7 +1476,7 @@ namespace Ricciolo.StylesExplorer.MarkupReflection
private string FormatPropertyDeclaration(PropertyDeclaration propertyDeclaration, bool withPrefix, bool useReading, bool checkType)
string FormatPropertyDeclaration(PropertyDeclaration propertyDeclaration, bool withPrefix, bool useReading, bool checkType)
{
StringBuilder sb = new StringBuilder();
@ -1465,19 +1491,16 @@ namespace Ricciolo.StylesExplorer.MarkupReflection @@ -1465,19 +1491,16 @@ namespace Ricciolo.StylesExplorer.MarkupReflection
bool isAttached = (descriptor != null && descriptor.IsAttached);
bool differentType = ((propertyDeclaration.DeclaringType != propertyDeclaration.DeclaringType || !isDescendant));
if (withPrefix)
{
if (withPrefix) {
XmlPIMapping mapping = FindByClrNamespaceAndAssemblyId(propertyDeclaration.DeclaringType.Namespace, propertyDeclaration.DeclaringType.AssemblyId);
string prefix = (mapping != null) ? this.LookupPrefix(mapping.XmlNamespace, false) : null;
if (!String.IsNullOrEmpty(prefix))
{
if (!String.IsNullOrEmpty(prefix)) {
sb.Append(prefix);
sb.Append(":");
}
}
if ((differentType || isAttached || !checkType) && propertyDeclaration.DeclaringType.Name.Length > 0)
{
if ((differentType || isAttached || !checkType) && propertyDeclaration.DeclaringType.Name.Length > 0) {
sb.Append(propertyDeclaration.DeclaringType.Name);
sb.Append(".");
}
@ -1486,47 +1509,33 @@ namespace Ricciolo.StylesExplorer.MarkupReflection @@ -1486,47 +1509,33 @@ namespace Ricciolo.StylesExplorer.MarkupReflection
return sb.ToString();
}
private void ReadPropertyWithStaticResourceIdentifier()
void ReadPropertyWithStaticResourceIdentifier()
{
short identifier = reader.ReadInt16();
short staticIdentifier = reader.ReadInt16();
PropertyDeclaration pd = this.GetPropertyDeclaration(identifier);
object staticResource = this.GetStaticResource(staticIdentifier);
object staticResource = GetStaticResource(staticIdentifier);
string prefix = this.LookupPrefix(XmlPIMapping.PresentationNamespace, false);
string value = String.Format("{{{0}{1}StaticResource {2}}}", prefix, (String.IsNullOrEmpty(prefix)) ? String.Empty : ":", staticResource);
XmlBamlProperty property = new XmlBamlProperty(PropertyType.Value, pd);
XmlBamlProperty property = new XmlBamlProperty(elements.Peek(), PropertyType.Value, pd);
property.Value = value;
nodes.Enqueue(property);
}
private object GetStaticResource(short identifier)
object GetStaticResource(short identifier)
{
// Recupero la risorsa nel gruppo corrente
foreach (KeysResourcesCollection resource in keysResources)
{
// TODO: controllare. Se non lo trova nel gruppo corrente, va in quello successivo
for (int x = 0; x < resource.Count; x++)
{
KeysResource resourceGroup = resource[x];
if (resourceGroup.StaticResources.Count > identifier)
if (x > 0)
break;
//return "%" + resourceGroup.StaticResources[identifier] + "%";
else
return resourceGroup.StaticResources[identifier];
}
}
if (identifier < LastKey.StaticResources.Count)
return LastKey.StaticResources[(int)identifier];
//return "???";
// return "???" + identifier +"???";
throw new ArgumentException("Cannot find StaticResource", "identifier");
}
private void ReadTextWithConverter()
void ReadTextWithConverter()
{
string text = reader.ReadString();
reader.ReadInt16();
@ -1534,7 +1543,7 @@ namespace Ricciolo.StylesExplorer.MarkupReflection @@ -1534,7 +1543,7 @@ namespace Ricciolo.StylesExplorer.MarkupReflection
nodes.Enqueue(new XmlBamlText(text));
}
private void ReadTypeInfo()
void ReadTypeInfo()
{
short typeId = reader.ReadInt16();
short assemblyId = reader.ReadInt16();
@ -1555,21 +1564,21 @@ namespace Ricciolo.StylesExplorer.MarkupReflection @@ -1555,21 +1564,21 @@ namespace Ricciolo.StylesExplorer.MarkupReflection
this.typeTable.Add(typeId, declaration);
}
private void ReadAssemblyInfo()
void ReadAssemblyInfo()
{
short key = reader.ReadInt16();
string text = reader.ReadString();
this.assemblyTable.Add(key, text);
}
private void ReadStringInfo()
void ReadStringInfo()
{
short key = reader.ReadInt16();
string text = reader.ReadString();
this.stringTable.Add(key, text);
}
private TypeDeclaration GetTypeDeclaration(short identifier)
TypeDeclaration GetTypeDeclaration(short identifier)
{
TypeDeclaration declaration;
if (identifier >= 0)
@ -1598,7 +1607,7 @@ namespace Ricciolo.StylesExplorer.MarkupReflection @@ -1598,7 +1607,7 @@ namespace Ricciolo.StylesExplorer.MarkupReflection
return this.assemblyTable[identifier];
}
private XmlBamlNode CurrentNode
XmlBamlNode CurrentNode
{
get
{
@ -1624,13 +1633,17 @@ namespace Ricciolo.StylesExplorer.MarkupReflection @@ -1624,13 +1633,17 @@ namespace Ricciolo.StylesExplorer.MarkupReflection
XmlBamlNode node = this.CurrentNode;
if (node is XmlBamlSimpleProperty)
return ((XmlBamlSimpleProperty)node).NamespaceName;
else if (node is XmlBamlProperty)
{
else if (node is XmlBamlProperty) {
declaration = ((XmlBamlProperty)node).PropertyDeclaration.DeclaringType;
TypeDeclaration elementDeclaration = this.readingElements.Peek().TypeDeclaration;
XmlPIMapping propertyMapping = FindByClrNamespaceAndAssemblyId(declaration) ?? XmlPIMapping.Presentation;
XmlPIMapping elementMapping = FindByClrNamespaceAndAssemblyId(elementDeclaration) ?? XmlPIMapping.Presentation;
if (((XmlBamlProperty)node).PropertyDeclaration.Name == "Name" &&
_resolver.IsLocalAssembly(((XmlBamlProperty)node).Parent.TypeDeclaration.Assembly))
return XWPFNamespace;
if (String.CompareOrdinal(propertyMapping.XmlNamespace, elementMapping.XmlNamespace) == 0
|| (elementDeclaration.Type != null && declaration.Type != null && elementDeclaration.Type.IsSubclassOf(declaration.Type)))
return String.Empty;
@ -1886,7 +1899,7 @@ namespace Ricciolo.StylesExplorer.MarkupReflection @@ -1886,7 +1899,7 @@ namespace Ricciolo.StylesExplorer.MarkupReflection
return this.LookupPrefix(namespaceName, true);
}
private string LookupPrefix(string namespaceName, bool useReading)
string LookupPrefix(string namespaceName, bool useReading)
{
Stack<XmlBamlElement> elements;
if (useReading)
@ -1900,7 +1913,7 @@ namespace Ricciolo.StylesExplorer.MarkupReflection @@ -1900,7 +1913,7 @@ namespace Ricciolo.StylesExplorer.MarkupReflection
return LookupPrefix(namespaceName, namespaces);
}
private static string LookupPrefix(string namespaceName, XmlNamespaceCollection namespaces)
static string LookupPrefix(string namespaceName, XmlNamespaceCollection namespaces)
{
for (int x = 0; x < namespaces.Count; x++)
{
@ -1959,7 +1972,7 @@ namespace Ricciolo.StylesExplorer.MarkupReflection @@ -1959,7 +1972,7 @@ namespace Ricciolo.StylesExplorer.MarkupReflection
return DequeueInternal(false);
}
private XmlBamlNode DequeueInternal(bool remove)
XmlBamlNode DequeueInternal(bool remove)
{
if (this.Count > 0)
{

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

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

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

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

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

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

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

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

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

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

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

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

26
ILSpy.BamlDecompiler/Tests/Cases/MyControl.xaml.cs

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

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

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

26
ILSpy.BamlDecompiler/Tests/Cases/Resources.xaml.cs

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

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

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

26
ILSpy.BamlDecompiler/Tests/Cases/SimpleNames.xaml.cs

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

24
ILSpy.BamlDecompiler/Tests/ILSpy.BamlDecompiler.Tests.csproj

@ -66,10 +66,27 @@ @@ -66,10 +66,27 @@
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="Cases\AttachedEvent.xaml.cs">
<DependentUpon>AttachedEvent.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
<Compile Include="Cases\MyControl.xaml.cs">
<DependentUpon>MyControl.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
<Compile Include="Cases\Resources.xaml.cs">
<DependentUpon>Resources.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
<Compile Include="Cases\Simple.xaml.cs">
<DependentUpon>Simple.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
<Compile Include="Cases\SimpleNames.xaml.cs">
<DependentUpon>SimpleNames.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
<Compile Include="Mocks\AvalonDock.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="TestRunner.cs" />
</ItemGroup>
@ -97,13 +114,20 @@ @@ -97,13 +114,20 @@
</ItemGroup>
<ItemGroup>
<Folder Include="Cases" />
<Folder Include="Mocks" />
<Folder Include="Properties" />
</ItemGroup>
<ItemGroup>
<Page Include="Cases\AttachedEvent.xaml" />
<Page Include="Cases\AvalonDockBrushes.xaml" />
<Page Include="Cases\AvalonDockCommon.xaml" />
<Page Include="Cases\MyControl.xaml" />
<Page Include="Cases\Resources.xaml" />
<Page Include="Cases\Simple.xaml">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Page>
<Page Include="Cases\SimpleDictionary.xaml" />
<Page Include="Cases\SimpleNames.xaml" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.Targets" />
</Project>

70
ILSpy.BamlDecompiler/Tests/Mocks/AvalonDock.cs

@ -0,0 +1,70 @@ @@ -0,0 +1,70 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using System;
using System.Windows;
using System.Windows.Controls.Primitives;
namespace AvalonDock
{
public class DockingManager
{
public DockingManager()
{
}
}
public class Resizer : Thumb
{
static Resizer()
{
//This OverrideMetadata call tells the system that this element wants to provide a style that is different than its base class.
//This style is defined in themes\generic.xaml
DefaultStyleKeyProperty.OverrideMetadata(typeof(Resizer), new FrameworkPropertyMetadata(typeof(Resizer)));
MinWidthProperty.OverrideMetadata(typeof(Resizer), new FrameworkPropertyMetadata(6.0, FrameworkPropertyMetadataOptions.AffectsParentMeasure));
MinHeightProperty.OverrideMetadata(typeof(Resizer), new FrameworkPropertyMetadata(6.0, FrameworkPropertyMetadataOptions.AffectsParentMeasure));
HorizontalAlignmentProperty.OverrideMetadata(typeof(Resizer), new FrameworkPropertyMetadata(HorizontalAlignment.Stretch, FrameworkPropertyMetadataOptions.AffectsParentMeasure));
VerticalAlignmentProperty.OverrideMetadata(typeof(Resizer), new FrameworkPropertyMetadata(VerticalAlignment.Stretch, FrameworkPropertyMetadataOptions.AffectsParentMeasure));
}
}
public enum AvalonDockBrushes
{
DefaultBackgroundBrush,
DockablePaneTitleBackground,
DockablePaneTitleBackgroundSelected,
DockablePaneTitleForeground,
DockablePaneTitleForegroundSelected,
PaneHeaderCommandBackground,
PaneHeaderCommandBorderBrush,
DocumentHeaderBackground,
DocumentHeaderForeground,
DocumentHeaderForegroundSelected,
DocumentHeaderForegroundSelectedActivated,
DocumentHeaderBackgroundSelected,
DocumentHeaderBackgroundSelectedActivated,
DocumentHeaderBackgroundMouseOver,
DocumentHeaderBorderBrushMouseOver,
DocumentHeaderBorder,
DocumentHeaderBorderSelected,
DocumentHeaderBorderSelectedActivated,
NavigatorWindowTopBackground,
NavigatorWindowTitleForeground,
NavigatorWindowDocumentTypeForeground,
NavigatorWindowInfoTipForeground,
NavigatorWindowForeground,
NavigatorWindowBackground,
NavigatorWindowSelectionBackground,
NavigatorWindowSelectionBorderbrush,
NavigatorWindowBottomBackground
}
public enum ContextMenuElement
{
DockablePane,
DocumentPane,
DockableFloatingWindow,
DocumentFloatingWindow
}
}

34
ILSpy.BamlDecompiler/Tests/TestRunner.cs

@ -31,6 +31,37 @@ namespace ILSpy.BamlDecompiler.Tests @@ -31,6 +31,37 @@ namespace ILSpy.BamlDecompiler.Tests
RunTest("cases/simpledictionary");
}
[Test]
public void Resources()
{
RunTest("cases/resources");
}
[Test]
public void SimpleNames()
{
RunTest("cases/simplenames");
}
[Test]
public void AvalonDockBrushes()
{
RunTest("cases/avalondockbrushes");
}
[Test]
public void AvalonDockCommon()
{
RunTest("cases/avalondockcommon");
}
[Test]
public void AttachedEvent()
{
RunTest("cases/attachedevent");
}
#region RunTest
void RunTest(string name)
{
string asmPath = typeof(TestRunner).Assembly.Location;
@ -41,7 +72,7 @@ namespace ILSpy.BamlDecompiler.Tests @@ -41,7 +72,7 @@ namespace ILSpy.BamlDecompiler.Tests
XDocument document = BamlResourceEntryNode.LoadIntoDocument(new DefaultAssemblyResolver(), assembly, bamlStream);
string path = Path.Combine("..\\..\\Tests", name + ".xaml");
CodeAssert.AreEqual(document.ToString(), File.ReadAllText(path));
CodeAssert.AreEqual(File.ReadAllText(path), document.ToString());
}
Stream LoadBaml(Resource res, string name)
@ -69,5 +100,6 @@ namespace ILSpy.BamlDecompiler.Tests @@ -69,5 +100,6 @@ namespace ILSpy.BamlDecompiler.Tests
return null;
}
#endregion
}
}

31
ILSpy/Commands/ShowAnalyzerCommand.cs

@ -1,31 +0,0 @@ @@ -1,31 +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;
namespace ICSharpCode.ILSpy
{
[ExportMainMenuCommand(Menu = "_View", Header = "_Analyzer", MenuCategory = "ShowPane", MenuOrder = 100)]
sealed class ShowAnalyzerCommand : SimpleCommand
{
public override void Execute(object parameter)
{
AnalyzerTreeView.Instance.Show();
}
}
}

2
ILSpy/ILSpy.csproj

@ -117,7 +117,6 @@ @@ -117,7 +117,6 @@
<Compile Include="CommandLineArguments.cs" />
<Compile Include="Commands\ExitCommand.cs" />
<Compile Include="Commands\CommandWrapper.cs" />
<Compile Include="ConnectMethodDecompiler.cs" />
<Compile Include="Controls\DockedPane.cs" />
<Compile Include="Commands\DecompileAllCommand.cs" />
<Compile Include="Commands\ExportCommandAttribute.cs" />
@ -173,7 +172,6 @@ @@ -173,7 +172,6 @@
<SubType>Code</SubType>
</Compile>
<Compile Include="Commands\SimpleCommand.cs" />
<Compile Include="Commands\ShowAnalyzerCommand.cs" />
<Compile Include="TreeNodes\Analyzer\AnalyzeContextMenuEntry.cs" />
<Compile Include="TreeNodes\Analyzer\AnalyzedEventOverridesTreeNode.cs" />
<Compile Include="TreeNodes\Analyzer\AnalyzedEventTreeNode.cs" />

1
ILSpy/Languages/CSharpLanguage.cs

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

4
ILSpy/LoadedAssembly.cs

@ -212,6 +212,10 @@ namespace ICSharpCode.ILSpy @@ -212,6 +212,10 @@ namespace ICSharpCode.ILSpy
return this.assemblyTask.ContinueWith(onAssemblyLoaded, taskScheduler);
}
/// <summary>
/// Wait until the assembly is loaded.
/// Throws an AggregateException when loading the assembly fails.
/// </summary>
public void WaitUntilLoaded()
{
assemblyTask.Wait();

12
ILSpy/TreeNodes/AssemblyTreeNode.cs

@ -195,7 +195,17 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -195,7 +195,17 @@ namespace ICSharpCode.ILSpy.TreeNodes
public override void Decompile(Language language, ITextOutput output, DecompilationOptions options)
{
assembly.WaitUntilLoaded(); // necessary so that load errors are passed on to the caller
try {
assembly.WaitUntilLoaded(); // necessary so that load errors are passed on to the caller
} catch (AggregateException ex) {
language.WriteCommentLine(output, assembly.FileName);
if (ex.InnerException is BadImageFormatException) {
language.WriteCommentLine(output, "This file does not contain a managed assembly.");
return;
} else {
throw;
}
}
language.DecompileAssembly(assembly, output, options);
}

25
ILSpy/TreeNodes/FieldTreeNode.cs

@ -59,12 +59,31 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -59,12 +59,31 @@ namespace ICSharpCode.ILSpy.TreeNodes
if (field.IsLiteral)
return Images.GetIcon(MemberIcon.Literal, GetOverlayIcon(field.Attributes), false);
else if (field.IsInitOnly)
return Images.GetIcon(MemberIcon.FieldReadOnly, GetOverlayIcon(field.Attributes), field.IsStatic);
else
else if (field.IsInitOnly) {
if (IsDecimalConstant(field))
return Images.GetIcon(MemberIcon.Literal, GetOverlayIcon(field.Attributes), false);
else
return Images.GetIcon(MemberIcon.FieldReadOnly, GetOverlayIcon(field.Attributes), field.IsStatic);
} else
return Images.GetIcon(MemberIcon.Field, GetOverlayIcon(field.Attributes), field.IsStatic);
}
private static bool IsDecimalConstant(Mono.Cecil.FieldDefinition field)
{
var fieldType = field.FieldType;
if (fieldType.Name == "Decimal" && fieldType.Namespace == "System") {
if (field.HasCustomAttributes) {
var attrs = field.CustomAttributes;
for (int i = 0; i < attrs.Count; i++) {
var attrType = attrs[i].AttributeType;
if (attrType.Name == "DecimalConstantAttribute" && attrType.Namespace == "System.Runtime.CompilerServices")
return true;
}
}
}
return false;
}
private static AccessOverlayIcon GetOverlayIcon(FieldAttributes fieldAttributes)
{
switch (fieldAttributes & FieldAttributes.FieldAccessMask) {

1
NRefactory/ICSharpCode.NRefactory/CSharp/OutputVisitor/OutputVisitor.cs

@ -838,6 +838,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -838,6 +838,7 @@ namespace ICSharpCode.NRefactory.CSharp
public object VisitEmptyExpression (EmptyExpression emptyExpression, object data)
{
StartNode(emptyExpression);
return EndNode (emptyExpression);
}
#region VisitPrimitiveExpression

2
SharpTreeView/SharpTreeNodeView.cs

@ -97,8 +97,6 @@ namespace ICSharpCode.TreeView @@ -97,8 +97,6 @@ namespace ICSharpCode.TreeView
} else if (e.PropertyName == "IsExpanded") {
if (Node.IsExpanded)
ParentTreeView.HandleExpanding(Node);
else
ParentTreeView.HandleCollapsing(Node);
}
}

43
SharpTreeView/SharpTreeView.cs

@ -3,6 +3,7 @@ @@ -3,6 +3,7 @@
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Diagnostics;
using System.Linq;
using System.Text;
@ -130,10 +131,30 @@ namespace ICSharpCode.TreeView @@ -130,10 +131,30 @@ namespace ICSharpCode.TreeView
Root.IsExpanded = true;
}
flattener = new TreeFlattener(Root, ShowRoot);
flattener.CollectionChanged += flattener_CollectionChanged;
this.ItemsSource = flattener;
}
}
void flattener_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
// Deselect nodes that are being hidden
if (e.Action == NotifyCollectionChangedAction.Remove) {
List<SharpTreeNode> selectedOldItems = null;
foreach (SharpTreeNode node in e.OldItems) {
if (node.IsSelected) {
if (selectedOldItems == null)
selectedOldItems = new List<SharpTreeNode>();
selectedOldItems.Add(node);
}
}
if (selectedOldItems != null) {
var list = SelectedItems.Cast<SharpTreeNode>().Except(selectedOldItems).ToList();
SetSelectedItems(list);
}
}
}
protected override DependencyObject GetContainerForItemOverride()
{
return new SharpTreeViewItem();
@ -151,8 +172,16 @@ namespace ICSharpCode.TreeView @@ -151,8 +172,16 @@ namespace ICSharpCode.TreeView
container.ParentTreeView = this;
}
bool doNotScrollOnExpanding;
/// <summary>
/// Handles the node expanding event in the tree view.
/// This method gets called only if the node is in the visible region (a SharpTreeNodeView exists).
/// </summary>
internal void HandleExpanding(SharpTreeNode node)
{
if (doNotScrollOnExpanding)
return;
SharpTreeNode lastVisibleChild = node;
while (true) {
SharpTreeNode tmp = lastVisibleChild.Children.LastOrDefault(c => c.IsVisible);
@ -174,16 +203,6 @@ namespace ICSharpCode.TreeView @@ -174,16 +203,6 @@ namespace ICSharpCode.TreeView
}
}
internal void HandleCollapsing(SharpTreeNode node)
{
var selectedChilds = node.VisibleDescendants().Where(n => n.IsSelected);
if (selectedChilds.Any()) {
var list = SelectedItems.Cast<SharpTreeNode>().Except(selectedChilds).ToList();
list.AddOnce(node);
SetSelectedItems(list);
}
}
protected override void OnKeyDown(KeyEventArgs e)
{
SharpTreeViewItem container = e.OriginalSource as SharpTreeViewItem;
@ -269,8 +288,10 @@ namespace ICSharpCode.TreeView @@ -269,8 +288,10 @@ namespace ICSharpCode.TreeView
{
if (node == null)
throw new ArgumentNullException("node");
doNotScrollOnExpanding = true;
foreach (SharpTreeNode ancestor in node.Ancestors())
ancestor.IsExpanded = true;
doNotScrollOnExpanding = false;
base.ScrollIntoView(node);
}

2
TestPlugin/TestPlugin.csproj

@ -16,7 +16,7 @@ @@ -16,7 +16,7 @@
<StartArguments>/separate</StartArguments>
</PropertyGroup>
<PropertyGroup Condition=" '$(Platform)' == 'AnyCPU' ">
<PlatformTarget>x86</PlatformTarget>
<PlatformTarget>AnyCPU</PlatformTarget>
<RegisterForComInterop>False</RegisterForComInterop>
<GenerateSerializationAssemblies>Auto</GenerateSerializationAssemblies>
<BaseAddress>4194304</BaseAddress>

Loading…
Cancel
Save