diff --git a/AvalonEdit/ICSharpCode.AvalonEdit/ICSharpCode.AvalonEdit.csproj b/AvalonEdit/ICSharpCode.AvalonEdit/ICSharpCode.AvalonEdit.csproj index 0b12dff5b..ee5e00268 100644 --- a/AvalonEdit/ICSharpCode.AvalonEdit/ICSharpCode.AvalonEdit.csproj +++ b/AvalonEdit/ICSharpCode.AvalonEdit/ICSharpCode.AvalonEdit.csproj @@ -215,6 +215,7 @@ + IBackgroundRenderer.cs diff --git a/ICSharpCode.Decompiler/Ast/AstBuilder.cs b/ICSharpCode.Decompiler/Ast/AstBuilder.cs index 21c5d73a4..28ab00f07 100644 --- a/ICSharpCode.Decompiler/Ast/AstBuilder.cs +++ b/ICSharpCode.Decompiler/Ast/AstBuilder.cs @@ -28,7 +28,8 @@ namespace ICSharpCode.Decompiler.Ast { None = 0, IncludeNamespace = 1, - IncludeTypeParameterDefinitions = 2 + IncludeTypeParameterDefinitions = 2, + DoNotUsePrimitiveTypeNames = 4 } public class AstBuilder : BaseCodeMappings @@ -127,8 +128,28 @@ namespace ICSharpCode.Decompiler.Ast public void AddAssembly(AssemblyDefinition assemblyDefinition, bool onlyAssemblyLevel = false) { + if (assemblyDefinition.Name.Version != null) { + astCompileUnit.AddChild( + new AttributeSection { + AttributeTarget = "assembly", + Attributes = { + new NRefactory.CSharp.Attribute { + Type = new SimpleType("AssemblyVersion") + .WithAnnotation(new TypeReference( + "System.Reflection", "AssemblyVersionAttribute", + assemblyDefinition.MainModule, assemblyDefinition.MainModule.TypeSystem.Corlib)), + Arguments = { + new PrimitiveExpression(assemblyDefinition.Name.Version.ToString()) + } + } + } + }, AttributedNode.AttributeRole); + } + ConvertCustomAttributes(astCompileUnit, assemblyDefinition, "assembly"); + ConvertSecurityAttributes(astCompileUnit, assemblyDefinition, "assembly"); ConvertCustomAttributes(astCompileUnit, assemblyDefinition.MainModule, "module"); + AddTypeForwarderAttributes(astCompileUnit, assemblyDefinition.MainModule, "assembly"); if (!onlyAssemblyLevel) { foreach (TypeDefinition typeDef in assemblyDefinition.MainModule.Types) { @@ -143,6 +164,30 @@ namespace ICSharpCode.Decompiler.Ast } } + void AddTypeForwarderAttributes(CompilationUnit astCompileUnit, ModuleDefinition module, string target) + { + if (!module.HasExportedTypes) + return; + foreach (ExportedType type in module.ExportedTypes) { + if (type.IsForwarder) { + var forwardedType = CreateTypeOfExpression(new TypeReference(type.Namespace, type.Name, module, type.Scope)); + astCompileUnit.AddChild( + new AttributeSection { + AttributeTarget = target, + Attributes = { + new NRefactory.CSharp.Attribute { + Type = new SimpleType("TypeForwardedTo") + .WithAnnotation(new TypeReference( + "System.Runtime.CompilerServices", "TypeForwardedToAttribute", + module, module.TypeSystem.Corlib)), + Arguments = { forwardedType } + } + } + }, AttributedNode.AttributeRole); + } + } + } + NamespaceDeclaration GetCodeNamespace(string name) { if (string.IsNullOrEmpty(name)) { @@ -226,15 +271,6 @@ namespace ICSharpCode.Decompiler.Ast astType.TypeParameters.AddRange(MakeTypeParameters(genericParameters)); astType.Constraints.AddRange(MakeConstraints(genericParameters)); - // Nested types - foreach (TypeDefinition nestedTypeDef in typeDef.NestedTypes) { - if (MemberIsHidden(nestedTypeDef, context.Settings)) - continue; - var nestedType = CreateType(nestedTypeDef); - SetNewModifier(nestedType); - astType.AddChild(nestedType, TypeDeclaration.MemberRole); - } - AttributedNode result = astType; if (typeDef.IsEnum) { long expectedEnumMemberValue = 0; @@ -312,6 +348,45 @@ namespace ICSharpCode.Decompiler.Ast return name; } + #region Create TypeOf Expression + /// + /// Creates a typeof-expression for the specified type. + /// + public static TypeOfExpression CreateTypeOfExpression(TypeReference type) + { + return new TypeOfExpression(AddEmptyTypeArgumentsForUnboundGenerics(ConvertType(type))); + } + + static AstType AddEmptyTypeArgumentsForUnboundGenerics(AstType type) + { + TypeReference typeRef = type.Annotation(); + if (typeRef == null) + return type; + TypeDefinition typeDef = typeRef.Resolve(); // need to resolve to figure out the number of type parameters + if (typeDef == null || !typeDef.HasGenericParameters) + return type; + SimpleType sType = type as SimpleType; + MemberType mType = type as MemberType; + if (sType != null) { + while (typeDef.GenericParameters.Count > sType.TypeArguments.Count) { + sType.TypeArguments.Add(new SimpleType("")); + } + } + + if (mType != null) { + AddEmptyTypeArgumentsForUnboundGenerics(mType.Target); + + int outerTypeParamCount = typeDef.DeclaringType == null ? 0 : typeDef.DeclaringType.GenericParameters.Count; + + while (typeDef.GenericParameters.Count - outerTypeParamCount > mType.TypeArguments.Count) { + mType.TypeArguments.Add(new SimpleType("")); + } + } + + return type; + } + #endregion + #region Convert Type Reference /// /// Converts a type reference. @@ -386,39 +461,42 @@ namespace ICSharpCode.Decompiler.Ast return new PrimitiveType("dynamic"); } else { if (ns == "System") { - switch (name) { - case "SByte": - return new PrimitiveType("sbyte"); - case "Int16": - return new PrimitiveType("short"); - case "Int32": - return new PrimitiveType("int"); - case "Int64": - return new PrimitiveType("long"); - case "Byte": - return new PrimitiveType("byte"); - case "UInt16": - return new PrimitiveType("ushort"); - case "UInt32": - return new PrimitiveType("uint"); - case "UInt64": - return new PrimitiveType("ulong"); - case "String": - return new PrimitiveType("string"); - case "Single": - return new PrimitiveType("float"); - case "Double": - return new PrimitiveType("double"); - case "Decimal": - return new PrimitiveType("decimal"); - case "Char": - return new PrimitiveType("char"); - case "Boolean": - return new PrimitiveType("bool"); - case "Void": - return new PrimitiveType("void"); - case "Object": - return new PrimitiveType("object"); + if ((options & ConvertTypeOptions.DoNotUsePrimitiveTypeNames) + != ConvertTypeOptions.DoNotUsePrimitiveTypeNames) { + switch (name) { + case "SByte": + return new PrimitiveType("sbyte"); + case "Int16": + return new PrimitiveType("short"); + case "Int32": + return new PrimitiveType("int"); + case "Int64": + return new PrimitiveType("long"); + case "Byte": + return new PrimitiveType("byte"); + case "UInt16": + return new PrimitiveType("ushort"); + case "UInt32": + return new PrimitiveType("uint"); + case "UInt64": + return new PrimitiveType("ulong"); + case "String": + return new PrimitiveType("string"); + case "Single": + return new PrimitiveType("float"); + case "Double": + return new PrimitiveType("double"); + case "Decimal": + return new PrimitiveType("decimal"); + case "Char": + return new PrimitiveType("char"); + case "Boolean": + return new PrimitiveType("bool"); + case "Void": + return new PrimitiveType("void"); + case "Object": + return new PrimitiveType("object"); + } } } @@ -595,6 +673,15 @@ namespace ICSharpCode.Decompiler.Ast void AddTypeMembers(TypeDeclaration astType, TypeDefinition typeDef) { + // Nested types + foreach (TypeDefinition nestedTypeDef in typeDef.NestedTypes) { + if (MemberIsHidden(nestedTypeDef, context.Settings)) + continue; + var nestedType = CreateType(nestedTypeDef); + SetNewModifier(nestedType); + astType.AddChild(nestedType, TypeDeclaration.MemberRole); + } + // Add fields foreach(FieldDefinition fieldDef in typeDef.Fields) { if (MemberIsHidden(fieldDef, context.Settings)) continue; @@ -729,6 +816,9 @@ namespace ICSharpCode.Decompiler.Ast astMethod.Body = CreateMethodBody(methodDef, astMethod.Parameters); ConvertAttributes(astMethod, methodDef); astMethod.WithAnnotation(methodMapping); + if (methodDef.IsStatic && methodDef.DeclaringType.IsBeforeFieldInit && !astMethod.Body.IsNull) { + astMethod.Body.InsertChildAfter(null, new Comment(" Note: this type is marked as 'beforefieldinit'."), AstNode.Roles.Comment); + } return astMethod; } @@ -801,7 +891,13 @@ namespace ICSharpCode.Decompiler.Ast astProp.Setter.Body = CreateMethodBody(propDef.SetMethod); astProp.Setter.AddAnnotation(propDef.SetMethod); ConvertAttributes(astProp.Setter, propDef.SetMethod); - ConvertCustomAttributes(astProp.Setter, propDef.SetMethod.Parameters.Last(), "param"); + ParameterDefinition lastParam = propDef.SetMethod.Parameters.LastOrDefault(); + if (lastParam != null) { + ConvertCustomAttributes(astProp.Setter, lastParam, "param"); + if (lastParam.HasMarshalInfo) { + astProp.Setter.Attributes.Add(new AttributeSection(ConvertMarshalInfo(lastParam, propDef.Module)) { AttributeTarget = "param" }); + } + } if ((setterModifiers & Modifiers.VisibilityMask) != (astProp.Modifiers & Modifiers.VisibilityMask)) astProp.Setter.Modifiers = setterModifiers & Modifiers.VisibilityMask; @@ -989,6 +1085,7 @@ namespace ICSharpCode.Decompiler.Ast void ConvertAttributes(AttributedNode attributedNode, TypeDefinition typeDefinition) { ConvertCustomAttributes(attributedNode, typeDefinition); + ConvertSecurityAttributes(attributedNode, typeDefinition); // Handle the non-custom attributes: #region SerializableAttribute @@ -1039,6 +1136,7 @@ namespace ICSharpCode.Decompiler.Ast void ConvertAttributes(AttributedNode attributedNode, MethodDefinition methodDefinition) { ConvertCustomAttributes(attributedNode, methodDefinition); + ConvertSecurityAttributes(attributedNode, methodDefinition); MethodImplAttributes implAttributes = methodDefinition.ImplAttributes & ~MethodImplAttributes.CodeTypeMask; @@ -1175,6 +1273,37 @@ namespace ICSharpCode.Decompiler.Ast Ast.Attribute attr = CreateNonCustomAttribute(typeof(MarshalAsAttribute), module); var unmanagedType = new TypeReference("System.Runtime.InteropServices", "UnmanagedType", module, module.TypeSystem.Corlib); attr.Arguments.Add(MakePrimitive((int)marshalInfo.NativeType, unmanagedType)); + + FixedArrayMarshalInfo fami = marshalInfo as FixedArrayMarshalInfo; + if (fami != null) { + attr.AddNamedArgument("SizeConst", new PrimitiveExpression(fami.Size)); + if (fami.ElementType != NativeType.None) + attr.AddNamedArgument("ArraySubType", MakePrimitive((int)fami.ElementType, unmanagedType)); + } + SafeArrayMarshalInfo sami = marshalInfo as SafeArrayMarshalInfo; + if (sami != null && sami.ElementType != VariantType.None) { + var varEnum = new TypeReference("System.Runtime.InteropServices", "VarEnum", module, module.TypeSystem.Corlib); + attr.AddNamedArgument("SafeArraySubType", MakePrimitive((int)sami.ElementType, varEnum)); + } + ArrayMarshalInfo ami = marshalInfo as ArrayMarshalInfo; + if (ami != null) { + if (ami.ElementType != NativeType.Max) + attr.AddNamedArgument("ArraySubType", MakePrimitive((int)ami.ElementType, unmanagedType)); + if (ami.Size >= 0) + attr.AddNamedArgument("SizeConst", new PrimitiveExpression(ami.Size)); + if (ami.SizeParameterMultiplier != 0 && ami.SizeParameterIndex >= 0) + attr.AddNamedArgument("SizeParamIndex", new PrimitiveExpression(ami.SizeParameterIndex)); + } + CustomMarshalInfo cmi = marshalInfo as CustomMarshalInfo; + if (cmi != null) { + attr.AddNamedArgument("MarshalType", new PrimitiveExpression(cmi.ManagedType.FullName)); + if (!string.IsNullOrEmpty(cmi.Cookie)) + attr.AddNamedArgument("MarshalCookie", new PrimitiveExpression(cmi.Cookie)); + } + FixedSysStringMarshalInfo fssmi = marshalInfo as FixedSysStringMarshalInfo; + if (fssmi != null) { + attr.AddNamedArgument("SizeConst", new PrimitiveExpression(fssmi.Size)); + } return attr; } #endregion @@ -1264,6 +1393,65 @@ namespace ICSharpCode.Decompiler.Ast } } + static void ConvertSecurityAttributes(AstNode attributedNode, ISecurityDeclarationProvider secDeclProvider, string attributeTarget = null) + { + if (!secDeclProvider.HasSecurityDeclarations) + return; + var attributes = new List(); + foreach (var secDecl in secDeclProvider.SecurityDeclarations) { + foreach (var secAttribute in secDecl.SecurityAttributes) { + var attribute = new ICSharpCode.NRefactory.CSharp.Attribute(); + attribute.AddAnnotation(secAttribute); + attribute.Type = ConvertType(secAttribute.AttributeType); + attributes.Add(attribute); + + SimpleType st = attribute.Type as SimpleType; + if (st != null && st.Identifier.EndsWith("Attribute", StringComparison.Ordinal)) { + st.Identifier = st.Identifier.Substring(0, st.Identifier.Length - "Attribute".Length); + } + + var module = secAttribute.AttributeType.Module; + var securityActionType = new TypeReference("System.Security.Permissions", "SecurityAction", module, module.TypeSystem.Corlib); + attribute.Arguments.Add(MakePrimitive((int)secDecl.Action, securityActionType)); + + if (secAttribute.HasProperties) { + TypeDefinition resolvedAttributeType = secAttribute.AttributeType.Resolve(); + foreach (var propertyNamedArg in secAttribute.Properties) { + var propertyReference = resolvedAttributeType != null ? resolvedAttributeType.Properties.FirstOrDefault(pr => pr.Name == propertyNamedArg.Name) : null; + var propertyName = new IdentifierExpression(propertyNamedArg.Name).WithAnnotation(propertyReference); + var argumentValue = ConvertArgumentValue(propertyNamedArg.Argument); + attribute.Arguments.Add(new AssignmentExpression(propertyName, argumentValue)); + } + } + + if (secAttribute.HasFields) { + TypeDefinition resolvedAttributeType = secAttribute.AttributeType.Resolve(); + foreach (var fieldNamedArg in secAttribute.Fields) { + var fieldReference = resolvedAttributeType != null ? resolvedAttributeType.Fields.FirstOrDefault(f => f.Name == fieldNamedArg.Name) : null; + var fieldName = new IdentifierExpression(fieldNamedArg.Name).WithAnnotation(fieldReference); + var argumentValue = ConvertArgumentValue(fieldNamedArg.Argument); + attribute.Arguments.Add(new AssignmentExpression(fieldName, argumentValue)); + } + } + } + } + if (attributeTarget == "module" || attributeTarget == "assembly") { + // use separate section for each attribute + foreach (var attribute in attributes) { + var section = new AttributeSection(); + section.AttributeTarget = attributeTarget; + section.Attributes.Add(attribute); + attributedNode.AddChild(section, AttributedNode.AttributeRole); + } + } else if (attributes.Count > 0) { + // use single section for all attributes + var section = new AttributeSection(); + section.AttributeTarget = attributeTarget; + section.Attributes.AddRange(attributes); + attributedNode.AddChild(section, AttributedNode.AttributeRole); + } + } + private static Expression ConvertArgumentValue(CustomAttributeArgument argument) { if (argument.Value is CustomAttributeArgument[]) { @@ -1284,9 +1472,7 @@ namespace ICSharpCode.Decompiler.Ast if (type != null && type.IsEnum) { return MakePrimitive(Convert.ToInt64(argument.Value), type); } else if (argument.Value is TypeReference) { - return new TypeOfExpression() { - Type = ConvertType((TypeReference)argument.Value), - }; + return CreateTypeOfExpression((TypeReference)argument.Value); } else { return new PrimitiveExpression(argument.Value); } @@ -1441,7 +1627,7 @@ namespace ICSharpCode.Decompiler.Ast if (baseType.HasFields && AnyIsHiddenBy(baseType.Fields, member)) return true; if (includeBaseMethods && baseType.HasMethods - && AnyIsHiddenBy(baseType.Methods, member, m => !m.IsSpecialName)) + && AnyIsHiddenBy(baseType.Methods, member, m => !m.IsSpecialName)) return true; if (baseType.HasNestedTypes && AnyIsHiddenBy(baseType.NestedTypes, member)) return true; @@ -1455,8 +1641,8 @@ namespace ICSharpCode.Decompiler.Ast where T : IMemberDefinition { return members.Any(m => m.Name == derived.Name - && (condition == null || condition(m)) - && TypesHierarchyHelpers.IsVisibleFromDerived(m, derived.DeclaringType)); + && (condition == null || condition(m)) + && TypesHierarchyHelpers.IsVisibleFromDerived(m, derived.DeclaringType)); } /// diff --git a/ICSharpCode.Decompiler/Ast/AstMethodBodyBuilder.cs b/ICSharpCode.Decompiler/Ast/AstMethodBodyBuilder.cs index 4d184ad02..b82101562 100644 --- a/ICSharpCode.Decompiler/Ast/AstMethodBodyBuilder.cs +++ b/ICSharpCode.Decompiler/Ast/AstMethodBodyBuilder.cs @@ -485,9 +485,12 @@ namespace ICSharpCode.Decompiler.Ast return arg1; else return arg1.CastTo(operandAsTypeRef); - case ILCode.Isinst: return arg1.CastAs(operandAsTypeRef); - case ILCode.Box: return arg1; - case ILCode.Unbox: return InlineAssembly(byteCode, args); + case ILCode.Isinst: + return arg1.CastAs(operandAsTypeRef); + case ILCode.Box: + return arg1; + case ILCode.Unbox: + return MakeRef(arg1.CastTo(operandAsTypeRef)); #endregion #region Indirect case ILCode.Ldind_Ref: @@ -539,11 +542,7 @@ namespace ICSharpCode.Decompiler.Ast case ILCode.Endfilter: return InlineAssembly(byteCode, args); case ILCode.Endfinally: return null; case ILCode.Initblk: return InlineAssembly(byteCode, args); - case ILCode.Initobj: - if (args[0] is DirectionExpression) - return new AssignmentExpression(((DirectionExpression)args[0]).Expression.Detach(), MakeDefaultValue((TypeReference)operand)); - else - return InlineAssembly(byteCode, args); + case ILCode.Initobj: return InlineAssembly(byteCode, args); case ILCode.DefaultValue: return MakeDefaultValue((TypeReference)operand); case ILCode.Jmp: return InlineAssembly(byteCode, args); @@ -602,7 +601,7 @@ namespace ICSharpCode.Decompiler.Ast case ILCode.Ldstr: return new Ast.PrimitiveExpression(operand); case ILCode.Ldtoken: if (operand is Cecil.TypeReference) { - return new Ast.TypeOfExpression { Type = operandAsTypeRef }.Member("TypeHandle"); + return AstBuilder.CreateTypeOfExpression((TypeReference)operand).Member("TypeHandle"); } else { return InlineAssembly(byteCode, args); } diff --git a/ICSharpCode.Decompiler/Ast/NameVariables.cs b/ICSharpCode.Decompiler/Ast/NameVariables.cs index 66f50ff13..c7ac8f385 100644 --- a/ICSharpCode.Decompiler/Ast/NameVariables.cs +++ b/ICSharpCode.Decompiler/Ast/NameVariables.cs @@ -279,6 +279,8 @@ namespace ICSharpCode.Decompiler.Ast name = "array"; } else if (type.IsPointer || type.IsByReference) { name = "ptr"; + } else if (type.Name.EndsWith("Exception", StringComparison.Ordinal)) { + name = "ex"; } else if (!typeNameToVariableNameDict.TryGetValue(type.FullName, out name)) { name = type.Name; // remove the 'I' for interfaces diff --git a/ICSharpCode.Decompiler/Ast/TextOutputFormatter.cs b/ICSharpCode.Decompiler/Ast/TextOutputFormatter.cs index e4ab53351..627ad6380 100644 --- a/ICSharpCode.Decompiler/Ast/TextOutputFormatter.cs +++ b/ICSharpCode.Decompiler/Ast/TextOutputFormatter.cs @@ -17,6 +17,7 @@ namespace ICSharpCode.Decompiler.Ast readonly ITextOutput output; readonly Stack nodeStack = new Stack(); int braceLevelWithinType = -1; + bool inDocumentationComment = false; public TextOutputFormatter(ITextOutput output) { @@ -115,8 +116,17 @@ namespace ICSharpCode.Decompiler.Ast output.Write("*/"); break; case CommentType.Documentation: + if (!inDocumentationComment) + output.MarkFoldStart("///" + content, true); output.Write("///"); - output.WriteLine(content); + output.Write(content); + inDocumentationComment = true; + bool isLastLine = !(nodeStack.Peek().NextSibling is Comment); + if (isLastLine) { + inDocumentationComment = false; + output.MarkFoldEnd(); + } + output.WriteLine(); break; } } @@ -127,7 +137,8 @@ namespace ICSharpCode.Decompiler.Ast var ranges = node.Annotation>(); if (ranges != null && ranges.Count > 0) { // find the ancestor that has method mapping as annotation - if (node.Ancestors != null && node.Ancestors.Count() > 0) { + if (node.Parent != null) + { var n = node.Ancestors.FirstOrDefault(a => a.Annotation() != null); if (n != null) { MemberMapping mapping = n.Annotation(); diff --git a/ICSharpCode.Decompiler/Ast/Transforms/ConvertConstructorCallIntoInitializer.cs b/ICSharpCode.Decompiler/Ast/Transforms/ConvertConstructorCallIntoInitializer.cs index 716754595..054d3066e 100644 --- a/ICSharpCode.Decompiler/Ast/Transforms/ConvertConstructorCallIntoInitializer.cs +++ b/ICSharpCode.Decompiler/Ast/Transforms/ConvertConstructorCallIntoInitializer.cs @@ -17,6 +17,7 @@ // DEALINGS IN THE SOFTWARE. using System; +using System.Collections.Generic; using System.Linq; using ICSharpCode.NRefactory.CSharp; using ICSharpCode.NRefactory.PatternMatching; @@ -69,9 +70,29 @@ namespace ICSharpCode.Decompiler.Ast.Transforms public override object VisitTypeDeclaration(TypeDeclaration typeDeclaration, object data) { - var instanceCtors = typeDeclaration.Members.OfType().Where(c => (c.Modifiers & Modifiers.Static) == 0).ToArray(); + // Handle initializers on instance fields + HandleInstanceFieldInitializers(typeDeclaration.Members); + + // Now convert base constructor calls to initializers: + base.VisitTypeDeclaration(typeDeclaration, data); + + // Remove single empty constructor: + RemoveSingleEmptyConstructor(typeDeclaration); + + // Handle initializers on static fields: + HandleStaticFieldInitializers(typeDeclaration.Members); + return null; + } + + void HandleInstanceFieldInitializers(IEnumerable members) + { + var instanceCtors = members.OfType().Where(c => (c.Modifiers & Modifiers.Static) == 0).ToArray(); var instanceCtorsNotChainingWithThis = instanceCtors.Where(ctor => !thisCallPattern.IsMatch(ctor.Body.Statements.FirstOrDefault())).ToArray(); - if (instanceCtorsNotChainingWithThis.Length > 0 && typeDeclaration.ClassType == NRefactory.TypeSystem.ClassType.Class) { + if (instanceCtorsNotChainingWithThis.Length > 0) { + MethodDefinition ctorMethodDef = instanceCtorsNotChainingWithThis[0].Annotation(); + if (ctorMethodDef != null && ctorMethodDef.DeclaringType.IsValueType) + return; + // Recognize field initializers: // Convert first statement in all ctors (if all ctors have the same statement) into a field initializer. bool allSame; @@ -83,7 +104,7 @@ namespace ICSharpCode.Decompiler.Ast.Transforms FieldDefinition fieldDef = m.Get("fieldAccess").Single().Annotation().ResolveWithinSameModule(); if (fieldDef == null) break; - AttributedNode fieldOrEventDecl = typeDeclaration.Members.FirstOrDefault(f => f.Annotation() == fieldDef); + AstNode fieldOrEventDecl = members.FirstOrDefault(f => f.Annotation() == fieldDef); if (fieldOrEventDecl == null) break; @@ -99,11 +120,11 @@ namespace ICSharpCode.Decompiler.Ast.Transforms } } while (allSame); } - - // Now convert base constructor calls to initializers: - base.VisitTypeDeclaration(typeDeclaration, data); - - // Remove single empty constructor: + } + + void RemoveSingleEmptyConstructor(TypeDeclaration typeDeclaration) + { + var instanceCtors = typeDeclaration.Members.OfType().Where(c => (c.Modifiers & Modifiers.Static) == 0).ToArray(); if (instanceCtors.Length == 1) { ConstructorDeclaration emptyCtor = new ConstructorDeclaration(); emptyCtor.Modifiers = ((typeDeclaration.Modifiers & Modifiers.Abstract) == Modifiers.Abstract ? Modifiers.Protected : Modifiers.Public); @@ -111,12 +132,15 @@ namespace ICSharpCode.Decompiler.Ast.Transforms if (emptyCtor.IsMatch(instanceCtors[0])) instanceCtors[0].Remove(); } - + } + + void HandleStaticFieldInitializers(IEnumerable members) + { // Convert static constructor into field initializers if the class is BeforeFieldInit - var staticCtor = typeDeclaration.Members.OfType().FirstOrDefault(c => (c.Modifiers & Modifiers.Static) == Modifiers.Static); + var staticCtor = members.OfType().FirstOrDefault(c => (c.Modifiers & Modifiers.Static) == Modifiers.Static); if (staticCtor != null) { - TypeDefinition typeDef = typeDeclaration.Annotation(); - if (typeDef != null && typeDef.IsBeforeFieldInit) { + MethodDefinition ctorMethodDef = staticCtor.Annotation(); + if (ctorMethodDef != null && ctorMethodDef.DeclaringType.IsBeforeFieldInit) { while (true) { ExpressionStatement es = staticCtor.Body.Statements.FirstOrDefault() as ExpressionStatement; if (es == null) @@ -127,7 +151,7 @@ namespace ICSharpCode.Decompiler.Ast.Transforms FieldDefinition fieldDef = assignment.Left.Annotation().ResolveWithinSameModule(); if (fieldDef == null || !fieldDef.IsStatic) break; - FieldDeclaration fieldDecl = typeDeclaration.Members.OfType().FirstOrDefault(f => f.Annotation() == fieldDef); + FieldDeclaration fieldDecl = members.OfType().FirstOrDefault(f => f.Annotation() == fieldDef); if (fieldDecl == null) break; fieldDecl.Variables.Single().Initializer = assignment.Right.Detach(); @@ -137,11 +161,15 @@ namespace ICSharpCode.Decompiler.Ast.Transforms staticCtor.Remove(); } } - return null; } void IAstTransform.Run(AstNode node) { + // If we're viewing some set of members (fields are direct children of CompilationUnit), + // we also need to handle those: + HandleInstanceFieldInitializers(node.Children); + HandleStaticFieldInitializers(node.Children); + node.AcceptVisitor(this, null); } } diff --git a/ICSharpCode.Decompiler/Ast/Transforms/DecimalConstantTransform.cs b/ICSharpCode.Decompiler/Ast/Transforms/DecimalConstantTransform.cs new file mode 100644 index 000000000..298682afb --- /dev/null +++ b/ICSharpCode.Decompiler/Ast/Transforms/DecimalConstantTransform.cs @@ -0,0 +1,58 @@ +// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team +// +// Permission is hereby granted, free of charge, to any person obtaining a copy of this +// software and associated documentation files (the "Software"), to deal in the Software +// without restriction, including without limitation the rights to use, copy, modify, merge, +// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons +// to whom the Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all copies or +// substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE +// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. + +using System; +using ICSharpCode.NRefactory.CSharp; +using ICSharpCode.NRefactory.PatternMatching; +using Mono.Cecil; + +namespace ICSharpCode.Decompiler.Ast.Transforms +{ + /// + /// Transforms decimal constant fields. + /// + public class DecimalConstantTransform : DepthFirstAstVisitor, IAstTransform + { + static readonly PrimitiveType decimalType = new PrimitiveType("decimal"); + + public override object VisitFieldDeclaration(FieldDeclaration fieldDeclaration, object data) + { + const Modifiers staticReadOnly = Modifiers.Static | Modifiers.Readonly; + if ((fieldDeclaration.Modifiers & staticReadOnly) == staticReadOnly && decimalType.IsMatch(fieldDeclaration.ReturnType)) { + foreach (var attributeSection in fieldDeclaration.Attributes) { + foreach (var attribute in attributeSection.Attributes) { + TypeReference tr = attribute.Type.Annotation(); + if (tr != null && tr.Name == "DecimalConstantAttribute" && tr.Namespace == "System.Runtime.CompilerServices") { + attribute.Remove(); + if (attributeSection.Attributes.Count == 0) + attributeSection.Remove(); + fieldDeclaration.Modifiers = (fieldDeclaration.Modifiers & ~staticReadOnly) | Modifiers.Const; + return null; + } + } + } + } + return null; + } + + public void Run(AstNode compilationUnit) + { + compilationUnit.AcceptVisitor(this, null); + } + } +} diff --git a/ICSharpCode.Decompiler/Ast/Transforms/DelegateConstruction.cs b/ICSharpCode.Decompiler/Ast/Transforms/DelegateConstruction.cs index 6a5256b44..85ac9da1e 100644 --- a/ICSharpCode.Decompiler/Ast/Transforms/DelegateConstruction.cs +++ b/ICSharpCode.Decompiler/Ast/Transforms/DelegateConstruction.cs @@ -61,7 +61,7 @@ namespace ICSharpCode.Decompiler.Ast.Transforms public override object VisitObjectCreateExpression(ObjectCreateExpression objectCreateExpression, object data) { - if (objectCreateExpression.Arguments.Count() == 2) { + if (objectCreateExpression.Arguments.Count == 2) { Expression obj = objectCreateExpression.Arguments.First(); Expression func = objectCreateExpression.Arguments.Last(); Annotation annotation = func.Annotation(); @@ -115,7 +115,7 @@ namespace ICSharpCode.Decompiler.Ast.Transforms internal static bool IsAnonymousMethod(DecompilerContext context, MethodDefinition method) { - if (method == null || !method.Name.StartsWith("<", StringComparison.Ordinal)) + if (method == null || !(method.Name.StartsWith("<", StringComparison.Ordinal) || method.Name.Contains("$"))) return false; if (!(method.IsCompilerGenerated() || IsPotentialClosure(context, method.DeclaringType))) return false; @@ -388,10 +388,13 @@ namespace ICSharpCode.Decompiler.Ast.Transforms continue; // skip static fields if (dict.ContainsKey(field)) // skip field if it already was handled as parameter continue; - EnsureVariableNameIsAvailable(blockStatement, field.Name); - currentlyUsedVariableNames.Add(field.Name); - variablesToDeclare.Add(Tuple.Create(AstBuilder.ConvertType(field.FieldType, field), field.Name)); - dict[field] = new IdentifierExpression(field.Name); + string capturedVariableName = field.Name; + if (capturedVariableName.StartsWith("$VB$Local_", StringComparison.Ordinal) && capturedVariableName.Length > 10) + capturedVariableName = capturedVariableName.Substring(10); + EnsureVariableNameIsAvailable(blockStatement, capturedVariableName); + currentlyUsedVariableNames.Add(capturedVariableName); + variablesToDeclare.Add(Tuple.Create(AstBuilder.ConvertType(field.FieldType, field), capturedVariableName)); + dict[field] = new IdentifierExpression(capturedVariableName); } // Now figure out where the closure was accessed and use the simpler replacement expression there: diff --git a/ICSharpCode.Decompiler/Ast/Transforms/PatternStatementTransform.cs b/ICSharpCode.Decompiler/Ast/Transforms/PatternStatementTransform.cs index bc17d13cc..3d5c0e596 100644 --- a/ICSharpCode.Decompiler/Ast/Transforms/PatternStatementTransform.cs +++ b/ICSharpCode.Decompiler/Ast/Transforms/PatternStatementTransform.cs @@ -154,7 +154,7 @@ namespace ICSharpCode.Decompiler.Ast.Transforms } static readonly AstNode usingTryCatchPattern = new TryCatchStatement { - TryBlock = new AnyNode("body"), + TryBlock = new AnyNode(), FinallyBlock = new BlockStatement { new Choice { { "valueType", @@ -180,44 +180,60 @@ namespace ICSharpCode.Decompiler.Ast.Transforms { Match m1 = variableAssignPattern.Match(node); if (!m1.Success) return null; - AstNode tryCatch = node.NextSibling; + TryCatchStatement tryCatch = node.NextSibling as TryCatchStatement; Match m2 = usingTryCatchPattern.Match(tryCatch); if (!m2.Success) return null; string variableName = m1.Get("variable").Single().Identifier; - if (variableName == m2.Get("ident").Single().Identifier) { - if (m2.Has("valueType")) { - // if there's no if(x!=null), then it must be a value type - ILVariable v = m1.Get("variable").Single().Annotation(); - if (v == null || v.Type == null || !v.Type.IsValueType) - return null; - } - node.Remove(); - BlockStatement body = m2.Get("body").Single(); - UsingStatement usingStatement = new UsingStatement(); - usingStatement.ResourceAcquisition = node.Expression.Detach(); - usingStatement.EmbeddedStatement = body.Detach(); - tryCatch.ReplaceWith(usingStatement); - // Move the variable declaration into the resource acquisition, if possible - // This is necessary for the foreach-pattern to work on the result of the using-pattern - VariableDeclarationStatement varDecl = FindVariableDeclaration(usingStatement, variableName); - if (varDecl != null && varDecl.Parent is BlockStatement) { - Statement declarationPoint; - if (CanMoveVariableDeclarationIntoStatement(varDecl, usingStatement, out declarationPoint)) { - // Moving the variable into the UsingStatement is allowed: - usingStatement.ResourceAcquisition = new VariableDeclarationStatement { - Type = (AstType)varDecl.Type.Clone(), - Variables = { - new VariableInitializer { - Name = variableName, - Initializer = m1.Get("initializer").Single().Detach() - }.CopyAnnotationsFrom(usingStatement.ResourceAcquisition) - } - }.CopyAnnotationsFrom(node); + if (variableName != m2.Get("ident").Single().Identifier) + return null; + if (m2.Has("valueType")) { + // if there's no if(x!=null), then it must be a value type + ILVariable v = m1.Get("variable").Single().Annotation(); + if (v == null || v.Type == null || !v.Type.IsValueType) + return null; + } + + // There are two variants of the using statement: + // "using (var a = init)" and "using (expr)". + // The former declares a read-only variable 'a', and the latter declares an unnamed read-only variable + // to store the original value of 'expr'. + // This means that in order to introduce a using statement, in both cases we need to detect a read-only + // variable that is used only within that block. + + if (HasAssignment(tryCatch, variableName)) + return null; + + VariableDeclarationStatement varDecl = FindVariableDeclaration(node, variableName); + if (varDecl == null || !(varDecl.Parent is BlockStatement)) + return null; + + // Validate that the variable is not used after the using statement: + if (!IsVariableValueUnused(varDecl, tryCatch)) + return null; + + node.Remove(); + + UsingStatement usingStatement = new UsingStatement(); + usingStatement.EmbeddedStatement = tryCatch.TryBlock.Detach(); + tryCatch.ReplaceWith(usingStatement); + + // If possible, we'll eliminate the variable completely: + if (usingStatement.EmbeddedStatement.Descendants.OfType().Any(ident => ident.Identifier == variableName)) { + // variable is used, so we'll create a variable declaration + usingStatement.ResourceAcquisition = new VariableDeclarationStatement { + Type = (AstType)varDecl.Type.Clone(), + Variables = { + new VariableInitializer { + Name = variableName, + Initializer = m1.Get("initializer").Single().Detach() + }.CopyAnnotationsFrom(node.Expression) } - } - return usingStatement; + }.CopyAnnotationsFrom(node); + } else { + // the variable is never used; eliminate it: + usingStatement.ResourceAcquisition = m1.Get("initializer").Single().Detach(); } - return null; + return usingStatement; } internal static VariableDeclarationStatement FindVariableDeclaration(AstNode node, string identifier) @@ -235,6 +251,29 @@ namespace ICSharpCode.Decompiler.Ast.Transforms return null; } + /// + /// Gets whether the old variable value (assigned inside 'targetStatement' or earlier) + /// is read anywhere in the remaining scope of the variable declaration. + /// + bool IsVariableValueUnused(VariableDeclarationStatement varDecl, Statement targetStatement) + { + Debug.Assert(targetStatement.Ancestors.Contains(varDecl.Parent)); + BlockStatement block = (BlockStatement)varDecl.Parent; + DefiniteAssignmentAnalysis daa = new DefiniteAssignmentAnalysis(block, context.CancellationToken); + daa.SetAnalyzedRange(targetStatement, block, startInclusive: false); + daa.Analyze(varDecl.Variables.Single().Name); + return daa.UnassignedVariableUses.Count == 0; + } + + // I used this in the first implementation of the using-statement transform, but now no longer + // because there were problems when multiple using statements were using the same variable + // - no single using statement could be transformed without making the C# code invalid, + // but transforming both would work. + // We now use 'IsVariableValueUnused' which will perform the transform + // even if it results in two variables with the same name and overlapping scopes. + // (this issue could be fixed later by renaming one of the variables) + + // I'm not sure whether the other consumers of 'CanMoveVariableDeclarationIntoStatement' should be changed the same way. bool CanMoveVariableDeclarationIntoStatement(VariableDeclarationStatement varDecl, Statement targetStatement, out Statement declarationPoint) { Debug.Assert(targetStatement.Ancestors.Contains(varDecl.Parent)); @@ -251,6 +290,24 @@ namespace ICSharpCode.Decompiler.Ast.Transforms } return true; } + + /// + /// Gets whether there is an assignment to 'variableName' anywhere within the given node. + /// + bool HasAssignment(AstNode root, string variableName) + { + foreach (AstNode node in root.DescendantsAndSelf) { + IdentifierExpression ident = node as IdentifierExpression; + if (ident != null && ident.Identifier == variableName) { + if (ident.Parent is AssignmentExpression && ident.Role == AssignmentExpression.LeftRole + || ident.Parent is DirectionExpression) + { + return true; + } + } + } + return false; + } #endregion #region foreach (generic) @@ -648,7 +705,7 @@ namespace ICSharpCode.Decompiler.Ast.Transforms // switchVar must be the same as switchExpr; or switchExpr must be an assignment and switchVar the left side of that assignment if (!m.Get("switchVar").Single().IsMatch(m.Get("switchExpr").Single())) { AssignmentExpression assign = m.Get("switchExpr").Single() as AssignmentExpression; - if (!m.Get("switchVar").Single().IsMatch(assign.Left)) + if (!(assign != null && m.Get("switchVar").Single().IsMatch(assign.Left))) return null; } FieldReference cachedDictField = m.Get("cachedDict").Single().Annotation(); diff --git a/ICSharpCode.Decompiler/Ast/Transforms/ReplaceMethodCallsWithOperators.cs b/ICSharpCode.Decompiler/Ast/Transforms/ReplaceMethodCallsWithOperators.cs index 7a9eaa365..ba641e77d 100644 --- a/ICSharpCode.Decompiler/Ast/Transforms/ReplaceMethodCallsWithOperators.cs +++ b/ICSharpCode.Decompiler/Ast/Transforms/ReplaceMethodCallsWithOperators.cs @@ -50,7 +50,7 @@ namespace ICSharpCode.Decompiler.Ast.Transforms var arguments = invocationExpression.Arguments.ToArray(); // Reduce "String.Concat(a, b)" to "a + b" - if (methodRef != null && methodRef.Name == "Concat" && methodRef.DeclaringType.FullName == "System.String" && arguments.Length >= 2) + if (methodRef.Name == "Concat" && methodRef.DeclaringType.FullName == "System.String" && arguments.Length >= 2) { invocationExpression.Arguments.Clear(); // detach arguments from invocationExpression Expression expr = arguments[0]; @@ -97,7 +97,10 @@ namespace ICSharpCode.Decompiler.Ast.Transforms return null; } if (methodRef.Name == "op_Implicit" && arguments.Length == 1) { - arguments[0].Remove(); // detach argument + invocationExpression.ReplaceWith(arguments[0]); + return null; + } + if (methodRef.Name == "op_True" && arguments.Length == 1 && invocationExpression.Role == AstNode.Roles.Condition) { invocationExpression.ReplaceWith(arguments[0]); return null; } diff --git a/ICSharpCode.Decompiler/Ast/Transforms/TransformationPipeline.cs b/ICSharpCode.Decompiler/Ast/Transforms/TransformationPipeline.cs index 686a73a61..13730ea1d 100644 --- a/ICSharpCode.Decompiler/Ast/Transforms/TransformationPipeline.cs +++ b/ICSharpCode.Decompiler/Ast/Transforms/TransformationPipeline.cs @@ -40,6 +40,7 @@ namespace ICSharpCode.Decompiler.Ast.Transforms new AddCheckedBlocks(), new DeclareVariables(context), // should run after most transforms that modify statements new ConvertConstructorCallIntoInitializer(), // must run after DeclareVariables + new DecimalConstantTransform(), new IntroduceUsingDeclarations(context), new IntroduceExtensionMethods(context), // must run after IntroduceUsingDeclarations new IntroduceQueryExpressions(context), // must run after IntroduceExtensionMethods diff --git a/ICSharpCode.Decompiler/Disassembler/DisassemblerHelpers.cs b/ICSharpCode.Decompiler/Disassembler/DisassemblerHelpers.cs index 0060b71d8..df66c2650 100644 --- a/ICSharpCode.Decompiler/Disassembler/DisassemblerHelpers.cs +++ b/ICSharpCode.Decompiler/Disassembler/DisassemblerHelpers.cs @@ -17,11 +17,32 @@ // DEALINGS IN THE SOFTWARE. using System; +using System.Collections.Generic; using Mono.Cecil; using Mono.Cecil.Cil; namespace ICSharpCode.Decompiler.Disassembler { + public enum ILNameSyntax + { + /// + /// class/valuetype + TypeName (built-in types use keyword syntax) + /// + Signature, + /// + /// Like signature, but always refers to type parameters using their position + /// + SignatureNoNamedTypeParameters, + /// + /// [assembly]Full.Type.Name (even for built-in types) + /// + TypeName, + /// + /// Name (but built-in types use keyword syntax) + /// + ShortTypeName + } + public static class DisassemblerHelpers { public static void WriteOffsetReference(ITextOutput writer, Instruction instruction) @@ -35,6 +56,7 @@ namespace ICSharpCode.Decompiler.Disassembler WriteOffsetReference(writer, exceptionHandler.TryStart); writer.Write('-'); WriteOffsetReference(writer, exceptionHandler.TryEnd); + writer.Write(' '); writer.Write(exceptionHandler.HandlerType.ToString()); if (exceptionHandler.FilterStart != null) { writer.Write(' '); @@ -56,8 +78,14 @@ namespace ICSharpCode.Decompiler.Disassembler writer.WriteDefinition(CecilExtensions.OffsetToString(instruction.Offset), instruction); writer.Write(": "); writer.WriteReference(instruction.OpCode.Name, instruction.OpCode); - if(null != instruction.Operand) { + if (instruction.Operand != null) { writer.Write(' '); + if (instruction.OpCode == OpCodes.Ldtoken) { + if (instruction.Operand is MethodReference) + writer.Write("method "); + else if (instruction.Operand is FieldReference) + writer.Write("field "); + } WriteOperand(writer, instruction.Operand); } } @@ -82,46 +110,131 @@ namespace ICSharpCode.Decompiler.Disassembler public static void WriteTo(this MethodReference method, ITextOutput writer) { - if (method.HasThis) + if (method.ExplicitThis) { + writer.Write("instance explicit "); + } + else if (method.HasThis) { writer.Write("instance "); - method.ReturnType.WriteTo(writer); + } + method.ReturnType.WriteTo(writer, ILNameSyntax.SignatureNoNamedTypeParameters); writer.Write(' '); if (method.DeclaringType != null) { - method.DeclaringType.WriteTo(writer, true); + method.DeclaringType.WriteTo(writer, ILNameSyntax.TypeName); writer.Write("::"); } - writer.WriteReference(method.Name, method); + MethodDefinition md = method as MethodDefinition; + if (md != null && md.IsCompilerControlled) { + writer.WriteReference(Escape(method.Name + "$PST" + method.MetadataToken.ToInt32().ToString("X8")), method); + } else { + writer.WriteReference(Escape(method.Name), method); + } + GenericInstanceMethod gim = method as GenericInstanceMethod; + if (gim != null) { + writer.Write('<'); + for (int i = 0; i < gim.GenericArguments.Count; i++) { + if (i > 0) + writer.Write(", "); + gim.GenericArguments[i].WriteTo(writer); + } + writer.Write('>'); + } writer.Write("("); var parameters = method.Parameters; for(int i = 0; i < parameters.Count; ++i) { if (i > 0) writer.Write(", "); - parameters[i].ParameterType.WriteTo(writer); + parameters[i].ParameterType.WriteTo(writer, ILNameSyntax.SignatureNoNamedTypeParameters); } writer.Write(")"); } static void WriteTo(this FieldReference field, ITextOutput writer) { - field.FieldType.WriteTo(writer); + field.FieldType.WriteTo(writer, ILNameSyntax.SignatureNoNamedTypeParameters); writer.Write(' '); - field.DeclaringType.WriteTo(writer); + field.DeclaringType.WriteTo(writer, ILNameSyntax.TypeName); writer.Write("::"); - writer.WriteReference(field.Name, field); + writer.WriteReference(Escape(field.Name), field); + } + + static bool IsValidIdentifierCharacter(char c) + { + return c == '_' || c == '$' || c == '@' || c == '?' || c == '`'; + } + + static bool IsValidIdentifier(string identifier) + { + if (string.IsNullOrEmpty(identifier)) + return false; + if (!(char.IsLetter(identifier[0]) || IsValidIdentifierCharacter(identifier[0]))) { + // As a special case, .ctor and .cctor are valid despite starting with a dot + return identifier == ".ctor" || identifier == ".cctor"; + } + for (int i = 1; i < identifier.Length; i++) { + if (!(char.IsLetterOrDigit(identifier[i]) || IsValidIdentifierCharacter(identifier[i]) || identifier[i] == '.')) + return false; + } + return true; + } + + static readonly HashSet ilKeywords = BuildKeywordList( + "abstract", "algorithm", "alignment", "ansi", "any", "arglist", + "array", "as", "assembly", "assert", "at", "auto", "autochar", "beforefieldinit", + "blob", "blob_object", "bool", "brnull", "brnull.s", "brzero", "brzero.s", "bstr", + "bytearray", "byvalstr", "callmostderived", "carray", "catch", "cdecl", "cf", + "char", "cil", "class", "clsid", "const", "currency", "custom", "date", "decimal", + "default", "demand", "deny", "endmac", "enum", "error", "explicit", "extends", "extern", + "false", "famandassem", "family", "famorassem", "fastcall", "fault", "field", "filetime", + "filter", "final", "finally", "fixed", "float", "float32", "float64", "forwardref", + "fromunmanaged", "handler", "hidebysig", "hresult", "idispatch", "il", "illegal", + "implements", "implicitcom", "implicitres", "import", "in", "inheritcheck", "init", + "initonly", "instance", "int", "int16", "int32", "int64", "int8", "interface", "internalcall", + "iunknown", "lasterr", "lcid", "linkcheck", "literal", "localloc", "lpstr", "lpstruct", "lptstr", + "lpvoid", "lpwstr", "managed", "marshal", "method", "modopt", "modreq", "native", "nested", + "newslot", "noappdomain", "noinlining", "nomachine", "nomangle", "nometadata", "noncasdemand", + "noncasinheritance", "noncaslinkdemand", "noprocess", "not", "not_in_gc_heap", "notremotable", + "notserialized", "null", "nullref", "object", "objectref", "opt", "optil", "out", + "permitonly", "pinned", "pinvokeimpl", "prefix1", "prefix2", "prefix3", "prefix4", "prefix5", "prefix6", + "prefix7", "prefixref", "prejitdeny", "prejitgrant", "preservesig", "private", "privatescope", "protected", + "public", "record", "refany", "reqmin", "reqopt", "reqrefuse", "reqsecobj", "request", "retval", + "rtspecialname", "runtime", "safearray", "sealed", "sequential", "serializable", "special", "specialname", + "static", "stdcall", "storage", "stored_object", "stream", "streamed_object", "string", "struct", + "synchronized", "syschar", "sysstring", "tbstr", "thiscall", "tls", "to", "true", "typedref", + "unicode", "unmanaged", "unmanagedexp", "unsigned", "unused", "userdefined", "value", "valuetype", + "vararg", "variant", "vector", "virtual", "void", "wchar", "winapi", "with", "wrapper", + + // These are not listed as keywords in spec, but ILAsm treats them as such + "property", "type", "flags", "callconv", "strict" + ); + + static HashSet BuildKeywordList(params string[] keywords) + { + HashSet s = new HashSet(keywords); + foreach (var field in typeof(OpCodes).GetFields()) { + s.Add(((OpCode)field.GetValue(null)).Name); + } + return s; } public static string Escape(string identifier) { - return identifier; + if (IsValidIdentifier(identifier) && !ilKeywords.Contains(identifier)) { + return identifier; + } else { + // The ECMA specification says that ' inside SQString should be ecaped using an octal escape sequence, + // but we follow Microsoft's ILDasm and use \'. + return "'" + NRefactory.CSharp.OutputVisitor.ConvertString(identifier).Replace("'", "\\'") + "'"; + } } - public static void WriteTo(this TypeReference type, ITextOutput writer, bool onlyName = false, bool shortName = false) + public static void WriteTo(this TypeReference type, ITextOutput writer, ILNameSyntax syntax = ILNameSyntax.Signature) { + ILNameSyntax syntaxForElementTypes = syntax == ILNameSyntax.SignatureNoNamedTypeParameters ? syntax : ILNameSyntax.Signature; if (type is PinnedType) { - writer.Write("pinned "); - ((PinnedType)type).ElementType.WriteTo(writer, onlyName, shortName); + ((PinnedType)type).ElementType.WriteTo(writer, syntaxForElementTypes); + writer.Write(" pinned"); } else if (type is ArrayType) { ArrayType at = (ArrayType)type; - at.ElementType.WriteTo(writer, onlyName, shortName); + at.ElementType.WriteTo(writer, syntaxForElementTypes); writer.Write('['); writer.Write(string.Join(", ", at.Dimensions)); writer.Write(']'); @@ -129,49 +242,57 @@ namespace ICSharpCode.Decompiler.Disassembler writer.Write('!'); if (((GenericParameter)type).Owner.GenericParameterType == GenericParameterType.Method) writer.Write('!'); - writer.Write(type.Name); + if (string.IsNullOrEmpty(type.Name) || type.Name[0] == '!' || syntax == ILNameSyntax.SignatureNoNamedTypeParameters) + writer.Write(((GenericParameter)type).Position.ToString()); + else + writer.Write(Escape(type.Name)); } else if (type is ByReferenceType) { - ((ByReferenceType)type).ElementType.WriteTo(writer, onlyName, shortName); + ((ByReferenceType)type).ElementType.WriteTo(writer, syntaxForElementTypes); writer.Write('&'); } else if (type is PointerType) { - ((PointerType)type).ElementType.WriteTo(writer, onlyName, shortName); + ((PointerType)type).ElementType.WriteTo(writer, syntaxForElementTypes); writer.Write('*'); } else if (type is GenericInstanceType) { - type.GetElementType().WriteTo(writer, onlyName, shortName); + type.GetElementType().WriteTo(writer, syntaxForElementTypes); writer.Write('<'); var arguments = ((GenericInstanceType)type).GenericArguments; for (int i = 0; i < arguments.Count; i++) { if (i > 0) writer.Write(", "); - arguments[i].WriteTo(writer, onlyName, shortName); + arguments[i].WriteTo(writer, syntaxForElementTypes); } writer.Write('>'); } else if (type is OptionalModifierType) { - writer.Write("modopt("); - ((OptionalModifierType)type).ModifierType.WriteTo(writer, true, shortName); + ((OptionalModifierType)type).ElementType.WriteTo(writer, syntax); + writer.Write(" modopt("); + ((OptionalModifierType)type).ModifierType.WriteTo(writer, ILNameSyntax.TypeName); writer.Write(") "); - ((OptionalModifierType)type).ElementType.WriteTo(writer, onlyName, shortName); } else if (type is RequiredModifierType) { - writer.Write("modreq("); - ((RequiredModifierType)type).ModifierType.WriteTo(writer, true, shortName); + ((RequiredModifierType)type).ElementType.WriteTo(writer, syntax); + writer.Write(" modreq("); + ((RequiredModifierType)type).ModifierType.WriteTo(writer, ILNameSyntax.TypeName); writer.Write(") "); - ((RequiredModifierType)type).ElementType.WriteTo(writer, onlyName, shortName); } else { - string name = PrimitiveTypeName(type); - if (name != null) { + string name = PrimitiveTypeName(type.FullName); + if (syntax == ILNameSyntax.ShortTypeName) { + if (name != null) + writer.Write(name); + else + writer.WriteReference(Escape(type.Name), type); + } else if ((syntax == ILNameSyntax.Signature || syntax == ILNameSyntax.SignatureNoNamedTypeParameters) && name != null) { writer.Write(name); } else { - if (!onlyName) + if (syntax == ILNameSyntax.Signature || syntax == ILNameSyntax.SignatureNoNamedTypeParameters) writer.Write(type.IsValueType ? "valuetype " : "class "); if (type.DeclaringType != null) { - type.DeclaringType.WriteTo(writer, true, shortName); + type.DeclaringType.WriteTo(writer, ILNameSyntax.TypeName); writer.Write('/'); writer.WriteReference(Escape(type.Name), type); } else { - if (!type.IsDefinition && type.Scope != null && !shortName && !(type is TypeSpecification)) + if (!type.IsDefinition && type.Scope != null && !(type is TypeSpecification)) writer.Write("[{0}]", Escape(type.Scope.Name)); - writer.WriteReference(shortName ? type.Name : type.FullName, type); + writer.WriteReference(Escape(type.FullName), type); } } } @@ -196,7 +317,19 @@ namespace ICSharpCode.Decompiler.Disassembler VariableReference variableRef = operand as VariableReference; if (variableRef != null) { - writer.WriteReference(variableRef.Index.ToString(), variableRef); + if (string.IsNullOrEmpty(variableRef.Name)) + writer.WriteReference(variableRef.Index.ToString(), variableRef); + else + writer.WriteReference(Escape(variableRef.Name), variableRef); + return; + } + + ParameterReference paramRef = operand as ParameterReference; + if (paramRef != null) { + if (string.IsNullOrEmpty(paramRef.Name)) + writer.WriteReference(paramRef.Index.ToString(), paramRef); + else + writer.WriteReference(Escape(paramRef.Name), paramRef); return; } @@ -208,7 +341,7 @@ namespace ICSharpCode.Decompiler.Disassembler TypeReference typeRef = operand as TypeReference; if (typeRef != null) { - typeRef.WriteTo(writer); + typeRef.WriteTo(writer, ILNameSyntax.TypeName); return; } @@ -220,17 +353,52 @@ namespace ICSharpCode.Decompiler.Disassembler string s = operand as string; if (s != null) { - writer.Write("\"" + s.Replace("\\", "\\\\").Replace("\"", "\\\"") + "\""); - return; + writer.Write("\"" + NRefactory.CSharp.OutputVisitor.ConvertString(s) + "\""); + } else if (operand is char) { + writer.Write(((int)(char)operand).ToString()); + } else if (operand is float) { + float val = (float)operand; + if (val == 0) { + writer.Write("0.0"); + } else if (float.IsInfinity(val) || float.IsNaN(val)) { + byte[] data = BitConverter.GetBytes(val); + writer.Write('('); + for (int i = 0; i < data.Length; i++) { + if (i > 0) + writer.Write(' '); + writer.Write(data[i].ToString("X2")); + } + writer.Write(')'); + } else { + writer.Write(val.ToString("R", System.Globalization.CultureInfo.InvariantCulture)); + } + } else if (operand is double) { + double val = (double)operand; + if (val == 0) { + writer.Write("0.0"); + } else if (double.IsInfinity(val) || double.IsNaN(val)) { + byte[] data = BitConverter.GetBytes(val); + writer.Write('('); + for (int i = 0; i < data.Length; i++) { + if (i > 0) + writer.Write(' '); + writer.Write(data[i].ToString("X2")); + } + writer.Write(')'); + } else { + writer.Write(val.ToString("R", System.Globalization.CultureInfo.InvariantCulture)); + } + } else if (operand is bool) { + writer.Write((bool)operand ? "true" : "false"); + } else { + s = ToInvariantCultureString(operand); + writer.Write(s); } - - s = ToInvariantCultureString(operand); - writer.Write(s); } - public static string PrimitiveTypeName(this TypeReference type) + public static string PrimitiveTypeName(string fullName) { - switch (type.FullName) { + switch (fullName) { case "System.SByte": return "int8"; case "System.Int16": @@ -261,6 +429,8 @@ namespace ICSharpCode.Decompiler.Disassembler return "char"; case "System.Object": return "object"; + case "System.IntPtr": + return "native int"; default: return null; } diff --git a/ICSharpCode.Decompiler/Disassembler/ILStructure.cs b/ICSharpCode.Decompiler/Disassembler/ILStructure.cs index 5fc29a9bd..4c681e3c1 100644 --- a/ICSharpCode.Decompiler/Disassembler/ILStructure.cs +++ b/ICSharpCode.Decompiler/Disassembler/ILStructure.cs @@ -88,8 +88,10 @@ namespace ICSharpCode.Decompiler.Disassembler : this(ILStructureType.Root, 0, body.CodeSize) { // Build the tree of exception structures: - foreach (ExceptionHandler eh in body.ExceptionHandlers) { - AddNestedStructure(new ILStructure(ILStructureType.Try, eh.TryStart.Offset, eh.TryEnd.Offset, eh)); + for (int i = 0; i < body.ExceptionHandlers.Count; i++) { + ExceptionHandler eh = body.ExceptionHandlers[i]; + if (!body.ExceptionHandlers.Take(i).Any(oldEh => oldEh.TryStart == eh.TryStart && oldEh.TryEnd == eh.TryEnd)) + AddNestedStructure(new ILStructure(ILStructureType.Try, eh.TryStart.Offset, eh.TryEnd.Offset, eh)); if (eh.HandlerType == ExceptionHandlerType.Filter) AddNestedStructure(new ILStructure(ILStructureType.Filter, eh.FilterStart.Offset, eh.HandlerStart.Offset, eh)); AddNestedStructure(new ILStructure(ILStructureType.Handler, eh.HandlerStart.Offset, eh.HandlerEnd == null ? body.CodeSize : eh.HandlerEnd.Offset, eh)); diff --git a/ICSharpCode.Decompiler/Disassembler/MethodBodyDisassembler.cs b/ICSharpCode.Decompiler/Disassembler/MethodBodyDisassembler.cs index ef2f8a980..2fcde2335 100644 --- a/ICSharpCode.Decompiler/Disassembler/MethodBodyDisassembler.cs +++ b/ICSharpCode.Decompiler/Disassembler/MethodBodyDisassembler.cs @@ -52,9 +52,6 @@ namespace ICSharpCode.Decompiler.Disassembler // start writing IL code MethodDefinition method = body.Method; output.WriteLine("// Method begins at RVA 0x{0:x4}", method.RVA); - if (method.HasOverrides) - foreach (var methodOverride in method.Overrides) - output.WriteLine(".override {0}::{1}", methodOverride.DeclaringType.FullName, methodOverride.Name); output.WriteLine("// Code size {0} (0x{0:x})", body.CodeSize); output.WriteLine(".maxstack {0}", body.MaxStackSize); if (method.DeclaringType.Module.Assembly.EntryPoint == method) @@ -69,8 +66,12 @@ namespace ICSharpCode.Decompiler.Disassembler foreach (var v in method.Body.Variables) { output.WriteDefinition("[" + v.Index + "] ", v); v.VariableType.WriteTo(output); - output.Write(' '); - output.Write(DisassemblerHelpers.Escape(v.Name)); + if (!string.IsNullOrEmpty(v.Name)) { + output.Write(' '); + output.Write(DisassemblerHelpers.Escape(v.Name)); + } + if (v.Index + 1 < method.Body.Variables.Count) + output.Write(','); output.WriteLine(); } output.Unindent(); @@ -80,29 +81,49 @@ namespace ICSharpCode.Decompiler.Disassembler if (detectControlStructure && body.Instructions.Count > 0) { Instruction inst = body.Instructions[0]; - WriteStructureBody(new ILStructure(body), ref inst, methodMapping, method.Body.CodeSize); + HashSet branchTargets = GetBranchTargets(body.Instructions); + WriteStructureBody(new ILStructure(body), branchTargets, ref inst, methodMapping, method.Body.CodeSize); } else { foreach (var inst in method.Body.Instructions) { inst.WriteTo(output); - // add IL code mappings - used in debugger - methodMapping.MemberCodeMappings.Add( - new SourceCodeMapping() { - SourceCodeLine = output.CurrentLine, - ILInstructionOffset = new ILRange { From = inst.Offset, To = inst.Next == null ? method.Body.CodeSize : inst.Next.Offset }, - MemberMapping = methodMapping - }); + if (methodMapping != null) { + // add IL code mappings - used in debugger + methodMapping.MemberCodeMappings.Add( + new SourceCodeMapping() { + SourceCodeLine = output.CurrentLine, + ILInstructionOffset = new ILRange { From = inst.Offset, To = inst.Next == null ? method.Body.CodeSize : inst.Next.Offset }, + MemberMapping = methodMapping + }); + } output.WriteLine(); } - output.WriteLine(); - foreach (var eh in method.Body.ExceptionHandlers) { - eh.WriteTo(output); + if (method.Body.HasExceptionHandlers) { output.WriteLine(); + foreach (var eh in method.Body.ExceptionHandlers) { + eh.WriteTo(output); + output.WriteLine(); + } } } } + HashSet GetBranchTargets(IEnumerable instructions) + { + HashSet branchTargets = new HashSet(); + foreach (var inst in instructions) { + Instruction target = inst.Operand as Instruction; + if (target != null) + branchTargets.Add(target.Offset); + Instruction[] targets = inst.Operand as Instruction[]; + if (targets != null) + foreach (Instruction t in targets) + branchTargets.Add(t.Offset); + } + return branchTargets; + } + void WriteStructureHeader(ILStructure s) { switch (s.Type) { @@ -116,7 +137,8 @@ namespace ICSharpCode.Decompiler.Disassembler output.WriteLine(); break; case ILStructureType.Try: - output.WriteLine(".try {"); + output.WriteLine(".try"); + output.WriteLine("{"); break; case ILStructureType.Handler: switch (s.ExceptionHandler.HandlerType) { @@ -125,22 +147,24 @@ namespace ICSharpCode.Decompiler.Disassembler output.Write("catch"); if (s.ExceptionHandler.CatchType != null) { output.Write(' '); - s.ExceptionHandler.CatchType.WriteTo(output); + s.ExceptionHandler.CatchType.WriteTo(output, ILNameSyntax.TypeName); } - output.WriteLine(" {"); + output.WriteLine(); break; case Mono.Cecil.Cil.ExceptionHandlerType.Finally: - output.WriteLine("finally {"); + output.WriteLine("finally"); break; case Mono.Cecil.Cil.ExceptionHandlerType.Fault: - output.WriteLine("fault {"); + output.WriteLine("fault"); break; default: throw new NotSupportedException(); } + output.WriteLine("{"); break; case ILStructureType.Filter: - output.WriteLine("filter {"); + output.WriteLine("filter"); + output.WriteLine("{"); break; default: throw new NotSupportedException(); @@ -148,17 +172,22 @@ namespace ICSharpCode.Decompiler.Disassembler output.Indent(); } - void WriteStructureBody(ILStructure s, ref Instruction inst, MemberMapping currentMethodMapping, int codeSize) + void WriteStructureBody(ILStructure s, HashSet branchTargets, ref Instruction inst, MemberMapping currentMethodMapping, int codeSize) { + bool isFirstInstructionInStructure = true; + bool prevInstructionWasBranch = false; int childIndex = 0; while (inst != null && inst.Offset < s.EndOffset) { int offset = inst.Offset; if (childIndex < s.Children.Count && s.Children[childIndex].StartOffset <= offset && offset < s.Children[childIndex].EndOffset) { ILStructure child = s.Children[childIndex++]; WriteStructureHeader(child); - WriteStructureBody(child, ref inst, currentMethodMapping, codeSize); + WriteStructureBody(child, branchTargets, ref inst, currentMethodMapping, codeSize); WriteStructureFooter(child); } else { + if (!isFirstInstructionInStructure && (prevInstructionWasBranch || branchTargets.Contains(offset))) { + output.WriteLine(); // put an empty line after branches, and in front of branch targets + } inst.WriteTo(output); // add IL code mappings - used in debugger @@ -172,8 +201,15 @@ namespace ICSharpCode.Decompiler.Disassembler } output.WriteLine(); + + prevInstructionWasBranch = inst.OpCode.FlowControl == FlowControl.Branch + || inst.OpCode.FlowControl == FlowControl.Cond_Branch + || inst.OpCode.FlowControl == FlowControl.Return + || inst.OpCode.FlowControl == FlowControl.Throw; + inst = inst.Next; } + isFirstInstructionInStructure = false; } } diff --git a/ICSharpCode.Decompiler/Disassembler/ReflectionDisassembler.cs b/ICSharpCode.Decompiler/Disassembler/ReflectionDisassembler.cs index 87a746a1c..502ed57bb 100644 --- a/ICSharpCode.Decompiler/Disassembler/ReflectionDisassembler.cs +++ b/ICSharpCode.Decompiler/Disassembler/ReflectionDisassembler.cs @@ -18,8 +18,10 @@ using System; using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Text; using System.Threading; - using Mono.Cecil; using Mono.Collections.Generic; @@ -32,7 +34,6 @@ namespace ICSharpCode.Decompiler.Disassembler { ITextOutput output; CancellationToken cancellationToken; - bool detectControlStructure; bool isInType; // whether we are currently disassembling a whole type (-> defaultCollapsed for foldings) MethodBodyDisassembler methodBodyDisassembler; MemberReference currentMember; @@ -43,7 +44,6 @@ namespace ICSharpCode.Decompiler.Disassembler throw new ArgumentNullException("output"); this.output = output; this.cancellationToken = cancellationToken; - this.detectControlStructure = detectControlStructure; this.methodBodyDisassembler = new MethodBodyDisassembler(output, detectControlStructure, cancellationToken); this.CodeMappings = new Dictionary>(); @@ -52,17 +52,19 @@ namespace ICSharpCode.Decompiler.Disassembler #region Disassemble Method EnumNameCollection methodAttributeFlags = new EnumNameCollection() { - { MethodAttributes.Static, "static" }, { MethodAttributes.Final, "final" }, - { MethodAttributes.Virtual, "virtual" }, { MethodAttributes.HideBySig, "hidebysig" }, - { MethodAttributes.Abstract, "abstract" }, { MethodAttributes.SpecialName, "specialname" }, - { MethodAttributes.PInvokeImpl, "pinvokeimpl" }, + { MethodAttributes.PInvokeImpl, null }, // handled separately { MethodAttributes.UnmanagedExport, "export" }, { MethodAttributes.RTSpecialName, "rtspecialname" }, - { MethodAttributes.RequireSecObject, "requiresecobj" }, - { MethodAttributes.NewSlot, "newslot" } + { MethodAttributes.RequireSecObject, "reqsecobj" }, + { MethodAttributes.NewSlot, "newslot" }, + { MethodAttributes.CheckAccessOnOverride, "strict" }, + { MethodAttributes.Abstract, "abstract" }, + { MethodAttributes.Virtual, "virtual" }, + { MethodAttributes.Static, "static" }, + { MethodAttributes.HasSecurity, null }, // ?? also invisible in ILDasm }; EnumNameCollection methodVisibility = new EnumNameCollection() { @@ -80,7 +82,7 @@ namespace ICSharpCode.Decompiler.Disassembler { MethodCallingConvention.ThisCall, "unmanaged thiscall" }, { MethodCallingConvention.FastCall, "unmanaged fastcall" }, { MethodCallingConvention.VarArg, "vararg" }, - { MethodCallingConvention.Generic, "generic" }, + { MethodCallingConvention.Generic, null }, }; EnumNameCollection methodCodeType = new EnumNameCollection() { @@ -94,6 +96,9 @@ namespace ICSharpCode.Decompiler.Disassembler { MethodImplAttributes.Synchronized, "synchronized" }, { MethodImplAttributes.NoInlining, "noinlining" }, { MethodImplAttributes.NoOptimization, "nooptimization" }, + { MethodImplAttributes.PreserveSig, "preservesig" }, + { MethodImplAttributes.InternalCall, "internalcall" }, + { MethodImplAttributes.ForwardRef, "forwardref" }, }; public void DisassembleMethod(MethodDefinition method) @@ -115,12 +120,53 @@ namespace ICSharpCode.Decompiler.Disassembler //emit flags WriteEnum(method.Attributes & MethodAttributes.MemberAccessMask, methodVisibility); WriteFlags(method.Attributes & ~MethodAttributes.MemberAccessMask, methodAttributeFlags); + if(method.IsCompilerControlled) output.Write("privatescope "); + + if ((method.Attributes & MethodAttributes.PInvokeImpl) == MethodAttributes.PInvokeImpl) { + output.Write("pinvokeimpl"); + if (method.HasPInvokeInfo) { + PInvokeInfo info = method.PInvokeInfo; + output.Write("(\"" + NRefactory.CSharp.OutputVisitor.ConvertString(info.Module.Name) + "\""); + + if (!string.IsNullOrEmpty(info.EntryPoint) && info.EntryPoint != method.Name) + output.Write(" as \"" + NRefactory.CSharp.OutputVisitor.ConvertString(info.EntryPoint) + "\""); + + if (info.IsNoMangle) + output.Write(" nomangle"); + + if (info.IsCharSetAnsi) + output.Write(" ansi"); + else if (info.IsCharSetAuto) + output.Write(" autochar"); + else if (info.IsCharSetUnicode) + output.Write(" unicode"); + + if (info.SupportsLastError) + output.Write(" lasterr"); + + if (info.IsCallConvCdecl) + output.Write(" cdecl"); + else if (info.IsCallConvFastcall) + output.Write(" fastcall"); + else if (info.IsCallConvStdCall) + output.Write(" stdcall"); + else if (info.IsCallConvThiscall) + output.Write(" thiscall"); + else if (info.IsCallConvWinapi) + output.Write(" winapi"); + + output.Write(')'); + } + output.Write(' '); + } output.WriteLine(); output.Indent(); - - if (method.HasThis) + if (method.ExplicitThis) { + output.Write("instance explicit "); + } else if (method.HasThis) { output.Write("instance "); + } //call convention WriteEnum(method.CallingConvention & (MethodCallingConvention)0x1f, callingConvention); @@ -128,7 +174,16 @@ namespace ICSharpCode.Decompiler.Disassembler //return type method.ReturnType.WriteTo(output); output.Write(' '); - output.Write(DisassemblerHelpers.Escape(method.Name)); + if (method.MethodReturnType.HasMarshalInfo) { + WriteMarshalInfo(method.MethodReturnType.MarshalInfo); + } + + if (method.IsCompilerControlled) { + output.Write(DisassemblerHelpers.Escape(method.Name + "$PST" + method.MetadataToken.ToInt32().ToString("X8"))); + } else { + output.Write(DisassemblerHelpers.Escape(method.Name)); + } + WriteTypeParameters(output, method); //( params ) @@ -149,36 +204,455 @@ namespace ICSharpCode.Decompiler.Disassembler WriteFlags(method.ImplAttributes & ~(MethodImplAttributes.CodeTypeMask | MethodImplAttributes.ManagedMask), methodImpl); output.Unindent(); - if (method.HasBody || method.HasCustomAttributes) { - OpenBlock(defaultCollapsed: isInType); - WriteAttributes(method.CustomAttributes); - - if (method.HasBody) { - // create IL code mappings - used in debugger - CreateCodeMappings(method.MetadataToken.ToInt32(), currentMember); - MemberMapping methodMapping = method.CreateCodeMapping(this.CodeMappings[method.MetadataToken.ToInt32()], currentMember); + OpenBlock(defaultCollapsed: isInType); + WriteAttributes(method.CustomAttributes); + if (method.HasOverrides) { + foreach (var methodOverride in method.Overrides) { + output.Write(".override method "); + methodOverride.WriteTo(output); + output.WriteLine(); + } + } + foreach (var p in method.Parameters) { + WriteParameterAttributes(p); + } + WriteSecurityDeclarations(method); + + if (method.HasBody) { + // create IL code mappings - used in debugger + CreateCodeMappings(method.MetadataToken.ToInt32(), currentMember); + MemberMapping methodMapping = method.CreateCodeMapping(this.CodeMappings[method.MetadataToken.ToInt32()], currentMember); + methodBodyDisassembler.Disassemble(method.Body, methodMapping); + } + + CloseBlock("end of method " + DisassemblerHelpers.Escape(method.DeclaringType.Name) + "::" + DisassemblerHelpers.Escape(method.Name)); + } + + #region Write Security Declarations + void WriteSecurityDeclarations(ISecurityDeclarationProvider secDeclProvider) + { + if (!secDeclProvider.HasSecurityDeclarations) + return; + foreach (var secdecl in secDeclProvider.SecurityDeclarations) { + output.Write(".permissionset "); + switch (secdecl.Action) { + case SecurityAction.Request: + output.Write("request"); + break; + case SecurityAction.Demand: + output.Write("demand"); + break; + case SecurityAction.Assert: + output.Write("assert"); + break; + case SecurityAction.Deny: + output.Write("deny"); + break; + case SecurityAction.PermitOnly: + output.Write("permitonly"); + break; + case SecurityAction.LinkDemand: + output.Write("linkcheck"); + break; + case SecurityAction.InheritDemand: + output.Write("inheritcheck"); + break; + case SecurityAction.RequestMinimum: + output.Write("reqmin"); + break; + case SecurityAction.RequestOptional: + output.Write("reqopt"); + break; + case SecurityAction.RequestRefuse: + output.Write("reqrefuse"); + break; + case SecurityAction.PreJitGrant: + output.Write("prejitgrant"); + break; + case SecurityAction.PreJitDeny: + output.Write("prejitdeny"); + break; + case SecurityAction.NonCasDemand: + output.Write("noncasdemand"); + break; + case SecurityAction.NonCasLinkDemand: + output.Write("noncaslinkdemand"); + break; + case SecurityAction.NonCasInheritance: + output.Write("noncasinheritance"); + break; + default: + output.Write(secdecl.Action.ToString()); + break; + } + output.WriteLine(" = {"); + output.Indent(); + for (int i = 0; i < secdecl.SecurityAttributes.Count; i++) { + SecurityAttribute sa = secdecl.SecurityAttributes[i]; + if (sa.AttributeType.Scope == sa.AttributeType.Module) { + output.Write("class "); + output.Write(DisassemblerHelpers.Escape(GetAssemblyQualifiedName(sa.AttributeType))); + } else { + sa.AttributeType.WriteTo(output, ILNameSyntax.TypeName); + } + output.Write(" = {"); + if (sa.HasFields || sa.HasProperties) { + output.WriteLine(); + output.Indent(); + + foreach (CustomAttributeNamedArgument na in sa.Fields) { + output.Write("field "); + WriteSecurityDeclarationArgument(na); + output.WriteLine(); + } + + foreach (CustomAttributeNamedArgument na in sa.Properties) { + output.Write("property "); + WriteSecurityDeclarationArgument(na); + output.WriteLine(); + } + + output.Unindent(); + } + output.Write('}'); - methodBodyDisassembler.Disassemble(method.Body, methodMapping); + if (i + 1< secdecl.SecurityAttributes.Count) + output.Write(','); + output.WriteLine(); + } + output.Unindent(); + output.WriteLine("}"); + } + } + + void WriteSecurityDeclarationArgument(CustomAttributeNamedArgument na) + { + TypeReference type = na.Argument.Type; + if (type.MetadataType == MetadataType.Class || type.MetadataType == MetadataType.ValueType) { + output.Write("enum "); + if (type.Scope != type.Module) { + output.Write("class "); + output.Write(DisassemblerHelpers.Escape(GetAssemblyQualifiedName(type))); + } else { + type.WriteTo(output, ILNameSyntax.TypeName); } - - CloseBlock("End of method " + method.DeclaringType.Name + "." + method.Name); } else { - output.WriteLine(); + type.WriteTo(output); + } + output.Write(' '); + output.Write(DisassemblerHelpers.Escape(na.Name)); + output.Write(" = "); + if (na.Argument.Value is string) { + // secdecls use special syntax for strings + output.Write("string('{0}')", NRefactory.CSharp.OutputVisitor.ConvertString((string)na.Argument.Value).Replace("'", "\'")); + } else { + WriteConstant(na.Argument.Value); + } + } + + string GetAssemblyQualifiedName(TypeReference type) + { + AssemblyNameReference anr = type.Scope as AssemblyNameReference; + if (anr == null) { + ModuleDefinition md = type.Scope as ModuleDefinition; + if (md != null) { + anr = md.Assembly.Name; + } + } + if (anr != null) { + return type.FullName + ", " + anr.FullName; + } else { + return type.FullName; + } + } + #endregion + + #region WriteMarshalInfo + void WriteMarshalInfo(MarshalInfo marshalInfo) + { + output.Write("marshal("); + WriteNativeType(marshalInfo.NativeType, marshalInfo); + output.Write(") "); + } + + void WriteNativeType(NativeType nativeType, MarshalInfo marshalInfo = null) + { + switch (nativeType) { + case NativeType.None: + break; + case NativeType.Boolean: + output.Write("bool"); + break; + case NativeType.I1: + output.Write("int8"); + break; + case NativeType.U1: + output.Write("unsigned int8"); + break; + case NativeType.I2: + output.Write("int16"); + break; + case NativeType.U2: + output.Write("unsigned int16"); + break; + case NativeType.I4: + output.Write("int32"); + break; + case NativeType.U4: + output.Write("unsigned int32"); + break; + case NativeType.I8: + output.Write("int64"); + break; + case NativeType.U8: + output.Write("unsigned int64"); + break; + case NativeType.R4: + output.Write("float32"); + break; + case NativeType.R8: + output.Write("float64"); + break; + case NativeType.LPStr: + output.Write("lpstr"); + break; + case NativeType.Int: + output.Write("int"); + break; + case NativeType.UInt: + output.Write("unsigned int"); + break; + case NativeType.Func: + goto default; // ?? + case NativeType.Array: + ArrayMarshalInfo ami = (ArrayMarshalInfo)marshalInfo; + if (ami == null) + goto default; + if (ami.ElementType != NativeType.Max) + WriteNativeType(ami.ElementType); + output.Write('['); + if (ami.SizeParameterMultiplier == 0) { + output.Write(ami.Size.ToString()); + } else { + if (ami.Size >= 0) + output.Write(ami.Size.ToString()); + output.Write(" + "); + output.Write(ami.SizeParameterIndex.ToString()); + } + output.Write(']'); + break; + case NativeType.Currency: + output.Write("currency"); + break; + case NativeType.BStr: + output.Write("bstr"); + break; + case NativeType.LPWStr: + output.Write("lpwstr"); + break; + case NativeType.LPTStr: + output.Write("lptstr"); + break; + case NativeType.FixedSysString: + output.Write("fixed sysstring[{0}]", ((FixedSysStringMarshalInfo)marshalInfo).Size); + break; + case NativeType.IUnknown: + output.Write("iunknown"); + break; + case NativeType.IDispatch: + output.Write("idispatch"); + break; + case NativeType.Struct: + output.Write("struct"); + break; + case NativeType.IntF: + output.Write("interface"); + break; + case NativeType.SafeArray: + output.Write("safearray "); + SafeArrayMarshalInfo sami = marshalInfo as SafeArrayMarshalInfo; + if (sami != null) { + switch (sami.ElementType) { + case VariantType.None: + break; + case VariantType.I2: + output.Write("int16"); + break; + case VariantType.I4: + output.Write("int32"); + break; + case VariantType.R4: + output.Write("float32"); + break; + case VariantType.R8: + output.Write("float64"); + break; + case VariantType.CY: + output.Write("currency"); + break; + case VariantType.Date: + output.Write("date"); + break; + case VariantType.BStr: + output.Write("bstr"); + break; + case VariantType.Dispatch: + output.Write("idispatch"); + break; + case VariantType.Error: + output.Write("error"); + break; + case VariantType.Bool: + output.Write("bool"); + break; + case VariantType.Variant: + output.Write("variant"); + break; + case VariantType.Unknown: + output.Write("iunknown"); + break; + case VariantType.Decimal: + output.Write("decimal"); + break; + case VariantType.I1: + output.Write("int8"); + break; + case VariantType.UI1: + output.Write("unsigned int8"); + break; + case VariantType.UI2: + output.Write("unsigned int16"); + break; + case VariantType.UI4: + output.Write("unsigned int32"); + break; + case VariantType.Int: + output.Write("int"); + break; + case VariantType.UInt: + output.Write("unsigned int"); + break; + default: + output.Write(sami.ElementType.ToString()); + break; + } + } + break; + case NativeType.FixedArray: + output.Write("fixed array"); + FixedArrayMarshalInfo fami = marshalInfo as FixedArrayMarshalInfo; + if (fami != null) { + output.Write("[{0}]", fami.Size); + if (fami.ElementType != NativeType.None) { + output.Write(' '); + WriteNativeType(fami.ElementType); + } + } + break; + case NativeType.ByValStr: + output.Write("byvalstr"); + break; + case NativeType.ANSIBStr: + output.Write("ansi bstr"); + break; + case NativeType.TBStr: + output.Write("tbstr"); + break; + case NativeType.VariantBool: + output.Write("variant bool"); + break; + case NativeType.ASAny: + output.Write("as any"); + break; + case NativeType.LPStruct: + output.Write("lpstruct"); + break; + case NativeType.CustomMarshaler: + CustomMarshalInfo cmi = marshalInfo as CustomMarshalInfo; + if (cmi == null) + goto default; + output.Write("custom(\"{0}\", \"{1}\"", + NRefactory.CSharp.OutputVisitor.ConvertString(cmi.ManagedType.FullName), + NRefactory.CSharp.OutputVisitor.ConvertString(cmi.Cookie)); + if (cmi.Guid != Guid.Empty || !string.IsNullOrEmpty(cmi.UnmanagedType)) { + output.Write(", \"{0}\", \"{1}\"", cmi.Guid.ToString(), NRefactory.CSharp.OutputVisitor.ConvertString(cmi.UnmanagedType)); + } + output.Write(')'); + break; + case NativeType.Error: + output.Write("error"); + break; + default: + output.Write(nativeType.ToString()); + break; } } + #endregion void WriteParameters(Collection parameters) { for (int i = 0; i < parameters.Count; i++) { var p = parameters[i]; + if (p.IsIn) + output.Write("[in] "); + if (p.IsOut) + output.Write("[out] "); + if (p.IsOptional) + output.Write("[opt] "); p.ParameterType.WriteTo(output); output.Write(' '); + if (p.HasMarshalInfo) { + WriteMarshalInfo(p.MarshalInfo); + } output.WriteDefinition(DisassemblerHelpers.Escape(p.Name), p); if (i < parameters.Count - 1) output.Write(','); output.WriteLine(); } } + + bool HasParameterAttributes(ParameterDefinition p) + { + return p.HasConstant || p.HasCustomAttributes; + } + + void WriteParameterAttributes(ParameterDefinition p) + { + if (!HasParameterAttributes(p)) + return; + output.Write(".param [{0}]", p.Index + 1); + if (p.HasConstant) { + output.Write(" = "); + WriteConstant(p.Constant); + } + output.WriteLine(); + WriteAttributes(p.CustomAttributes); + } + + void WriteConstant(object constant) + { + if (constant == null) { + output.Write("nullref"); + } else { + string typeName = DisassemblerHelpers.PrimitiveTypeName(constant.GetType().FullName); + if (typeName != null && typeName != "string") { + output.Write(typeName); + output.Write('('); + float? cf = constant as float?; + double? cd = constant as double?; + if (cf.HasValue && (float.IsNaN(cf.Value) || float.IsInfinity(cf.Value))) { + output.Write("0x{0:x8}", BitConverter.ToInt32(BitConverter.GetBytes(cf.Value), 0)); + } else if (cd.HasValue && (double.IsNaN(cd.Value) || double.IsInfinity(cd.Value))) { + output.Write("0x{0:x16}", BitConverter.DoubleToInt64Bits(cd.Value)); + } else { + DisassemblerHelpers.WriteOperand(output, constant); + } + output.Write(')'); + } else { + DisassemblerHelpers.WriteOperand(output, constant); + } + } + } #endregion #region Disassemble Field @@ -207,20 +681,26 @@ namespace ICSharpCode.Decompiler.Disassembler output.WriteDefinition(".field ", field); WriteEnum(field.Attributes & FieldAttributes.FieldAccessMask, fieldVisibility); - WriteFlags(field.Attributes & ~(FieldAttributes.FieldAccessMask | FieldAttributes.HasDefault), fieldAttributes); + const FieldAttributes hasXAttributes = FieldAttributes.HasDefault | FieldAttributes.HasFieldMarshal | FieldAttributes.HasFieldRVA; + WriteFlags(field.Attributes & ~(FieldAttributes.FieldAccessMask | hasXAttributes), fieldAttributes); + if (field.HasMarshalInfo) { + WriteMarshalInfo(field.MarshalInfo); + } field.FieldType.WriteTo(output); output.Write(' '); output.Write(DisassemblerHelpers.Escape(field.Name)); + if ((field.Attributes & FieldAttributes.HasFieldRVA) == FieldAttributes.HasFieldRVA) { + output.Write(" at I_{0:x8}", field.RVA); + } if (field.HasConstant) { output.Write(" = "); - DisassemblerHelpers.WriteOperand(output, field.Constant); + WriteConstant(field.Constant); } + output.WriteLine(); if (field.HasCustomAttributes) { - OpenBlock(false); + output.MarkFoldStart(); WriteAttributes(field.CustomAttributes); - CloseBlock(); - } else { - output.WriteLine(); + output.MarkFoldEnd(); } } #endregion @@ -239,16 +719,28 @@ namespace ICSharpCode.Decompiler.Disassembler output.WriteDefinition(".property ", property); WriteFlags(property.Attributes, propertyAttributes); + if (property.HasThis) + output.Write("instance "); property.PropertyType.WriteTo(output); output.Write(' '); output.Write(DisassemblerHelpers.Escape(property.Name)); + + output.Write("("); + if (property.HasParameters) { + output.WriteLine(); + output.Indent(); + WriteParameters(property.Parameters); + output.Unindent(); + } + output.Write(")"); + OpenBlock(false); WriteAttributes(property.CustomAttributes); WriteNestedMethod(".get", property.GetMethod); WriteNestedMethod(".set", property.SetMethod); foreach (var method in property.OtherMethods) { - WriteNestedMethod(".method", method); + WriteNestedMethod(".other", method); } CloseBlock(); } @@ -257,16 +749,10 @@ namespace ICSharpCode.Decompiler.Disassembler { if (method == null) return; - if (detectControlStructure) { - output.WriteDefinition(keyword, method); - output.Write(' '); - DisassembleMethodInternal(method); - } else { - output.Write(keyword); - output.Write(' '); - method.WriteTo(output); - output.WriteLine(); - } + output.Write(keyword); + output.Write(' '); + method.WriteTo(output); + output.WriteLine(); } #endregion @@ -283,16 +769,16 @@ namespace ICSharpCode.Decompiler.Disassembler output.WriteDefinition(".event ", ev); WriteFlags(ev.Attributes, eventAttributes); - ev.EventType.WriteTo(output); + ev.EventType.WriteTo(output, ILNameSyntax.TypeName); output.Write(' '); output.Write(DisassemblerHelpers.Escape(ev.Name)); OpenBlock(false); WriteAttributes(ev.CustomAttributes); - WriteNestedMethod(".add", ev.AddMethod); - WriteNestedMethod(".remove", ev.RemoveMethod); - WriteNestedMethod(".invoke", ev.InvokeMethod); + WriteNestedMethod(".addon", ev.AddMethod); + WriteNestedMethod(".removeon", ev.RemoveMethod); + WriteNestedMethod(".fire", ev.InvokeMethod); foreach (var method in ev.OtherMethods) { - WriteNestedMethod(".method", method); + WriteNestedMethod(".other", method); } CloseBlock(); } @@ -345,7 +831,7 @@ namespace ICSharpCode.Decompiler.Disassembler const TypeAttributes masks = TypeAttributes.ClassSemanticMask | TypeAttributes.VisibilityMask | TypeAttributes.LayoutMask | TypeAttributes.StringFormatMask; WriteFlags(type.Attributes & ~masks, typeAttributes); - output.Write(DisassemblerHelpers.Escape(type.Name)); + output.Write(DisassemblerHelpers.Escape(type.DeclaringType != null ? type.Name : type.FullName)); WriteTypeParameters(output, type); output.MarkFoldStart(defaultCollapsed: isInType); output.WriteLine(); @@ -353,7 +839,7 @@ namespace ICSharpCode.Decompiler.Disassembler if (type.BaseType != null) { output.Indent(); output.Write("extends "); - type.BaseType.WriteTo(output, true); + type.BaseType.WriteTo(output, ILNameSyntax.TypeName); output.WriteLine(); output.Unindent(); } @@ -366,9 +852,7 @@ namespace ICSharpCode.Decompiler.Disassembler output.Write("implements "); else output.Write(" "); - if (type.Interfaces[index].Namespace != null) - output.Write("{0}.", type.Interfaces[index].Namespace); - output.Write(type.Interfaces[index].Name); + type.Interfaces[index].WriteTo(output, ILNameSyntax.TypeName); } output.WriteLine(); output.Unindent(); @@ -379,6 +863,7 @@ namespace ICSharpCode.Decompiler.Disassembler bool oldIsInType = isInType; isInType = true; WriteAttributes(type.CustomAttributes); + WriteSecurityDeclarations(type); if (type.HasLayoutInfo) { output.WriteLine(".pack {0}", type.PackingSize); output.WriteLine(".size {0}", type.ClassSize); @@ -401,13 +886,13 @@ namespace ICSharpCode.Decompiler.Disassembler } output.WriteLine(); } - if (type.HasProperties) { - output.WriteLine("// Properties"); - foreach (var prop in type.Properties) { + if (type.HasMethods) { + output.WriteLine("// Methods"); + foreach (var m in type.Methods) { cancellationToken.ThrowIfCancellationRequested(); - DisassembleProperty(prop); + DisassembleMethod(m); + output.WriteLine(); } - output.WriteLine(); } if (type.HasEvents) { output.WriteLine("// Events"); @@ -418,18 +903,15 @@ namespace ICSharpCode.Decompiler.Disassembler } output.WriteLine(); } - if (type.HasMethods) { - output.WriteLine("// Methods"); - var accessorMethods = type.GetAccessorMethods(); - foreach (var m in type.Methods) { + if (type.HasProperties) { + output.WriteLine("// Properties"); + foreach (var prop in type.Properties) { cancellationToken.ThrowIfCancellationRequested(); - if (!(detectControlStructure && accessorMethods.Contains(m))) { - DisassembleMethod(m); - output.WriteLine(); - } + DisassembleProperty(prop); } + output.WriteLine(); } - CloseBlock("End of class " + type.FullName); + CloseBlock("end of class " + (type.DeclaringType != null ? type.Name : type.FullName)); isInType = oldIsInType; } @@ -446,18 +928,18 @@ namespace ICSharpCode.Decompiler.Disassembler } else if (gp.HasNotNullableValueTypeConstraint) { output.Write("valuetype "); } + if (gp.HasDefaultConstructorConstraint) { + output.Write(".ctor "); + } if (gp.HasConstraints) { output.Write('('); for (int j = 0; j < gp.Constraints.Count; j++) { if (j > 0) output.Write(", "); - gp.Constraints[j].WriteTo(output, true); + gp.Constraints[j].WriteTo(output, ILNameSyntax.TypeName); } output.Write(") "); } - if (gp.HasDefaultConstructorConstraint) { - output.Write(".ctor "); - } if (gp.IsContravariant) { output.Write('-'); } else if (gp.IsCovariant) { @@ -600,9 +1082,12 @@ namespace ICSharpCode.Decompiler.Disassembler { output.Write(".assembly " + DisassemblerHelpers.Escape(asm.Name.Name)); OpenBlock(false); - Version v = asm.Name.Version; - if (v != null) { - output.WriteLine(".ver {0}:{1}:{2}:{3}", v.Major, v.Minor, v.Build, v.Revision); + WriteAttributes(asm.CustomAttributes); + WriteSecurityDeclarations(asm); + if (asm.Name.PublicKey != null && asm.Name.PublicKey.Length > 0) { + output.Write(".publickey = "); + WriteBlob(asm.Name.PublicKey); + output.WriteLine(); } if (asm.Name.HashAlgorithm != AssemblyHashAlgorithm.None) { output.Write(".hash algorithm 0x{0:x8}", (int)asm.Name.HashAlgorithm); @@ -610,13 +1095,64 @@ namespace ICSharpCode.Decompiler.Disassembler output.Write(" // SHA1"); output.WriteLine(); } - if (asm.Name.PublicKey != null && asm.Name.PublicKey.Length > 0) { - output.Write(".publickey = "); - WriteBlob(asm.Name.PublicKey); - output.WriteLine(); + Version v = asm.Name.Version; + if (v != null) { + output.WriteLine(".ver {0}:{1}:{2}:{3}", v.Major, v.Minor, v.Build, v.Revision); } - WriteAttributes(asm.CustomAttributes); CloseBlock(); } + + public void WriteAssemblyReferences(ModuleDefinition module) + { + foreach (var mref in module.ModuleReferences) { + output.WriteLine(".module extern {0}", DisassemblerHelpers.Escape(mref.Name)); + } + foreach (var aref in module.AssemblyReferences) { + output.Write(".assembly extern {0}", DisassemblerHelpers.Escape(aref.Name)); + OpenBlock(false); + if (aref.PublicKeyToken != null) { + output.Write(".publickeytoken = "); + WriteBlob(aref.PublicKeyToken); + output.WriteLine(); + } + if (aref.Version != null) { + output.WriteLine(".ver {0}:{1}:{2}:{3}", aref.Version.Major, aref.Version.Minor, aref.Version.Build, aref.Version.Revision); + } + CloseBlock(); + } + } + + public void WriteModuleHeader(ModuleDefinition module) + { + if (module.HasExportedTypes) { + foreach (ExportedType exportedType in module.ExportedTypes) { + output.Write(".class extern "); + if (exportedType.IsForwarder) + output.Write("forwarder "); + output.Write(exportedType.DeclaringType != null ? exportedType.Name : exportedType.FullName); + OpenBlock(false); + if (exportedType.DeclaringType != null) + output.WriteLine(".class extern {0}", DisassemblerHelpers.Escape(exportedType.DeclaringType.FullName)); + else + output.WriteLine(".assembly extern {0}", DisassemblerHelpers.Escape(exportedType.Scope.Name)); + CloseBlock(); + } + } + + output.WriteLine(".module {0}", module.Name); + output.WriteLine("// MVID: {0}", module.Mvid.ToString("B").ToUpperInvariant()); + // TODO: imagebase, file alignment, stackreserve, subsystem + output.WriteLine(".corflags 0x{0:x} // {1}", module.Attributes, module.Attributes.ToString()); + + WriteAttributes(module.CustomAttributes); + } + + public void WriteModuleContents(ModuleDefinition module) + { + foreach (TypeDefinition td in module.Types) { + DisassembleType(td); + output.WriteLine(); + } + } } } diff --git a/ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj b/ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj index d003c00cd..603543820 100644 --- a/ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj +++ b/ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj @@ -61,6 +61,7 @@ + diff --git a/ICSharpCode.Decompiler/ILAst/GotoRemoval.cs b/ICSharpCode.Decompiler/ILAst/GotoRemoval.cs index b1d883019..351c28428 100644 --- a/ICSharpCode.Decompiler/ILAst/GotoRemoval.cs +++ b/ICSharpCode.Decompiler/ILAst/GotoRemoval.cs @@ -91,7 +91,7 @@ namespace ICSharpCode.Decompiler.ILAst } } - var defaultCase = ilSwitch.CaseBlocks.Where(cb => cb.Values == null).SingleOrDefault(); + var defaultCase = ilSwitch.CaseBlocks.SingleOrDefault(cb => cb.Values == null); // If there is no default block, remove empty case blocks if (defaultCase == null || (defaultCase.Body.Count == 1 && defaultCase.Body.Single().Match(ILCode.LoopOrSwitchBreak))) { ilSwitch.CaseBlocks.RemoveAll(b => b.Body.Count == 1 && b.Body.Single().Match(ILCode.LoopOrSwitchBreak)); @@ -140,14 +140,14 @@ namespace ICSharpCode.Decompiler.ILAst return true; } - ILNode breakBlock = GetParents(gotoExpr).Where(n => n is ILWhileLoop || n is ILSwitch).FirstOrDefault(); + ILNode breakBlock = GetParents(gotoExpr).FirstOrDefault(n => n is ILWhileLoop || n is ILSwitch); if (breakBlock != null && target == Exit(breakBlock, new HashSet() { gotoExpr })) { gotoExpr.Code = ILCode.LoopOrSwitchBreak; gotoExpr.Operand = null; return true; } - ILNode continueBlock = GetParents(gotoExpr).Where(n => n is ILWhileLoop).FirstOrDefault(); + ILNode continueBlock = GetParents(gotoExpr).FirstOrDefault(n => n is ILWhileLoop); if (continueBlock != null && target == Enter(continueBlock, new HashSet() { gotoExpr })) { gotoExpr.Code = ILCode.LoopContinue; gotoExpr.Operand = null; @@ -209,10 +209,10 @@ namespace ICSharpCode.Decompiler.ILAst } else if (expr.Code == ILCode.Nop) { return Exit(expr, visitedNodes); } else if (expr.Code == ILCode.LoopOrSwitchBreak) { - ILNode breakBlock = GetParents(expr).Where(n => n is ILWhileLoop || n is ILSwitch).First(); + ILNode breakBlock = GetParents(expr).First(n => n is ILWhileLoop || n is ILSwitch); return Exit(breakBlock, new HashSet() { expr }); } else if (expr.Code == ILCode.LoopContinue) { - ILNode continueBlock = GetParents(expr).Where(n => n is ILWhileLoop).First(); + ILNode continueBlock = GetParents(expr).First(n => n is ILWhileLoop); return Enter(continueBlock, new HashSet() { expr }); } else { return expr; diff --git a/ICSharpCode.Decompiler/ILAst/ILAstBuilder.cs b/ICSharpCode.Decompiler/ILAst/ILAstBuilder.cs index 9c845293b..f6edfad85 100644 --- a/ICSharpCode.Decompiler/ILAst/ILAstBuilder.cs +++ b/ICSharpCode.Decompiler/ILAst/ILAstBuilder.cs @@ -426,13 +426,12 @@ namespace ICSharpCode.Decompiler.ILAst } } - // Occasionally the compiler generates unreachable code - it can be usually just ignored - var reachableBody = body.Where(b => b.StackBefore != null); - var unreachableBody = body.Where(b => b.StackBefore == null); + // Occasionally the compilers or obfuscators generate unreachable code (which migt be intentonally invalid) + // I belive it is safe to just remove it + body.RemoveAll(b => b.StackBefore == null); // Genertate temporary variables to replace stack - // Unrachable code does not need temporary variables - the values are never pushed on the stack for consuption - foreach(ByteCode byteCode in reachableBody) { + foreach(ByteCode byteCode in body) { int argIdx = 0; int popCount = byteCode.PopCount ?? byteCode.StackBefore.Count; for (int i = byteCode.StackBefore.Count - popCount; i < byteCode.StackBefore.Count; i++) { @@ -450,19 +449,18 @@ namespace ICSharpCode.Decompiler.ILAst // Try to use single temporary variable insted of several if possilbe (especially useful for dup) // This has to be done after all temporary variables are assigned so we know about all loads - // Unrachable code will not have any StoreTo - foreach(ByteCode byteCode in reachableBody) { + foreach(ByteCode byteCode in body) { if (byteCode.StoreTo != null && byteCode.StoreTo.Count > 1) { var locVars = byteCode.StoreTo; // For each of the variables, find the location where it is loaded - there should be preciesly one - var loadedBy = locVars.Select(locVar => reachableBody.SelectMany(bc => bc.StackBefore).Where(s => s.LoadFrom == locVar).Single()).ToList(); + var loadedBy = locVars.Select(locVar => body.SelectMany(bc => bc.StackBefore).Single(s => s.LoadFrom == locVar)).ToList(); // We now know that all the variables have a single load, // Let's make sure that they have also a single store - us if (loadedBy.All(slot => slot.PushedBy.Length == 1 && slot.PushedBy[0] == byteCode)) { // Great - we can reduce everything into single variable ILVariable tmpVar = new ILVariable() { Name = string.Format("expr_{0:X2}", byteCode.Offset), IsGenerated = true }; byteCode.StoreTo = new List() { tmpVar }; - foreach(ByteCode bc in reachableBody) { + foreach(ByteCode bc in body) { for (int i = 0; i < bc.StackBefore.Count; i++) { // Is it one of the variable to be merged? if (locVars.Contains(bc.StackBefore[i].LoadFrom)) { @@ -572,7 +570,7 @@ namespace ICSharpCode.Decompiler.ILAst Loads = new List() { load } }); } else if (storedBy.Length == 1) { - VariableInfo newVar = newVars.Where(v => v.Stores.Contains(storedBy[0])).Single(); + VariableInfo newVar = newVars.Single(v => v.Stores.Contains(storedBy[0])); newVar.Loads.Add(load); } else { List mergeVars = newVars.Where(v => v.Stores.Union(storedBy).Any()).ToList(); @@ -658,12 +656,14 @@ namespace ICSharpCode.Decompiler.ILAst // Find the first and widest scope int tryStart = ehs.Min(eh => eh.TryStart.Offset); int tryEnd = ehs.Where(eh => eh.TryStart.Offset == tryStart).Max(eh => eh.TryEnd.Offset); - var handlers = ehs.Where(eh => eh.TryStart.Offset == tryStart && eh.TryEnd.Offset == tryEnd).ToList(); + var handlers = ehs.Where(eh => eh.TryStart.Offset == tryStart && eh.TryEnd.Offset == tryEnd).OrderBy(eh => eh.TryStart.Offset).ToList(); + + // Remember that any part of the body migt have been removed due to unreachability // Cut all instructions up to the try block { - int tryStartIdx; - for (tryStartIdx = 0; body[tryStartIdx].Offset != tryStart; tryStartIdx++); + int tryStartIdx = 0; + while (tryStartIdx < body.Count && body[tryStartIdx].Offset < tryStart) tryStartIdx++; ast.AddRange(ConvertToAst(body.CutRange(0, tryStartIdx))); } @@ -671,24 +671,22 @@ namespace ICSharpCode.Decompiler.ILAst { HashSet nestedEHs = new HashSet(ehs.Where(eh => (tryStart <= eh.TryStart.Offset && eh.TryEnd.Offset < tryEnd) || (tryStart < eh.TryStart.Offset && eh.TryEnd.Offset <= tryEnd))); ehs.ExceptWith(nestedEHs); - int tryEndIdx; - for (tryEndIdx = 0; tryEndIdx < body.Count && body[tryEndIdx].Offset != tryEnd; tryEndIdx++); + int tryEndIdx = 0; + while (tryEndIdx < body.Count && body[tryEndIdx].Offset < tryEnd) tryEndIdx++; tryCatchBlock.TryBlock = new ILBlock(ConvertToAst(body.CutRange(0, tryEndIdx), nestedEHs)); } // Cut all handlers tryCatchBlock.CatchBlocks = new List(); foreach(ExceptionHandler eh in handlers) { - int startIndex; - for (startIndex = 0; body[startIndex].Offset != eh.HandlerStart.Offset; startIndex++); - int endInclusiveIndex; - if (eh.HandlerEnd == null) endInclusiveIndex = body.Count - 1; - // Note that the end(exclusive) instruction may not necessarly be in our body - else for (endInclusiveIndex = 0; body[endInclusiveIndex].Next.Offset != eh.HandlerEnd.Offset; endInclusiveIndex++); - int count = 1 + endInclusiveIndex - startIndex; - HashSet nestedEHs = new HashSet(ehs.Where(e => (eh.HandlerStart.Offset <= e.TryStart.Offset && e.TryEnd.Offset < eh.HandlerEnd.Offset) || (eh.HandlerStart.Offset < e.TryStart.Offset && e.TryEnd.Offset <= eh.HandlerEnd.Offset))); + int handlerEndOffset = eh.HandlerEnd == null ? methodDef.Body.CodeSize : eh.HandlerEnd.Offset; + int startIdx = 0; + while (startIdx < body.Count && body[startIdx].Offset < eh.HandlerStart.Offset) startIdx++; + int endIdx = 0; + while (endIdx < body.Count && body[endIdx].Offset < handlerEndOffset) endIdx++; + HashSet nestedEHs = new HashSet(ehs.Where(e => (eh.HandlerStart.Offset <= e.TryStart.Offset && e.TryEnd.Offset < handlerEndOffset) || (eh.HandlerStart.Offset < e.TryStart.Offset && e.TryEnd.Offset <= handlerEndOffset))); ehs.ExceptWith(nestedEHs); - List handlerAst = ConvertToAst(body.CutRange(startIndex, count), nestedEHs); + List handlerAst = ConvertToAst(body.CutRange(startIdx, endIdx - startIdx), nestedEHs); if (eh.HandlerType == ExceptionHandlerType.Catch) { ILTryCatchBlock.CatchBlock catchBlock = new ILTryCatchBlock.CatchBlock() { ExceptionType = eh.CatchType, diff --git a/ICSharpCode.Decompiler/ILAst/ILAstOptimizer.cs b/ICSharpCode.Decompiler/ILAst/ILAstOptimizer.cs index be7e16e2d..ef6ab4e54 100644 --- a/ICSharpCode.Decompiler/ILAst/ILAstOptimizer.cs +++ b/ICSharpCode.Decompiler/ILAst/ILAstOptimizer.cs @@ -44,6 +44,7 @@ namespace ICSharpCode.Decompiler.ILAst JoinBasicBlocks, TransformDecimalCtorToConstant, SimplifyLdObjAndStObj, + SimplifyCustomShortCircuit, TransformArrayInitializers, TransformObjectInitializers, MakeAssignmentExpression, @@ -136,6 +137,9 @@ namespace ICSharpCode.Decompiler.ILAst if (abortBeforeStep == ILAstOptimizationStep.SimplifyLdObjAndStObj) return; modified |= block.RunOptimization(SimplifyLdObjAndStObj); + if (abortBeforeStep == ILAstOptimizationStep.SimplifyCustomShortCircuit) return; + modified |= block.RunOptimization(new SimpleControlFlow(context, method).SimplifyCustomShortCircuit); + if (abortBeforeStep == ILAstOptimizationStep.TransformArrayInitializers) return; modified |= block.RunOptimization(TransformArrayInitializers); @@ -308,6 +312,8 @@ namespace ICSharpCode.Decompiler.ILAst /// Converts call and callvirt instructions that read/write properties into CallGetter/CallSetter instructions. /// /// CallGetter/CallSetter is used to allow the ILAst to represent "while ((SomeProperty = value) != null)". + /// + /// Also simplifies 'newobj(SomeDelegate, target, ldvirtftn(F, target))' to 'newobj(SomeDelegate, target, ldvirtftn(F))' /// void IntroducePropertyAccessInstructions(ILNode node) { @@ -365,6 +371,19 @@ namespace ICSharpCode.Decompiler.ILAst expr.Code = (expr.Code == ILCode.Call) ? ILCode.CallSetter : ILCode.CallvirtSetter; } } + } else if (expr.Code == ILCode.Newobj && expr.Arguments.Count == 2) { + // Might be 'newobj(SomeDelegate, target, ldvirtftn(F, target))'. + ILVariable target; + if (expr.Arguments[0].Match(ILCode.Ldloc, out target) + && expr.Arguments[1].Code == ILCode.Ldvirtftn + && expr.Arguments[1].Arguments.Count == 1 + && expr.Arguments[1].Arguments[0].MatchLdloc(target)) + { + // Remove the 'target' argument from the ldvirtftn instruction. + // It's not needed in the translation to C#, and needs to be eliminated so that the target expression + // can be inlined. + expr.Arguments[1].Arguments.Clear(); + } } } @@ -398,7 +417,7 @@ namespace ICSharpCode.Decompiler.ILAst lastNode.IsUnconditionalControlFlow()) { // Try to reuse the label - ILLabel label = currNode is ILLabel ? ((ILLabel)currNode) : new ILLabel() { Name = "Block_" + (nextLabelIndex++) }; + ILLabel label = currNode as ILLabel ?? new ILLabel() { Name = "Block_" + (nextLabelIndex++).ToString() }; // Terminate the last block if (!lastNode.IsUnconditionalControlFlow()) { diff --git a/ICSharpCode.Decompiler/ILAst/ILAstTypes.cs b/ICSharpCode.Decompiler/ILAst/ILAstTypes.cs index 1d366c06c..f86225fb8 100644 --- a/ICSharpCode.Decompiler/ILAst/ILAstTypes.cs +++ b/ICSharpCode.Decompiler/ILAst/ILAstTypes.cs @@ -141,6 +141,10 @@ namespace ICSharpCode.Decompiler.ILAst { output.Write("catch "); output.WriteReference(ExceptionType.FullName, ExceptionType); + if (ExceptionVariable != null) { + output.Write(' '); + output.Write(ExceptionVariable.Name); + } output.WriteLine(" {"); output.Indent(); base.WriteTo(output); @@ -378,10 +382,10 @@ namespace ICSharpCode.Decompiler.ILAst output.Write(((ILVariable)Operand).Name); if (this.InferredType != null) { output.Write(':'); - this.InferredType.WriteTo(output, true, true); + this.InferredType.WriteTo(output, ILNameSyntax.ShortTypeName); if (this.ExpectedType != null && this.ExpectedType.FullName != this.InferredType.FullName) { output.Write("[exp:"); - this.ExpectedType.WriteTo(output, true, true); + this.ExpectedType.WriteTo(output, ILNameSyntax.ShortTypeName); output.Write(']'); } } @@ -399,15 +403,15 @@ namespace ICSharpCode.Decompiler.ILAst output.Write(Code.GetName()); if (this.InferredType != null) { output.Write(':'); - this.InferredType.WriteTo(output, true, true); + this.InferredType.WriteTo(output, ILNameSyntax.ShortTypeName); if (this.ExpectedType != null && this.ExpectedType.FullName != this.InferredType.FullName) { output.Write("[exp:"); - this.ExpectedType.WriteTo(output, true, true); + this.ExpectedType.WriteTo(output, ILNameSyntax.ShortTypeName); output.Write(']'); } } else if (this.ExpectedType != null) { output.Write("[exp:"); - this.ExpectedType.WriteTo(output, true, true); + this.ExpectedType.WriteTo(output, ILNameSyntax.ShortTypeName); output.Write(']'); } output.Write('('); @@ -425,13 +429,13 @@ namespace ICSharpCode.Decompiler.ILAst } else if (Operand is MethodReference) { MethodReference method = (MethodReference)Operand; if (method.DeclaringType != null) { - method.DeclaringType.WriteTo(output, true, true); + method.DeclaringType.WriteTo(output, ILNameSyntax.ShortTypeName); output.Write("::"); } output.WriteReference(method.Name, method); } else if (Operand is FieldReference) { FieldReference field = (FieldReference)Operand; - field.DeclaringType.WriteTo(output, true, true); + field.DeclaringType.WriteTo(output, ILNameSyntax.ShortTypeName); output.Write("::"); output.WriteReference(field.Name, field); } else { diff --git a/ICSharpCode.Decompiler/ILAst/ILInlining.cs b/ICSharpCode.Decompiler/ILAst/ILInlining.cs index 76fde12bf..d839f41ef 100644 --- a/ICSharpCode.Decompiler/ILAst/ILInlining.cs +++ b/ICSharpCode.Decompiler/ILAst/ILInlining.cs @@ -47,7 +47,13 @@ namespace ICSharpCode.Decompiler.ILAst numLdloca.Clear(); // Analyse the whole method - foreach(ILExpression expr in method.GetSelfAndChildrenRecursive()) { + AnalyzeNode(method); + } + + void AnalyzeNode(ILNode node) + { + ILExpression expr = node as ILExpression; + if (expr != null) { ILVariable locVar = expr.Operand as ILVariable; if (locVar != null) { if (expr.Code == ILCode.Stloc) { @@ -60,6 +66,16 @@ namespace ICSharpCode.Decompiler.ILAst throw new NotSupportedException(expr.Code.ToString()); } } + foreach (ILExpression child in expr.Arguments) + AnalyzeNode(child); + } else { + var catchBlock = node as ILTryCatchBlock.CatchBlock; + if (catchBlock != null && catchBlock.ExceptionVariable != null) { + numStloc[catchBlock.ExceptionVariable] = numStloc.GetOrDefault(catchBlock.ExceptionVariable) + 1; + } + + foreach (ILNode child in node.GetChildren()) + AnalyzeNode(child); } } @@ -76,6 +92,20 @@ namespace ICSharpCode.Decompiler.ILAst { bool modified = false; List body = block.Body; + if (block is ILTryCatchBlock.CatchBlock && body.Count > 1) { + ILVariable v = ((ILTryCatchBlock.CatchBlock)block).ExceptionVariable; + if (v != null && v.IsGenerated) { + if (numLdloca.GetOrDefault(v) == 0 && numStloc.GetOrDefault(v) == 1 && numLdloc.GetOrDefault(v) == 1) { + ILVariable v2; + ILExpression ldException; + if (body[0].Match(ILCode.Stloc, out v2, out ldException) && ldException.MatchLdloc(v)) { + body.RemoveAt(0); + ((ILTryCatchBlock.CatchBlock)block).ExceptionVariable = v2; + modified = true; + } + } + } + } for(int i = 0; i < body.Count - 1;) { ILVariable locVar; ILExpression expr; diff --git a/ICSharpCode.Decompiler/ILAst/LoopsAndConditions.cs b/ICSharpCode.Decompiler/ILAst/LoopsAndConditions.cs index cd5656c9d..e5409a2e5 100644 --- a/ICSharpCode.Decompiler/ILAst/LoopsAndConditions.cs +++ b/ICSharpCode.Decompiler/ILAst/LoopsAndConditions.cs @@ -31,7 +31,7 @@ namespace ICSharpCode.Decompiler.ILAst { Dictionary labelToCfNode = new Dictionary(); - DecompilerContext context; + readonly DecompilerContext context; uint nextLabelIndex = 0; @@ -286,7 +286,7 @@ namespace ICSharpCode.Decompiler.ILAst ILLabel condLabel = caseLabels[i]; // Find or create new case block - ILSwitch.CaseBlock caseBlock = ilSwitch.CaseBlocks.Where(b => b.EntryGoto.Operand == condLabel).FirstOrDefault(); + ILSwitch.CaseBlock caseBlock = ilSwitch.CaseBlocks.FirstOrDefault(b => b.EntryGoto.Operand == condLabel); if (caseBlock == null) { caseBlock = new ILSwitch.CaseBlock() { Values = new List(), diff --git a/ICSharpCode.Decompiler/ILAst/PeepholeTransform.cs b/ICSharpCode.Decompiler/ILAst/PeepholeTransform.cs index 270b9f7d4..f9e596514 100644 --- a/ICSharpCode.Decompiler/ILAst/PeepholeTransform.cs +++ b/ICSharpCode.Decompiler/ILAst/PeepholeTransform.cs @@ -90,6 +90,10 @@ namespace ICSharpCode.Decompiler.ILAst expr.Code = ILCode.Stobj; expr.Arguments.Add(new ILExpression(ILCode.DefaultValue, expr.Operand)); modified = true; + } else if (expr.Code == ILCode.Cpobj) { + expr.Code = ILCode.Stobj; + expr.Arguments[1] = new ILExpression(ILCode.Ldobj, expr.Operand, expr.Arguments[1]); + modified = true; } ILExpression arg, arg2; TypeReference type; @@ -440,6 +444,7 @@ namespace ICSharpCode.Decompiler.ILAst #endregion #region IntroducePostIncrement + bool IntroducePostIncrement(List body, ILExpression expr, int pos) { bool modified = IntroducePostIncrementForVariables(body, expr, pos); @@ -452,7 +457,7 @@ namespace ICSharpCode.Decompiler.ILAst } return modified; } - + bool IntroducePostIncrementForVariables(List body, ILExpression expr, int pos) { // Works for variables and static fields/properties @@ -465,19 +470,50 @@ namespace ICSharpCode.Decompiler.ILAst ILExpression exprInit; if (!(expr.Match(ILCode.Stloc, out exprVar, out exprInit) && exprVar.IsGenerated)) return false; - if (!(exprInit.Code == ILCode.Ldloc || exprInit.Code == ILCode.Ldsfld || (exprInit.Code == ILCode.CallGetter && exprInit.Arguments.Count == 0))) - return false; + //The next expression ILExpression nextExpr = body.ElementAtOrDefault(pos + 1) as ILExpression; if (nextExpr == null) return false; - if (exprInit.Code == ILCode.CallGetter) { - if (!(nextExpr.Code == ILCode.CallSetter && IsGetterSetterPair(exprInit.Operand, nextExpr.Operand))) - return false; - } else { - if (!(nextExpr.Code == (exprInit.Code == ILCode.Ldloc ? ILCode.Stloc : ILCode.Stsfld) && nextExpr.Operand == exprInit.Operand)) + + ILCode loadInstruction = exprInit.Code; + ILCode storeInstruction = nextExpr.Code; + bool recombineVariable = false; + + // We only recognise local variables, static fields, and static getters with no arguments + switch (loadInstruction) { + case ILCode.Ldloc: + //Must be a matching store type + if (storeInstruction != ILCode.Stloc) + return false; + ILVariable loadVar = (ILVariable)exprInit.Operand; + ILVariable storeVar = (ILVariable)nextExpr.Operand; + if (loadVar != storeVar) { + if (loadVar.OriginalVariable != null && loadVar.OriginalVariable == storeVar.OriginalVariable) + recombineVariable = true; + else + return false; + } + break; + case ILCode.Ldsfld: + if (storeInstruction != ILCode.Stsfld) + return false; + if (exprInit.Operand != nextExpr.Operand) + return false; + break; + case ILCode.CallGetter: + // non-static getters would have the 'this' argument + if (exprInit.Arguments.Count != 0) + return false; + if (storeInstruction != ILCode.CallSetter) + return false; + if (!IsGetterSetterPair(exprInit.Operand, nextExpr.Operand)) + return false; + break; + default: return false; } + ILExpression addExpr = nextExpr.Arguments[0]; int incrementAmount; @@ -485,12 +521,23 @@ namespace ICSharpCode.Decompiler.ILAst if (!(incrementAmount != 0 && addExpr.Arguments[0].MatchLdloc(exprVar))) return false; - if (exprInit.Code == ILCode.Ldloc) - exprInit.Code = ILCode.Ldloca; - else if (exprInit.Code == ILCode.CallGetter) - exprInit = new ILExpression(ILCode.AddressOf, null, exprInit); - else - exprInit.Code = ILCode.Ldsflda; + if (recombineVariable) { + // Split local variable, unsplit these two instances + foreach (var ilExpression in method.GetSelfAndChildrenRecursive(expression => expression.Operand == nextExpr.Operand)) + ilExpression.Operand = exprInit.Operand; + } + + switch (loadInstruction) { + case ILCode.Ldloc: + exprInit.Code = ILCode.Ldloca; + break; + case ILCode.Ldsfld: + exprInit.Code = ILCode.Ldsflda; + break; + case ILCode.CallGetter: + exprInit = new ILExpression(ILCode.AddressOf, null, exprInit); + break; + } expr.Arguments[0] = new ILExpression(incrementCode, incrementAmount, exprInit); body.RemoveAt(pos + 1); // TODO ILRanges return true; diff --git a/ICSharpCode.Decompiler/ILAst/SimpleControlFlow.cs b/ICSharpCode.Decompiler/ILAst/SimpleControlFlow.cs index e477dbff5..319e18bbb 100644 --- a/ICSharpCode.Decompiler/ILAst/SimpleControlFlow.cs +++ b/ICSharpCode.Decompiler/ILAst/SimpleControlFlow.cs @@ -115,7 +115,7 @@ namespace ICSharpCode.Decompiler.ILAst newExpr = MakeLeftAssociativeShortCircuit(ILCode.LogicAnd, condExpr, trueExpr); } } else { - // Ternary operator tends to create long complicated return statements + // Ternary operator tends to create long complicated return statements if (opCode == ILCode.Ret) return false; @@ -156,7 +156,7 @@ namespace ICSharpCode.Decompiler.ILAst // ... // v = NullCoalescing(ldloc(leftVar), rightExpr) // br(endBBLabel) - + ILVariable v, v2; ILExpression leftExpr, leftExpr2; ILVariable leftVar; @@ -165,7 +165,7 @@ namespace ICSharpCode.Decompiler.ILAst ILBasicBlock rightBB; ILExpression rightExpr; if (head.Body.Count >= 3 && - head.Body[head.Body.Count - 3].Match(ILCode.Stloc, out v, out leftExpr) && + head.Body[head.Body.Count - 3].Match(ILCode.Stloc, out v, out leftExpr) && leftExpr.Match(ILCode.Ldloc, out leftVar) && head.MatchLastAndBr(ILCode.Brtrue, out endBBLabel, out leftExpr2, out rightBBLabel) && leftExpr2.MatchLdloc(leftVar) && @@ -234,6 +234,107 @@ namespace ICSharpCode.Decompiler.ILAst return false; } + public bool SimplifyCustomShortCircuit(List body, ILBasicBlock head, int pos) + { + Debug.Assert(body.Contains(head)); + + // --- looking for the following pattern --- + // stloc(targetVar, leftVar) + // brtrue(exitLabel, call(op_False, leftVar) + // br(followingBlock) + // + // FollowingBlock: + // stloc(targetVar, call(op_BitwiseAnd, leftVar, rightExpression)) + // br(exitLabel) + // --- + + if (head.Body.Count < 3) + return false; + + // looking for: + // stloc(targetVar, leftVar) + ILVariable targetVar; + ILExpression targetVarInitExpr; + if (!head.Body[head.Body.Count - 3].Match(ILCode.Stloc, out targetVar, out targetVarInitExpr)) + return false; + + ILVariable leftVar; + if (!targetVarInitExpr.Match(ILCode.Ldloc, out leftVar)) + return false; + + // looking for: + // brtrue(exitLabel, call(op_False, leftVar) + // br(followingBlock) + ILExpression callExpr; + ILLabel exitLabel; + ILLabel followingBlock; + if(!head.MatchLastAndBr(ILCode.Brtrue, out exitLabel, out callExpr, out followingBlock)) + return false; + + if (labelGlobalRefCount[followingBlock] > 1) + return false; + + MethodReference opFalse; + ILExpression opFalseArg; + if (!callExpr.Match(ILCode.Call, out opFalse, out opFalseArg)) + return false; + + // ignore operators other than op_False and op_True + if (opFalse.Name != "op_False" && opFalse.Name != "op_True") + return false; + + if (!opFalseArg.MatchLdloc(leftVar)) + return false; + + ILBasicBlock followingBasicBlock = labelToBasicBlock[followingBlock]; + + // FollowingBlock: + // stloc(targetVar, call(op_BitwiseAnd, leftVar, rightExpression)) + // br(exitLabel) + ILVariable _targetVar; + ILExpression opBitwiseCallExpr; + ILLabel _exitLabel; + if (!followingBasicBlock.MatchSingleAndBr(ILCode.Stloc, out _targetVar, out opBitwiseCallExpr, out _exitLabel)) + return false; + + if (_targetVar != targetVar || exitLabel != _exitLabel) + return false; + + MethodReference opBitwise; + ILExpression leftVarExpression; + ILExpression rightExpression; + if (!opBitwiseCallExpr.Match(ILCode.Call, out opBitwise, out leftVarExpression, out rightExpression)) + return false; + + if (!opFalseArg.MatchLdloc(leftVarExpression.Operand as ILVariable)) + return false; + + // ignore operators other than op_BitwiseAnd and op_BitwiseOr + if (opBitwise.Name != "op_BitwiseAnd" && opBitwise.Name != "op_BitwiseOr") + return false; + + // insert: + // stloc(targetVar, LogicAnd(C::op_BitwiseAnd, leftVar, rightExpression) + // br(exitLabel) + ILCode op = opBitwise.Name == "op_BitwiseAnd" ? ILCode.LogicAnd : ILCode.LogicOr; + + if (op == ILCode.LogicAnd && opFalse.Name != "op_False") + return false; + + if (op == ILCode.LogicOr && opFalse.Name != "op_True") + return false; + + ILExpression shortCircuitExpr = MakeLeftAssociativeShortCircuit(op, opFalseArg, rightExpression); + shortCircuitExpr.Operand = opBitwise; + + head.Body.RemoveTail(ILCode.Stloc, ILCode.Brtrue, ILCode.Br); + head.Body.Add(new ILExpression(ILCode.Stloc, targetVar, shortCircuitExpr)); + head.Body.Add(new ILExpression(ILCode.Br, exitLabel)); + body.Remove(followingBasicBlock); + + return true; + } + ILExpression MakeLeftAssociativeShortCircuit(ILCode code, ILExpression left, ILExpression right) { // Assuming that the inputs are already left associative diff --git a/ICSharpCode.Decompiler/ILAst/TypeAnalysis.cs b/ICSharpCode.Decompiler/ILAst/TypeAnalysis.cs index 1aa21a276..3c5c47bf6 100644 --- a/ICSharpCode.Decompiler/ILAst/TypeAnalysis.cs +++ b/ICSharpCode.Decompiler/ILAst/TypeAnalysis.cs @@ -267,6 +267,10 @@ namespace ICSharpCode.Decompiler.ILAst return typeSystem.Boolean; case ILCode.LogicAnd: case ILCode.LogicOr: + // if Operand is set the logic and/or expression is a custom operator + // we can deal with it the same as a normal invocation. + if (expr.Operand != null) + goto case ILCode.Call; if (forceInferChildren) { InferTypeForExpression(expr.Arguments[0], typeSystem.Boolean); InferTypeForExpression(expr.Arguments[1], typeSystem.Boolean); diff --git a/ICSharpCode.Decompiler/Tests/CustomShortCircuitOperators.cs b/ICSharpCode.Decompiler/Tests/CustomShortCircuitOperators.cs new file mode 100644 index 000000000..30a94a6e6 --- /dev/null +++ b/ICSharpCode.Decompiler/Tests/CustomShortCircuitOperators.cs @@ -0,0 +1,75 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under MIT X11 license (for details please see \doc\license.txt) + +using System; + +public static class CustomShortCircuitOperators +{ + private class B + { + public static bool operator true(CustomShortCircuitOperators.B x) + { + return true; + } + + public static bool operator false(CustomShortCircuitOperators.B x) + { + return false; + } + } + + private class C : CustomShortCircuitOperators.B + { + public static CustomShortCircuitOperators.C operator &(CustomShortCircuitOperators.C x, CustomShortCircuitOperators.C y) + { + return null; + } + + public static CustomShortCircuitOperators.C operator |(CustomShortCircuitOperators.C x, CustomShortCircuitOperators.C y) + { + return null; + } + + public static bool operator !(CustomShortCircuitOperators.C x) + { + return false; + } + + private static void Main() + { + CustomShortCircuitOperators.C c = new CustomShortCircuitOperators.C(); + CustomShortCircuitOperators.C c2 = new CustomShortCircuitOperators.C(); + CustomShortCircuitOperators.C c3 = c && c2; + CustomShortCircuitOperators.C c4 = c || c2; + Console.WriteLine(c3.ToString()); + Console.WriteLine(c4.ToString()); + } + + private static void Test2() + { + CustomShortCircuitOperators.C c = new CustomShortCircuitOperators.C(); + if (c && c) + { + Console.WriteLine(c.ToString()); + } + + if (!(c && c)) + { + Console.WriteLine(c.ToString()); + } + } + + private static void Test3() + { + CustomShortCircuitOperators.C c = new CustomShortCircuitOperators.C(); + if (c) + { + Console.WriteLine(c.ToString()); + } + if (!c) + { + Console.WriteLine(c.ToString()); + } + } + } +} \ No newline at end of file diff --git a/ICSharpCode.Decompiler/Tests/ExceptionHandling.cs b/ICSharpCode.Decompiler/Tests/ExceptionHandling.cs index 5fdc27dc5..7f6e506ee 100644 --- a/ICSharpCode.Decompiler/Tests/ExceptionHandling.cs +++ b/ICSharpCode.Decompiler/Tests/ExceptionHandling.cs @@ -2,6 +2,7 @@ // This code is distributed under MIT X11 license (for details please see \doc\license.txt) using System; +using System.Threading; public class ExceptionHandling { @@ -55,13 +56,38 @@ public class ExceptionHandling { Console.WriteLine(ex.Message); } - catch (Exception ex) + catch (Exception ex2) { - Console.WriteLine(ex.Message); + Console.WriteLine(ex2.Message); } catch { Console.WriteLine("other"); } } + + public void NoUsingStatementBecauseTheVariableIsAssignedTo() + { + CancellationTokenSource cancellationTokenSource = null; + try + { + cancellationTokenSource = new CancellationTokenSource(); + } + finally + { + if (cancellationTokenSource != null) + { + cancellationTokenSource.Dispose(); + } + } + } + + public void UsingStatementThatChangesTheVariable() + { + CancellationTokenSource cancellationTokenSource = null; + using (cancellationTokenSource) + { + cancellationTokenSource = new CancellationTokenSource(); + } + } } diff --git a/ICSharpCode.Decompiler/Tests/Generics.cs b/ICSharpCode.Decompiler/Tests/Generics.cs index 53cd5f623..e5b6e2eb7 100644 --- a/ICSharpCode.Decompiler/Tests/Generics.cs +++ b/ICSharpCode.Decompiler/Tests/Generics.cs @@ -60,6 +60,12 @@ public static class Generics } } + private static Type type1 = typeof(List<>); + private static Type type2 = typeof(Generics.MyArray<>); + private static Type type3 = typeof(List<>.Enumerator); + private static Type type4 = typeof(Generics.MyArray<>.NestedClass<>); + private static Type type5 = typeof(List[]); + public static void MethodWithConstraint() where T : class, S where S : ICloneable, new() { } diff --git a/ICSharpCode.Decompiler/Tests/Helpers/RemoveCompilerAttribute.cs b/ICSharpCode.Decompiler/Tests/Helpers/RemoveCompilerAttribute.cs index 0076eb2ba..251916557 100644 --- a/ICSharpCode.Decompiler/Tests/Helpers/RemoveCompilerAttribute.cs +++ b/ICSharpCode.Decompiler/Tests/Helpers/RemoveCompilerAttribute.cs @@ -15,7 +15,7 @@ namespace ICSharpCode.Decompiler.Tests.Helpers var section = (AttributeSection)attribute.Parent; SimpleType type = attribute.Type as SimpleType; if (section.AttributeTarget == "assembly" && - (type.Identifier == "CompilationRelaxations" || type.Identifier == "RuntimeCompatibility")) + (type.Identifier == "CompilationRelaxations" || type.Identifier == "RuntimeCompatibility" || type.Identifier == "SecurityPermission" || type.Identifier == "AssemblyVersion")) { attribute.Remove(); if (section.Attributes.Count == 0) diff --git a/ICSharpCode.Decompiler/Tests/ICSharpCode.Decompiler.Tests.csproj b/ICSharpCode.Decompiler/Tests/ICSharpCode.Decompiler.Tests.csproj index b4906c60f..33227a313 100644 --- a/ICSharpCode.Decompiler/Tests/ICSharpCode.Decompiler.Tests.csproj +++ b/ICSharpCode.Decompiler/Tests/ICSharpCode.Decompiler.Tests.csproj @@ -57,8 +57,10 @@ + + diff --git a/ICSharpCode.Decompiler/Tests/IncrementDecrement.cs b/ICSharpCode.Decompiler/Tests/IncrementDecrement.cs index 02a72190f..12c47186d 100644 --- a/ICSharpCode.Decompiler/Tests/IncrementDecrement.cs +++ b/ICSharpCode.Decompiler/Tests/IncrementDecrement.cs @@ -176,6 +176,12 @@ public class IncrementDecrement return i++ + j; } + public void PostIncrementInlineLocalVariable(Func f) + { + int num = 0; + f(num++); + } + public int PostIncrementArrayElement(int[] array, int pos) { return array[pos]--; diff --git a/ICSharpCode.Decompiler/Tests/PInvoke.cs b/ICSharpCode.Decompiler/Tests/PInvoke.cs new file mode 100644 index 000000000..fe9b9b5bc --- /dev/null +++ b/ICSharpCode.Decompiler/Tests/PInvoke.cs @@ -0,0 +1,87 @@ +// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team +// +// Permission is hereby granted, free of charge, to any person obtaining a copy of this +// software and associated documentation files (the "Software"), to deal in the Software +// without restriction, including without limitation the rights to use, copy, modify, merge, +// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons +// to whom the Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all copies or +// substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE +// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. + +using System; +using System.Runtime.InteropServices; + +// P/Invoke and marshalling attribute tests +public class PInvoke +{ + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode, Pack = 2)] + public struct MarshalAsTest + { + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)] + public uint[] FixedArray; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4, ArraySubType = UnmanagedType.Bool)] + public int[] FixedBoolArray; + + [MarshalAs(UnmanagedType.SafeArray, SafeArraySubType = VarEnum.VT_BSTR)] + public string[] SafeBStrArray; + + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 8)] + public string FixedString; + } + + [StructLayout(LayoutKind.Explicit)] + public struct Rect + { + [FieldOffset(0)] + public int left; + [FieldOffset(4)] + public int top; + [FieldOffset(8)] + public int right; + [FieldOffset(12)] + public int bottom; + } + + public static decimal MarshalAttributesOnPropertyAccessors + { + [return: MarshalAs(UnmanagedType.Currency)] + get + { + return 0m; + } + [param: MarshalAs(UnmanagedType.Currency)] + set + { + } + } + + [DllImport("xyz.dll", CharSet = CharSet.Auto)] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool Method([MarshalAs(UnmanagedType.LPStr)] string input); + + [DllImport("xyz.dll")] + private static extern void New1(int ElemCnt, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] int[] ar); + + [DllImport("xyz.dll")] + private static extern void New2([MarshalAs(UnmanagedType.LPArray, SizeConst = 128)] int[] ar); + + [DllImport("xyz.dll")] + private static extern void New3([MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.Bool, SizeConst = 64, SizeParamIndex = 1)] int[] ar); + + public void CustomMarshal1([MarshalAs(UnmanagedType.CustomMarshaler, MarshalType = "MyCompany.MyMarshaler")] object o) + { + } + + public void CustomMarshal2([MarshalAs(UnmanagedType.CustomMarshaler, MarshalType = "MyCompany.MyMarshaler", MarshalCookie = "Cookie")] object o) + { + } +} diff --git a/ICSharpCode.Decompiler/Tests/TestRunner.cs b/ICSharpCode.Decompiler/Tests/TestRunner.cs index 998c17370..a3100391c 100644 --- a/ICSharpCode.Decompiler/Tests/TestRunner.cs +++ b/ICSharpCode.Decompiler/Tests/TestRunner.cs @@ -37,7 +37,7 @@ namespace ICSharpCode.Decompiler.Tests TestFile(@"..\..\Tests\DelegateConstruction.cs"); } - [Test, Ignore("arg-Variables in catch clauses")] + [Test] public void ExceptionHandling() { TestFile(@"..\..\Tests\ExceptionHandling.cs"); @@ -49,6 +49,12 @@ namespace ICSharpCode.Decompiler.Tests TestFile(@"..\..\Tests\Generics.cs"); } + [Test] + public void CustomShortCircuitOperators() + { + TestFile(@"..\..\Tests\CustomShortCircuitOperators.cs"); + } + [Test] public void IncrementDecrement() { @@ -73,6 +79,12 @@ namespace ICSharpCode.Decompiler.Tests TestFile(@"..\..\Tests\MultidimensionalArray.cs"); } + [Test] + public void PInvoke() + { + TestFile(@"..\..\Tests\PInvoke.cs"); + } + [Test] public void PropertiesAndEvents() { diff --git a/ILSpy.BamlDecompiler/BamlResourceEntryNode.cs b/ILSpy.BamlDecompiler/BamlResourceEntryNode.cs new file mode 100644 index 000000000..40d850c4a --- /dev/null +++ b/ILSpy.BamlDecompiler/BamlResourceEntryNode.cs @@ -0,0 +1,61 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team +// This code is distributed under the MS-PL (for details please see \doc\MS-PL.txt) + +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Threading.Tasks; +using System.Xml.Linq; + +using ICSharpCode.AvalonEdit.Highlighting; +using ICSharpCode.ILSpy.TextView; +using ICSharpCode.ILSpy.TreeNodes; +using Ricciolo.StylesExplorer.MarkupReflection; + +namespace ILSpy.BamlDecompiler +{ + public sealed class BamlResourceEntryNode : ResourceEntryNode + { + public BamlResourceEntryNode(string key, Stream data) : base(key, data) + { + } + + public override bool View(DecompilerTextView textView) + { + AvalonEditTextOutput output = new AvalonEditTextOutput(); + IHighlightingDefinition highlighting = null; + + textView.RunWithCancellation( + token => Task.Factory.StartNew( + () => { + try { + if (LoadBaml(output)) + highlighting = HighlightingManager.Instance.GetDefinitionByExtension(".xml"); + } catch (Exception ex) { + output.Write(ex.ToString()); + } + return output; + }), + t => textView.ShowNode(t.Result, this, highlighting) + ); + return true; + } + + bool LoadBaml(AvalonEditTextOutput output) + { + var asm = this.Ancestors().OfType().FirstOrDefault().LoadedAssembly; + MemoryStream bamlStream = new MemoryStream(); + Data.Position = 0; + Data.CopyTo(bamlStream); + bamlStream.Position = 0; + + XDocument xamlDocument; + using (XmlBamlReader reader = new XmlBamlReader(bamlStream)) + xamlDocument = XDocument.Load(reader); + + output.Write(xamlDocument.ToString()); + return true; + } + } +} \ No newline at end of file diff --git a/ILSpy.BamlDecompiler/BamlResourceNodeFactory.cs b/ILSpy.BamlDecompiler/BamlResourceNodeFactory.cs new file mode 100644 index 000000000..a1b77fb6b --- /dev/null +++ b/ILSpy.BamlDecompiler/BamlResourceNodeFactory.cs @@ -0,0 +1,29 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team +// This code is distributed under the MS-PL (for details please see \doc\MS-PL.txt) + +using System; +using System.Collections.Generic; +using System.ComponentModel.Composition; +using System.IO; + +using ICSharpCode.ILSpy.TreeNodes; + +namespace ILSpy.BamlDecompiler +{ + [Export(typeof(IResourceNodeFactory))] + public sealed class BamlResourceNodeFactory : IResourceNodeFactory + { + public ILSpyTreeNode CreateNode(Mono.Cecil.Resource resource) + { + return null; + } + + public ILSpyTreeNode CreateNode(string key, Stream data) + { + if (key.EndsWith(".baml", StringComparison.OrdinalIgnoreCase)) + return new BamlResourceEntryNode(key, data); + else + return null; + } + } +} diff --git a/ILSpy.BamlDecompiler/ILSpy.BamlDecompiler.csproj b/ILSpy.BamlDecompiler/ILSpy.BamlDecompiler.csproj new file mode 100644 index 000000000..587959be6 --- /dev/null +++ b/ILSpy.BamlDecompiler/ILSpy.BamlDecompiler.csproj @@ -0,0 +1,124 @@ + + + + {A6BAD2BA-76BA-461C-8B6D-418607591247} + Debug + x86 + Library + ILSpy.BamlDecompiler + ILSpy.BamlDecompiler.Plugin + v4.0 + Client + Properties + False + False + 4 + false + + + x86 + False + Auto + 4194304 + 4096 + + + ..\ILSpy\bin\Debug\ + true + Full + False + True + DEBUG;TRACE + + + ..\ILSpy\bin\Release\ + false + None + True + False + TRACE + + + + 3.0 + + + 3.0 + + + + 4.0 + + + 3.5 + + + 4.0 + + + + 3.5 + + + 3.0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {6C55B776-26D4-4DB3-A6AB-87E783B2F3D1} + ICSharpCode.AvalonEdit + False + + + {984CC812-9470-4A13-AFF9-CC44068D666C} + ICSharpCode.Decompiler + False + + + {1E85EFF9-E370-4683-83E4-8A3D063FF791} + ILSpy + False + + + {D68133BD-1E63-496E-9EDE-4FBDBF77B486} + Mono.Cecil + False + + + {DDE2A481-8271-4EAC-A330-8FA6A38D13D1} + ICSharpCode.TreeView + False + + + + \ No newline at end of file diff --git a/ILSpy.BamlDecompiler/Properties/AssemblyInfo.cs b/ILSpy.BamlDecompiler/Properties/AssemblyInfo.cs new file mode 100644 index 000000000..f28440c93 --- /dev/null +++ b/ILSpy.BamlDecompiler/Properties/AssemblyInfo.cs @@ -0,0 +1,31 @@ +#region Using directives + +using System; +using System.Reflection; +using System.Runtime.InteropServices; + +#endregion + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("ILSpy.BamlDecompiler.Plugin")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("ILSpy.BamlDecompiler.Plugin")] +[assembly: AssemblyCopyright("Copyright 2011")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// This sets the default COM visibility of types in the assembly to invisible. +// If you need to expose a type to COM, use [ComVisible(true)] on that type. +[assembly: ComVisible(false)] + +// The assembly version has following format : +// +// Major.Minor.Build.Revision +// +// You can specify all the values or you can use the default the Revision and +// Build Numbers by using the '*' as shown below: +[assembly: AssemblyVersion("1.0.*")] diff --git a/ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/AppDomainTypeResolver.cs b/ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/AppDomainTypeResolver.cs new file mode 100644 index 000000000..9cc329459 --- /dev/null +++ b/ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/AppDomainTypeResolver.cs @@ -0,0 +1,172 @@ +// Copyright (c) Cristian Civera (cristian@aspitalia.com) +// This code is distributed under the MS-PL (for details please see \doc\MS-PL.txt) + +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Reflection; +using System.Text; +using System.IO; +using System.Linq; +using Microsoft.Win32; +using System.Threading; +using System.Security.Permissions; +using System.Security; + +namespace Ricciolo.StylesExplorer.MarkupReflection +{ + public delegate void AssemblyResolveEventHandler(object s, AssemblyResolveEventArgs e); + + public class AppDomainTypeResolver : MarshalByRefObject, ITypeResolver + { + private readonly AppDomain _domain; + private string baseDir; + + public event AssemblyResolveEventHandler AssemblyResolve; + + public static AppDomainTypeResolver GetIntoNewAppDomain(string baseDir) + { + AppDomainSetup info = new AppDomainSetup(); + info.ApplicationBase = Environment.CurrentDirectory; + AppDomain domain = AppDomain.CreateDomain("AppDomainTypeResolver", null, info, new PermissionSet(PermissionState.Unrestricted)); + AppDomainTypeResolver resolver = (AppDomainTypeResolver)domain.CreateInstanceAndUnwrap(typeof(AppDomainTypeResolver).Assembly.FullName, + typeof(AppDomainTypeResolver).FullName, false, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.CreateInstance, null, new object[] { domain, baseDir }, null, null, null); + + return resolver; + } + + Assembly domain_AssemblyResolve(object sender, ResolveEventArgs args) + { + // Cerco di risolvere automaticamente + AssemblyName name = new AssemblyName(args.Name); + string fileName = Path.Combine(this.baseDir, name.Name + ".exe"); + if (!File.Exists(fileName)) + fileName = Path.Combine(this.baseDir, name.Name + ".dll"); + + // Carico il percorso autocalcolato + if (File.Exists(fileName)) + return Assembly.LoadFile(fileName); + + if (AssemblyResolve != null) + { + AssemblyResolveEventArgs e = new AssemblyResolveEventArgs(args.Name, this.baseDir); + AssemblyResolve(this, e); + if (!String.IsNullOrEmpty(e.Location) && File.Exists(e.Location)) + return Assembly.LoadFile(e.Location); + } + + return null; + } + + public static void DestroyResolver(AppDomainTypeResolver resolver) + { + if (resolver == null) throw new ArgumentNullException("resolver"); + + ThreadPool.QueueUserWorkItem(delegate + { + AppDomain.Unload(resolver.Domain); + }); + } + + protected AppDomainTypeResolver(AppDomain domain, string baseDir) + { + _domain = domain; + this.baseDir = baseDir; + + domain.AssemblyResolve += new ResolveEventHandler(domain_AssemblyResolve); + } + + public BamlAssembly LoadAssembly(AssemblyName asm) + { + //return new BamlAssembly(Assembly.Load(asm)); + return new BamlAssembly(_domain.Load(asm)); + } + + public BamlAssembly LoadAssembly(string location) + { + Assembly asm = Assembly.LoadFile(location); + return new BamlAssembly(asm); + //return _domain.Load(System.IO.File.ReadAllBytes(location)); + //return Assembly.LoadFrom(location); + } + + public BamlAssembly[] GetReferencedAssemblies(BamlAssembly asm) + { + AssemblyName[] list = asm.Assembly.GetReferencedAssemblies(); + + return (from an in list + select this.LoadAssembly(an)).ToArray(); + } + + public AppDomain Domain + { + get { return _domain; } + } + + #region ITypeResolver Members + + public IType GetTypeByAssemblyQualifiedName(string name) + { + return new DotNetType(name); + } + + public IDependencyPropertyDescriptor GetDependencyPropertyDescriptor(string name, IType ownerType, IType targetType) + { + if (name == null) throw new ArgumentNullException("name"); + if (ownerType == null) throw new ArgumentNullException("ownerType"); + if (targetType == null) throw new ArgumentNullException("targetType"); + + Type dOwnerType = ((DotNetType)ownerType).Type; + Type dTargetType = ((DotNetType)targetType).Type; + + try + { + DependencyPropertyDescriptor propertyDescriptor = DependencyPropertyDescriptor.FromName(name, dOwnerType, dTargetType); + if (propertyDescriptor != null) + return new WpfDependencyPropertyDescriptor(propertyDescriptor); + return null; + } + catch (Exception) + { + return null; + } + } + + #endregion + + public override object InitializeLifetimeService() + { + return null; + } + } + + public class AssemblyResolveEventArgs : MarshalByRefObject + { + + private string _location; + private string _name; + private string _baseDir; + + public AssemblyResolveEventArgs(string name, string baseDir) + { + _name = name; + _baseDir = baseDir; + } + + public string Location + { + get { return _location; } + set { _location = value; } + } + + public string Name + { + get { return _name; } + } + + public string BaseDir + { + get { return _baseDir; } + } + } +} diff --git a/ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/BamlAssembly.cs b/ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/BamlAssembly.cs new file mode 100644 index 000000000..d9d71860f --- /dev/null +++ b/ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/BamlAssembly.cs @@ -0,0 +1,112 @@ +// Copyright (c) Cristian Civera (cristian@aspitalia.com) +// This code is distributed under the MS-PL (for details please see \doc\MS-PL.txt) + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.IO; +using System.Reflection; +using System.Resources; +using System.Text; + +namespace Ricciolo.StylesExplorer.MarkupReflection +{ + public class BamlAssembly : MarshalByRefObject + { + private readonly string _filePath; + private Assembly _assembly; + private BamlFileList _bamlFile; + + public BamlAssembly(Assembly assembly) + { + _assembly = assembly; + _filePath = assembly.CodeBase; + + ReadBaml(); + } + + public BamlAssembly(string filePath) + { + this._filePath = Path.GetFullPath(filePath); + this._assembly = Assembly.LoadFile(this.FilePath); + if (String.Compare(this.Assembly.CodeBase, this.FilePath, true) != 0) + throw new ArgumentException("Cannot load filePath because Assembly is already loaded", "filePath"); + + ReadBaml(); + } + + private void ReadBaml() + { + // Get available names + string[] resources = this.Assembly.GetManifestResourceNames(); + foreach (string res in resources) + { + // Solo le risorse + if (String.Compare(Path.GetExtension(res), ".resources", true) != 0) continue; + + // Get stream + using (Stream stream = this.Assembly.GetManifestResourceStream(res)) + { + try + { + ResourceReader reader = new ResourceReader(stream); + foreach (DictionaryEntry entry in reader) + { + if (String.Compare(Path.GetExtension(entry.Key.ToString()), ".baml", true) == 0 && entry.Value is Stream) + { + BamlFile bm = new BamlFile(GetAssemblyResourceUri(entry.Key.ToString()), (Stream)entry.Value); + this.BamlFiles.Add(bm); + } + } + } + catch (ArgumentException) + {} + } + } + } + + private Uri GetAssemblyResourceUri(string resourceName) + { + AssemblyName asm = this.Assembly.GetName(); + byte[] data = asm.GetPublicKeyToken(); + StringBuilder token = new StringBuilder(data.Length * 2); + for (int x = 0; x < data.Length; x++) + { + token.Append(data[x].ToString("x", System.Globalization.CultureInfo.InvariantCulture)); + } + + return new Uri(String.Format(@"{0};V{1};{2};component\{3}", asm.Name, asm.Version, token, Path.ChangeExtension(resourceName, ".xaml")), UriKind.RelativeOrAbsolute); + } + + public string FilePath + { + get { return _filePath; } + } + + public Assembly Assembly + { + get { return _assembly; } + } + + public BamlFileList BamlFiles + { + get + { + if (_bamlFile == null) + _bamlFile = new BamlFileList(); + return _bamlFile; + } + } + + public override object InitializeLifetimeService() + { + return null; + } + } + + [Serializable()] + public class BamlFileList : Collection + {} + +} diff --git a/ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/BamlBinaryReader.cs b/ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/BamlBinaryReader.cs new file mode 100644 index 000000000..6df206561 --- /dev/null +++ b/ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/BamlBinaryReader.cs @@ -0,0 +1,47 @@ +// Copyright (c) Cristian Civera (cristian@aspitalia.com) +// This code is distributed under the MS-PL (for details please see \doc\MS-PL.txt) + +using System; +using System.IO; +using System.Text; + +namespace Ricciolo.StylesExplorer.MarkupReflection +{ + internal class BamlBinaryReader : BinaryReader + { + // Methods + public BamlBinaryReader(Stream stream) + : base(stream) + { + } + + public virtual double ReadCompressedDouble() + { + switch (this.ReadByte()) + { + case 1: + return 0; + + case 2: + return 1; + + case 3: + return -1; + + case 4: + { + double num = this.ReadInt32(); + return (num * 1E-06); + } + case 5: + return this.ReadDouble(); + } + throw new NotSupportedException(); + } + + public int ReadCompressedInt32() + { + return base.Read7BitEncodedInt(); + } + } +} \ No newline at end of file diff --git a/ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/BamlFile.cs b/ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/BamlFile.cs new file mode 100644 index 000000000..d4af6bb81 --- /dev/null +++ b/ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/BamlFile.cs @@ -0,0 +1,80 @@ +// Copyright (c) Cristian Civera (cristian@aspitalia.com) +// This code is distributed under the MS-PL (for details please see \doc\MS-PL.txt) + +using System; +using System.Collections; +using System.Collections.Generic; +using System.ComponentModel; +using System.IO; +using System.Resources; +using System.Text; +using System.Windows; + +namespace Ricciolo.StylesExplorer.MarkupReflection +{ + /// + /// Rappresenta un singole file Baml all'interno di un assembly + /// + public class BamlFile : Component + { + private Uri _uri; + private readonly Stream _stream; + + public BamlFile(Uri uri, Stream stream) + { + if (uri == null) + new ArgumentNullException("uri"); + if (stream == null) + throw new ArgumentNullException("stream"); + + _uri = uri; + _stream = stream; + } + + /// + /// Carica il Baml attraverso il motore di WPF con Application.LoadComponent + /// + /// + public object LoadContent() + { + try + { + return Application.LoadComponent(this.Uri); + } + catch (Exception e) + { + throw new InvalidOperationException("Invalid baml file.", e); + } + } + + protected override void Dispose(bool disposing) + { + base.Dispose(disposing); + + if (disposing) + this.Stream.Dispose(); + } + + public override object InitializeLifetimeService() + { + return null; + } + + /// + /// Restituisce lo stream originale contenente il Baml + /// + public Stream Stream + { + get { return _stream; } + } + + /// + /// Restituisce l'indirizzo secondo lo schema pack:// + /// + public Uri Uri + { + get { return _uri; } + } + + } +} diff --git a/ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/BamlRecordType.cs b/ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/BamlRecordType.cs new file mode 100644 index 000000000..50ca01ddb --- /dev/null +++ b/ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/BamlRecordType.cs @@ -0,0 +1,72 @@ +// Copyright (c) Cristian Civera (cristian@aspitalia.com) +// This code is distributed under the MS-PL (for details please see \doc\MS-PL.txt) + +using System; +using System.Collections.Generic; +using System.Text; + +namespace Ricciolo.StylesExplorer.MarkupReflection +{ + internal enum BamlRecordType : byte + { + AssemblyInfo = 0x1c, + AttributeInfo = 0x1f, + ClrEvent = 0x13, + Comment = 0x17, + ConnectionId = 0x2d, + ConstructorParametersEnd = 0x2b, + ConstructorParametersStart = 0x2a, + ConstructorParameterType = 0x2c, + ContentProperty = 0x2e, + DefAttribute = 0x19, + DefAttributeKeyString = 0x26, + DefAttributeKeyType = 0x27, + DeferableContentStart = 0x25, + DefTag = 0x18, + DocumentEnd = 2, + DocumentStart = 1, + ElementEnd = 4, + ElementStart = 3, + EndAttributes = 0x1a, + KeyElementEnd = 0x29, + KeyElementStart = 40, + LastRecordType = 0x39, + LineNumberAndPosition = 0x35, + LinePosition = 0x36, + LiteralContent = 15, + NamedElementStart = 0x2f, + OptimizedStaticResource = 0x37, + PIMapping = 0x1b, + PresentationOptionsAttribute = 0x34, + ProcessingInstruction = 0x16, + Property = 5, + PropertyArrayEnd = 10, + PropertyArrayStart = 9, + PropertyComplexEnd = 8, + PropertyComplexStart = 7, + PropertyCustom = 6, + PropertyDictionaryEnd = 14, + PropertyDictionaryStart = 13, + PropertyListEnd = 12, + PropertyListStart = 11, + PropertyStringReference = 0x21, + PropertyTypeReference = 0x22, + PropertyWithConverter = 0x24, + PropertyWithExtension = 0x23, + PropertyWithStaticResourceId = 0x38, + RoutedEvent = 0x12, + StaticResourceEnd = 0x31, + StaticResourceId = 50, + StaticResourceStart = 0x30, + StringInfo = 0x20, + Text = 0x10, + TextWithConverter = 0x11, + TextWithId = 0x33, + TypeInfo = 0x1d, + TypeSerializerInfo = 30, + Unknown = 0, + XmlAttribute = 0x15, + XmlnsProperty = 20 + } + +} diff --git a/ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/DotNetType.cs b/ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/DotNetType.cs new file mode 100644 index 000000000..1dbf1b21a --- /dev/null +++ b/ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/DotNetType.cs @@ -0,0 +1,58 @@ +// Copyright (c) Cristian Civera (cristian@aspitalia.com) +// This code is distributed under the MS-PL (for details please see \doc\MS-PL.txt) + +using System; +using System.Collections.Generic; +using System.Text; + +namespace Ricciolo.StylesExplorer.MarkupReflection +{ + public class DotNetType : MarshalByRefObject, IType + { + private readonly string _assemblyQualifiedName; + private Type _type; + + public DotNetType(string assemblyQualifiedName) + { + if (assemblyQualifiedName == null) throw new ArgumentNullException("assemblyQualifiedName"); + + _assemblyQualifiedName = assemblyQualifiedName; + _type = Type.GetType(assemblyQualifiedName, false, true); + } + + #region IType Members + + public string AssemblyQualifiedName + { + get { return _assemblyQualifiedName; } + } + + public bool IsSubclassOf(IType type) + { + if (type == null) throw new ArgumentNullException("type"); + if (!(type is DotNetType)) throw new ArgumentException("type"); + if (_type == null) return false; + return this._type.IsSubclassOf(((DotNetType)type).Type); + } + + public bool Equals(IType type) + { + if (type == null) throw new ArgumentNullException("type"); + if (!(type is DotNetType)) throw new ArgumentException("type"); + if (_type == null) return false; + return this._type.Equals(((DotNetType)type).Type); + } + + #endregion + + public Type Type + { + get { return _type; } + } + + public override object InitializeLifetimeService() + { + return null; + } + } +} diff --git a/ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/IDependencyPropertyDescriptor.cs b/ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/IDependencyPropertyDescriptor.cs new file mode 100644 index 000000000..0005efa52 --- /dev/null +++ b/ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/IDependencyPropertyDescriptor.cs @@ -0,0 +1,14 @@ +// Copyright (c) Cristian Civera (cristian@aspitalia.com) +// This code is distributed under the MS-PL (for details please see \doc\MS-PL.txt) + +using System; +using System.Collections.Generic; +using System.Text; + +namespace Ricciolo.StylesExplorer.MarkupReflection +{ + public interface IDependencyPropertyDescriptor + { + bool IsAttached { get; } + } +} diff --git a/ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/IType.cs b/ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/IType.cs new file mode 100644 index 000000000..7ec8c79e4 --- /dev/null +++ b/ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/IType.cs @@ -0,0 +1,19 @@ +// Copyright (c) Cristian Civera (cristian@aspitalia.com) +// This code is distributed under the MS-PL (for details please see \doc\MS-PL.txt) + +using System; +using System.Collections.Generic; +using System.Text; + +namespace Ricciolo.StylesExplorer.MarkupReflection +{ + /// + /// Interface rappresenting a DotNet type + /// + public interface IType + { + string AssemblyQualifiedName { get; } + bool IsSubclassOf(IType type); + bool Equals(IType type); + } +} diff --git a/ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/ITypeResolver.cs b/ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/ITypeResolver.cs new file mode 100644 index 000000000..71e802a61 --- /dev/null +++ b/ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/ITypeResolver.cs @@ -0,0 +1,15 @@ +// Copyright (c) Cristian Civera (cristian@aspitalia.com) +// This code is distributed under the MS-PL (for details please see \doc\MS-PL.txt) + +using System; +using System.Collections.Generic; +using System.Text; + +namespace Ricciolo.StylesExplorer.MarkupReflection +{ + public interface ITypeResolver + { + IType GetTypeByAssemblyQualifiedName(string name); + IDependencyPropertyDescriptor GetDependencyPropertyDescriptor(string name, IType ownerType, IType targetType); + } +} diff --git a/ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/KnownInfo.cs b/ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/KnownInfo.cs new file mode 100644 index 000000000..e58762f41 --- /dev/null +++ b/ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/KnownInfo.cs @@ -0,0 +1,1319 @@ +// Copyright (c) Cristian Civera (cristian@aspitalia.com) +// This code is distributed under the MS-PL (for details please see \doc\MS-PL.txt) + +using System; +using System.Collections; +using System.Collections.Generic; + +namespace Ricciolo.StylesExplorer.MarkupReflection +{ + public class KnownInfo + { + internal TypeDeclaration[] KnownTypeTable = null; + internal PropertyDeclaration[] KnownPropertyTable = null; + internal static String[] KnownAssemblyTable = null; + internal Hashtable KnownResourceTable = new Hashtable(); + + #region Initialize + + static KnownInfo() + { + KnownAssemblyTable = new string[5]; + KnownAssemblyTable[0] = + "PresentationFramework, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"; + KnownAssemblyTable[1] = + "PresentationCore, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"; + KnownAssemblyTable[2] = "mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"; + KnownAssemblyTable[3] = "System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"; + KnownAssemblyTable[4] = "WindowBase, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"; + } + + public KnownInfo() : this(null) + { + } + + public KnownInfo(ITypeResolver resolver) + { + KnownAssemblyTable = new string[5]; + KnownAssemblyTable[0] = "PresentationFramework, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"; + KnownAssemblyTable[1] = "PresentationCore, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"; + KnownAssemblyTable[2] = "mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"; + KnownAssemblyTable[3] = "System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"; + KnownAssemblyTable[4] = "WindowBase, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"; + + KnownTypeTable = new TypeDeclaration[760]; + KnownTypeTable[0] = new TypeDeclaration(resolver, string.Empty, string.Empty, 0); + KnownTypeTable[1] = new TypeDeclaration(resolver, "AccessText", "System.Windows.Controls", 0); + KnownTypeTable[2] = new TypeDeclaration(resolver, "AdornedElementPlaceholder", "System.Windows.Controls", 0); + KnownTypeTable[3] = new TypeDeclaration(resolver, "Adorner", "System.Windows.Documents", 0); + KnownTypeTable[4] = new TypeDeclaration(resolver, "AdornerDecorator", "System.Windows.Documents", 0); + KnownTypeTable[5] = new TypeDeclaration(resolver, "AdornerLayer", "System.Windows.Documents", 0); + KnownTypeTable[6] = new TypeDeclaration(resolver, "AffineTransform3D", "System.Windows.Media.Media3D", 1); + KnownTypeTable[7] = new TypeDeclaration(resolver, "AmbientLight", "System.Windows.Media.Media3D", 1); + KnownTypeTable[8] = new TypeDeclaration(resolver, "AnchoredBlock", "System.Windows.Documents", 0); + KnownTypeTable[9] = new TypeDeclaration(resolver, "Animatable", "System.Windows.Media.Animaton", 1); + KnownTypeTable[10] = new TypeDeclaration(resolver, "AnimationClock", "System.Windows.Media.Animation", 1); + KnownTypeTable[11] = new TypeDeclaration(resolver, "AnimationTimeline", "System.Windows.Media.Animation", 1); + KnownTypeTable[12] = new TypeDeclaration(resolver, "Application", "System.Net.Mime", 3); + KnownTypeTable[13] = new TypeDeclaration(resolver, "ArcSegment", "System.Windows.Media", 1); + KnownTypeTable[14] = new TypeDeclaration(resolver, "ArrayExtension", "System.Windows.Markup", 0); + KnownTypeTable[15] = new TypeDeclaration(resolver, "AxisAngleRotation3D", "System.Windows.Media.Media3D", 1); + KnownTypeTable[0x10] = new TypeDeclaration(resolver, "BaseIListConverter", "System.Windows.Media.Converters", 1); + KnownTypeTable[0x11] = new TypeDeclaration(resolver, "BeginStoryboard", "System.Windows.Media.Animation", 0); + KnownTypeTable[0x12] = new TypeDeclaration(resolver, "BevelBitmapEffect", "System.Windows.Media.Effects", 1); + KnownTypeTable[0x13] = new TypeDeclaration(resolver, "BezierSegment", "System.Windows.Media", 1); + KnownTypeTable[20] = new TypeDeclaration(resolver, "Binding", "System.Windows.Data", 0, true); + KnownTypeTable[0x15] = new TypeDeclaration(resolver, "BindingBase", "System.Windows.Data", 0); + KnownTypeTable[0x16] = new TypeDeclaration(resolver, "BindingExpression", "System.Windows.Data", 0); + KnownTypeTable[0x17] = new TypeDeclaration(resolver, "BindingExpressionBase", "System.Windows.Data", 0); + KnownTypeTable[0x18] = new TypeDeclaration(resolver, "BindingListCollectionView", "System.Windows.Data", 0); + KnownTypeTable[0x19] = new TypeDeclaration(resolver, "BitmapDecoder", "System.Windows.Media.Imaging", 1); + KnownTypeTable[0x1a] = new TypeDeclaration(resolver, "BitmapEffect", "System.Windows.Media.Effects", 1); + KnownTypeTable[0x1b] = new TypeDeclaration(resolver, "BitmapEffectCollection", "System.Windows.Media.Effects", 1); + KnownTypeTable[0x1c] = new TypeDeclaration(resolver, "BitmapEffectGroup", "System.Windows.Media.Effects", 1); + KnownTypeTable[0x1d] = new TypeDeclaration(resolver, "BitmapEffectInput", "System.Windows.Media.Effects", 1); + KnownTypeTable[30] = new TypeDeclaration(resolver, "BitmapEncoder", "System.Windows.Media.Imaging", 1); + KnownTypeTable[0x1f] = new TypeDeclaration(resolver, "BitmapFrame", "System.Windows.Media.Imaging", 1); + KnownTypeTable[0x20] = new TypeDeclaration(resolver, "BitmapImage", "System.Windows.Media.Imaging", 1); + KnownTypeTable[0x21] = new TypeDeclaration(resolver, "BitmapMetadata", "System.Windows.Media.Imaging", 1); + KnownTypeTable[0x22] = new TypeDeclaration(resolver, "BitmapPalette", "System.Windows.Media.Imaging", 1); + KnownTypeTable[0x23] = new TypeDeclaration(resolver, "BitmapSource", "System.Windows.Media.Imaging", 1); + KnownTypeTable[0x24] = new TypeDeclaration(resolver, "Block", "System.Windows.Documents", 0); + KnownTypeTable[0x25] = new TypeDeclaration(resolver, "BlockUIContainer", "System.Windows.Documents", 0); + KnownTypeTable[0x26] = new TypeDeclaration(resolver, "BlurBitmapEffect", "System.Windows.Media.Effects", 1); + KnownTypeTable[0x27] = new TypeDeclaration(resolver, "BmpBitmapDecoder", "System.Windows.Media.Imaging", 1); + KnownTypeTable[40] = new TypeDeclaration(resolver, "BmpBitmapEncoder", "System.Windows.Media.Imaging", 1); + KnownTypeTable[0x29] = new TypeDeclaration(resolver, "Bold", "System.Windows.Documents", 0); + KnownTypeTable[0x2b] = new TypeDeclaration(resolver, "Boolean", "System", 2); + KnownTypeTable[0x2c] = new TypeDeclaration(resolver, "BooleanAnimationBase", "System.Windows.Media.Animation", 1); + KnownTypeTable[0x2d] = new TypeDeclaration(resolver, "BooleanAnimationUsingKeyFrames", "System.Windows.Media.Animation", 1); + KnownTypeTable[0x2e] = new TypeDeclaration(resolver, "BooleanConverter", "System.ComponentModel", 3); + KnownTypeTable[0x2f] = new TypeDeclaration(resolver, "BooleanKeyFrame", "System.Windows.Media.Animation", 1); + KnownTypeTable[0x30] = new TypeDeclaration(resolver, "BooleanKeyFrameCollection", "System.Windows.Media.Animation", 1); + KnownTypeTable[0x31] = new TypeDeclaration(resolver, "BooleanToVisibilityConverter", "System.Windows.Controls", 0); + KnownTypeTable[0x2a] = new TypeDeclaration(resolver, "BoolIListConverter", "System.Windows.Media.Converters", 1); + KnownTypeTable[50] = new TypeDeclaration(resolver, "Border", "System.Windows.Controls", 0); + KnownTypeTable[0x33] = new TypeDeclaration(resolver, "BorderGapMaskConverter", "System.Windows.Controls", 0); + KnownTypeTable[0x34] = new TypeDeclaration(resolver, "Brush", "System.Windows.Media", 1); + KnownTypeTable[0x35] = new TypeDeclaration(resolver, "BrushConverter", "System.Windows.Media", 1); + KnownTypeTable[0x36] = new TypeDeclaration(resolver, "BulletDecorator", "System.Windows.Controls.Primitives", 0); + KnownTypeTable[0x37] = new TypeDeclaration(resolver, "Button", "System.Windows.Controls", 0); + KnownTypeTable[0x38] = new TypeDeclaration(resolver, "ButtonBase", "System.Windows.Controls.Primitives", 0); + KnownTypeTable[0x39] = new TypeDeclaration(resolver, "Byte", "System", 2); + KnownTypeTable[0x3a] = new TypeDeclaration(resolver, "ByteAnimation", "System.Windows.Media.Animation", 1); + KnownTypeTable[0x3b] = new TypeDeclaration(resolver, "ByteAnimationBase", "System.Windows.Media.Animation", 1); + KnownTypeTable[60] = new TypeDeclaration(resolver, "ByteAnimationUsingKeyFrames", "System.Windows.Media.Animation", 1); + KnownTypeTable[0x3d] = new TypeDeclaration(resolver, "ByteConverter", "System.ComponentModel", 3); + KnownTypeTable[0x3e] = new TypeDeclaration(resolver, "ByteKeyFrame", "System.Windows.Media.Animation", 1); + KnownTypeTable[0x3f] = new TypeDeclaration(resolver, "ByteKeyFrameCollection", "System.Windows.Media.Animation", 1); + KnownTypeTable[0x40] = new TypeDeclaration(resolver, "CachedBitmap", "System.Windows.Media.Imaging", 1); + KnownTypeTable[0x41] = new TypeDeclaration(resolver, "Camera", "System.Windows.Media.Media3D", 1); + KnownTypeTable[0x42] = new TypeDeclaration(resolver, "Canvas", "System.Windows.Controls", 0); + KnownTypeTable[0x43] = new TypeDeclaration(resolver, "Char", "System", 2); + KnownTypeTable[0x44] = new TypeDeclaration(resolver, "CharAnimationBase", "System.Windows.Media.Animation", 1); + KnownTypeTable[0x45] = new TypeDeclaration(resolver, "CharAnimationUsingKeyFrames", "System.Windows.Media.Animation", 1); + KnownTypeTable[70] = new TypeDeclaration(resolver, "CharConverter", "System.ComponentModel", 3); + KnownTypeTable[0x47] = new TypeDeclaration(resolver, "CharIListConverter", "System.Windows.Media.Converters", 1); + KnownTypeTable[0x48] = new TypeDeclaration(resolver, "CharKeyFrame", "System.Windows.Media.Animation", 1); + KnownTypeTable[0x49] = new TypeDeclaration(resolver, "CharKeyFrameCollection", "System.Windows.Media.Animation", 1); + KnownTypeTable[0x4a] = new TypeDeclaration(resolver, "CheckBox", "System.Windows.Controls", 0); + KnownTypeTable[0x4b] = new TypeDeclaration(resolver, "Clock", "System.Windows.Media.Animation", 1); + KnownTypeTable[0x4c] = new TypeDeclaration(resolver, "ClockController", "System.Windows.Media.Animation", 1); + KnownTypeTable[0x4d] = new TypeDeclaration(resolver, "ClockGroup", "System.Windows.Media.Animation", 1); + KnownTypeTable[0x4e] = new TypeDeclaration(resolver, "CollectionContainer", "System.Windows.Data", 0); + KnownTypeTable[0x4f] = new TypeDeclaration(resolver, "CollectionView", "System.Windows.Data", 0); + KnownTypeTable[80] = new TypeDeclaration(resolver, "CollectionViewSource", "System.Windows.Data", 0); + KnownTypeTable[0x51] = new TypeDeclaration(resolver, "Color", "Microsoft.Win32", 2); + KnownTypeTable[0x52] = new TypeDeclaration(resolver, "ColorAnimation", "System.Windows.Media.Animation", 1); + KnownTypeTable[0x53] = new TypeDeclaration(resolver, "ColorAnimationBase", "System.Windows.Media.Animation", 1); + KnownTypeTable[0x54] = new TypeDeclaration(resolver, "ColorAnimationUsingKeyFrames", "System.Windows.Media.Animation", 1); + KnownTypeTable[0x55] = new TypeDeclaration(resolver, "ColorConvertedBitmap", "System.Windows.Media.Imaging", 1); + KnownTypeTable[0x56] = new TypeDeclaration(resolver, "ColorConvertedBitmapExtension", "System.Windows", 0); + KnownTypeTable[0x57] = new TypeDeclaration(resolver, "ColorConverter", "System.Windows.Media", 1); + KnownTypeTable[0x58] = new TypeDeclaration(resolver, "ColorKeyFrame", "System.Windows.Media.Animation", 1); + KnownTypeTable[0x59] = new TypeDeclaration(resolver, "ColorKeyFrameCollection", "System.Windows.Media.Animation", 1); + KnownTypeTable[90] = new TypeDeclaration(resolver, "ColumnDefinition", "System.Windows.Controls", 0); + KnownTypeTable[0x5b] = new TypeDeclaration(resolver, "CombinedGeometry", "System.Windows.Media", 1); + KnownTypeTable[0x5c] = new TypeDeclaration(resolver, "ComboBox", "System.Windows.Controls", 0); + KnownTypeTable[0x5d] = new TypeDeclaration(resolver, "ComboBoxItem", "System.Windows.Controls", 0); + KnownTypeTable[0x5e] = new TypeDeclaration(resolver, "CommandConverter", "System.Windows.Input", 0); + KnownTypeTable[0x5f] = new TypeDeclaration(resolver, "ComponentResourceKey", "System.Windows", 0, true); + KnownTypeTable[0x60] = new TypeDeclaration(resolver, "ComponentResourceKeyConverter", "System.Windows.Markup", 0); + KnownTypeTable[0x61] = new TypeDeclaration(resolver, "CompositionTarget", "System.Windows.Media", 1); + KnownTypeTable[0x62] = new TypeDeclaration(resolver, "Condition", "System.Windows", 0); + KnownTypeTable[0x63] = new TypeDeclaration(resolver, "ContainerVisual", "System.Windows.Media", 1); + KnownTypeTable[100] = new TypeDeclaration(resolver, "ContentControl", "System.Windows.Controls", 0); + KnownTypeTable[0x65] = new TypeDeclaration(resolver, "ContentElement", "System.Windows", 1); + KnownTypeTable[0x66] = new TypeDeclaration(resolver, "ContentPresenter", "System.Windows.Controls", 0); + KnownTypeTable[0x67] = new TypeDeclaration(resolver, "ContentPropertyAttribute", "System.Windows.Markup", 4); + KnownTypeTable[0x68] = new TypeDeclaration(resolver, "ContentWrapperAttribute", "System.Windows.Markup", 4); + KnownTypeTable[0x69] = new TypeDeclaration(resolver, "ContextMenu", "System.Windows.Controls", 0); + KnownTypeTable[0x6a] = new TypeDeclaration(resolver, "ContextMenuService", "System.Windows.Controls", 0); + KnownTypeTable[0x6b] = new TypeDeclaration(resolver, "Control", "System.Windows.Controls", 0); + KnownTypeTable[0x6d] = new TypeDeclaration(resolver, "ControllableStoryboardAction", "System.Windows.Media.Animation", 0); + KnownTypeTable[0x6c] = new TypeDeclaration(resolver, "ControlTemplate", "System.Windows.Controls", 0); + KnownTypeTable[110] = new TypeDeclaration(resolver, "CornerRadius", "System.Windows", 0); + KnownTypeTable[0x6f] = new TypeDeclaration(resolver, "CornerRadiusConverter", "System.Windows", 0); + KnownTypeTable[0x70] = new TypeDeclaration(resolver, "CroppedBitmap", "System.Windows.Media.Imaging", 1); + KnownTypeTable[0x71] = new TypeDeclaration(resolver, "CultureInfo", "System.Globalization", 2); + KnownTypeTable[0x72] = new TypeDeclaration(resolver, "CultureInfoConverter", "System.ComponentModel", 3); + KnownTypeTable[0x73] = new TypeDeclaration(resolver, "CultureInfoIetfLanguageTagConverter", "System.Windows", 1); + KnownTypeTable[0x74] = new TypeDeclaration(resolver, "Cursor", "System.Windows.Input", 1); + KnownTypeTable[0x75] = new TypeDeclaration(resolver, "CursorConverter", "System.Windows.Input", 1); + KnownTypeTable[0x76] = new TypeDeclaration(resolver, "DashStyle", "System.Windows.Media", 1); + KnownTypeTable[0x77] = new TypeDeclaration(resolver, "DataChangedEventManager", "System.Windows.Data", 0); + KnownTypeTable[120] = new TypeDeclaration(resolver, "DataTemplate", "System.Windows", 0); + KnownTypeTable[0x79] = new TypeDeclaration(resolver, "DataTemplateKey", "System.Windows", 0, true); + KnownTypeTable[0x7a] = new TypeDeclaration(resolver, "DataTrigger", "System.Windows", 0); + KnownTypeTable[0x7b] = new TypeDeclaration(resolver, "DateTime", "System", 2); + KnownTypeTable[0x7c] = new TypeDeclaration(resolver, "DateTimeConverter", "System.ComponentModel", 3); + KnownTypeTable[0x7d] = new TypeDeclaration(resolver, "DateTimeConverter2", "System.Windows.Markup", 4); + KnownTypeTable[0x7e] = new TypeDeclaration(resolver, "Decimal", "System", 2); + KnownTypeTable[0x7f] = new TypeDeclaration(resolver, "DecimalAnimation", "System.Windows.Media.Animation", 1); + KnownTypeTable[0x80] = new TypeDeclaration(resolver, "DecimalAnimationBase", "System.Windows.Media.Animation", 1); + KnownTypeTable[0x81] = new TypeDeclaration(resolver, "DecimalAnimationUsingKeyFrames", "System.Windows.Media.Animation", 1); + KnownTypeTable[130] = new TypeDeclaration(resolver, "DecimalConverter", "System.ComponentModel", 3); + KnownTypeTable[0x83] = new TypeDeclaration(resolver, "DecimalKeyFrame", "System.Windows.Media.Animation", 1); + KnownTypeTable[0x84] = new TypeDeclaration(resolver, "DecimalKeyFrameCollection", "System.Windows.Media.Animation", 1); + KnownTypeTable[0x85] = new TypeDeclaration(resolver, "Decorator", "System.Windows.Controls", 0); + KnownTypeTable[0x86] = new TypeDeclaration(resolver, "DefinitionBase", "System.Windows.Controls", 0); + KnownTypeTable[0x87] = new TypeDeclaration(resolver, "DependencyObject", "System.Windows", 4); + KnownTypeTable[0x88] = new TypeDeclaration(resolver, "DependencyProperty", "System.Windows", 4); + KnownTypeTable[0x89] = new TypeDeclaration(resolver, "DependencyPropertyConverter", "System.Windows.Markup", 0); + KnownTypeTable[0x8a] = new TypeDeclaration(resolver, "DialogResultConverter", "System.Windows", 0); + KnownTypeTable[0x8b] = new TypeDeclaration(resolver, "DiffuseMaterial", "System.Windows.Media.Media3D", 1); + KnownTypeTable[140] = new TypeDeclaration(resolver, "DirectionalLight", "System.Windows.Media.Media3D", 1); + KnownTypeTable[0x8d] = new TypeDeclaration(resolver, "DiscreteBooleanKeyFrame", "System.Windows.Media.Animation", 1); + KnownTypeTable[0x8e] = new TypeDeclaration(resolver, "DiscreteByteKeyFrame", "System.Windows.Media.Animation", 1); + KnownTypeTable[0x8f] = new TypeDeclaration(resolver, "DiscreteCharKeyFrame", "System.Windows.Media.Animation", 1); + KnownTypeTable[0x90] = new TypeDeclaration(resolver, "DiscreteColorKeyFrame", "System.Windows.Media.Animation", 1); + KnownTypeTable[0x91] = new TypeDeclaration(resolver, "DiscreteDecimalKeyFrame", "System.Windows.Media.Animation", 1); + KnownTypeTable[0x92] = new TypeDeclaration(resolver, "DiscreteDoubleKeyFrame", "System.Windows.Media.Animation", 1); + KnownTypeTable[0x93] = new TypeDeclaration(resolver, "DiscreteInt16KeyFrame", "System.Windows.Media.Animation", 1); + KnownTypeTable[0x94] = new TypeDeclaration(resolver, "DiscreteInt32KeyFrame", "System.Windows.Media.Animation", 1); + KnownTypeTable[0x95] = new TypeDeclaration(resolver, "DiscreteInt64KeyFrame", "System.Windows.Media.Animation", 1); + KnownTypeTable[150] = new TypeDeclaration(resolver, "DiscreteMatrixKeyFrame", "System.Windows.Media.Animation", 1); + KnownTypeTable[0x97] = new TypeDeclaration(resolver, "DiscreteObjectKeyFrame", "System.Windows.Media.Animation", 1); + KnownTypeTable[0x98] = new TypeDeclaration(resolver, "DiscretePoint3DKeyFrame", "System.Windows.Media.Animation", 1); + KnownTypeTable[0x99] = new TypeDeclaration(resolver, "DiscretePointKeyFrame", "System.Windows.Media.Animation", 1); + KnownTypeTable[0x9a] = new TypeDeclaration(resolver, "DiscreteQuaternionKeyFrame", "System.Windows.Media.Animation", 1); + KnownTypeTable[0x9b] = new TypeDeclaration(resolver, "DiscreteRectKeyFrame", "System.Windows.Media.Animation", 1); + KnownTypeTable[0x9c] = new TypeDeclaration(resolver, "DiscreteRotation3DKeyFrame", "System.Windows.Media.Animation", 1); + KnownTypeTable[0x9d] = new TypeDeclaration(resolver, "DiscreteSingleKeyFrame", "System.Windows.Media.Animation", 1); + KnownTypeTable[0x9e] = new TypeDeclaration(resolver, "DiscreteSizeKeyFrame", "System.Windows.Media.Animation", 1); + KnownTypeTable[0x9f] = new TypeDeclaration(resolver, "DiscreteStringKeyFrame", "System.Windows.Media.Animation", 1); + KnownTypeTable[160] = new TypeDeclaration(resolver, "DiscreteThicknessKeyFrame", "System.Windows.Media.Animation", 0); + KnownTypeTable[0xa1] = new TypeDeclaration(resolver, "DiscreteVector3DKeyFrame", "System.Windows.Media.Animation", 1); + KnownTypeTable[0xa2] = new TypeDeclaration(resolver, "DiscreteVectorKeyFrame", "System.Windows.Media.Animation", 1); + KnownTypeTable[0xa3] = new TypeDeclaration(resolver, "DockPanel", "System.Windows.Controls", 0); + KnownTypeTable[0xa4] = new TypeDeclaration(resolver, "DocumentPageView", "System.Windows.Controls.Primitives", 0); + KnownTypeTable[0xa5] = new TypeDeclaration(resolver, "DocumentReference", "System.Windows.Documents", 0); + KnownTypeTable[0xa6] = new TypeDeclaration(resolver, "DocumentViewer", "System.Windows.Controls", 0); + KnownTypeTable[0xa7] = new TypeDeclaration(resolver, "DocumentViewerBase", "System.Windows.Controls.Primitives", 0); + KnownTypeTable[0xa8] = new TypeDeclaration(resolver, "Double", "System", 2); + KnownTypeTable[0xa9] = new TypeDeclaration(resolver, "DoubleAnimation", "System.Windows.Media.Animation", 1); + KnownTypeTable[170] = new TypeDeclaration(resolver, "DoubleAnimationBase", "System.Windows.Media.Animation", 1); + KnownTypeTable[0xab] = new TypeDeclaration(resolver, "DoubleAnimationUsingKeyFrames", "System.Windows.Media.Animation", 1); + KnownTypeTable[0xac] = new TypeDeclaration(resolver, "DoubleAnimationUsingPath", "System.Windows.Media.Animation", 1); + KnownTypeTable[0xad] = new TypeDeclaration(resolver, "DoubleCollection", "System.Windows.Media", 1); + KnownTypeTable[0xae] = new TypeDeclaration(resolver, "DoubleCollectionConverter", "System.Windows.Media", 1); + KnownTypeTable[0xaf] = new TypeDeclaration(resolver, "DoubleConverter", "System.ComponentModel", 3); + KnownTypeTable[0xb0] = new TypeDeclaration(resolver, "DoubleIListConverter", "System.Windows.Media.Converters", 1); + KnownTypeTable[0xb1] = new TypeDeclaration(resolver, "DoubleKeyFrame", "System.Windows.Media.Animation", 1); + KnownTypeTable[0xb2] = new TypeDeclaration(resolver, "DoubleKeyFrameCollection", "System.Windows.Media.Animation", 1); + KnownTypeTable[0xb3] = new TypeDeclaration(resolver, "Drawing", "System.Windows.Media", 1); + KnownTypeTable[180] = new TypeDeclaration(resolver, "DrawingBrush", "System.Windows.Media", 1); + KnownTypeTable[0xb5] = new TypeDeclaration(resolver, "DrawingCollection", "System.Windows.Media", 1); + KnownTypeTable[0xb6] = new TypeDeclaration(resolver, "DrawingContext", "System.Windows.Media", 1); + KnownTypeTable[0xb7] = new TypeDeclaration(resolver, "DrawingGroup", "System.Windows.Media", 1); + KnownTypeTable[0xb8] = new TypeDeclaration(resolver, "DrawingImage", "System.Windows.Media", 1); + KnownTypeTable[0xb9] = new TypeDeclaration(resolver, "DrawingVisual", "System.Windows.Media", 1); + KnownTypeTable[0xba] = new TypeDeclaration(resolver, "DropShadowBitmapEffect", "System.Windows.Media.Effects", 1); + KnownTypeTable[0xbb] = new TypeDeclaration(resolver, "Duration", "System.Windows", 1); + KnownTypeTable[0xbc] = new TypeDeclaration(resolver, "DurationConverter", "System.Windows", 1); + KnownTypeTable[0xbd] = new TypeDeclaration(resolver, "DynamicResourceExtension", "System.Windows", 0, true); + KnownTypeTable[190] = new TypeDeclaration(resolver, "DynamicResourceExtensionConverter", "System.Windows", 0); + KnownTypeTable[0xbf] = new TypeDeclaration(resolver, "Ellipse", "System.Windows.Shapes", 0); + KnownTypeTable[0xc0] = new TypeDeclaration(resolver, "EllipseGeometry", "System.Windows.Media", 1); + KnownTypeTable[0xc1] = new TypeDeclaration(resolver, "EmbossBitmapEffect", "System.Windows.Media.Effects", 1); + KnownTypeTable[0xc2] = new TypeDeclaration(resolver, "EmissiveMaterial", "System.Windows.Media.Media3D", 1); + KnownTypeTable[0xc3] = new TypeDeclaration(resolver, "EnumConverter", "System.ComponentModel", 3); + KnownTypeTable[0xc4] = new TypeDeclaration(resolver, "EventManager", "System.Windows", 1); + KnownTypeTable[0xc5] = new TypeDeclaration(resolver, "EventSetter", "System.Windows", 0); + KnownTypeTable[0xc6] = new TypeDeclaration(resolver, "EventTrigger", "System.Windows", 0); + KnownTypeTable[0xc7] = new TypeDeclaration(resolver, "Expander", "System.Windows.Controls", 0); + KnownTypeTable[200] = new TypeDeclaration(resolver, "Expression", "System.Windows", 4); + KnownTypeTable[0xc9] = new TypeDeclaration(resolver, "ExpressionConverter", "System.Windows", 4); + KnownTypeTable[0xca] = new TypeDeclaration(resolver, "Figure", "System.Windows.Documents", 0); + KnownTypeTable[0xcb] = new TypeDeclaration(resolver, "FigureLength", "System.Windows", 0); + KnownTypeTable[0xcc] = new TypeDeclaration(resolver, "FigureLengthConverter", "System.Windows", 0); + KnownTypeTable[0xcd] = new TypeDeclaration(resolver, "FixedDocument", "System.Windows.Documents", 0); + KnownTypeTable[0xce] = new TypeDeclaration(resolver, "FixedDocumentSequence", "System.Windows.Documents", 0); + KnownTypeTable[0xcf] = new TypeDeclaration(resolver, "FixedPage", "System.Windows.Documents", 0); + KnownTypeTable[0xd0] = new TypeDeclaration(resolver, "Floater", "System.Windows.Documents", 0); + KnownTypeTable[0xd1] = new TypeDeclaration(resolver, "FlowDocument", "System.Windows.Documents", 0); + KnownTypeTable[210] = new TypeDeclaration(resolver, "FlowDocumentPageViewer", "System.Windows.Controls", 0); + KnownTypeTable[0xd3] = new TypeDeclaration(resolver, "FlowDocumentReader", "System.Windows.Controls", 0); + KnownTypeTable[0xd4] = new TypeDeclaration(resolver, "FlowDocumentScrollViewer", "System.Windows.Controls", 0); + KnownTypeTable[0xd5] = new TypeDeclaration(resolver, "FocusManager", "System.Windows.Input", 1); + KnownTypeTable[0xd6] = new TypeDeclaration(resolver, "FontFamily", "System.Windows.Media", 1); + KnownTypeTable[0xd7] = new TypeDeclaration(resolver, "FontFamilyConverter", "System.Windows.Media", 1); + KnownTypeTable[0xd8] = new TypeDeclaration(resolver, "FontSizeConverter", "System.Windows", 0); + KnownTypeTable[0xd9] = new TypeDeclaration(resolver, "FontStretch", "System.Windows", 1); + KnownTypeTable[0xda] = new TypeDeclaration(resolver, "FontStretchConverter", "System.Windows", 1); + KnownTypeTable[0xdb] = new TypeDeclaration(resolver, "FontStyle", "System.Windows", 1); + KnownTypeTable[220] = new TypeDeclaration(resolver, "FontStyleConverter", "System.Windows", 1); + KnownTypeTable[0xdd] = new TypeDeclaration(resolver, "FontWeight", "System.Windows", 1); + KnownTypeTable[0xde] = new TypeDeclaration(resolver, "FontWeightConverter", "System.Windows", 1); + KnownTypeTable[0xdf] = new TypeDeclaration(resolver, "FormatConvertedBitmap", "System.Windows.Media.Imaging", 1); + KnownTypeTable[0xe0] = new TypeDeclaration(resolver, "Frame", "System.Windows.Controls", 0); + KnownTypeTable[0xe1] = new TypeDeclaration(resolver, "FrameworkContentElement", "System.Windows", 0); + KnownTypeTable[0xe2] = new TypeDeclaration(resolver, "FrameworkElement", "System.Windows", 0); + KnownTypeTable[0xe3] = new TypeDeclaration(resolver, "FrameworkElementFactory", "System.Windows", 0); + KnownTypeTable[0xe4] = new TypeDeclaration(resolver, "FrameworkPropertyMetadata", "System.Windows", 0); + KnownTypeTable[0xe5] = new TypeDeclaration(resolver, "FrameworkPropertyMetadataOptions", "System.Windows", 0); + KnownTypeTable[230] = new TypeDeclaration(resolver, "FrameworkRichTextComposition", "System.Windows.Documents", 0); + KnownTypeTable[0xe7] = new TypeDeclaration(resolver, "FrameworkTemplate", "System.Windows", 0); + KnownTypeTable[0xe8] = new TypeDeclaration(resolver, "FrameworkTextComposition", "System.Windows.Documents", 0); + KnownTypeTable[0xe9] = new TypeDeclaration(resolver, "Freezable", "System.Windows", 4); + KnownTypeTable[0xea] = new TypeDeclaration(resolver, "GeneralTransform", "System.Windows.Media", 1); + KnownTypeTable[0xeb] = new TypeDeclaration(resolver, "GeneralTransformCollection", "System.Windows.Media", 1); + KnownTypeTable[0xec] = new TypeDeclaration(resolver, "GeneralTransformGroup", "System.Windows.Media", 1); + KnownTypeTable[0xed] = new TypeDeclaration(resolver, "Geometry", "System.Windows.Media", 1); + KnownTypeTable[0xee] = new TypeDeclaration(resolver, "Geometry3D", "System.Windows.Media.Media3D", 1); + KnownTypeTable[0xef] = new TypeDeclaration(resolver, "GeometryCollection", "System.Windows.Media", 1); + KnownTypeTable[240] = new TypeDeclaration(resolver, "GeometryConverter", "System.Windows.Media", 1); + KnownTypeTable[0xf1] = new TypeDeclaration(resolver, "GeometryDrawing", "System.Windows.Media", 1); + KnownTypeTable[0xf2] = new TypeDeclaration(resolver, "GeometryGroup", "System.Windows.Media", 1); + KnownTypeTable[0xf3] = new TypeDeclaration(resolver, "GeometryModel3D", "System.Windows.Media.Media3D", 1); + KnownTypeTable[0xf4] = new TypeDeclaration(resolver, "GestureRecognizer", "System.Windows.Ink", 1); + KnownTypeTable[0xf5] = new TypeDeclaration(resolver, "GifBitmapDecoder", "System.Windows.Media.Imaging", 1); + KnownTypeTable[0xf6] = new TypeDeclaration(resolver, "GifBitmapEncoder", "System.Windows.Media.Imaging", 1); + KnownTypeTable[0xf7] = new TypeDeclaration(resolver, "GlyphRun", "System.Windows.Media", 1); + KnownTypeTable[0xf8] = new TypeDeclaration(resolver, "GlyphRunDrawing", "System.Windows.Media", 1); + KnownTypeTable[250] = new TypeDeclaration(resolver, "Glyphs", "System.Windows.Documents", 0); + KnownTypeTable[0xf9] = new TypeDeclaration(resolver, "GlyphTypeface", "System.Windows.Media", 1); + KnownTypeTable[0xfb] = new TypeDeclaration(resolver, "GradientBrush", "System.Windows.Media", 1); + KnownTypeTable[0xfc] = new TypeDeclaration(resolver, "GradientStop", "System.Windows.Media", 1); + KnownTypeTable[0xfd] = new TypeDeclaration(resolver, "GradientStopCollection", "System.Windows.Media", 1); + KnownTypeTable[0xfe] = new TypeDeclaration(resolver, "Grid", "System.Windows.Controls", 0); + KnownTypeTable[0xff] = new TypeDeclaration(resolver, "GridLength", "System.Windows", 0); + KnownTypeTable[0x100] = new TypeDeclaration(resolver, "GridLengthConverter", "System.Windows", 0); + KnownTypeTable[0x101] = new TypeDeclaration(resolver, "GridSplitter", "System.Windows.Controls", 0); + KnownTypeTable[0x102] = new TypeDeclaration(resolver, "GridView", "System.Windows.Controls", 0); + KnownTypeTable[0x103] = new TypeDeclaration(resolver, "GridViewColumn", "System.Windows.Controls", 0); + KnownTypeTable[260] = new TypeDeclaration(resolver, "GridViewColumnHeader", "System.Windows.Controls", 0); + KnownTypeTable[0x105] = new TypeDeclaration(resolver, "GridViewHeaderRowPresenter", "System.Windows.Controls", 0); + KnownTypeTable[0x106] = new TypeDeclaration(resolver, "GridViewRowPresenter", "System.Windows.Controls", 0); + KnownTypeTable[0x107] = new TypeDeclaration(resolver, "GridViewRowPresenterBase", "System.Windows.Controls.Primitives", 0); + KnownTypeTable[0x108] = new TypeDeclaration(resolver, "GroupBox", "System.Windows.Controls", 0); + KnownTypeTable[0x109] = new TypeDeclaration(resolver, "GroupItem", "System.Windows.Controls", 0); + KnownTypeTable[0x10a] = new TypeDeclaration(resolver, "Guid", "System", 2); + KnownTypeTable[0x10b] = new TypeDeclaration(resolver, "GuidConverter", "System.ComponentModel", 3); + KnownTypeTable[0x10c] = new TypeDeclaration(resolver, "GuidelineSet", "System.Windows.Media", 1); + KnownTypeTable[0x10d] = new TypeDeclaration(resolver, "HeaderedContentControl", "System.Windows.Controls", 0); + KnownTypeTable[270] = new TypeDeclaration(resolver, "HeaderedItemsControl", "System.Windows.Controls", 0); + KnownTypeTable[0x10f] = new TypeDeclaration(resolver, "HierarchicalDataTemplate", "System.Windows", 0); + KnownTypeTable[0x110] = new TypeDeclaration(resolver, "HostVisual", "System.Windows.Media", 1); + KnownTypeTable[0x111] = new TypeDeclaration(resolver, "Hyperlink", "System.Windows.Documents", 0); + KnownTypeTable[0x112] = new TypeDeclaration(resolver, "IAddChild", "System.Windows.Markup", 1); + KnownTypeTable[0x113] = new TypeDeclaration(resolver, "IAddChildInternal", "System.Windows.Markup", 1); + KnownTypeTable[0x114] = new TypeDeclaration(resolver, "ICommand", "System.Windows.Input", 1); + KnownTypeTable[0x115] = new TypeDeclaration(resolver, "IComponentConnector", "System.Windows.Markup", 4); + KnownTypeTable[280] = new TypeDeclaration(resolver, "IconBitmapDecoder", "System.Windows.Media.Imaging", 1); + KnownTypeTable[0x119] = new TypeDeclaration(resolver, "Image", "System.Windows.Controls", 0); + KnownTypeTable[0x11a] = new TypeDeclaration(resolver, "ImageBrush", "System.Windows.Media", 1); + KnownTypeTable[0x11b] = new TypeDeclaration(resolver, "ImageDrawing", "System.Windows.Media", 1); + KnownTypeTable[0x11c] = new TypeDeclaration(resolver, "ImageMetadata", "System.Windows.Media", 1); + KnownTypeTable[0x11d] = new TypeDeclaration(resolver, "ImageSource", "System.Windows.Media", 1); + KnownTypeTable[0x11e] = new TypeDeclaration(resolver, "ImageSourceConverter", "System.Windows.Media", 1); + KnownTypeTable[0x116] = new TypeDeclaration(resolver, "INameScope", "System.Windows.Markup", 4); + KnownTypeTable[0x120] = new TypeDeclaration(resolver, "InkCanvas", "System.Windows.Controls", 0); + KnownTypeTable[0x121] = new TypeDeclaration(resolver, "InkPresenter", "System.Windows.Controls", 0); + KnownTypeTable[290] = new TypeDeclaration(resolver, "Inline", "System.Windows.Documents", 0); + KnownTypeTable[0x123] = new TypeDeclaration(resolver, "InlineCollection", "System.Windows.Documents", 0); + KnownTypeTable[0x124] = new TypeDeclaration(resolver, "InlineUIContainer", "System.Windows.Documents", 0); + KnownTypeTable[0x11f] = new TypeDeclaration(resolver, "InPlaceBitmapMetadataWriter", "System.Windows.Media.Imaging", 1); + KnownTypeTable[0x125] = new TypeDeclaration(resolver, "InputBinding", "System.Windows.Input", 1); + KnownTypeTable[0x126] = new TypeDeclaration(resolver, "InputDevice", "System.Windows.Input", 1); + KnownTypeTable[0x127] = new TypeDeclaration(resolver, "InputLanguageManager", "System.Windows.Input", 1); + KnownTypeTable[0x128] = new TypeDeclaration(resolver, "InputManager", "System.Windows.Input", 1); + KnownTypeTable[0x129] = new TypeDeclaration(resolver, "InputMethod", "System.Windows.Input", 1); + KnownTypeTable[0x12a] = new TypeDeclaration(resolver, "InputScope", "System.Windows.Input", 1); + KnownTypeTable[0x12b] = new TypeDeclaration(resolver, "InputScopeConverter", "System.Windows.Input", 1); + KnownTypeTable[300] = new TypeDeclaration(resolver, "InputScopeName", "System.Windows.Input", 1); + KnownTypeTable[0x12d] = new TypeDeclaration(resolver, "InputScopeNameConverter", "System.Windows.Input", 1); + KnownTypeTable[0x12e] = new TypeDeclaration(resolver, "Int16", "System", 2); + KnownTypeTable[0x12f] = new TypeDeclaration(resolver, "Int16Animation", "System.Windows.Media.Animation", 1); + KnownTypeTable[0x130] = new TypeDeclaration(resolver, "Int16AnimationBase", "System.Windows.Media.Animation", 1); + KnownTypeTable[0x131] = new TypeDeclaration(resolver, "Int16AnimationUsingKeyFrames", "System.Windows.Media.Animation", 1); + KnownTypeTable[0x132] = new TypeDeclaration(resolver, "Int16Converter", "System.ComponentModel", 3); + KnownTypeTable[0x133] = new TypeDeclaration(resolver, "Int16KeyFrame", "System.Windows.Media.Animation", 1); + KnownTypeTable[0x134] = new TypeDeclaration(resolver, "Int16KeyFrameCollection", "System.Windows.Media.Animation", 1); + KnownTypeTable[0x135] = new TypeDeclaration(resolver, "Int32", "System", 2); + KnownTypeTable[310] = new TypeDeclaration(resolver, "Int32Animation", "System.Windows.Media.Animation", 1); + KnownTypeTable[0x137] = new TypeDeclaration(resolver, "Int32AnimationBase", "System.Windows.Media.Animation", 1); + KnownTypeTable[0x138] = new TypeDeclaration(resolver, "Int32AnimationUsingKeyFrames", "System.Windows.Media.Animation", 1); + KnownTypeTable[0x139] = new TypeDeclaration(resolver, "Int32Collection", "System.Windows.Media", 1); + KnownTypeTable[0x13a] = new TypeDeclaration(resolver, "Int32CollectionConverter", "System.Windows.Media", 1); + KnownTypeTable[0x13b] = new TypeDeclaration(resolver, "Int32Converter", "System.ComponentModel", 3); + KnownTypeTable[0x13c] = new TypeDeclaration(resolver, "Int32KeyFrame", "System.Windows.Media.Animation", 1); + KnownTypeTable[0x13d] = new TypeDeclaration(resolver, "Int32KeyFrameCollection", "System.Windows.Media.Animation", 1); + KnownTypeTable[0x13e] = new TypeDeclaration(resolver, "Int32Rect", "System.Windows", 4); + KnownTypeTable[0x13f] = new TypeDeclaration(resolver, "Int32RectConverter", "System.Windows", 4); + KnownTypeTable[320] = new TypeDeclaration(resolver, "Int64", "System", 2); + KnownTypeTable[0x141] = new TypeDeclaration(resolver, "Int64Animation", "System.Windows.Media.Animation", 1); + KnownTypeTable[0x142] = new TypeDeclaration(resolver, "Int64AnimationBase", "System.Windows.Media.Animation", 1); + KnownTypeTable[0x143] = new TypeDeclaration(resolver, "Int64AnimationUsingKeyFrames", "System.Windows.Media.Animation", 1); + KnownTypeTable[0x144] = new TypeDeclaration(resolver, "Int64Converter", "System.ComponentModel", 3); + KnownTypeTable[0x145] = new TypeDeclaration(resolver, "Int64KeyFrame", "System.Windows.Media.Animation", 1); + KnownTypeTable[0x146] = new TypeDeclaration(resolver, "Int64KeyFrameCollection", "System.Windows.Media.Animation", 1); + KnownTypeTable[0x117] = new TypeDeclaration(resolver, "IStyleConnector", "System.Windows.Markup", 0); + KnownTypeTable[0x147] = new TypeDeclaration(resolver, "Italic", "System.Windows.Documents", 0); + KnownTypeTable[0x148] = new TypeDeclaration(resolver, "ItemCollection", "System.Windows.Controls", 0); + KnownTypeTable[0x149] = new TypeDeclaration(resolver, "ItemsControl", "System.Windows.Controls", 0); + KnownTypeTable[330] = new TypeDeclaration(resolver, "ItemsPanelTemplate", "System.Windows.Controls", 0); + KnownTypeTable[0x14b] = new TypeDeclaration(resolver, "ItemsPresenter", "System.Windows.Controls", 0); + KnownTypeTable[0x14c] = new TypeDeclaration(resolver, "JournalEntry", "System.Windows.Navigation", 0); + KnownTypeTable[0x14d] = new TypeDeclaration(resolver, "JournalEntryListConverter", "System.Windows.Navigation", 0); + KnownTypeTable[0x14e] = new TypeDeclaration(resolver, "JournalEntryUnifiedViewConverter", "System.Windows.Navigation", 0); + KnownTypeTable[0x14f] = new TypeDeclaration(resolver, "JpegBitmapDecoder", "System.Windows.Media.Imaging", 1); + KnownTypeTable[0x150] = new TypeDeclaration(resolver, "JpegBitmapEncoder", "System.Windows.Media.Imaging", 1); + KnownTypeTable[0x151] = new TypeDeclaration(resolver, "KeyBinding", "System.Windows.Input", 1); + KnownTypeTable[0x159] = new TypeDeclaration(resolver, "KeyboardDevice", "System.Windows.Input", 1); + KnownTypeTable[0x152] = new TypeDeclaration(resolver, "KeyConverter", "System.Windows.Input", 4); + KnownTypeTable[0x153] = new TypeDeclaration(resolver, "KeyGesture", "System.Windows.Input", 1); + KnownTypeTable[340] = new TypeDeclaration(resolver, "KeyGestureConverter", "System.Windows.Input", 1); + KnownTypeTable[0x155] = new TypeDeclaration(resolver, "KeySpline", "System.Windows.Media.Animation", 1); + KnownTypeTable[0x156] = new TypeDeclaration(resolver, "KeySplineConverter", "System.Windows", 1); + KnownTypeTable[0x157] = new TypeDeclaration(resolver, "KeyTime", "System.Windows.Media.Animation", 1); + KnownTypeTable[0x158] = new TypeDeclaration(resolver, "KeyTimeConverter", "System.Windows", 1); + KnownTypeTable[0x15a] = new TypeDeclaration(resolver, "Label", "System.Windows.Controls", 0); + KnownTypeTable[0x15b] = new TypeDeclaration(resolver, "LateBoundBitmapDecoder", "System.Windows.Media.Imaging", 1); + KnownTypeTable[0x15c] = new TypeDeclaration(resolver, "LengthConverter", "System.Windows", 0); + KnownTypeTable[0x15d] = new TypeDeclaration(resolver, "Light", "System.Windows.Media.Media3D", 1); + KnownTypeTable[350] = new TypeDeclaration(resolver, "Line", "System.Windows.Shapes", 0); + KnownTypeTable[0x162] = new TypeDeclaration(resolver, "LinearByteKeyFrame", "System.Windows.Media.Animation", 1); + KnownTypeTable[0x163] = new TypeDeclaration(resolver, "LinearColorKeyFrame", "System.Windows.Media.Animation", 1); + KnownTypeTable[0x164] = new TypeDeclaration(resolver, "LinearDecimalKeyFrame", "System.Windows.Media.Animation", 1); + KnownTypeTable[0x165] = new TypeDeclaration(resolver, "LinearDoubleKeyFrame", "System.Windows.Media.Animation", 1); + KnownTypeTable[0x166] = new TypeDeclaration(resolver, "LinearGradientBrush", "System.Windows.Media", 1); + KnownTypeTable[0x167] = new TypeDeclaration(resolver, "LinearInt16KeyFrame", "System.Windows.Media.Animation", 1); + KnownTypeTable[360] = new TypeDeclaration(resolver, "LinearInt32KeyFrame", "System.Windows.Media.Animation", 1); + KnownTypeTable[0x169] = new TypeDeclaration(resolver, "LinearInt64KeyFrame", "System.Windows.Media.Animation", 1); + KnownTypeTable[0x16a] = new TypeDeclaration(resolver, "LinearPoint3DKeyFrame", "System.Windows.Media.Animation", 1); + KnownTypeTable[0x16b] = new TypeDeclaration(resolver, "LinearPointKeyFrame", "System.Windows.Media.Animation", 1); + KnownTypeTable[0x16c] = new TypeDeclaration(resolver, "LinearQuaternionKeyFrame", "System.Windows.Media.Animation", 1); + KnownTypeTable[0x16d] = new TypeDeclaration(resolver, "LinearRectKeyFrame", "System.Windows.Media.Animation", 1); + KnownTypeTable[0x16e] = new TypeDeclaration(resolver, "LinearRotation3DKeyFrame", "System.Windows.Media.Animation", 1); + KnownTypeTable[0x16f] = new TypeDeclaration(resolver, "LinearSingleKeyFrame", "System.Windows.Media.Animation", 1); + KnownTypeTable[0x170] = new TypeDeclaration(resolver, "LinearSizeKeyFrame", "System.Windows.Media.Animation", 1); + KnownTypeTable[0x171] = new TypeDeclaration(resolver, "LinearThicknessKeyFrame", "System.Windows.Media.Animation", 0); + KnownTypeTable[370] = new TypeDeclaration(resolver, "LinearVector3DKeyFrame", "System.Windows.Media.Animation", 1); + KnownTypeTable[0x173] = new TypeDeclaration(resolver, "LinearVectorKeyFrame", "System.Windows.Media.Animation", 1); + KnownTypeTable[0x15f] = new TypeDeclaration(resolver, "LineBreak", "System.Windows.Documents", 0); + KnownTypeTable[0x160] = new TypeDeclaration(resolver, "LineGeometry", "System.Windows.Media", 1); + KnownTypeTable[0x161] = new TypeDeclaration(resolver, "LineSegment", "System.Windows.Media", 1); + KnownTypeTable[0x174] = new TypeDeclaration(resolver, "List", "System.Windows.Documents", 0); + KnownTypeTable[0x175] = new TypeDeclaration(resolver, "ListBox", "System.Windows.Controls", 0); + KnownTypeTable[0x176] = new TypeDeclaration(resolver, "ListBoxItem", "System.Windows.Controls", 0); + KnownTypeTable[0x177] = new TypeDeclaration(resolver, "ListCollectionView", "System.Windows.Data", 0); + KnownTypeTable[0x178] = new TypeDeclaration(resolver, "ListItem", "System.Windows.Documents", 0); + KnownTypeTable[0x179] = new TypeDeclaration(resolver, "ListView", "System.Windows.Controls", 0); + KnownTypeTable[0x17a] = new TypeDeclaration(resolver, "ListViewItem", "System.Windows.Controls", 0); + KnownTypeTable[0x17b] = new TypeDeclaration(resolver, "Localization", "System.Windows", 0); + KnownTypeTable[380] = new TypeDeclaration(resolver, "LostFocusEventManager", "System.Windows", 0); + KnownTypeTable[0x17d] = new TypeDeclaration(resolver, "MarkupExtension", "System.Windows.Markup", 4); + KnownTypeTable[0x17e] = new TypeDeclaration(resolver, "Material", "System.Windows.Media.Media3D", 1); + KnownTypeTable[0x17f] = new TypeDeclaration(resolver, "MaterialCollection", "System.Windows.Media.Media3D", 1); + KnownTypeTable[0x180] = new TypeDeclaration(resolver, "MaterialGroup", "System.Windows.Media.Media3D", 1); + KnownTypeTable[0x181] = new TypeDeclaration(resolver, "Matrix", "System.Windows.Media", 4); + KnownTypeTable[0x182] = new TypeDeclaration(resolver, "Matrix3D", "System.Windows.Media.Media3D", 1); + KnownTypeTable[0x183] = new TypeDeclaration(resolver, "Matrix3DConverter", "System.Windows.Media.Media3D", 1); + KnownTypeTable[0x184] = new TypeDeclaration(resolver, "MatrixAnimationBase", "System.Windows.Media.Animation", 1); + KnownTypeTable[0x185] = new TypeDeclaration(resolver, "MatrixAnimationUsingKeyFrames", "System.Windows.Media.Animation", 1); + KnownTypeTable[390] = new TypeDeclaration(resolver, "MatrixAnimationUsingPath", "System.Windows.Media.Animation", 1); + KnownTypeTable[0x187] = new TypeDeclaration(resolver, "MatrixCamera", "System.Windows.Media.Media3D", 1); + KnownTypeTable[0x188] = new TypeDeclaration(resolver, "MatrixConverter", "System.Windows.Media", 4); + KnownTypeTable[0x189] = new TypeDeclaration(resolver, "MatrixKeyFrame", "System.Windows.Media.Animation", 1); + KnownTypeTable[0x18a] = new TypeDeclaration(resolver, "MatrixKeyFrameCollection", "System.Windows.Media.Animation", 1); + KnownTypeTable[0x18b] = new TypeDeclaration(resolver, "MatrixTransform", "System.Windows.Media", 1); + KnownTypeTable[0x18c] = new TypeDeclaration(resolver, "MatrixTransform3D", "System.Windows.Media.Media3D", 1); + KnownTypeTable[0x18d] = new TypeDeclaration(resolver, "MediaClock", "System.Windows.Media", 1); + KnownTypeTable[0x18e] = new TypeDeclaration(resolver, "MediaElement", "System.Windows.Controls", 0); + KnownTypeTable[0x18f] = new TypeDeclaration(resolver, "MediaPlayer", "System.Windows.Media", 1); + KnownTypeTable[400] = new TypeDeclaration(resolver, "MediaTimeline", "System.Windows.Media", 1); + KnownTypeTable[0x191] = new TypeDeclaration(resolver, "Menu", "System.Windows.Controls", 0); + KnownTypeTable[0x192] = new TypeDeclaration(resolver, "MenuBase", "System.Windows.Controls.Primitives", 0); + KnownTypeTable[0x193] = new TypeDeclaration(resolver, "MenuItem", "System.Windows.Controls", 0); + KnownTypeTable[0x194] = new TypeDeclaration(resolver, "MenuScrollingVisibilityConverter", "System.Windows.Controls", 0); + KnownTypeTable[0x195] = new TypeDeclaration(resolver, "MeshGeometry3D", "System.Windows.Media.Media3D", 1); + KnownTypeTable[0x196] = new TypeDeclaration(resolver, "Model3D", "System.Windows.Media.Media3D", 1); + KnownTypeTable[0x197] = new TypeDeclaration(resolver, "Model3DCollection", "System.Windows.Media.Media3D", 1); + KnownTypeTable[0x198] = new TypeDeclaration(resolver, "Model3DGroup", "System.Windows.Media.Media3D", 1); + KnownTypeTable[0x199] = new TypeDeclaration(resolver, "ModelVisual3D", "System.Windows.Media.Media3D", 1); + KnownTypeTable[410] = new TypeDeclaration(resolver, "ModifierKeysConverter", "System.Windows.Input", 4); + KnownTypeTable[0x19b] = new TypeDeclaration(resolver, "MouseActionConverter", "System.Windows.Input", 1); + KnownTypeTable[0x19c] = new TypeDeclaration(resolver, "MouseBinding", "System.Windows.Input", 1); + KnownTypeTable[0x19d] = new TypeDeclaration(resolver, "MouseDevice", "System.Windows.Input", 1); + KnownTypeTable[0x19e] = new TypeDeclaration(resolver, "MouseGesture", "System.Windows.Input", 1); + KnownTypeTable[0x19f] = new TypeDeclaration(resolver, "MouseGestureConverter", "System.Windows.Input", 1); + KnownTypeTable[0x1a0] = new TypeDeclaration(resolver, "MultiBinding", "System.Windows.Data", 0, false); + KnownTypeTable[0x1a1] = new TypeDeclaration(resolver, "MultiBindingExpression", "System.Windows.Data", 0); + KnownTypeTable[0x1a2] = new TypeDeclaration(resolver, "MultiDataTrigger", "System.Windows", 0); + KnownTypeTable[0x1a3] = new TypeDeclaration(resolver, "MultiTrigger", "System.Windows", 0); + KnownTypeTable[420] = new TypeDeclaration(resolver, "NameScope", "System.Windows", 0); + KnownTypeTable[0x1a5] = new TypeDeclaration(resolver, "NavigationWindow", "System.Windows.Navigation", 0); + KnownTypeTable[0x1a7] = new TypeDeclaration(resolver, "NullableBoolConverter", "System.Windows", 0); + KnownTypeTable[0x1a8] = new TypeDeclaration(resolver, "NullableConverter", "System.ComponentModel", 3); + KnownTypeTable[0x1a6] = new TypeDeclaration(resolver, "NullExtension", "System.Windows.Markup", 0, true); + KnownTypeTable[0x1a9] = new TypeDeclaration(resolver, "NumberSubstitution", "System.Windows.Media", 1); + KnownTypeTable[0x1aa] = new TypeDeclaration(resolver, "Object", "System", 2); + KnownTypeTable[0x1ab] = new TypeDeclaration(resolver, "ObjectAnimationBase", "System.Windows.Media.Animation", 1); + KnownTypeTable[0x1ac] = new TypeDeclaration(resolver, "ObjectAnimationUsingKeyFrames", "System.Windows.Media.Animation", 1); + KnownTypeTable[0x1ad] = new TypeDeclaration(resolver, "ObjectDataProvider", "System.Windows.Data", 0); + KnownTypeTable[430] = new TypeDeclaration(resolver, "ObjectKeyFrame", "System.Windows.Media.Animation", 1); + KnownTypeTable[0x1af] = new TypeDeclaration(resolver, "ObjectKeyFrameCollection", "System.Windows.Media.Animation", 1); + KnownTypeTable[0x1b0] = new TypeDeclaration(resolver, "OrthographicCamera", "System.Windows.Media.Media3D", 1); + KnownTypeTable[0x1b1] = new TypeDeclaration(resolver, "OuterGlowBitmapEffect", "System.Windows.Media.Effects", 1); + KnownTypeTable[0x1b2] = new TypeDeclaration(resolver, "Page", "System.Windows.Controls", 0); + KnownTypeTable[0x1b3] = new TypeDeclaration(resolver, "PageContent", "System.Windows.Documents", 0); + KnownTypeTable[0x1b4] = new TypeDeclaration(resolver, "PageFunctionBase", "System.Windows.Navigation", 0); + KnownTypeTable[0x1b5] = new TypeDeclaration(resolver, "Panel", "System.Windows.Controls", 0); + KnownTypeTable[0x1b6] = new TypeDeclaration(resolver, "Paragraph", "System.Windows.Documents", 0); + KnownTypeTable[0x1b7] = new TypeDeclaration(resolver, "ParallelTimeline", "System.Windows.Media.Animation", 1); + KnownTypeTable[440] = new TypeDeclaration(resolver, "ParserContext", "System.Windows.Markup", 0); + KnownTypeTable[0x1b9] = new TypeDeclaration(resolver, "PasswordBox", "System.Windows.Controls", 0); + KnownTypeTable[0x1ba] = new TypeDeclaration(resolver, "Path", "System.Windows.Shapes", 0); + KnownTypeTable[0x1bb] = new TypeDeclaration(resolver, "PathFigure", "System.Windows.Media", 1); + KnownTypeTable[0x1bc] = new TypeDeclaration(resolver, "PathFigureCollection", "System.Windows.Media", 1); + KnownTypeTable[0x1bd] = new TypeDeclaration(resolver, "PathFigureCollectionConverter", "System.Windows.Media", 1); + KnownTypeTable[0x1be] = new TypeDeclaration(resolver, "PathGeometry", "System.Windows.Media", 1); + KnownTypeTable[0x1bf] = new TypeDeclaration(resolver, "PathSegment", "System.Windows.Media", 1); + KnownTypeTable[0x1c0] = new TypeDeclaration(resolver, "PathSegmentCollection", "System.Windows.Media", 1); + KnownTypeTable[0x1c1] = new TypeDeclaration(resolver, "PauseStoryboard", "System.Windows.Media.Animation", 0); + KnownTypeTable[450] = new TypeDeclaration(resolver, "Pen", "System.Windows.Media", 1); + KnownTypeTable[0x1c3] = new TypeDeclaration(resolver, "PerspectiveCamera", "System.Windows.Media.Media3D", 1); + KnownTypeTable[0x1c4] = new TypeDeclaration(resolver, "PixelFormat", "System.Windows.Media", 1); + KnownTypeTable[0x1c5] = new TypeDeclaration(resolver, "PixelFormatConverter", "System.Windows.Media", 1); + KnownTypeTable[0x1c6] = new TypeDeclaration(resolver, "PngBitmapDecoder", "System.Windows.Media.Imaging", 1); + KnownTypeTable[0x1c7] = new TypeDeclaration(resolver, "PngBitmapEncoder", "System.Windows.Media.Imaging", 1); + KnownTypeTable[0x1c8] = new TypeDeclaration(resolver, "Point", "System.Windows", 4); + KnownTypeTable[0x1c9] = new TypeDeclaration(resolver, "Point3D", "System.Windows.Media.Media3D", 1); + KnownTypeTable[0x1ca] = new TypeDeclaration(resolver, "Point3DAnimation", "System.Windows.Media.Animation", 1); + KnownTypeTable[0x1cb] = new TypeDeclaration(resolver, "Point3DAnimationBase", "System.Windows.Media.Animation", 1); + KnownTypeTable[460] = new TypeDeclaration(resolver, "Point3DAnimationUsingKeyFrames", "System.Windows.Media.Animation", 1); + KnownTypeTable[0x1cd] = new TypeDeclaration(resolver, "Point3DCollection", "System.Windows.Media.Media3D", 1); + KnownTypeTable[0x1ce] = new TypeDeclaration(resolver, "Point3DCollectionConverter", "System.Windows.Media.Media3D", 1); + KnownTypeTable[0x1cf] = new TypeDeclaration(resolver, "Point3DConverter", "System.Windows.Media.Media3D", 1); + KnownTypeTable[0x1d0] = new TypeDeclaration(resolver, "Point3DKeyFrame", "System.Windows.Media.Animation", 1); + KnownTypeTable[0x1d1] = new TypeDeclaration(resolver, "Point3DKeyFrameCollection", "System.Windows.Media.Animation", 1); + KnownTypeTable[0x1d2] = new TypeDeclaration(resolver, "Point4D", "System.Windows.Media.Media3D", 1); + KnownTypeTable[0x1d3] = new TypeDeclaration(resolver, "Point4DConverter", "System.Windows.Media.Media3D", 1); + KnownTypeTable[0x1d4] = new TypeDeclaration(resolver, "PointAnimation", "System.Windows.Media.Animation", 1); + KnownTypeTable[0x1d5] = new TypeDeclaration(resolver, "PointAnimationBase", "System.Windows.Media.Animation", 1); + KnownTypeTable[470] = new TypeDeclaration(resolver, "PointAnimationUsingKeyFrames", "System.Windows.Media.Animation", 1); + KnownTypeTable[0x1d7] = new TypeDeclaration(resolver, "PointAnimationUsingPath", "System.Windows.Media.Animation", 1); + KnownTypeTable[0x1d8] = new TypeDeclaration(resolver, "PointCollection", "System.Windows.Media", 1); + KnownTypeTable[0x1d9] = new TypeDeclaration(resolver, "PointCollectionConverter", "System.Windows.Media", 1); + KnownTypeTable[0x1da] = new TypeDeclaration(resolver, "PointConverter", "System.Windows", 4); + KnownTypeTable[0x1db] = new TypeDeclaration(resolver, "PointIListConverter", "System.Windows.Media.Converters", 1); + KnownTypeTable[0x1dc] = new TypeDeclaration(resolver, "PointKeyFrame", "System.Windows.Media.Animation", 1); + KnownTypeTable[0x1dd] = new TypeDeclaration(resolver, "PointKeyFrameCollection", "System.Windows.Media.Animation", 1); + KnownTypeTable[0x1de] = new TypeDeclaration(resolver, "PointLight", "System.Windows.Media.Media3D", 1); + KnownTypeTable[0x1df] = new TypeDeclaration(resolver, "PointLightBase", "System.Windows.Media.Media3D", 1); + KnownTypeTable[480] = new TypeDeclaration(resolver, "PolyBezierSegment", "System.Windows.Media", 1); + KnownTypeTable[0x1e3] = new TypeDeclaration(resolver, "Polygon", "System.Windows.Shapes", 0); + KnownTypeTable[0x1e4] = new TypeDeclaration(resolver, "Polyline", "System.Windows.Shapes", 0); + KnownTypeTable[0x1e1] = new TypeDeclaration(resolver, "PolyLineSegment", "System.Windows.Media", 1); + KnownTypeTable[0x1e2] = new TypeDeclaration(resolver, "PolyQuadraticBezierSegment", "System.Windows.Media", 1); + KnownTypeTable[0x1e5] = new TypeDeclaration(resolver, "Popup", "System.Windows.Controls.Primitives", 0); + KnownTypeTable[0x1e6] = new TypeDeclaration(resolver, "PresentationSource", "System.Windows", 1); + KnownTypeTable[0x1e7] = new TypeDeclaration(resolver, "PriorityBinding", "System.Windows.Data", 0, true); + KnownTypeTable[0x1e8] = new TypeDeclaration(resolver, "PriorityBindingExpression", "System.Windows.Data", 0); + KnownTypeTable[0x1e9] = new TypeDeclaration(resolver, "ProgressBar", "System.Windows.Controls", 0); + KnownTypeTable[490] = new TypeDeclaration(resolver, "ProjectionCamera", "System.Windows.Media.Media3D", 1); + KnownTypeTable[0x1eb] = new TypeDeclaration(resolver, "PropertyPath", "System.Windows", 0); + KnownTypeTable[0x1ec] = new TypeDeclaration(resolver, "PropertyPathConverter", "System.Windows", 0); + KnownTypeTable[0x1ed] = new TypeDeclaration(resolver, "QuadraticBezierSegment", "System.Windows.Media", 1); + KnownTypeTable[0x1ee] = new TypeDeclaration(resolver, "Quaternion", "System.Windows.Media.Media3D", 1); + KnownTypeTable[0x1ef] = new TypeDeclaration(resolver, "QuaternionAnimation", "System.Windows.Media.Animation", 1); + KnownTypeTable[0x1f0] = new TypeDeclaration(resolver, "QuaternionAnimationBase", "System.Windows.Media.Animation", 1); + KnownTypeTable[0x1f1] = new TypeDeclaration(resolver, "QuaternionAnimationUsingKeyFrames", "System.Windows.Media.Animation", 1); + KnownTypeTable[0x1f2] = new TypeDeclaration(resolver, "QuaternionConverter", "System.Windows.Media.Media3D", 1); + KnownTypeTable[0x1f3] = new TypeDeclaration(resolver, "QuaternionKeyFrame", "System.Windows.Media.Animation", 1); + KnownTypeTable[500] = new TypeDeclaration(resolver, "QuaternionKeyFrameCollection", "System.Windows.Media.Animation", 1); + KnownTypeTable[0x1f5] = new TypeDeclaration(resolver, "QuaternionRotation3D", "System.Windows.Media.Media3D", 1); + KnownTypeTable[0x1f6] = new TypeDeclaration(resolver, "RadialGradientBrush", "System.Windows.Media", 1); + KnownTypeTable[0x1f7] = new TypeDeclaration(resolver, "RadioButton", "System.Windows.Controls", 0); + KnownTypeTable[0x1f8] = new TypeDeclaration(resolver, "RangeBase", "System.Windows.Controls.Primitives", 0); + KnownTypeTable[0x1f9] = new TypeDeclaration(resolver, "Rect", "System.Windows", 1); + KnownTypeTable[0x1fa] = new TypeDeclaration(resolver, "Rect3D", "System.Windows.Media.Media3D", 1); + KnownTypeTable[0x1fb] = new TypeDeclaration(resolver, "Rect3DConverter", "System.Windows.Media.Media3D", 1); + KnownTypeTable[0x202] = new TypeDeclaration(resolver, "Rectangle", "System.Windows.Shapes", 0); + KnownTypeTable[0x203] = new TypeDeclaration(resolver, "RectangleGeometry", "System.Windows.Media", 1); + KnownTypeTable[0x1fc] = new TypeDeclaration(resolver, "RectAnimation", "System.Windows.Media.Animation", 1); + KnownTypeTable[0x1fd] = new TypeDeclaration(resolver, "RectAnimationBase", "System.Windows.Media.Animation", 1); + KnownTypeTable[510] = new TypeDeclaration(resolver, "RectAnimationUsingKeyFrames", "System.Windows.Media.Animation", 1); + KnownTypeTable[0x1ff] = new TypeDeclaration(resolver, "RectConverter", "System.Windows", 4); + KnownTypeTable[0x200] = new TypeDeclaration(resolver, "RectKeyFrame", "System.Windows.Media.Animation", 1); + KnownTypeTable[0x201] = new TypeDeclaration(resolver, "RectKeyFrameCollection", "System.Windows.Media.Animation", 1); + KnownTypeTable[0x204] = new TypeDeclaration(resolver, "RelativeSource", "System.Windows.Data", 0, true); + KnownTypeTable[0x205] = new TypeDeclaration(resolver, "RemoveStoryboard", "System.Windows.Media.Animation", 0); + KnownTypeTable[0x206] = new TypeDeclaration(resolver, "RenderOptions", "System.Windows.Media", 1); + KnownTypeTable[0x207] = new TypeDeclaration(resolver, "RenderTargetBitmap", "System.Windows.Media.Imaging", 1); + KnownTypeTable[520] = new TypeDeclaration(resolver, "RepeatBehavior", "System.Windows.Media.Animation", 1); + KnownTypeTable[0x209] = new TypeDeclaration(resolver, "RepeatBehaviorConverter", "System.Windows.Media.Animation", 1); + KnownTypeTable[0x20a] = new TypeDeclaration(resolver, "RepeatButton", "System.Windows.Controls.Primitives", 0); + KnownTypeTable[0x20b] = new TypeDeclaration(resolver, "ResizeGrip", "System.Windows.Controls.Primitives", 0); + KnownTypeTable[0x20c] = new TypeDeclaration(resolver, "ResourceDictionary", "System.Windows", 0); + KnownTypeTable[0x20d] = new TypeDeclaration(resolver, "ResourceKey", "System.Windows", 0, true); + KnownTypeTable[0x20e] = new TypeDeclaration(resolver, "ResumeStoryboard", "System.Windows.Media.Animation", 0); + KnownTypeTable[0x20f] = new TypeDeclaration(resolver, "RichTextBox", "System.Windows.Controls", 0); + KnownTypeTable[0x210] = new TypeDeclaration(resolver, "RotateTransform", "System.Windows.Media", 1); + KnownTypeTable[0x211] = new TypeDeclaration(resolver, "RotateTransform3D", "System.Windows.Media.Media3D", 1); + KnownTypeTable[530] = new TypeDeclaration(resolver, "Rotation3D", "System.Windows.Media.Media3D", 1); + KnownTypeTable[0x213] = new TypeDeclaration(resolver, "Rotation3DAnimation", "System.Windows.Media.Animation", 1); + KnownTypeTable[0x214] = new TypeDeclaration(resolver, "Rotation3DAnimationBase", "System.Windows.Media.Animation", 1); + KnownTypeTable[0x215] = new TypeDeclaration(resolver, "Rotation3DAnimationUsingKeyFrames", "System.Windows.Media.Animation", 1); + KnownTypeTable[0x216] = new TypeDeclaration(resolver, "Rotation3DKeyFrame", "System.Windows.Media.Animation", 1); + KnownTypeTable[0x217] = new TypeDeclaration(resolver, "Rotation3DKeyFrameCollection", "System.Windows.Media.Animation", 1); + KnownTypeTable[0x218] = new TypeDeclaration(resolver, "RoutedCommand", "System.Windows.Input", 1); + KnownTypeTable[0x219] = new TypeDeclaration(resolver, "RoutedEvent", "System.Windows", 1); + KnownTypeTable[0x21a] = new TypeDeclaration(resolver, "RoutedEventConverter", "System.Windows.Markup", 0); + KnownTypeTable[0x21b] = new TypeDeclaration(resolver, "RoutedUICommand", "System.Windows.Input", 1); + KnownTypeTable[540] = new TypeDeclaration(resolver, "RoutingStrategy", "System.Windows", 1); + KnownTypeTable[0x21d] = new TypeDeclaration(resolver, "RowDefinition", "System.Windows.Controls", 0); + KnownTypeTable[0x21e] = new TypeDeclaration(resolver, "Run", "System.Windows.Documents", 0); + KnownTypeTable[0x21f] = new TypeDeclaration(resolver, "RuntimeNamePropertyAttribute", "System.Windows.Markup", 4); + KnownTypeTable[0x220] = new TypeDeclaration(resolver, "SByte", "System", 2); + KnownTypeTable[0x221] = new TypeDeclaration(resolver, "SByteConverter", "System.ComponentModel", 3); + KnownTypeTable[0x222] = new TypeDeclaration(resolver, "ScaleTransform", "System.Windows.Media", 1); + KnownTypeTable[0x223] = new TypeDeclaration(resolver, "ScaleTransform3D", "System.Windows.Media.Media3D", 1); + KnownTypeTable[0x224] = new TypeDeclaration(resolver, "ScrollBar", "System.Windows.Controls.Primitives", 0); + KnownTypeTable[0x225] = new TypeDeclaration(resolver, "ScrollContentPresenter", "System.Windows.Controls", 0); + KnownTypeTable[550] = new TypeDeclaration(resolver, "ScrollViewer", "System.Windows.Controls", 0); + KnownTypeTable[0x227] = new TypeDeclaration(resolver, "Section", "System.Windows.Documents", 0); + KnownTypeTable[0x228] = new TypeDeclaration(resolver, "SeekStoryboard", "System.Windows.Media.Animation", 0); + KnownTypeTable[0x229] = new TypeDeclaration(resolver, "Selector", "System.Windows.Controls.Primitives", 0); + KnownTypeTable[0x22a] = new TypeDeclaration(resolver, "Separator", "System.Windows.Controls", 0); + KnownTypeTable[0x22b] = new TypeDeclaration(resolver, "SetStoryboardSpeedRatio", "System.Windows.Media.Animation", 0); + KnownTypeTable[0x22c] = new TypeDeclaration(resolver, "Setter", "System.Windows", 0); + KnownTypeTable[0x22d] = new TypeDeclaration(resolver, "SetterBase", "System.Windows", 0); + KnownTypeTable[0x22e] = new TypeDeclaration(resolver, "Shape", "System.Windows.Shapes", 0); + KnownTypeTable[0x22f] = new TypeDeclaration(resolver, "Single", "System", 2); + KnownTypeTable[560] = new TypeDeclaration(resolver, "SingleAnimation", "System.Windows.Media.Animation", 1); + KnownTypeTable[0x231] = new TypeDeclaration(resolver, "SingleAnimationBase", "System.Windows.Media.Animation", 1); + KnownTypeTable[0x232] = new TypeDeclaration(resolver, "SingleAnimationUsingKeyFrames", "System.Windows.Media.Animation", 1); + KnownTypeTable[0x233] = new TypeDeclaration(resolver, "SingleConverter", "System.ComponentModel", 3); + KnownTypeTable[0x234] = new TypeDeclaration(resolver, "SingleKeyFrame", "System.Windows.Media.Animation", 1); + KnownTypeTable[0x235] = new TypeDeclaration(resolver, "SingleKeyFrameCollection", "System.Windows.Media.Animation", 1); + KnownTypeTable[0x236] = new TypeDeclaration(resolver, "Size", "System.Windows", 4); + KnownTypeTable[0x237] = new TypeDeclaration(resolver, "Size3D", "System.Windows.Media.Media3D", 1); + KnownTypeTable[0x238] = new TypeDeclaration(resolver, "Size3DConverter", "System.Windows.Media.Media3D", 1); + KnownTypeTable[0x239] = new TypeDeclaration(resolver, "SizeAnimation", "System.Windows.Media.Animation", 1); + KnownTypeTable[570] = new TypeDeclaration(resolver, "SizeAnimationBase", "System.Windows.Media.Animation", 1); + KnownTypeTable[0x23b] = new TypeDeclaration(resolver, "SizeAnimationUsingKeyFrames", "System.Windows.Media.Animation", 1); + KnownTypeTable[0x23c] = new TypeDeclaration(resolver, "SizeConverter", "System.Windows", 4); + KnownTypeTable[0x23d] = new TypeDeclaration(resolver, "SizeKeyFrame", "System.Windows.Media.Animation", 1); + KnownTypeTable[0x23e] = new TypeDeclaration(resolver, "SizeKeyFrameCollection", "System.Windows.Media.Animation", 1); + KnownTypeTable[0x23f] = new TypeDeclaration(resolver, "SkewTransform", "System.Windows.Media", 1); + KnownTypeTable[0x240] = new TypeDeclaration(resolver, "SkipStoryboardToFill", "System.Windows.Media.Animation", 0); + KnownTypeTable[0x241] = new TypeDeclaration(resolver, "Slider", "System.Windows.Controls", 0); + KnownTypeTable[0x242] = new TypeDeclaration(resolver, "SolidColorBrush", "System.Windows.Media", 1); + KnownTypeTable[0x243] = new TypeDeclaration(resolver, "SoundPlayerAction", "System.Windows.Controls", 0); + KnownTypeTable[580] = new TypeDeclaration(resolver, "Span", "System.Windows.Documents", 0); + KnownTypeTable[0x245] = new TypeDeclaration(resolver, "SpecularMaterial", "System.Windows.Media.Media3D", 1); + KnownTypeTable[0x246] = new TypeDeclaration(resolver, "SpellCheck", "System.Windows.Controls", 0); + KnownTypeTable[0x247] = new TypeDeclaration(resolver, "SplineByteKeyFrame", "System.Windows.Media.Animation", 1); + KnownTypeTable[0x248] = new TypeDeclaration(resolver, "SplineColorKeyFrame", "System.Windows.Media.Animation", 1); + KnownTypeTable[0x249] = new TypeDeclaration(resolver, "SplineDecimalKeyFrame", "System.Windows.Media.Animation", 1); + KnownTypeTable[0x24a] = new TypeDeclaration(resolver, "SplineDoubleKeyFrame", "System.Windows.Media.Animation", 1); + KnownTypeTable[0x24b] = new TypeDeclaration(resolver, "SplineInt16KeyFrame", "System.Windows.Media.Animation", 1); + KnownTypeTable[0x24c] = new TypeDeclaration(resolver, "SplineInt32KeyFrame", "System.Windows.Media.Animation", 1); + KnownTypeTable[0x24d] = new TypeDeclaration(resolver, "SplineInt64KeyFrame", "System.Windows.Media.Animation", 1); + KnownTypeTable[590] = new TypeDeclaration(resolver, "SplinePoint3DKeyFrame", "System.Windows.Media.Animation", 1); + KnownTypeTable[0x24f] = new TypeDeclaration(resolver, "SplinePointKeyFrame", "System.Windows.Media.Animation", 1); + KnownTypeTable[0x250] = new TypeDeclaration(resolver, "SplineQuaternionKeyFrame", "System.Windows.Media.Animation", 1); + KnownTypeTable[0x251] = new TypeDeclaration(resolver, "SplineRectKeyFrame", "System.Windows.Media.Animation", 1); + KnownTypeTable[0x252] = new TypeDeclaration(resolver, "SplineRotation3DKeyFrame", "System.Windows.Media.Animation", 1); + KnownTypeTable[0x253] = new TypeDeclaration(resolver, "SplineSingleKeyFrame", "System.Windows.Media.Animation", 1); + KnownTypeTable[0x254] = new TypeDeclaration(resolver, "SplineSizeKeyFrame", "System.Windows.Media.Animation", 1); + KnownTypeTable[0x255] = new TypeDeclaration(resolver, "SplineThicknessKeyFrame", "System.Windows.Media.Animation", 0); + KnownTypeTable[0x256] = new TypeDeclaration(resolver, "SplineVector3DKeyFrame", "System.Windows.Media.Animation", 1); + KnownTypeTable[0x257] = new TypeDeclaration(resolver, "SplineVectorKeyFrame", "System.Windows.Media.Animation", 1); + KnownTypeTable[600] = new TypeDeclaration(resolver, "SpotLight", "System.Windows.Media.Media3D", 1); + KnownTypeTable[0x259] = new TypeDeclaration(resolver, "StackPanel", "System.Windows.Controls", 0); + KnownTypeTable[0x25a] = new TypeDeclaration(resolver, "StaticExtension", "System.Windows.Markup", 0); + KnownTypeTable[0x25b] = new TypeDeclaration(resolver, "StaticResourceExtension", "System.Windows", 0, true); + KnownTypeTable[0x25c] = new TypeDeclaration(resolver, "StatusBar", "System.Windows.Controls.Primitives", 0); + KnownTypeTable[0x25d] = new TypeDeclaration(resolver, "StatusBarItem", "System.Windows.Controls.Primitives", 0); + KnownTypeTable[0x25e] = new TypeDeclaration(resolver, "StickyNoteControl", "System.Windows.Controls", 0); + KnownTypeTable[0x25f] = new TypeDeclaration(resolver, "StopStoryboard", "System.Windows.Media.Animation", 0); + KnownTypeTable[0x260] = new TypeDeclaration(resolver, "Storyboard", "System.Windows.Media.Animation", 0); + KnownTypeTable[0x261] = new TypeDeclaration(resolver, "StreamGeometry", "System.Windows.Media", 1); + KnownTypeTable[610] = new TypeDeclaration(resolver, "StreamGeometryContext", "System.Windows.Media", 1); + KnownTypeTable[0x263] = new TypeDeclaration(resolver, "StreamResourceInfo", "System.Windows.Resources", 0); + KnownTypeTable[0x264] = new TypeDeclaration(resolver, "String", "System", 2); + KnownTypeTable[0x265] = new TypeDeclaration(resolver, "StringAnimationBase", "System.Windows.Media.Animation", 1); + KnownTypeTable[0x266] = new TypeDeclaration(resolver, "StringAnimationUsingKeyFrames", "System.Windows.Media.Animation", 1); + KnownTypeTable[0x267] = new TypeDeclaration(resolver, "StringConverter", "System.ComponentModel", 3); + KnownTypeTable[0x268] = new TypeDeclaration(resolver, "StringKeyFrame", "System.Windows.Media.Animation", 1); + KnownTypeTable[0x269] = new TypeDeclaration(resolver, "StringKeyFrameCollection", "System.Windows.Media.Animation", 1); + KnownTypeTable[0x26a] = new TypeDeclaration(resolver, "StrokeCollection", "System.Windows.Ink", 1); + KnownTypeTable[0x26b] = new TypeDeclaration(resolver, "StrokeCollectionConverter", "System.Windows", 1); + KnownTypeTable[620] = new TypeDeclaration(resolver, "Style", "System.Windows", 0); + KnownTypeTable[0x26d] = new TypeDeclaration(resolver, "Stylus", "System.Windows.Input", 1); + KnownTypeTable[0x26e] = new TypeDeclaration(resolver, "StylusDevice", "System.Windows.Input", 1); + KnownTypeTable[0x26f] = new TypeDeclaration(resolver, "TabControl", "System.Windows.Controls", 0); + KnownTypeTable[0x270] = new TypeDeclaration(resolver, "TabItem", "System.Windows.Controls", 0); + KnownTypeTable[0x272] = new TypeDeclaration(resolver, "Table", "System.Windows.Documents", 0); + KnownTypeTable[0x273] = new TypeDeclaration(resolver, "TableCell", "System.Windows.Documents", 0); + KnownTypeTable[0x274] = new TypeDeclaration(resolver, "TableColumn", "System.Windows.Documents", 0); + KnownTypeTable[0x275] = new TypeDeclaration(resolver, "TableRow", "System.Windows.Documents", 0); + KnownTypeTable[630] = new TypeDeclaration(resolver, "TableRowGroup", "System.Windows.Documents", 0); + KnownTypeTable[0x277] = new TypeDeclaration(resolver, "TabletDevice", "System.Windows.Input", 1); + KnownTypeTable[0x271] = new TypeDeclaration(resolver, "TabPanel", "System.Windows.Controls.Primitives", 0); + KnownTypeTable[0x278] = new TypeDeclaration(resolver, "TemplateBindingExpression", "System.Windows", 0); + KnownTypeTable[0x279] = new TypeDeclaration(resolver, "TemplateBindingExpressionConverter", "System.Windows", 0); + KnownTypeTable[0x27a] = new TypeDeclaration(resolver, "TemplateBindingExtension", "System.Windows", 0); + KnownTypeTable[0x27b] = new TypeDeclaration(resolver, "TemplateBindingExtensionConverter", "System.Windows", 0); + KnownTypeTable[0x27c] = new TypeDeclaration(resolver, "TemplateKey", "System.Windows", 0, true); + KnownTypeTable[0x27d] = new TypeDeclaration(resolver, "TemplateKeyConverter", "System.Windows.Markup", 0); + KnownTypeTable[0x27e] = new TypeDeclaration(resolver, "TextBlock", "System.Windows.Controls", 0); + KnownTypeTable[0x27f] = new TypeDeclaration(resolver, "TextBox", "System.Windows.Controls", 0); + KnownTypeTable[640] = new TypeDeclaration(resolver, "TextBoxBase", "System.Windows.Controls.Primitives", 0); + KnownTypeTable[0x281] = new TypeDeclaration(resolver, "TextComposition", "System.Windows.Input", 1); + KnownTypeTable[0x282] = new TypeDeclaration(resolver, "TextCompositionManager", "System.Windows.Input", 1); + KnownTypeTable[0x283] = new TypeDeclaration(resolver, "TextDecoration", "System.Windows", 1); + KnownTypeTable[0x284] = new TypeDeclaration(resolver, "TextDecorationCollection", "System.Windows", 1); + KnownTypeTable[0x285] = new TypeDeclaration(resolver, "TextDecorationCollectionConverter", "System.Windows", 1); + KnownTypeTable[0x286] = new TypeDeclaration(resolver, "TextEffect", "System.Windows.Media", 1); + KnownTypeTable[0x287] = new TypeDeclaration(resolver, "TextEffectCollection", "System.Windows.Media", 1); + KnownTypeTable[0x288] = new TypeDeclaration(resolver, "TextElement", "System.Windows.Documents", 0); + KnownTypeTable[0x289] = new TypeDeclaration(resolver, "TextSearch", "System.Windows.Controls", 0); + KnownTypeTable[650] = new TypeDeclaration(resolver, "ThemeDictionaryExtension", "System.Windows", 0, true); + KnownTypeTable[0x28b] = new TypeDeclaration(resolver, "Thickness", "System.Windows", 0); + KnownTypeTable[0x28c] = new TypeDeclaration(resolver, "ThicknessAnimation", "System.Windows.Media.Animation", 0); + KnownTypeTable[0x28d] = new TypeDeclaration(resolver, "ThicknessAnimationBase", "System.Windows.Media.Animation", 0); + KnownTypeTable[0x28e] = new TypeDeclaration(resolver, "ThicknessAnimationUsingKeyFrames", "System.Windows.Media.Animation", 0); + KnownTypeTable[0x28f] = new TypeDeclaration(resolver, "ThicknessConverter", "System.Windows", 0); + KnownTypeTable[0x290] = new TypeDeclaration(resolver, "ThicknessKeyFrame", "System.Windows.Media.Animation", 0); + KnownTypeTable[0x291] = new TypeDeclaration(resolver, "ThicknessKeyFrameCollection", "System.Windows.Media.Animation", 0); + KnownTypeTable[0x292] = new TypeDeclaration(resolver, "Thumb", "System.Windows.Controls.Primitives", 0); + KnownTypeTable[0x293] = new TypeDeclaration(resolver, "TickBar", "System.Windows.Controls.Primitives", 0); + KnownTypeTable[660] = new TypeDeclaration(resolver, "TiffBitmapDecoder", "System.Windows.Media.Imaging", 1); + KnownTypeTable[0x295] = new TypeDeclaration(resolver, "TiffBitmapEncoder", "System.Windows.Media.Imaging", 1); + KnownTypeTable[0x296] = new TypeDeclaration(resolver, "TileBrush", "System.Windows.Media", 1); + KnownTypeTable[0x299] = new TypeDeclaration(resolver, "Timeline", "System.Windows.Media.Animation", 1); + KnownTypeTable[0x29a] = new TypeDeclaration(resolver, "TimelineCollection", "System.Windows.Media.Animation", 1); + KnownTypeTable[0x29b] = new TypeDeclaration(resolver, "TimelineGroup", "System.Windows.Media.Animation", 1); + KnownTypeTable[0x297] = new TypeDeclaration(resolver, "TimeSpan", "System", 2); + KnownTypeTable[0x298] = new TypeDeclaration(resolver, "TimeSpanConverter", "System.ComponentModel", 3); + KnownTypeTable[0x29c] = new TypeDeclaration(resolver, "ToggleButton", "System.Windows.Controls.Primitives", 0); + KnownTypeTable[0x29d] = new TypeDeclaration(resolver, "ToolBar", "System.Windows.Controls", 0); + KnownTypeTable[670] = new TypeDeclaration(resolver, "ToolBarOverflowPanel", "System.Windows.Controls.Primitives", 0); + KnownTypeTable[0x29f] = new TypeDeclaration(resolver, "ToolBarPanel", "System.Windows.Controls.Primitives", 0); + KnownTypeTable[0x2a0] = new TypeDeclaration(resolver, "ToolBarTray", "System.Windows.Controls", 0); + KnownTypeTable[0x2a1] = new TypeDeclaration(resolver, "ToolTip", "System.Windows.Controls", 0); + KnownTypeTable[0x2a2] = new TypeDeclaration(resolver, "ToolTipService", "System.Windows.Controls", 0); + KnownTypeTable[0x2a3] = new TypeDeclaration(resolver, "Track", "System.Windows.Controls.Primitives", 0); + KnownTypeTable[0x2a4] = new TypeDeclaration(resolver, "Transform", "System.Windows.Media", 1); + KnownTypeTable[0x2a5] = new TypeDeclaration(resolver, "Transform3D", "System.Windows.Media.Media3D", 1); + KnownTypeTable[0x2a6] = new TypeDeclaration(resolver, "Transform3DCollection", "System.Windows.Media.Media3D", 1); + KnownTypeTable[0x2a7] = new TypeDeclaration(resolver, "Transform3DGroup", "System.Windows.Media.Media3D", 1); + KnownTypeTable[680] = new TypeDeclaration(resolver, "TransformCollection", "System.Windows.Media", 1); + KnownTypeTable[0x2a9] = new TypeDeclaration(resolver, "TransformConverter", "System.Windows.Media", 1); + KnownTypeTable[0x2ab] = new TypeDeclaration(resolver, "TransformedBitmap", "System.Windows.Media.Imaging", 1); + KnownTypeTable[0x2aa] = new TypeDeclaration(resolver, "TransformGroup", "System.Windows.Media", 1); + KnownTypeTable[0x2ac] = new TypeDeclaration(resolver, "TranslateTransform", "System.Windows.Media", 1); + KnownTypeTable[0x2ad] = new TypeDeclaration(resolver, "TranslateTransform3D", "System.Windows.Media.Media3D", 1); + KnownTypeTable[0x2ae] = new TypeDeclaration(resolver, "TreeView", "System.Windows.Controls", 0); + KnownTypeTable[0x2af] = new TypeDeclaration(resolver, "TreeViewItem", "System.Windows.Controls", 0); + KnownTypeTable[0x2b0] = new TypeDeclaration(resolver, "Trigger", "System.Windows", 0); + KnownTypeTable[0x2b1] = new TypeDeclaration(resolver, "TriggerAction", "System.Windows", 0); + KnownTypeTable[690] = new TypeDeclaration(resolver, "TriggerBase", "System.Windows", 0); + KnownTypeTable[0x2b3] = new TypeDeclaration(resolver, "TypeExtension", "System.Windows.Markup", 0, true); + KnownTypeTable[0x2b4] = new TypeDeclaration(resolver, "TypeTypeConverter", "System.Net.Configuration", 3); + KnownTypeTable[0x2b5] = new TypeDeclaration(resolver, "Typography", "System.Windows.Documents", 0); + KnownTypeTable[0x2b6] = new TypeDeclaration(resolver, "UIElement", "System.Windows", 1); + KnownTypeTable[0x2b7] = new TypeDeclaration(resolver, "UInt16", "System", 2); + KnownTypeTable[0x2b8] = new TypeDeclaration(resolver, "UInt16Converter", "System.ComponentModel", 3); + KnownTypeTable[0x2b9] = new TypeDeclaration(resolver, "UInt32", "System", 2); + KnownTypeTable[0x2ba] = new TypeDeclaration(resolver, "UInt32Converter", "System.ComponentModel", 3); + KnownTypeTable[0x2bb] = new TypeDeclaration(resolver, "UInt64", "System", 2); + KnownTypeTable[700] = new TypeDeclaration(resolver, "UInt64Converter", "System.ComponentModel", 3); + KnownTypeTable[0x2be] = new TypeDeclaration(resolver, "Underline", "System.Windows.Documents", 0); + KnownTypeTable[0x2bf] = new TypeDeclaration(resolver, "UniformGrid", "System.Windows.Controls.Primitives", 0); + KnownTypeTable[0x2c0] = new TypeDeclaration(resolver, "Uri", "System", 3); + KnownTypeTable[0x2c1] = new TypeDeclaration(resolver, "UriTypeConverter", "System", 3); + KnownTypeTable[0x2c2] = new TypeDeclaration(resolver, "UserControl", "System.Windows.Controls", 0); + KnownTypeTable[0x2bd] = new TypeDeclaration(resolver, "UShortIListConverter", "System.Windows.Media.Converters", 1); + KnownTypeTable[0x2c3] = new TypeDeclaration(resolver, "Validation", "System.Windows.Controls", 0); + KnownTypeTable[0x2c4] = new TypeDeclaration(resolver, "Vector", "System.Windows", 1); + KnownTypeTable[0x2c5] = new TypeDeclaration(resolver, "Vector3D", "System.Windows.Media.Media3D", 1); + KnownTypeTable[710] = new TypeDeclaration(resolver, "Vector3DAnimation", "System.Windows.Media.Animation", 1); + KnownTypeTable[0x2c7] = new TypeDeclaration(resolver, "Vector3DAnimationBase", "System.Windows.Media.Animation", 1); + KnownTypeTable[0x2c8] = new TypeDeclaration(resolver, "Vector3DAnimationUsingKeyFrames", "System.Windows.Media.Animation", 1); + KnownTypeTable[0x2c9] = new TypeDeclaration(resolver, "Vector3DCollection", "System.Windows.Media.Media3D", 1); + KnownTypeTable[0x2ca] = new TypeDeclaration(resolver, "Vector3DCollectionConverter", "System.Windows.Media.Media3D", 1); + KnownTypeTable[0x2cb] = new TypeDeclaration(resolver, "Vector3DConverter", "System.Windows.Media.Media3D", 1); + KnownTypeTable[0x2cc] = new TypeDeclaration(resolver, "Vector3DKeyFrame", "System.Windows.Media.Animation", 1); + KnownTypeTable[0x2cd] = new TypeDeclaration(resolver, "Vector3DKeyFrameCollection", "System.Windows.Media.Animation", 1); + KnownTypeTable[0x2ce] = new TypeDeclaration(resolver, "VectorAnimation", "System.Windows.Media.Animation", 1); + KnownTypeTable[0x2cf] = new TypeDeclaration(resolver, "VectorAnimationBase", "System.Windows.Media.Animation", 1); + KnownTypeTable[720] = new TypeDeclaration(resolver, "VectorAnimationUsingKeyFrames", "System.Windows.Media.Animation", 1); + KnownTypeTable[0x2d1] = new TypeDeclaration(resolver, "VectorCollection", "System.Windows.Media", 1); + KnownTypeTable[0x2d2] = new TypeDeclaration(resolver, "VectorCollectionConverter", "System.Windows.Media", 1); + KnownTypeTable[0x2d3] = new TypeDeclaration(resolver, "VectorConverter", "System.Windows", 4); + KnownTypeTable[0x2d4] = new TypeDeclaration(resolver, "VectorKeyFrame", "System.Windows.Media.Animation", 1); + KnownTypeTable[0x2d5] = new TypeDeclaration(resolver, "VectorKeyFrameCollection", "System.Windows.Media.Animation", 1); + KnownTypeTable[0x2d6] = new TypeDeclaration(resolver, "VideoDrawing", "System.Windows.Media", 1); + KnownTypeTable[0x2d7] = new TypeDeclaration(resolver, "ViewBase", "System.Windows.Controls", 0); + KnownTypeTable[0x2d8] = new TypeDeclaration(resolver, "Viewbox", "System.Windows.Controls", 0); + KnownTypeTable[0x2d9] = new TypeDeclaration(resolver, "Viewport3D", "System.Windows.Controls", 0); + KnownTypeTable[730] = new TypeDeclaration(resolver, "Viewport3DVisual", "System.Windows.Media.Media3D", 1); + KnownTypeTable[0x2db] = new TypeDeclaration(resolver, "VirtualizingPanel", "System.Windows.Controls", 0); + KnownTypeTable[0x2dc] = new TypeDeclaration(resolver, "VirtualizingStackPanel", "System.Windows.Controls", 0); + KnownTypeTable[0x2dd] = new TypeDeclaration(resolver, "Visual", "System.Windows.Media", 1); + KnownTypeTable[0x2de] = new TypeDeclaration(resolver, "Visual3D", "System.Windows.Media.Media3D", 1); + KnownTypeTable[0x2df] = new TypeDeclaration(resolver, "VisualBrush", "System.Windows.Media", 1); + KnownTypeTable[0x2e0] = new TypeDeclaration(resolver, "VisualTarget", "System.Windows.Media", 1); + KnownTypeTable[0x2e1] = new TypeDeclaration(resolver, "WeakEventManager", "System.Windows", 4); + KnownTypeTable[0x2e2] = new TypeDeclaration(resolver, "WhitespaceSignificantCollectionAttribute", "System.Windows.Markup", 4); + KnownTypeTable[0x2e3] = new TypeDeclaration(resolver, "Window", "System.Windows", 0); + KnownTypeTable[740] = new TypeDeclaration(resolver, "WmpBitmapDecoder", "System.Windows.Media.Imaging", 1); + KnownTypeTable[0x2e5] = new TypeDeclaration(resolver, "WmpBitmapEncoder", "System.Windows.Media.Imaging", 1); + KnownTypeTable[0x2e6] = new TypeDeclaration(resolver, "WrapPanel", "System.Windows.Controls", 0); + KnownTypeTable[0x2e7] = new TypeDeclaration(resolver, "WriteableBitmap", "System.Windows.Media.Imaging", 1); + KnownTypeTable[0x2e8] = new TypeDeclaration(resolver, "XamlBrushSerializer", "System.Windows.Markup", 0); + KnownTypeTable[0x2e9] = new TypeDeclaration(resolver, "XamlInt32CollectionSerializer", "System.Windows.Markup", 0); + KnownTypeTable[0x2ea] = new TypeDeclaration(resolver, "XamlPathDataSerializer", "System.Windows.Markup", 0); + KnownTypeTable[0x2eb] = new TypeDeclaration(resolver, "XamlPoint3DCollectionSerializer", "System.Windows.Markup", 0); + KnownTypeTable[0x2ec] = new TypeDeclaration(resolver, "XamlPointCollectionSerializer", "System.Windows.Markup", 0); + KnownTypeTable[0x2ed] = new TypeDeclaration(resolver, "XamlReader", "System.Windows.Markup", 0); + KnownTypeTable[750] = new TypeDeclaration(resolver, "XamlStyleSerializer", "System.Windows.Markup", 0); + KnownTypeTable[0x2ef] = new TypeDeclaration(resolver, "XamlTemplateSerializer", "System.Windows.Markup", 0); + KnownTypeTable[0x2f0] = new TypeDeclaration(resolver, "XamlVector3DCollectionSerializer", "System.Windows.Markup", 0); + KnownTypeTable[0x2f1] = new TypeDeclaration(resolver, "XamlWriter", "System.Windows.Markup", 0); + KnownTypeTable[0x2f2] = new TypeDeclaration(resolver, "XmlDataProvider", "System.Windows.Data", 0); + KnownTypeTable[0x2f3] = new TypeDeclaration(resolver, "XmlLangPropertyAttribute", "System.Windows.Markup", 4); + KnownTypeTable[0x2f4] = new TypeDeclaration(resolver, "XmlLanguage", "System.Windows.Markup", 1); + KnownTypeTable[0x2f5] = new TypeDeclaration(resolver, "XmlLanguageConverter", "System.Windows.Markup", 1); + KnownTypeTable[0x2f6] = new TypeDeclaration(resolver, "XmlNamespaceMapping", "System.Windows.Data", 0); + KnownTypeTable[0x2f7] = new TypeDeclaration(resolver, "ZoomPercentageConverter", "System.Windows.Documents", 0); + KnownPropertyTable = new PropertyDeclaration[0x10d]; + KnownPropertyTable[1] = new PropertyDeclaration("Text", KnownTypeTable[1]); + KnownPropertyTable[2] = new PropertyDeclaration("Storyboard", KnownTypeTable[0x11]); + KnownPropertyTable[3] = new PropertyDeclaration("Children", KnownTypeTable[0x1c]); + KnownPropertyTable[4] = new PropertyDeclaration("Background", KnownTypeTable[50]); + KnownPropertyTable[5] = new PropertyDeclaration("BorderBrush", KnownTypeTable[50]); + KnownPropertyTable[6] = new PropertyDeclaration("BorderThickness", KnownTypeTable[50]); + KnownPropertyTable[7] = new PropertyDeclaration("Command", KnownTypeTable[0x38]); + KnownPropertyTable[8] = new PropertyDeclaration("CommandParameter", KnownTypeTable[0x38]); + KnownPropertyTable[9] = new PropertyDeclaration("CommandTarget", KnownTypeTable[0x38]); + KnownPropertyTable[10] = new PropertyDeclaration("IsPressed", KnownTypeTable[0x38]); + KnownPropertyTable[11] = new PropertyDeclaration("MaxWidth", KnownTypeTable[90]); + KnownPropertyTable[12] = new PropertyDeclaration("MinWidth", KnownTypeTable[90]); + KnownPropertyTable[13] = new PropertyDeclaration("Width", KnownTypeTable[90]); + KnownPropertyTable[14] = new PropertyDeclaration("Content", KnownTypeTable[100]); + KnownPropertyTable[15] = new PropertyDeclaration("ContentTemplate", KnownTypeTable[100]); + KnownPropertyTable[0x10] = new PropertyDeclaration("ContentTemplateSelector", KnownTypeTable[100]); + KnownPropertyTable[0x11] = new PropertyDeclaration("HasContent", KnownTypeTable[100]); + KnownPropertyTable[0x12] = new PropertyDeclaration("Focusable", KnownTypeTable[0x65]); + KnownPropertyTable[0x13] = new PropertyDeclaration("Content", KnownTypeTable[0x66]); + KnownPropertyTable[20] = new PropertyDeclaration("ContentSource", KnownTypeTable[0x66]); + KnownPropertyTable[0x15] = new PropertyDeclaration("ContentTemplate", KnownTypeTable[0x66]); + KnownPropertyTable[0x16] = new PropertyDeclaration("ContentTemplateSelector", KnownTypeTable[0x66]); + KnownPropertyTable[0x17] = new PropertyDeclaration("RecognizesAccessKey", KnownTypeTable[0x66]); + KnownPropertyTable[0x18] = new PropertyDeclaration("Background", KnownTypeTable[0x6b]); + KnownPropertyTable[0x19] = new PropertyDeclaration("BorderBrush", KnownTypeTable[0x6b]); + KnownPropertyTable[0x1a] = new PropertyDeclaration("BorderThickness", KnownTypeTable[0x6b]); + KnownPropertyTable[0x1b] = new PropertyDeclaration("FontFamily", KnownTypeTable[0x6b]); + KnownPropertyTable[0x1c] = new PropertyDeclaration("FontSize", KnownTypeTable[0x6b]); + KnownPropertyTable[0x1d] = new PropertyDeclaration("FontStretch", KnownTypeTable[0x6b]); + KnownPropertyTable[30] = new PropertyDeclaration("FontStyle", KnownTypeTable[0x6b]); + KnownPropertyTable[0x1f] = new PropertyDeclaration("FontWeight", KnownTypeTable[0x6b]); + KnownPropertyTable[0x20] = new PropertyDeclaration("Foreground", KnownTypeTable[0x6b]); + KnownPropertyTable[0x21] = new PropertyDeclaration("HorizontalContentAlignment", KnownTypeTable[0x6b]); + KnownPropertyTable[0x22] = new PropertyDeclaration("IsTabStop", KnownTypeTable[0x6b]); + KnownPropertyTable[0x23] = new PropertyDeclaration("Padding", KnownTypeTable[0x6b]); + KnownPropertyTable[0x24] = new PropertyDeclaration("TabIndex", KnownTypeTable[0x6b]); + KnownPropertyTable[0x25] = new PropertyDeclaration("Template", KnownTypeTable[0x6b]); + KnownPropertyTable[0x26] = new PropertyDeclaration("VerticalContentAlignment", KnownTypeTable[0x6b]); + KnownPropertyTable[0x27] = new PropertyDeclaration("Dock", KnownTypeTable[0xa3]); + KnownPropertyTable[40] = new PropertyDeclaration("LastChildFill", KnownTypeTable[0xa3]); + KnownPropertyTable[0x29] = new PropertyDeclaration("Document", KnownTypeTable[0xa7]); + KnownPropertyTable[0x2a] = new PropertyDeclaration("Children", KnownTypeTable[0xb7]); + KnownPropertyTable[0x2b] = new PropertyDeclaration("Document", KnownTypeTable[0xd3]); + KnownPropertyTable[0x2c] = new PropertyDeclaration("Document", KnownTypeTable[0xd4]); + KnownPropertyTable[0x2d] = new PropertyDeclaration("Style", KnownTypeTable[0xe1]); + KnownPropertyTable[0x2e] = new PropertyDeclaration("FlowDirection", KnownTypeTable[0xe2]); + KnownPropertyTable[0x2f] = new PropertyDeclaration("Height", KnownTypeTable[0xe2]); + KnownPropertyTable[0x30] = new PropertyDeclaration("HorizontalAlignment", KnownTypeTable[0xe2]); + KnownPropertyTable[0x31] = new PropertyDeclaration("Margin", KnownTypeTable[0xe2]); + KnownPropertyTable[50] = new PropertyDeclaration("MaxHeight", KnownTypeTable[0xe2]); + KnownPropertyTable[0x33] = new PropertyDeclaration("MaxWidth", KnownTypeTable[0xe2]); + KnownPropertyTable[0x34] = new PropertyDeclaration("MinHeight", KnownTypeTable[0xe2]); + KnownPropertyTable[0x35] = new PropertyDeclaration("MinWidth", KnownTypeTable[0xe2]); + KnownPropertyTable[0x36] = new PropertyDeclaration("Name", KnownTypeTable[0xe2]); + KnownPropertyTable[0x37] = new PropertyDeclaration("Style", KnownTypeTable[0xe2]); + KnownPropertyTable[0x38] = new PropertyDeclaration("VerticalAlignment", KnownTypeTable[0xe2]); + KnownPropertyTable[0x39] = new PropertyDeclaration("Width", KnownTypeTable[0xe2]); + KnownPropertyTable[0x3a] = new PropertyDeclaration("Children", KnownTypeTable[0xec]); + KnownPropertyTable[0x3b] = new PropertyDeclaration("Children", KnownTypeTable[0xf2]); + KnownPropertyTable[60] = new PropertyDeclaration("GradientStops", KnownTypeTable[0xfb]); + KnownPropertyTable[0x3d] = new PropertyDeclaration("Column", KnownTypeTable[0xfe]); + KnownPropertyTable[0x3e] = new PropertyDeclaration("ColumnSpan", KnownTypeTable[0xfe]); + KnownPropertyTable[0x3f] = new PropertyDeclaration("Row", KnownTypeTable[0xfe]); + KnownPropertyTable[0x40] = new PropertyDeclaration("RowSpan", KnownTypeTable[0xfe]); + KnownPropertyTable[0x41] = new PropertyDeclaration("Header", KnownTypeTable[0x103]); + KnownPropertyTable[0x42] = new PropertyDeclaration("HasHeader", KnownTypeTable[0x10d]); + KnownPropertyTable[0x43] = new PropertyDeclaration("Header", KnownTypeTable[0x10d]); + KnownPropertyTable[0x44] = new PropertyDeclaration("HeaderTemplate", KnownTypeTable[0x10d]); + KnownPropertyTable[0x45] = new PropertyDeclaration("HeaderTemplateSelector", KnownTypeTable[0x10d]); + KnownPropertyTable[70] = new PropertyDeclaration("HasHeader", KnownTypeTable[270]); + KnownPropertyTable[0x47] = new PropertyDeclaration("Header", KnownTypeTable[270]); + KnownPropertyTable[0x48] = new PropertyDeclaration("HeaderTemplate", KnownTypeTable[270]); + KnownPropertyTable[0x49] = new PropertyDeclaration("HeaderTemplateSelector", KnownTypeTable[270]); + KnownPropertyTable[0x4a] = new PropertyDeclaration("NavigateUri", KnownTypeTable[0x111]); + KnownPropertyTable[0x4b] = new PropertyDeclaration("Source", KnownTypeTable[0x119]); + KnownPropertyTable[0x4c] = new PropertyDeclaration("Stretch", KnownTypeTable[0x119]); + KnownPropertyTable[0x4d] = new PropertyDeclaration("ItemContainerStyle", KnownTypeTable[0x149]); + KnownPropertyTable[0x4e] = new PropertyDeclaration("ItemContainerStyleSelector", KnownTypeTable[0x149]); + KnownPropertyTable[0x4f] = new PropertyDeclaration("ItemTemplate", KnownTypeTable[0x149]); + KnownPropertyTable[80] = new PropertyDeclaration("ItemTemplateSelector", KnownTypeTable[0x149]); + KnownPropertyTable[0x51] = new PropertyDeclaration("ItemsPanel", KnownTypeTable[0x149]); + KnownPropertyTable[0x52] = new PropertyDeclaration("ItemsSource", KnownTypeTable[0x149]); + KnownPropertyTable[0x53] = new PropertyDeclaration("Children", KnownTypeTable[0x180]); + KnownPropertyTable[0x54] = new PropertyDeclaration("Children", KnownTypeTable[0x198]); + KnownPropertyTable[0x55] = new PropertyDeclaration("Content", KnownTypeTable[0x1b2]); + KnownPropertyTable[0x56] = new PropertyDeclaration("Background", KnownTypeTable[0x1b5]); + KnownPropertyTable[0x57] = new PropertyDeclaration("Data", KnownTypeTable[0x1ba]); + KnownPropertyTable[0x58] = new PropertyDeclaration("Segments", KnownTypeTable[0x1bb]); + KnownPropertyTable[0x59] = new PropertyDeclaration("Figures", KnownTypeTable[0x1be]); + KnownPropertyTable[90] = new PropertyDeclaration("Child", KnownTypeTable[0x1e5]); + KnownPropertyTable[0x5b] = new PropertyDeclaration("IsOpen", KnownTypeTable[0x1e5]); + KnownPropertyTable[0x5c] = new PropertyDeclaration("Placement", KnownTypeTable[0x1e5]); + KnownPropertyTable[0x5d] = new PropertyDeclaration("PopupAnimation", KnownTypeTable[0x1e5]); + KnownPropertyTable[0x5e] = new PropertyDeclaration("Height", KnownTypeTable[0x21d]); + KnownPropertyTable[0x5f] = new PropertyDeclaration("MaxHeight", KnownTypeTable[0x21d]); + KnownPropertyTable[0x60] = new PropertyDeclaration("MinHeight", KnownTypeTable[0x21d]); + KnownPropertyTable[0x61] = new PropertyDeclaration("CanContentScroll", KnownTypeTable[550]); + KnownPropertyTable[0x62] = new PropertyDeclaration("HorizontalScrollBarVisibility", KnownTypeTable[550]); + KnownPropertyTable[0x63] = new PropertyDeclaration("VerticalScrollBarVisibility", KnownTypeTable[550]); + KnownPropertyTable[100] = new PropertyDeclaration("Fill", KnownTypeTable[0x22e]); + KnownPropertyTable[0x65] = new PropertyDeclaration("Stroke", KnownTypeTable[0x22e]); + KnownPropertyTable[0x66] = new PropertyDeclaration("StrokeThickness", KnownTypeTable[0x22e]); + KnownPropertyTable[0x67] = new PropertyDeclaration("Background", KnownTypeTable[0x27e]); + KnownPropertyTable[0x68] = new PropertyDeclaration("FontFamily", KnownTypeTable[0x27e]); + KnownPropertyTable[0x69] = new PropertyDeclaration("FontSize", KnownTypeTable[0x27e]); + KnownPropertyTable[0x6a] = new PropertyDeclaration("FontStretch", KnownTypeTable[0x27e]); + KnownPropertyTable[0x6b] = new PropertyDeclaration("FontStyle", KnownTypeTable[0x27e]); + KnownPropertyTable[0x6c] = new PropertyDeclaration("FontWeight", KnownTypeTable[0x27e]); + KnownPropertyTable[0x6d] = new PropertyDeclaration("Foreground", KnownTypeTable[0x27e]); + KnownPropertyTable[110] = new PropertyDeclaration("Text", KnownTypeTable[0x27e]); + KnownPropertyTable[0x6f] = new PropertyDeclaration("TextDecorations", KnownTypeTable[0x27e]); + KnownPropertyTable[0x70] = new PropertyDeclaration("TextTrimming", KnownTypeTable[0x27e]); + KnownPropertyTable[0x71] = new PropertyDeclaration("TextWrapping", KnownTypeTable[0x27e]); + KnownPropertyTable[0x72] = new PropertyDeclaration("Text", KnownTypeTable[0x27f]); + KnownPropertyTable[0x73] = new PropertyDeclaration("Background", KnownTypeTable[0x288]); + KnownPropertyTable[0x74] = new PropertyDeclaration("FontFamily", KnownTypeTable[0x288]); + KnownPropertyTable[0x75] = new PropertyDeclaration("FontSize", KnownTypeTable[0x288]); + KnownPropertyTable[0x76] = new PropertyDeclaration("FontStretch", KnownTypeTable[0x288]); + KnownPropertyTable[0x77] = new PropertyDeclaration("FontStyle", KnownTypeTable[0x288]); + KnownPropertyTable[120] = new PropertyDeclaration("FontWeight", KnownTypeTable[0x288]); + KnownPropertyTable[0x79] = new PropertyDeclaration("Foreground", KnownTypeTable[0x288]); + KnownPropertyTable[0x7a] = new PropertyDeclaration("Children", KnownTypeTable[0x29b]); + KnownPropertyTable[0x7b] = new PropertyDeclaration("IsDirectionReversed", KnownTypeTable[0x2a3]); + KnownPropertyTable[0x7c] = new PropertyDeclaration("Maximum", KnownTypeTable[0x2a3]); + KnownPropertyTable[0x7d] = new PropertyDeclaration("Minimum", KnownTypeTable[0x2a3]); + KnownPropertyTable[0x7e] = new PropertyDeclaration("Orientation", KnownTypeTable[0x2a3]); + KnownPropertyTable[0x7f] = new PropertyDeclaration("Value", KnownTypeTable[0x2a3]); + KnownPropertyTable[0x80] = new PropertyDeclaration("ViewportSize", KnownTypeTable[0x2a3]); + KnownPropertyTable[0x81] = new PropertyDeclaration("Children", KnownTypeTable[0x2a7]); + KnownPropertyTable[130] = new PropertyDeclaration("Children", KnownTypeTable[0x2aa]); + KnownPropertyTable[0x83] = new PropertyDeclaration("ClipToBounds", KnownTypeTable[0x2b6]); + KnownPropertyTable[0x84] = new PropertyDeclaration("Focusable", KnownTypeTable[0x2b6]); + KnownPropertyTable[0x85] = new PropertyDeclaration("IsEnabled", KnownTypeTable[0x2b6]); + KnownPropertyTable[0x86] = new PropertyDeclaration("RenderTransform", KnownTypeTable[0x2b6]); + KnownPropertyTable[0x87] = new PropertyDeclaration("Visibility", KnownTypeTable[0x2b6]); + KnownPropertyTable[0x88] = new PropertyDeclaration("Children", KnownTypeTable[0x2d9]); + KnownPropertyTable[0x8a] = new PropertyDeclaration("Child", KnownTypeTable[2]); + KnownPropertyTable[0x8b] = new PropertyDeclaration("Child", KnownTypeTable[4]); + KnownPropertyTable[140] = new PropertyDeclaration("Blocks", KnownTypeTable[8]); + KnownPropertyTable[0x8d] = new PropertyDeclaration("Items", KnownTypeTable[14]); + KnownPropertyTable[0x8e] = new PropertyDeclaration("Child", KnownTypeTable[0x25]); + KnownPropertyTable[0x8f] = new PropertyDeclaration("Inlines", KnownTypeTable[0x29]); + KnownPropertyTable[0x90] = new PropertyDeclaration("KeyFrames", KnownTypeTable[0x2d]); + KnownPropertyTable[0x91] = new PropertyDeclaration("Child", KnownTypeTable[50]); + KnownPropertyTable[0x92] = new PropertyDeclaration("Child", KnownTypeTable[0x36]); + KnownPropertyTable[0x93] = new PropertyDeclaration("Content", KnownTypeTable[0x37]); + KnownPropertyTable[0x94] = new PropertyDeclaration("Content", KnownTypeTable[0x38]); + KnownPropertyTable[0x95] = new PropertyDeclaration("KeyFrames", KnownTypeTable[60]); + KnownPropertyTable[150] = new PropertyDeclaration("Children", KnownTypeTable[0x42]); + KnownPropertyTable[0x97] = new PropertyDeclaration("KeyFrames", KnownTypeTable[0x45]); + KnownPropertyTable[0x98] = new PropertyDeclaration("Content", KnownTypeTable[0x4a]); + KnownPropertyTable[0x99] = new PropertyDeclaration("KeyFrames", KnownTypeTable[0x54]); + KnownPropertyTable[0x9a] = new PropertyDeclaration("Items", KnownTypeTable[0x5c]); + KnownPropertyTable[0x9b] = new PropertyDeclaration("Content", KnownTypeTable[0x5d]); + KnownPropertyTable[0x9c] = new PropertyDeclaration("Items", KnownTypeTable[0x69]); + KnownPropertyTable[0x9d] = new PropertyDeclaration("VisualTree", KnownTypeTable[0x6c]); + KnownPropertyTable[0x9e] = new PropertyDeclaration("VisualTree", KnownTypeTable[120]); + KnownPropertyTable[0x9f] = new PropertyDeclaration("Setters", KnownTypeTable[0x7a]); + KnownPropertyTable[160] = new PropertyDeclaration("KeyFrames", KnownTypeTable[0x81]); + KnownPropertyTable[0xa1] = new PropertyDeclaration("Child", KnownTypeTable[0x85]); + KnownPropertyTable[0xa2] = new PropertyDeclaration("Children", KnownTypeTable[0xa3]); + KnownPropertyTable[0xa3] = new PropertyDeclaration("Document", KnownTypeTable[0xa6]); + KnownPropertyTable[0xa4] = new PropertyDeclaration("KeyFrames", KnownTypeTable[0xab]); + KnownPropertyTable[0xa5] = new PropertyDeclaration("Actions", KnownTypeTable[0xc6]); + KnownPropertyTable[0xa6] = new PropertyDeclaration("Content", KnownTypeTable[0xc7]); + KnownPropertyTable[0xa7] = new PropertyDeclaration("Blocks", KnownTypeTable[0xca]); + KnownPropertyTable[0xa8] = new PropertyDeclaration("Pages", KnownTypeTable[0xcd]); + KnownPropertyTable[0xa9] = new PropertyDeclaration("References", KnownTypeTable[0xce]); + KnownPropertyTable[170] = new PropertyDeclaration("Children", KnownTypeTable[0xcf]); + KnownPropertyTable[0xab] = new PropertyDeclaration("Blocks", KnownTypeTable[0xd0]); + KnownPropertyTable[0xac] = new PropertyDeclaration("Blocks", KnownTypeTable[0xd1]); + KnownPropertyTable[0xad] = new PropertyDeclaration("Document", KnownTypeTable[210]); + KnownPropertyTable[0xae] = new PropertyDeclaration("VisualTree", KnownTypeTable[0xe7]); + KnownPropertyTable[0xaf] = new PropertyDeclaration("Children", KnownTypeTable[0xfe]); + KnownPropertyTable[0xb0] = new PropertyDeclaration("Columns", KnownTypeTable[0x102]); + KnownPropertyTable[0xb1] = new PropertyDeclaration("Content", KnownTypeTable[260]); + KnownPropertyTable[0xb2] = new PropertyDeclaration("Content", KnownTypeTable[0x108]); + KnownPropertyTable[0xb3] = new PropertyDeclaration("Content", KnownTypeTable[0x109]); + KnownPropertyTable[180] = new PropertyDeclaration("Content", KnownTypeTable[0x10d]); + KnownPropertyTable[0xb5] = new PropertyDeclaration("Items", KnownTypeTable[270]); + KnownPropertyTable[0xb6] = new PropertyDeclaration("VisualTree", KnownTypeTable[0x10f]); + KnownPropertyTable[0xb7] = new PropertyDeclaration("Inlines", KnownTypeTable[0x111]); + KnownPropertyTable[0xb8] = new PropertyDeclaration("Children", KnownTypeTable[0x120]); + KnownPropertyTable[0xb9] = new PropertyDeclaration("Child", KnownTypeTable[0x121]); + KnownPropertyTable[0xba] = new PropertyDeclaration("Child", KnownTypeTable[0x124]); + KnownPropertyTable[0xbb] = new PropertyDeclaration("NameValue", KnownTypeTable[300]); + KnownPropertyTable[0xbc] = new PropertyDeclaration("KeyFrames", KnownTypeTable[0x131]); + KnownPropertyTable[0xbd] = new PropertyDeclaration("KeyFrames", KnownTypeTable[0x138]); + KnownPropertyTable[190] = new PropertyDeclaration("KeyFrames", KnownTypeTable[0x143]); + KnownPropertyTable[0xbf] = new PropertyDeclaration("Inlines", KnownTypeTable[0x147]); + KnownPropertyTable[0xc0] = new PropertyDeclaration("Items", KnownTypeTable[0x149]); + KnownPropertyTable[0xc1] = new PropertyDeclaration("VisualTree", KnownTypeTable[330]); + KnownPropertyTable[0xc2] = new PropertyDeclaration("Content", KnownTypeTable[0x15a]); + KnownPropertyTable[0xc3] = new PropertyDeclaration("GradientStops", KnownTypeTable[0x166]); + KnownPropertyTable[0xc4] = new PropertyDeclaration("ListItems", KnownTypeTable[0x174]); + KnownPropertyTable[0xc5] = new PropertyDeclaration("Items", KnownTypeTable[0x175]); + KnownPropertyTable[0xc6] = new PropertyDeclaration("Content", KnownTypeTable[0x176]); + KnownPropertyTable[0xc7] = new PropertyDeclaration("Blocks", KnownTypeTable[0x178]); + KnownPropertyTable[200] = new PropertyDeclaration("Items", KnownTypeTable[0x179]); + KnownPropertyTable[0xc9] = new PropertyDeclaration("Content", KnownTypeTable[0x17a]); + KnownPropertyTable[0xca] = new PropertyDeclaration("KeyFrames", KnownTypeTable[0x185]); + KnownPropertyTable[0xcb] = new PropertyDeclaration("Items", KnownTypeTable[0x191]); + KnownPropertyTable[0xcc] = new PropertyDeclaration("Items", KnownTypeTable[0x192]); + KnownPropertyTable[0xcd] = new PropertyDeclaration("Items", KnownTypeTable[0x193]); + KnownPropertyTable[0xce] = new PropertyDeclaration("Children", KnownTypeTable[0x199]); + KnownPropertyTable[0xcf] = new PropertyDeclaration("Bindings", KnownTypeTable[0x1a0]); + KnownPropertyTable[0xd0] = new PropertyDeclaration("Setters", KnownTypeTable[0x1a2]); + KnownPropertyTable[0xd1] = new PropertyDeclaration("Setters", KnownTypeTable[0x1a3]); + KnownPropertyTable[210] = new PropertyDeclaration("KeyFrames", KnownTypeTable[0x1ac]); + KnownPropertyTable[0xd3] = new PropertyDeclaration("Child", KnownTypeTable[0x1b3]); + KnownPropertyTable[0xd4] = new PropertyDeclaration("Content", KnownTypeTable[0x1b4]); + KnownPropertyTable[0xd5] = new PropertyDeclaration("Children", KnownTypeTable[0x1b5]); + KnownPropertyTable[0xd6] = new PropertyDeclaration("Inlines", KnownTypeTable[0x1b6]); + KnownPropertyTable[0xd7] = new PropertyDeclaration("Children", KnownTypeTable[0x1b7]); + KnownPropertyTable[0xd8] = new PropertyDeclaration("KeyFrames", KnownTypeTable[460]); + KnownPropertyTable[0xd9] = new PropertyDeclaration("KeyFrames", KnownTypeTable[470]); + KnownPropertyTable[0xda] = new PropertyDeclaration("Bindings", KnownTypeTable[0x1e7]); + KnownPropertyTable[0xdb] = new PropertyDeclaration("KeyFrames", KnownTypeTable[0x1f1]); + KnownPropertyTable[220] = new PropertyDeclaration("GradientStops", KnownTypeTable[0x1f6]); + KnownPropertyTable[0xdd] = new PropertyDeclaration("Content", KnownTypeTable[0x1f7]); + KnownPropertyTable[0xde] = new PropertyDeclaration("KeyFrames", KnownTypeTable[510]); + KnownPropertyTable[0xdf] = new PropertyDeclaration("Content", KnownTypeTable[0x20a]); + KnownPropertyTable[0xe0] = new PropertyDeclaration("Document", KnownTypeTable[0x20f]); + KnownPropertyTable[0xe1] = new PropertyDeclaration("KeyFrames", KnownTypeTable[0x215]); + KnownPropertyTable[0xe2] = new PropertyDeclaration("Text", KnownTypeTable[0x21e]); + KnownPropertyTable[0xe3] = new PropertyDeclaration("Content", KnownTypeTable[550]); + KnownPropertyTable[0xe4] = new PropertyDeclaration("Blocks", KnownTypeTable[0x227]); + KnownPropertyTable[0xe5] = new PropertyDeclaration("Items", KnownTypeTable[0x229]); + KnownPropertyTable[230] = new PropertyDeclaration("KeyFrames", KnownTypeTable[0x232]); + KnownPropertyTable[0xe7] = new PropertyDeclaration("KeyFrames", KnownTypeTable[0x23b]); + KnownPropertyTable[0xe8] = new PropertyDeclaration("Inlines", KnownTypeTable[580]); + KnownPropertyTable[0xe9] = new PropertyDeclaration("Children", KnownTypeTable[0x259]); + KnownPropertyTable[0xea] = new PropertyDeclaration("Items", KnownTypeTable[0x25c]); + KnownPropertyTable[0xeb] = new PropertyDeclaration("Content", KnownTypeTable[0x25d]); + KnownPropertyTable[0xec] = new PropertyDeclaration("Children", KnownTypeTable[0x260]); + KnownPropertyTable[0xed] = new PropertyDeclaration("KeyFrames", KnownTypeTable[0x266]); + KnownPropertyTable[0xee] = new PropertyDeclaration("Setters", KnownTypeTable[620]); + KnownPropertyTable[0xef] = new PropertyDeclaration("Items", KnownTypeTable[0x26f]); + KnownPropertyTable[240] = new PropertyDeclaration("Content", KnownTypeTable[0x270]); + KnownPropertyTable[0xf1] = new PropertyDeclaration("Children", KnownTypeTable[0x271]); + KnownPropertyTable[0xf2] = new PropertyDeclaration("RowGroups", KnownTypeTable[0x272]); + KnownPropertyTable[0xf3] = new PropertyDeclaration("Blocks", KnownTypeTable[0x273]); + KnownPropertyTable[0xf4] = new PropertyDeclaration("Cells", KnownTypeTable[0x275]); + KnownPropertyTable[0xf5] = new PropertyDeclaration("Rows", KnownTypeTable[630]); + KnownPropertyTable[0xf6] = new PropertyDeclaration("Inlines", KnownTypeTable[0x27e]); + KnownPropertyTable[0xf7] = new PropertyDeclaration("KeyFrames", KnownTypeTable[0x28e]); + KnownPropertyTable[0xf8] = new PropertyDeclaration("Content", KnownTypeTable[0x29c]); + KnownPropertyTable[0xf9] = new PropertyDeclaration("Items", KnownTypeTable[0x29d]); + KnownPropertyTable[250] = new PropertyDeclaration("Children", KnownTypeTable[670]); + KnownPropertyTable[0xfb] = new PropertyDeclaration("Children", KnownTypeTable[0x29f]); + KnownPropertyTable[0xfc] = new PropertyDeclaration("ToolBars", KnownTypeTable[0x2a0]); + KnownPropertyTable[0xfd] = new PropertyDeclaration("Content", KnownTypeTable[0x2a1]); + KnownPropertyTable[0xfe] = new PropertyDeclaration("Items", KnownTypeTable[0x2ae]); + KnownPropertyTable[0xff] = new PropertyDeclaration("Items", KnownTypeTable[0x2af]); + KnownPropertyTable[0x100] = new PropertyDeclaration("Setters", KnownTypeTable[0x2b0]); + KnownPropertyTable[0x101] = new PropertyDeclaration("Inlines", KnownTypeTable[0x2be]); + KnownPropertyTable[0x102] = new PropertyDeclaration("Children", KnownTypeTable[0x2bf]); + KnownPropertyTable[0x103] = new PropertyDeclaration("Content", KnownTypeTable[0x2c2]); + KnownPropertyTable[260] = new PropertyDeclaration("KeyFrames", KnownTypeTable[0x2c8]); + KnownPropertyTable[0x105] = new PropertyDeclaration("KeyFrames", KnownTypeTable[720]); + KnownPropertyTable[0x106] = new PropertyDeclaration("Child", KnownTypeTable[0x2d8]); + KnownPropertyTable[0x107] = new PropertyDeclaration("Children", KnownTypeTable[730]); + KnownPropertyTable[0x108] = new PropertyDeclaration("Children", KnownTypeTable[0x2db]); + KnownPropertyTable[0x109] = new PropertyDeclaration("Children", KnownTypeTable[0x2dc]); + KnownPropertyTable[0x10a] = new PropertyDeclaration("Content", KnownTypeTable[0x2e3]); + KnownPropertyTable[0x10b] = new PropertyDeclaration("Children", KnownTypeTable[0x2e6]); + KnownPropertyTable[0x10c] = new PropertyDeclaration("XmlSerializer", KnownTypeTable[0x2f2]); + KnownResourceTable.Add(1, new ResourceName("SystemColors.ActiveBorderBrush")); + KnownResourceTable.Add(0x1f, new ResourceName("SystemColors.ActiveBorderColor")); + KnownResourceTable.Add(2, new ResourceName("SystemColors.ActiveCaptionBrush")); + KnownResourceTable.Add(0x20, new ResourceName("SystemColors.ActiveCaptionColor")); + KnownResourceTable.Add(3, new ResourceName("SystemColors.ActiveCaptionTextBrush")); + KnownResourceTable.Add(0x21, new ResourceName("SystemColors.ActiveCaptionTextColor")); + KnownResourceTable.Add(4, new ResourceName("SystemColors.AppWorkspaceBrush")); + KnownResourceTable.Add(0x22, new ResourceName("SystemParameters.AppWorkspaceColor")); + KnownResourceTable.Add(0xc6, new ResourceName("SystemParameters.Border")); + KnownResourceTable.Add(0xca, new ResourceName("SystemParameters.BorderWidth")); + KnownResourceTable.Add(0x40, new ResourceName("SystemFonts.CaptionFontFamily")); + KnownResourceTable.Add(0x3f, new ResourceName("SystemFonts.CaptionFontSize")); + KnownResourceTable.Add(0x41, new ResourceName("SystemFonts.CaptionFontStyle")); + KnownResourceTable.Add(0x43, new ResourceName("SystemFonts.CaptionFontTextDecorations")); + KnownResourceTable.Add(0x42, new ResourceName("SystemFonts.CaptionFontWeight")); + KnownResourceTable.Add(0xce, new ResourceName("SystemParameters.CaptionHeight")); + KnownResourceTable.Add(0xcd, new ResourceName("SystemParameters.CaptionWidth")); + KnownResourceTable.Add(0xc7, new ResourceName("SystemParameters.CaretWidth")); + KnownResourceTable.Add(0xba, new ResourceName("SystemParameters.ClientAreaAnimation")); + KnownResourceTable.Add(0xb9, new ResourceName("SystemParameters.ComboBoxAnimation")); + KnownResourceTable.Add(210, new ResourceName("SystemParameters.ComboBoxPopupAnimation")); + KnownResourceTable.Add(5, new ResourceName("SystemColors.ControlBrush")); + KnownResourceTable.Add(0x23, new ResourceName("SystemColors.ControlColor")); + KnownResourceTable.Add(6, new ResourceName("SystemColors.ControlDarkBrush")); + KnownResourceTable.Add(0x24, new ResourceName("SystemColors.ControlDarkColor")); + KnownResourceTable.Add(7, new ResourceName("SystemColors.ControlDarkDarkBrush")); + KnownResourceTable.Add(0x25, new ResourceName("SystemColors.ControlDarkDarkColor")); + KnownResourceTable.Add(8, new ResourceName("SystemColors.ControlLightBrush")); + KnownResourceTable.Add(0x26, new ResourceName("SystemColors.ControlLightColor")); + KnownResourceTable.Add(9, new ResourceName("SystemColors.ControlLightLightBrush")); + KnownResourceTable.Add(0x27, new ResourceName("SystemColors.ControlLightLightColor")); + KnownResourceTable.Add(10, new ResourceName("SystemColors.ControlTextBrush")); + KnownResourceTable.Add(40, new ResourceName("SystemColors.ControlTextColor")); + KnownResourceTable.Add(0x62, new ResourceName("SystemParameters.CursorHeight")); + KnownResourceTable.Add(0xbb, new ResourceName("SystemParameters.CursorShadow")); + KnownResourceTable.Add(0x61, new ResourceName("SystemParameters.CursorWidth")); + KnownResourceTable.Add(11, new ResourceName("SystemColors.DesktopBrush")); + KnownResourceTable.Add(0x29, new ResourceName("SystemColors.DesktopColor")); + KnownResourceTable.Add(0xc9, new ResourceName("SystemParameters.DragFullWindows")); + KnownResourceTable.Add(0xa7, new ResourceName("SystemParameters.DropShadow")); + KnownResourceTable.Add(0x65, new ResourceName("SystemParameters.FixedFrameHorizontalBorderHeight")); + KnownResourceTable.Add(0x66, new ResourceName("SystemParameters.FixedFrameVerticalBorderWidth")); + KnownResourceTable.Add(0xa8, new ResourceName("SystemParameters.FlatMenu")); + KnownResourceTable.Add(0xa5, new ResourceName("SystemParameters.FocusBorderHeight")); + KnownResourceTable.Add(0xa4, new ResourceName("SystemParameters.FocusBorderWidth")); + KnownResourceTable.Add(0x67, new ResourceName("SystemParameters.FocusHorizontalBorderHeight")); + KnownResourceTable.Add(0x68, new ResourceName("SystemParameters.FocusVerticalBorderWidth")); + KnownResourceTable.Add(0xd7, new ResourceName("SystemParameters.FocusVisualStyle")); + KnownResourceTable.Add(200, new ResourceName("SystemParameters.ForegroundFlashCount")); + KnownResourceTable.Add(0x6a, new ResourceName("SystemParameters.FullPrimaryScreenHeight")); + KnownResourceTable.Add(0x69, new ResourceName("SystemParameters.FullPrimaryScreenWidth")); + KnownResourceTable.Add(12, new ResourceName("SystemColors.GradientActiveCaptionBrush")); + KnownResourceTable.Add(0x2a, new ResourceName("SystemColors.GradientActiveCaptionColor")); + KnownResourceTable.Add(0xbc, new ResourceName("SystemColors.GradientCaptions")); + KnownResourceTable.Add(13, new ResourceName("SystemColors.GradientInactiveCaptionBrush")); + KnownResourceTable.Add(0x2b, new ResourceName("SystemColors.GradientInactiveCaptionColor")); + KnownResourceTable.Add(14, new ResourceName("SystemColors.GrayTextBrush")); + KnownResourceTable.Add(0x2c, new ResourceName("SystemColors.GrayTextColor")); + KnownResourceTable.Add(0xde, new ResourceName("GridView.GridViewItemContainerStyle")); + KnownResourceTable.Add(220, new ResourceName("GridView.GridViewScrollViewerStyle")); + KnownResourceTable.Add(0xdd, new ResourceName("GridView.GridViewStyle")); + KnownResourceTable.Add(0xa6, new ResourceName("SystemParameters.HighContrast")); + KnownResourceTable.Add(15, new ResourceName("SystemColors.HighlightBrush")); + KnownResourceTable.Add(0x2d, new ResourceName("SystemColors.HighlightColor")); + KnownResourceTable.Add(0x10, new ResourceName("SystemColors.HighlightTextBrush")); + KnownResourceTable.Add(0x2e, new ResourceName("SystemColors.HighlightTextColor")); + KnownResourceTable.Add(0x6b, new ResourceName("SystemParameters.HorizontalScrollBarButtonWidth")); + KnownResourceTable.Add(0x6c, new ResourceName("SystemParameters.HorizontalScrollBarHeight")); + KnownResourceTable.Add(0x6d, new ResourceName("SystemParameters.HorizontalScrollBarThumbWidth")); + KnownResourceTable.Add(0x11, new ResourceName("SystemColors.HotTrackBrush")); + KnownResourceTable.Add(0x2f, new ResourceName("SystemColors.HotTrackColor")); + KnownResourceTable.Add(0xbd, new ResourceName("SystemParameters.HotTracking")); + KnownResourceTable.Add(0x59, new ResourceName("SystemParameters.IconFontFamily")); + KnownResourceTable.Add(0x58, new ResourceName("SystemParameters.IconFontSize")); + KnownResourceTable.Add(90, new ResourceName("SystemParameters.IconFontStyle")); + KnownResourceTable.Add(0x5c, new ResourceName("SystemParameters.IconFontTextDecorations")); + KnownResourceTable.Add(0x5b, new ResourceName("SystemParameters.IconFontWeight")); + KnownResourceTable.Add(0x71, new ResourceName("SystemParameters.IconGridHeight")); + KnownResourceTable.Add(0x70, new ResourceName("SystemParameters.IconGridWidth")); + KnownResourceTable.Add(0x6f, new ResourceName("SystemParameters.IconHeight")); + KnownResourceTable.Add(170, new ResourceName("SystemParameters.IconHorizontalSpacing")); + KnownResourceTable.Add(0xac, new ResourceName("SystemParameters.IconTitleWrap")); + KnownResourceTable.Add(0xab, new ResourceName("SystemParameters.IconVerticalSpacing")); + KnownResourceTable.Add(110, new ResourceName("SystemParameters.IconWidth")); + KnownResourceTable.Add(0x12, new ResourceName("SystemColors.InactiveBorderBrush")); + KnownResourceTable.Add(0x30, new ResourceName("SystemColors.InactiveBorderColor")); + KnownResourceTable.Add(0x13, new ResourceName("SystemColors.InactiveCaptionBrush")); + KnownResourceTable.Add(0x31, new ResourceName("SystemColors.InactiveCaptionColor")); + KnownResourceTable.Add(20, new ResourceName("SystemColors.InactiveCaptionTextBrush")); + KnownResourceTable.Add(50, new ResourceName("SystemColors.InactiveCaptionTextColor")); + KnownResourceTable.Add(0x15, new ResourceName("SystemColors.InfoBrush")); + KnownResourceTable.Add(0x33, new ResourceName("SystemColors.InfoColor")); + KnownResourceTable.Add(0x16, new ResourceName("SystemColors.InfoTextBrush")); + KnownResourceTable.Add(0x34, new ResourceName("SystemColors.InfoTextColor")); + KnownResourceTable.Add(0x3d, new ResourceName("SystemColors.InternalSystemColorsEnd")); + KnownResourceTable.Add(0, new ResourceName("InternalSystemColorsStart")); + KnownResourceTable.Add(0x5d, new ResourceName("InternalSystemFontsEnd")); + KnownResourceTable.Add(0x3e, new ResourceName("InternalSystemFontsStart")); + KnownResourceTable.Add(0xda, new ResourceName("InternalSystemParametersEnd")); + KnownResourceTable.Add(0x5e, new ResourceName("InternalSystemParametersStart")); + KnownResourceTable.Add(0xe8, new ResourceName("InternalSystemThemeStylesEnd")); + KnownResourceTable.Add(0xd6, new ResourceName("InternalSystemThemeStylesStart")); + KnownResourceTable.Add(0x95, new ResourceName("SystemParameters.IsImmEnabled")); + KnownResourceTable.Add(150, new ResourceName("SystemParameters.IsMediaCenter")); + KnownResourceTable.Add(0x97, new ResourceName("SystemParameters.IsMenuDropRightAligned")); + KnownResourceTable.Add(0x98, new ResourceName("SystemParameters.IsMiddleEastEnabled")); + KnownResourceTable.Add(0x99, new ResourceName("SystemParameters.IsMousePresent")); + KnownResourceTable.Add(0x9a, new ResourceName("SystemParameters.IsMouseWheelPresent")); + KnownResourceTable.Add(0x9b, new ResourceName("SystemParameters.IsPenWindows")); + KnownResourceTable.Add(0x9c, new ResourceName("SystemParameters.IsRemotelyControlled")); + KnownResourceTable.Add(0x9d, new ResourceName("SystemParameters.IsRemoteSession")); + KnownResourceTable.Add(0x9f, new ResourceName("SystemParameters.IsSlowMachine")); + KnownResourceTable.Add(0xa1, new ResourceName("SystemParameters.IsTabletPC")); + KnownResourceTable.Add(0x91, new ResourceName("SystemParameters.KanjiWindowHeight")); + KnownResourceTable.Add(0xad, new ResourceName("SystemParameters.KeyboardCues")); + KnownResourceTable.Add(0xae, new ResourceName("SystemParameters.KeyboardDelay")); + KnownResourceTable.Add(0xaf, new ResourceName("SystemParameters.KeyboardPreference")); + KnownResourceTable.Add(0xb0, new ResourceName("SystemParameters.KeyboardSpeed")); + KnownResourceTable.Add(190, new ResourceName("SystemParameters.ListBoxSmoothScrolling")); + KnownResourceTable.Add(0x73, new ResourceName("SystemParameters.MaximizedPrimaryScreenHeight")); + KnownResourceTable.Add(0x72, new ResourceName("SystemParameters.MaximizedPrimaryScreenWidth")); + KnownResourceTable.Add(0x75, new ResourceName("SystemParameters.MaximumWindowTrackHeight")); + KnownResourceTable.Add(0x74, new ResourceName("SystemParameters.MaximumWindowTrackWidth")); + KnownResourceTable.Add(0xbf, new ResourceName("SystemParameters.MenuAnimation")); + KnownResourceTable.Add(0x18, new ResourceName("SystemColors.MenuBarBrush")); + KnownResourceTable.Add(0x36, new ResourceName("SystemColors.MenuBarColor")); + KnownResourceTable.Add(0x92, new ResourceName("SystemParameters.MenuBarHeight")); + KnownResourceTable.Add(0x17, new ResourceName("SystemColors.MenuBrush")); + KnownResourceTable.Add(0x79, new ResourceName("SystemParameters.MenuButtonHeight")); + KnownResourceTable.Add(120, new ResourceName("SystemParameters.MenuButtonWidth")); + KnownResourceTable.Add(0x77, new ResourceName("SystemParameters.MenuCheckmarkHeight")); + KnownResourceTable.Add(0x76, new ResourceName("SystemParameters.MenuCheckmarkWidth")); + KnownResourceTable.Add(0x35, new ResourceName("SystemColors.MenuColor")); + KnownResourceTable.Add(0xb6, new ResourceName("SystemParameters.MenuDropAlignment")); + KnownResourceTable.Add(0xb7, new ResourceName("SystemParameters.MenuFade")); + KnownResourceTable.Add(0x4a, new ResourceName("SystemFonts.MenuFontFamily")); + KnownResourceTable.Add(0x49, new ResourceName("SystemFonts.MenuFontSize")); + KnownResourceTable.Add(0x4b, new ResourceName("SystemFonts.MenuFontStyle")); + KnownResourceTable.Add(0x4d, new ResourceName("SystemFonts.MenuFontTextDecorations")); + KnownResourceTable.Add(0x4c, new ResourceName("SystemFonts.MenuFontWeight")); + KnownResourceTable.Add(0xd1, new ResourceName("SystemParameters.MenuHeight")); + KnownResourceTable.Add(0x19, new ResourceName("SystemColors.MenuHighlightBrush")); + KnownResourceTable.Add(0x37, new ResourceName("SystemColors.MenuHighlightColor")); + KnownResourceTable.Add(0xdb, new ResourceName("MenuItem.MenuItemSeparatorStyle")); + KnownResourceTable.Add(0xd3, new ResourceName("SystemParameters.MenuPopupAnimation")); + KnownResourceTable.Add(0xb8, new ResourceName("SystemParameters.MenuShowDelay")); + KnownResourceTable.Add(0x1a, new ResourceName("SystemColors.MenuTextBrush")); + KnownResourceTable.Add(0x38, new ResourceName("SystemColors.MenuTextColor")); + KnownResourceTable.Add(0xd0, new ResourceName("SystemParameters.MenuWidth")); + KnownResourceTable.Add(0x54, new ResourceName("SystemFonts.MessageFontFamily")); + KnownResourceTable.Add(0x53, new ResourceName("SystemFonts..MessageFontSize")); + KnownResourceTable.Add(0x55, new ResourceName("SystemFonts.MessageFontStyle")); + KnownResourceTable.Add(0x57, new ResourceName("SystemFonts.MessageFontTextDecorations")); + KnownResourceTable.Add(0x56, new ResourceName("SystemFonts.MessageFontWeight")); + KnownResourceTable.Add(0xc5, new ResourceName("SystemParameters.MinimizeAnimation")); + KnownResourceTable.Add(0x7f, new ResourceName("SystemParameters.MinimizedGridHeight")); + KnownResourceTable.Add(0x7e, new ResourceName("SystemParameters.MinimizedGridWidth")); + KnownResourceTable.Add(0x7d, new ResourceName("SystemParameters.MinimizedWindowHeight")); + KnownResourceTable.Add(0x7c, new ResourceName("SystemParameters.MinimizedWindowWidth")); + KnownResourceTable.Add(0x7b, new ResourceName("SystemParameters.MinimumWindowHeight")); + KnownResourceTable.Add(0x81, new ResourceName("SystemParameters.MinimumWindowTrackHeight")); + KnownResourceTable.Add(0x80, new ResourceName("SystemParameters.MinimumWindowTrackWidth")); + KnownResourceTable.Add(0x7a, new ResourceName("SystemParameters.MinimumWindowWidth")); + KnownResourceTable.Add(180, new ResourceName("SystemParameters.MouseHoverHeight")); + KnownResourceTable.Add(0xb3, new ResourceName("SystemParameters.MouseHoverTime")); + KnownResourceTable.Add(0xb5, new ResourceName("SystemParameters.MouseHoverWidth")); + KnownResourceTable.Add(0xd8, new ResourceName("SystemParameters.NavigationChromeDownLevelStyle")); + KnownResourceTable.Add(0xd9, new ResourceName("SystemParameters.NavigationChromeStyle")); + KnownResourceTable.Add(0xd5, new ResourceName("SystemParameters.PowerLineStatus")); + KnownResourceTable.Add(0x83, new ResourceName("SystemParameters.PrimaryScreenHeight")); + KnownResourceTable.Add(130, new ResourceName("SystemParameters.PrimaryScreenWidth")); + KnownResourceTable.Add(0x86, new ResourceName("SystemParameters.ResizeFrameHorizontalBorderHeight")); + KnownResourceTable.Add(0x87, new ResourceName("SystemParameters.ResizeFrameVerticalBorderWidth")); + KnownResourceTable.Add(0x1b, new ResourceName("SystemColors.ScrollBarBrush")); + KnownResourceTable.Add(0x39, new ResourceName("SystemColors.ScrollBarColor")); + KnownResourceTable.Add(0xcc, new ResourceName("SystemParameters.ScrollHeight")); + KnownResourceTable.Add(0xcb, new ResourceName("SystemParameters.ScrollWidth")); + KnownResourceTable.Add(0xc0, new ResourceName("SystemParameters.SelectionFade")); + KnownResourceTable.Add(0x9e, new ResourceName("SystemParameters.ShowSounds")); + KnownResourceTable.Add(0x45, new ResourceName("SystemFonts.SmallCaptionFontFamily")); + KnownResourceTable.Add(0x44, new ResourceName("SystemFonts.SmallCaptionFontSize")); + KnownResourceTable.Add(70, new ResourceName("SystemFonts.SmallCaptionFontStyle")); + KnownResourceTable.Add(0x48, new ResourceName("SystemFonts.SmallCaptionFontTextDecorations")); + KnownResourceTable.Add(0x47, new ResourceName("SystemFonts.SmallCaptionFontWeight")); + KnownResourceTable.Add(0x93, new ResourceName("SystemParameters.SmallCaptionHeight")); + KnownResourceTable.Add(0xcf, new ResourceName("SystemParameters.SmallCaptionWidth")); + KnownResourceTable.Add(0x89, new ResourceName("SystemParameters.SmallIconHeight")); + KnownResourceTable.Add(0x88, new ResourceName("SystemParameters.SmallIconWidth")); + KnownResourceTable.Add(0x8b, new ResourceName("SystemParameters.SmallWindowCaptionButtonHeight")); + KnownResourceTable.Add(0x8a, new ResourceName("SystemParameters.SmallWindowCaptionButtonWidth")); + KnownResourceTable.Add(0xb1, new ResourceName("SystemParameters.SnapToDefaultButton")); + KnownResourceTable.Add(0xdf, new ResourceName("StatusBar.StatusBarSeparatorStyle")); + KnownResourceTable.Add(0x4f, new ResourceName("SystemFonts.StatusFontFamily")); + KnownResourceTable.Add(0x4e, new ResourceName("SystemFonts.StatusFontSize")); + KnownResourceTable.Add(80, new ResourceName("SystemFonts.StatusFontStyle")); + KnownResourceTable.Add(0x52, new ResourceName("SystemFonts.StatusFontTextDecorations")); + KnownResourceTable.Add(0x51, new ResourceName("SystemFonts.StatusFontWeight")); + KnownResourceTable.Add(0xc1, new ResourceName("SystemParameters.StylusHotTracking")); + KnownResourceTable.Add(160, new ResourceName("SystemParameters.SwapButtons")); + KnownResourceTable.Add(0x63, new ResourceName("SystemParameters.ThickHorizontalBorderHeight")); + KnownResourceTable.Add(100, new ResourceName("SystemParameters.ThickVerticalBorderWidth")); + KnownResourceTable.Add(0x5f, new ResourceName("SystemParameters.ThinHorizontalBorderHeight")); + KnownResourceTable.Add(0x60, new ResourceName("SystemParameters.ThinVerticalBorderWidth")); + KnownResourceTable.Add(0xe0, new ResourceName("ToolBar.ButtonStyle")); + KnownResourceTable.Add(0xe3, new ResourceName("ToolBar.CheckBoxStyle")); + KnownResourceTable.Add(0xe5, new ResourceName("ToolBar.ComboBoxStyle")); + KnownResourceTable.Add(0xe7, new ResourceName("ToolBar.MenuStyle")); + KnownResourceTable.Add(0xe4, new ResourceName("ToolBar.RadioButtonStyle")); + KnownResourceTable.Add(0xe2, new ResourceName("ToolBar.SeparatorStyle")); + KnownResourceTable.Add(230, new ResourceName("ToolBar.TextBoxStyle")); + KnownResourceTable.Add(0xe1, new ResourceName("ToolBar.ToggleButtonStyle")); + KnownResourceTable.Add(0xc2, new ResourceName("SystemParameters.ToolTipAnimation")); + KnownResourceTable.Add(0xc3, new ResourceName("SystemParameters.ToolTipFade")); + KnownResourceTable.Add(0xd4, new ResourceName("SystemParameters.ToolTipPopupAnimation")); + KnownResourceTable.Add(0xc4, new ResourceName("SystemParameters.UIEffects")); + KnownResourceTable.Add(0x8f, new ResourceName("SystemParameters.VerticalScrollBarButtonHeight")); + KnownResourceTable.Add(0x94, new ResourceName("SystemParameters.VerticalScrollBarThumbHeight")); + KnownResourceTable.Add(0x8e, new ResourceName("SystemParameters.VerticalScrollBarWidth")); + KnownResourceTable.Add(0x8d, new ResourceName("SystemParameters.VirtualScreenHeight")); + KnownResourceTable.Add(0xa2, new ResourceName("SystemParameters.VirtualScreenLeft")); + KnownResourceTable.Add(0xa3, new ResourceName("SystemParameters.VirtualScreenTop")); + KnownResourceTable.Add(140, new ResourceName("SystemParameters.VirtualScreenWidth")); + KnownResourceTable.Add(0xb2, new ResourceName("SystemParameters.WheelScrollLines")); + KnownResourceTable.Add(0x1c, new ResourceName("SystemColors.WindowBrush")); + KnownResourceTable.Add(0x85, new ResourceName("SystemParameters.WindowCaptionButtonHeight")); + KnownResourceTable.Add(0x84, new ResourceName("SystemParameters.WindowCaptionButtonWidth")); + KnownResourceTable.Add(0x90, new ResourceName("SystemParameters.WindowCaptionHeight")); + KnownResourceTable.Add(0x3a, new ResourceName("SystemColors.WindowColor")); + KnownResourceTable.Add(0x1d, new ResourceName("SystemColors.WindowFrameBrush")); + KnownResourceTable.Add(0x3b, new ResourceName("SystemColors.WindowFrameColor")); + KnownResourceTable.Add(30, new ResourceName("SystemColors.WindowTextBrush")); + KnownResourceTable.Add(60, new ResourceName("SystemColors.WindowTextColor")); + KnownResourceTable.Add(0xa9, new ResourceName("SystemParameters.WorkArea")); + } + + #endregion + + public bool IsKnownType(string type) + { + foreach (TypeDeclaration td in KnownTypeTable) + if (String.CompareOrdinal(td.Name, type) == 0) + return true; + + return false; + } + } +} diff --git a/ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/PropertyDeclaration.cs b/ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/PropertyDeclaration.cs new file mode 100644 index 000000000..fcb7f6ba4 --- /dev/null +++ b/ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/PropertyDeclaration.cs @@ -0,0 +1,58 @@ +// Copyright (c) Cristian Civera (cristian@aspitalia.com) +// This code is distributed under the MS-PL (for details please see \doc\MS-PL.txt) + +using System; +using System.Collections.Generic; +using System.Text; + +namespace Ricciolo.StylesExplorer.MarkupReflection +{ + internal class PropertyDeclaration + { + private TypeDeclaration declaringType; + private string name; + + // Methods + public PropertyDeclaration(string name) + { + this.name = name; + this.declaringType = null; + } + + public PropertyDeclaration(string name, TypeDeclaration declaringType) + { + this.name = name; + this.declaringType = declaringType; + } + + public override string ToString() + { + if (((this.DeclaringType != null) && (this.DeclaringType.Name == "XmlNamespace")) && ((this.DeclaringType.Namespace == null) && (this.DeclaringType.Assembly == null))) + { + if ((this.Name == null) || (this.Name.Length == 0)) + { + return "xmlns"; + } + return ("xmlns:" + this.Name); + } + return this.Name; + } + + // Properties + public TypeDeclaration DeclaringType + { + get + { + return this.declaringType; + } + } + + public string Name + { + get + { + return this.name; + } + } + } +} diff --git a/ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/ResourceName.cs b/ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/ResourceName.cs new file mode 100644 index 000000000..a8b0b37d2 --- /dev/null +++ b/ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/ResourceName.cs @@ -0,0 +1,32 @@ +// Copyright (c) Cristian Civera (cristian@aspitalia.com) +// This code is distributed under the MS-PL (for details please see \doc\MS-PL.txt) + +using System; +using System.Collections.Generic; +using System.Text; + +namespace Ricciolo.StylesExplorer.MarkupReflection +{ + public class ResourceName + { + private string name; + + public ResourceName(string name) + { + this.name = name; + } + + public override string ToString() + { + return this.Name; + } + + public string Name + { + get + { + return this.name; + } + } + } +} diff --git a/ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/TypeDeclaration.cs b/ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/TypeDeclaration.cs new file mode 100644 index 000000000..2efaab843 --- /dev/null +++ b/ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/TypeDeclaration.cs @@ -0,0 +1,137 @@ +// Copyright (c) Cristian Civera (cristian@aspitalia.com) +// This code is distributed under the MS-PL (for details please see \doc\MS-PL.txt) + +using System; + +namespace Ricciolo.StylesExplorer.MarkupReflection +{ + internal class TypeDeclaration + { + private readonly XmlBamlReader reader; + + private readonly short _assemblyId; + private readonly bool _isKnown; + private readonly string _name; + private readonly string _namespaceName; + private readonly bool _isExtension; + private IType _type; + private bool _typeLoaded; + private readonly ITypeResolver resolver; + + public TypeDeclaration(ITypeResolver resolver, string name, string namespaceName, short assemblyId) + : this(null, resolver, name, namespaceName, assemblyId, true) + { + + } + + public TypeDeclaration(ITypeResolver resolver, string name, string namespaceName, short assemblyId, bool isExtension) + : this(null, resolver, name, namespaceName, assemblyId, true) + { + _isExtension = isExtension; + } + + public TypeDeclaration(XmlBamlReader reader, ITypeResolver resolver, string name, string namespaceName, short assemblyId) + : this(reader, resolver, name, namespaceName, assemblyId, true) + { + } + + public TypeDeclaration(XmlBamlReader reader, ITypeResolver resolver, string name, string namespaceName, short assemblyId, bool isKnown) + { + this.reader = reader; + this.resolver = resolver; + this._name = name; + this._namespaceName = namespaceName; + this._assemblyId = assemblyId; + this._isKnown = isKnown; + + if (!_isExtension) + _isExtension = name.EndsWith("Extension"); + } + + public override string ToString() + { + return this._name; + } + + public bool IsExtension + { + get { return _isExtension; } + } + + public string Assembly + { + get + { + if (reader != null) + return this.reader.GetAssembly(this.AssemblyId); + else + return KnownInfo.KnownAssemblyTable[this.AssemblyId]; + } + } + + public short AssemblyId + { + get { return _assemblyId; } + } + + public string Name + { + get + { + return this._name; + } + } + + public bool IsKnown + { + get { return _isKnown; } + } + + //public Type DotNetType + //{ + // get + // { + // if (!_typeLoaded) + // { + // _type = Type.GetType(String.Format("{0}.{1}, {2}", this.Namespace, this.Name, this.Assembly), false, true); + // _typeLoaded = true; + // } + + // return _type; + // } + //} + + public IType Type + { + get + { + if (!_typeLoaded) + { + if (this.Name.Length > 0) + _type = resolver.GetTypeByAssemblyQualifiedName(String.Format("{0}.{1}, {2}", this.Namespace, this.Name, this.Assembly)); + _typeLoaded = true; + } + + return _type; + } + } + + public string Namespace + { + get + { + return this._namespaceName; + } + } + + public override bool Equals(object obj) + { + TypeDeclaration td = obj as TypeDeclaration; + if (td != null) + return (this.Name == td.Name && this.Namespace == td.Namespace && this.AssemblyId == td.AssemblyId); + else + return false; + } + } + +} diff --git a/ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/WpfDependencyPropertyDescriptor.cs b/ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/WpfDependencyPropertyDescriptor.cs new file mode 100644 index 000000000..2ac19f1a5 --- /dev/null +++ b/ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/WpfDependencyPropertyDescriptor.cs @@ -0,0 +1,35 @@ +// Copyright (c) Cristian Civera (cristian@aspitalia.com) +// This code is distributed under the MS-PL (for details please see \doc\MS-PL.txt) + +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Text; + +namespace Ricciolo.StylesExplorer.MarkupReflection +{ + public class WpfDependencyPropertyDescriptor : MarshalByRefObject, IDependencyPropertyDescriptor + { + private readonly DependencyPropertyDescriptor _propertyDescriptor; + + public WpfDependencyPropertyDescriptor(DependencyPropertyDescriptor propertyDescriptor) + { + if (propertyDescriptor == null) throw new ArgumentNullException("propertyDescriptor"); + _propertyDescriptor = propertyDescriptor; + } + + #region IDependencyPropertyDescriptor Members + + public bool IsAttached + { + get { return _propertyDescriptor.IsAttached; } + } + + #endregion + + public override object InitializeLifetimeService() + { + return null; + } + } +} diff --git a/ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/XmlBamlElement.cs b/ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/XmlBamlElement.cs new file mode 100644 index 000000000..393ac5c70 --- /dev/null +++ b/ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/XmlBamlElement.cs @@ -0,0 +1,193 @@ +// Copyright (c) Cristian Civera (cristian@aspitalia.com) +// This code is distributed under the MS-PL (for details please see \doc\MS-PL.txt) + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Text; +using System.Xml; + +namespace Ricciolo.StylesExplorer.MarkupReflection +{ + internal class XmlBamlElement : XmlBamlNode + { + private ArrayList _arguments = new ArrayList(); + private XmlNamespaceCollection _namespaces = new XmlNamespaceCollection(); + private TypeDeclaration _typeDeclaration; + private KeysResourcesCollection _keysResources = new KeysResourcesCollection(); + private long _position; + + public XmlBamlElement() + { + } + + + public XmlBamlElement(XmlBamlElement parent) + { + this.Namespaces.AddRange(parent.Namespaces); + } + + public XmlNamespaceCollection Namespaces + { + get { return _namespaces; } + } + + public TypeDeclaration TypeDeclaration + { + get + { + return this._typeDeclaration; + } + set + { + this._typeDeclaration = value; + } + } + + public override XmlNodeType NodeType + { + get + { + return XmlNodeType.Element; + } + } + + public long Position + { + get { return _position; } + set { _position = value; } + } + + public override string ToString() + { + return String.Format("Element: {0}", TypeDeclaration.Name); + } + } + + internal class XmlBamlEndElement : XmlBamlElement + { + public XmlBamlEndElement(XmlBamlElement start) + { + this.TypeDeclaration = start.TypeDeclaration; + this.Namespaces.AddRange(start.Namespaces); + } + + public override XmlNodeType NodeType + { + get + { + return XmlNodeType.EndElement; + } + } + + public override string ToString() + { + return String.Format("EndElement: {0}", TypeDeclaration.Name); + } + } + + internal class KeyMapping + { + private string _key; + private TypeDeclaration _declaration; + private string _trueKey; + + public KeyMapping(string key, TypeDeclaration declaration, string trueKey) + { + _key = key; + _declaration = declaration; + _trueKey = trueKey; + } + + public string Key + { + get { return _key; } + } + + public TypeDeclaration Declaration + { + get { return _declaration; } + } + + public string TrueKey + { + get { return _trueKey; } + } + + public override string ToString() + { + return String.Format("{0} - {1} - {2}", Key, Declaration, TrueKey); + } + } + + internal class KeysResourcesCollection : List + { + 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); + } + } +} diff --git a/ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/XmlBamlNode.cs b/ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/XmlBamlNode.cs new file mode 100644 index 000000000..1f27846b8 --- /dev/null +++ b/ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/XmlBamlNode.cs @@ -0,0 +1,21 @@ +// Copyright (c) Cristian Civera (cristian@aspitalia.com) +// This code is distributed under the MS-PL (for details please see \doc\MS-PL.txt) + +using System; +using System.Collections.Generic; +using System.Text; +using System.Xml; + +namespace Ricciolo.StylesExplorer.MarkupReflection +{ + internal class XmlBamlNode + { + public virtual XmlNodeType NodeType + { + get { return XmlNodeType.None;} + } + } + + internal class XmlBamlNodeCollection : List + {} +} diff --git a/ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/XmlBamlProperty.cs b/ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/XmlBamlProperty.cs new file mode 100644 index 000000000..2da34dd90 --- /dev/null +++ b/ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/XmlBamlProperty.cs @@ -0,0 +1,86 @@ +// Copyright (c) Cristian Civera (cristian@aspitalia.com) +// This code is distributed under the MS-PL (for details please see \doc\MS-PL.txt) + +using System; +using System.Collections.Generic; +using System.Text; +using System.Xml; + +namespace Ricciolo.StylesExplorer.MarkupReflection +{ + internal class XmlBamlProperty : XmlBamlNode + { + private PropertyDeclaration propertyDeclaration; + private PropertyType propertyType; + private object value; + + public XmlBamlProperty(PropertyType propertyType) + { + this.propertyType = propertyType; + } + + public XmlBamlProperty(PropertyType propertyType, PropertyDeclaration propertyDeclaration) + { + this.propertyDeclaration = propertyDeclaration; + this.propertyType = propertyType; + } + + public override string ToString() + { + return this.PropertyDeclaration.Name; + } + + public PropertyDeclaration PropertyDeclaration + { + get + { + return this.propertyDeclaration; + } + set + { + this.propertyDeclaration = value; + } + } + + public PropertyType PropertyType + { + get + { + return this.propertyType; + } + } + + public object Value + { + get + { + return this.value; + } + set + { + this.value = value; + } + } + + public override XmlNodeType NodeType + { + get + { + return XmlNodeType.Attribute; + } + } + } + + internal enum PropertyType + { + Key, + Value, + Content, + List, + Dictionary, + Complex + } + + internal class XmlBamlPropertyCollection : List + { } +} diff --git a/ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/XmlBamlPropertyElement.cs b/ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/XmlBamlPropertyElement.cs new file mode 100644 index 000000000..fbb312cf0 --- /dev/null +++ b/ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/XmlBamlPropertyElement.cs @@ -0,0 +1,48 @@ +// Copyright (c) Cristian Civera (cristian@aspitalia.com) +// This code is distributed under the MS-PL (for details please see \doc\MS-PL.txt) + +using System; +using System.Collections.Generic; +using System.Text; + +namespace Ricciolo.StylesExplorer.MarkupReflection +{ + internal class XmlBamlPropertyElement : XmlBamlElement + { + private readonly PropertyType _propertyType; + private PropertyDeclaration propertyDeclaration; + + + public XmlBamlPropertyElement(PropertyType propertyType, PropertyDeclaration propertyDeclaration) + { + _propertyType = propertyType; + this.propertyDeclaration = propertyDeclaration; + } + + public XmlBamlPropertyElement(XmlBamlElement parent, PropertyType propertyType, PropertyDeclaration propertyDeclaration) + : base(parent) + { + _propertyType = propertyType; + this.propertyDeclaration = propertyDeclaration; + this.TypeDeclaration = propertyDeclaration.DeclaringType; + } + + public PropertyDeclaration PropertyDeclaration + { + get + { + return this.propertyDeclaration; + } + } + + public PropertyType PropertyType + { + get { return _propertyType; } + } + + public override string ToString() + { + return String.Format("PropertyElement: {0}.{1}", TypeDeclaration.Name, PropertyDeclaration.Name); + } + } +} diff --git a/ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/XmlBamlReader.cs b/ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/XmlBamlReader.cs new file mode 100644 index 000000000..615c02d4d --- /dev/null +++ b/ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/XmlBamlReader.cs @@ -0,0 +1,1943 @@ +// Copyright (c) Cristian Civera (cristian@aspitalia.com) +// This code is distributed under the MS-PL (for details please see \doc\MS-PL.txt) + +using System; +using System.Collections; +using System.Collections.Generic; +using System.ComponentModel; +using System.Diagnostics; +using System.Globalization; +using System.IO; +using System.Reflection; +using System.Text; +using System.Xml; +using System.Windows.Media; + +namespace Ricciolo.StylesExplorer.MarkupReflection +{ + public class XmlBamlReader : XmlReader, IXmlNamespaceResolver + { + + #region Variables + + private BamlBinaryReader reader; + private Hashtable assemblyTable = new Hashtable(); + private Hashtable stringTable = new Hashtable(); + private Hashtable typeTable = new Hashtable(); + private Hashtable propertyTable = new Hashtable(); + + private readonly ITypeResolver _resolver; + + private BamlRecordType currentType; + + private Stack elements = new Stack(); + private Stack readingElements = new Stack(); + private Stack keysResources = new Stack(); + private NodesCollection nodes = new NodesCollection(); + private List _mappings = new List(); + private XmlBamlNode _currentNode; + + private readonly KnownInfo KnownInfo; + + private int complexPropertyOpened = 0; + + private bool intoAttribute = false; + private bool initialized; + private bool _eof; + + private bool isPartialDefKeysClosed = true; + private bool isDefKeysClosed = true; + + private 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 _rootNamespaces; + + #endregion + + public XmlBamlReader(Stream stream) : this (stream, AppDomainTypeResolver.GetIntoNewAppDomain(Environment.CurrentDirectory)) + { + + } + + public XmlBamlReader(Stream stream, ITypeResolver resolver) + { + if (stream == null) + throw new ArgumentNullException("stream"); + if (resolver == null) + throw new ArgumentNullException("resolver"); + + _resolver = resolver; + reader = new BamlBinaryReader(stream); + + XamlTypeDeclaration = new TypeDeclaration(this.Resolver, "", "System.Windows.Markup", 0); + KnownInfo = new KnownInfo(resolver); + } + + /// + ///When overridden in a derived class, gets the value of the attribute with the specified . + /// + /// + /// + ///The value of the specified attribute. If the attribute is not found, null is returned. + /// + /// + ///The qualified name of the attribute. + public override string GetAttribute(string name) + { + throw new NotImplementedException(); + } + + /// + ///When overridden in a derived class, gets the value of the attribute with the specified and . + /// + /// + /// + ///The value of the specified attribute. If the attribute is not found, null is returned. This method does not move the reader. + /// + /// + ///The namespace URI of the attribute. + ///The local name of the attribute. + public override string GetAttribute(string name, string namespaceURI) + { + throw new NotImplementedException(); + } + + /// + ///When overridden in a derived class, gets the value of the attribute with the specified index. + /// + /// + /// + ///The value of the specified attribute. This method does not move the reader. + /// + /// + ///The index of the attribute. The index is zero-based. (The first attribute has index 0.) + public override string GetAttribute(int i) + { + throw new NotImplementedException(); + } + + /// + ///When overridden in a derived class, moves to the attribute with the specified . + /// + /// + /// + ///true if the attribute is found; otherwise, false. If false, the reader's position does not change. + /// + /// + ///The qualified name of the attribute. + public override bool MoveToAttribute(string name) + { + throw new NotImplementedException(); + } + + /// + ///When overridden in a derived class, moves to the attribute with the specified and . + /// + /// + /// + ///true if the attribute is found; otherwise, false. If false, the reader's position does not change. + /// + /// + ///The local name of the attribute. + ///The namespace URI of the attribute. + public override bool MoveToAttribute(string name, string ns) + { + throw new NotImplementedException(); + } + + /// + ///When overridden in a derived class, moves to the first attribute. + /// + /// + /// + ///true if an attribute exists (the reader moves to the first attribute); otherwise, false (the position of the reader does not change). + /// + /// + public override bool MoveToFirstAttribute() + { + intoAttribute = false; + if (nodes.Count > 0 && nodes.Peek() is XmlBamlProperty) + { + _currentNode = nodes.Dequeue(); + return true; + } + return false; + } + + /// + ///When overridden in a derived class, moves to the next attribute. + /// + /// + /// + ///true if there is a next attribute; false if there are no more attributes. + /// + /// + public override bool MoveToNextAttribute() + { + intoAttribute = false; + if (nodes.Count > 0 && nodes.Peek() is XmlBamlProperty) + { + _currentNode = nodes.Dequeue(); + return true; + } + return false; + } + + /// + ///When overridden in a derived class, moves to the element that contains the current attribute node. + /// + /// + /// + ///true if the reader is positioned on an attribute (the reader moves to the element that owns the attribute); false if the reader is not positioned on an attribute (the position of the reader does not change). + /// + /// + public override bool MoveToElement() + { + while (nodes.Peek() is XmlBamlProperty) + { + nodes.Dequeue(); + } + + return true; + } + + /// + ///When overridden in a derived class, parses the attribute value into one or more Text, EntityReference, or EndEntity nodes. + /// + /// + /// + ///true if there are nodes to return.false if the reader is not positioned on an attribute node when the initial call is made or if all the attribute values have been read.An empty attribute, such as, misc="", returns true with a single node with a value of String.Empty. + /// + /// + public override bool ReadAttributeValue() + { + if (!intoAttribute) + { + intoAttribute = true; + return true; + } + return false; + } + + /// + ///When overridden in a derived class, reads the next node from the stream. + /// + /// + /// + ///true if the next node was read successfully; false if there are no more nodes to read. + /// + /// + ///An error occurred while parsing the XML. + public override bool Read() + { + return ReadInternal(); + } + + private bool ReadInternal() + { + EnsureInit(); + + if (SetNextNode()) + return true; + + try + { + do + { + currentType = (BamlRecordType)reader.ReadByte(); + //Debug.WriteLine(currentType); + if (currentType == BamlRecordType.DocumentEnd) break; + + long position = reader.BaseStream.Position; + + ComputeBytesToSkip(); + ProcessNext(); + + if (bytesToSkip > 0) + { + reader.BaseStream.Position = position + bytesToSkip; + } + } + //while (currentType != BamlRecordType.DocumentEnd); + while (nodes.Count == 0 || (currentType != BamlRecordType.ElementEnd) || complexPropertyOpened > 0); + + if (!SetNextNode()) { + _eof = true; + return false; + } + return true; + } + catch (EndOfStreamException) + { + _eof = true; + return false; + } + } + + private bool SetNextNode() + { + while (nodes.Count > 0) + { + _currentNode = nodes.Dequeue(); + + if ((_currentNode is XmlBamlProperty)) continue; + + if (this.NodeType == XmlNodeType.EndElement) + { + if (readingElements.Count == 1) + _rootNamespaces = ((IXmlNamespaceResolver)this).GetNamespacesInScope(XmlNamespaceScope.All); + readingElements.Pop(); + } + else if (this.NodeType == XmlNodeType.Element) + readingElements.Push((XmlBamlElement)_currentNode); + + return true; + } + + return false; + } + + private void ProcessNext() + { + switch (currentType) + { + case BamlRecordType.DocumentStart: + { + reader.ReadBoolean(); + reader.ReadInt32(); + reader.ReadBoolean(); + break; + } + case BamlRecordType.DocumentEnd: + break; + case BamlRecordType.ElementStart: + this.ReadElementStart(); + break; + case BamlRecordType.ElementEnd: + this.ReadElementEnd(); + break; + case BamlRecordType.AssemblyInfo: + this.ReadAssemblyInfo(); + break; + case BamlRecordType.StringInfo: + this.ReadStringInfo(); + break; + case BamlRecordType.LineNumberAndPosition: + reader.ReadInt32(); + reader.ReadInt32(); + break; + case BamlRecordType.LinePosition: + reader.ReadInt32(); + break; + case BamlRecordType.XmlnsProperty: + this.ReadXmlnsProperty(); + break; + case BamlRecordType.ConnectionId: + reader.ReadInt32(); + break; + case BamlRecordType.DeferableContentStart: + reader.ReadInt32(); + break; + case BamlRecordType.DefAttribute: + this.ReadDefAttribute(); + break; + case BamlRecordType.DefAttributeKeyType: + this.ReadDefAttributeKeyType(); + break; + case BamlRecordType.DefAttributeKeyString: + this.ReadDefAttributeKeyString(); + break; + case BamlRecordType.AttributeInfo: + this.ReadAttributeInfo(); + break; + case BamlRecordType.PropertyListStart: + this.ReadPropertyListStart(); + break; + case BamlRecordType.PropertyListEnd: + this.ReadPropertyListEnd(); + break; + case BamlRecordType.Property: + this.ReadProperty(); + break; + case BamlRecordType.PropertyWithConverter: + this.ReadPropertyWithConverter(); + break; + case BamlRecordType.PropertyWithExtension: + this.ReadPropertyWithExtension(); + break; + case BamlRecordType.PropertyDictionaryStart: + this.ReadPropertyDictionaryStart(); + break; + case BamlRecordType.PropertyCustom: + this.ReadPropertyCustom(); + break; + case BamlRecordType.PropertyDictionaryEnd: + this.ReadPropertyDictionaryEnd(); + break; + case BamlRecordType.PropertyComplexStart: + this.ReadPropertyComplexStart(); + break; + case BamlRecordType.PropertyComplexEnd: + this.ReadPropertyComplexEnd(); + break; + case BamlRecordType.PIMapping: + this.ReadPIMapping(); + break; + case BamlRecordType.TypeInfo: + this.ReadTypeInfo(); + break; + case BamlRecordType.ContentProperty: + this.ReadContentProperty(); + break; + case BamlRecordType.ConstructorParametersStart: + ReadConstructorParametersStart(); + break; + case BamlRecordType.ConstructorParametersEnd: + ReadConstructorParametersEnd(); + break; + case BamlRecordType.ConstructorParameterType: + this.ReadConstructorParameterType(); + break; + case BamlRecordType.Text: + this.ReadText(); + break; + case BamlRecordType.TextWithConverter: + this.ReadTextWithConverter(); + break; + case BamlRecordType.PropertyWithStaticResourceId: + this.ReadPropertyWithStaticResourceIdentifier(); + break; + case BamlRecordType.OptimizedStaticResource: + this.ReadOptimizedStaticResource(); + break; + case BamlRecordType.KeyElementStart: + this.ReadKeyElementStart(); + break; + case BamlRecordType.KeyElementEnd: + this.ReadKeyElementEnd(); + break; + case BamlRecordType.PropertyTypeReference: + this.ReadPropertyTypeReference(); + break; + case BamlRecordType.StaticResourceStart: + ReadStaticResourceStart(); + break; + case BamlRecordType.StaticResourceEnd: + ReadStaticResourceEnd(); + break; + case BamlRecordType.StaticResourceId: + ReadStaticResourceId(); + break; + case BamlRecordType.PresentationOptionsAttribute: + this.ReadPresentationOptionsAttribute(); + break; + default: + break; + } + } + + private void ComputeBytesToSkip() + { + bytesToSkip = 0; + switch (currentType) + { + case BamlRecordType.PropertyWithConverter: + case BamlRecordType.DefAttributeKeyString: + case BamlRecordType.PresentationOptionsAttribute: + case BamlRecordType.Property: + case BamlRecordType.PropertyCustom: + case BamlRecordType.Text: + case BamlRecordType.TextWithConverter: + case BamlRecordType.XmlnsProperty: + case BamlRecordType.DefAttribute: + case BamlRecordType.PIMapping: + case BamlRecordType.AssemblyInfo: + case BamlRecordType.TypeInfo: + case BamlRecordType.AttributeInfo: + case BamlRecordType.StringInfo: + bytesToSkip = reader.ReadCompressedInt32(); + break; + } + } + + private void EnsureInit() + { + if (!initialized) + { + int startChars = reader.ReadInt32(); + String type = new String(new BinaryReader(this.reader.BaseStream, Encoding.Unicode).ReadChars(startChars >> 1)); + if (type != "MSBAML") + throw new NotSupportedException("Not a MS BAML"); + + int r = reader.ReadInt32(); + int s = reader.ReadInt32(); + int t = reader.ReadInt32(); + if (((r != 0x600000) || (s != 0x600000)) || (t != 0x600000)) + throw new NotSupportedException(); + + initialized = true; + } + } + + /// + ///When overridden in a derived class, changes the to Closed. + /// + /// + public override void Close() + { + //if (reader != null) + // reader.Close(); + reader = null; + } + + /// + ///When overridden in a derived class, resolves a namespace prefix in the current element's scope. + /// + /// + /// + ///The namespace URI to which the prefix maps or null if no matching prefix is found. + /// + /// + ///The prefix whose namespace URI you want to resolve. To match the default namespace, pass an empty string. + public override string LookupNamespace(string prefix) + { + if (readingElements.Count == 0) return null; + + XmlNamespaceCollection namespaces = readingElements.Peek().Namespaces; + + for (int x = 0; x < namespaces.Count; x++) + { + if (String.CompareOrdinal(namespaces[x].Prefix, prefix) == 0) + return namespaces[x].Namespace; + } + + return null; + } + + /// + ///When overridden in a derived class, resolves the entity reference for EntityReference nodes. + /// + /// + ///The reader is not positioned on an EntityReference node; this implementation of the reader cannot resolve entities ( returns false). + public override void ResolveEntity() + { + throw new NotImplementedException(); + } + + /// + ///When overridden in a derived class, gets the type of the current node. + /// + /// + /// + ///One of the values representing the type of the current node. + /// + /// + public override XmlNodeType NodeType + { + get + { + if (intoAttribute) return XmlNodeType.Text; + + return this.CurrentNode.NodeType; + } + } + + /// + ///When overridden in a derived class, gets the local name of the current node. + /// + /// + /// + ///The name of the current node with the prefix removed. For example, LocalName is book for the element <bk:book>.For node types that do not have a name (like Text, Comment, and so on), this property returns String.Empty. + /// + /// + public override string LocalName + { + get + { + if (intoAttribute) return String.Empty; + + String localName = String.Empty; + + XmlBamlNode node = this.CurrentNode; + if (node is XmlBamlProperty) + { + PropertyDeclaration pd = ((XmlBamlProperty)node).PropertyDeclaration; + localName = FormatPropertyDeclaration(pd, false, true, true); + } + else if (node is XmlBamlPropertyElement) + { + XmlBamlPropertyElement property = (XmlBamlPropertyElement)node; + localName = String.Format("{0}.{1}", property.TypeDeclaration.Name, property.PropertyDeclaration.Name); + } + else if (node is XmlBamlElement) + localName = ((XmlBamlElement)node).TypeDeclaration.Name; + + localName = this.NameTable.Add(localName); + + return localName; + } + } + + private PropertyDeclaration GetPropertyDeclaration(short identifier) + { + PropertyDeclaration declaration; + if (identifier >= 0) + { + declaration = (PropertyDeclaration)this.propertyTable[identifier]; + } + else + { + declaration = KnownInfo.KnownPropertyTable[-identifier]; + } + if (declaration == null) + { + throw new NotSupportedException(); + } + return declaration; + } + + private object GetResourceName(short identifier) + { + if (identifier >= 0) + { + PropertyDeclaration declaration = (PropertyDeclaration)this.propertyTable[identifier]; + return declaration; + } + else + { + identifier = (short)-identifier; + bool isNotKey = (identifier > 0xe8); + if (isNotKey) + identifier = (short)(identifier - 0xe8); + ResourceName resource = (ResourceName) KnownInfo.KnownResourceTable[(int)identifier]; + if (!isNotKey) + return new ResourceName(resource.Name + "Key"); + return resource; + } + } + + private void ReadPropertyDictionaryStart() + { + short identifier = reader.ReadInt16(); + + PropertyDeclaration pd = this.GetPropertyDeclaration(identifier); + XmlBamlElement element = elements.Peek(); + XmlBamlPropertyElement property = new XmlBamlPropertyElement(element, PropertyType.Dictionary, pd); + elements.Push(property); + nodes.Enqueue(property); + + isDefKeysClosed = true; + isPartialDefKeysClosed = true; + } + + private void ReadPropertyDictionaryEnd() + { + keysResources.Pop(); + + CloseElement(); + } + + private void ReadPropertyCustom() + { + short identifier = reader.ReadInt16(); + short serializerTypeId = reader.ReadInt16(); + bool isValueTypeId = (serializerTypeId & 0x4000) == 0x4000; + if (isValueTypeId) + serializerTypeId = (short)(serializerTypeId & ~0x4000); + + PropertyDeclaration pd = this.GetPropertyDeclaration(identifier); + string value; + switch (serializerTypeId) + { + case 0x2e8: + value = new BrushConverter().ConvertToString(SolidColorBrush.DeserializeFrom(reader)); + break; + case 0x2e9: + value = new Int32CollectionConverter().ConvertToString(DeserializeInt32CollectionFrom(reader)); + break; + case 0x89: + + short typeIdentifier = reader.ReadInt16(); + if (isValueTypeId) + { + TypeDeclaration typeDeclaration = this.GetTypeDeclaration(typeIdentifier); + string name = reader.ReadString(); + value = FormatPropertyDeclaration(new PropertyDeclaration(name, typeDeclaration), true, false, true); + } + else + value = FormatPropertyDeclaration(this.GetPropertyDeclaration(typeIdentifier), true, false, true); + break; + + case 0x2ea: + value = ((IFormattable)staticConvertCustomBinaryToObjectMethod.Invoke(null, new object[] { this.reader })).ToString("G", CultureInfo.InvariantCulture); + break; + case 0x2eb: + case 0x2f0: + value = Deserialize3DPoints(); + break; + case 0x2ec: + value = DeserializePoints(); + break; + case 0xc3: + // Enum + uint num = reader.ReadUInt32(); + value = num.ToString(); + break; + case 0x2e: + int b = reader.ReadByte(); + value = (b == 1) ? Boolean.TrueString : Boolean.FalseString; + break; + default: + return; + } + + XmlBamlProperty property = new XmlBamlProperty(PropertyType.Value, pd); + property.Value = value; + + nodes.Enqueue(property); + } + + private string DeserializePoints() + { + using (StringWriter writer = new StringWriter()) + { + int num10 = reader.ReadInt32(); + for (int k = 0; k < num10; k++) + { + if (k != 0) + writer.Write(" "); + for (int m = 0; m < 2; m++) + { + if (m != 0) + writer.Write(","); + writer.Write(reader.ReadCompressedDouble().ToString()); + } + } + return writer.ToString(); + } + } + + private String Deserialize3DPoints() + { + using (StringWriter writer = new StringWriter()) + { + int num14 = reader.ReadInt32(); + for (int i = 0; i < num14; i++) + { + if (i != 0) + { + writer.Write(" "); + } + for (int j = 0; j < 3; j++) + { + if (j != 0) + { + writer.Write(","); + } + writer.Write(reader.ReadCompressedDouble().ToString()); + } + } + return writer.ToString(); + } + } + + private static Int32Collection DeserializeInt32CollectionFrom(BinaryReader reader) + { + IntegerCollectionType type = (IntegerCollectionType)reader.ReadByte(); + int capacity = reader.ReadInt32(); + if (capacity < 0) + throw new ArgumentException(); + + Int32Collection ints = new Int32Collection(capacity); + switch (type) + { + case IntegerCollectionType.Byte: + for (int i = 0; i < capacity; i++) + { + ints.Add(reader.ReadByte()); + } + return ints; + + case IntegerCollectionType.UShort: + for (int j = 0; j < capacity; j++) + { + ints.Add(reader.ReadUInt16()); + } + return ints; + + case IntegerCollectionType.Integer: + for (int k = 0; k < capacity; k++) + { + int num7 = reader.ReadInt32(); + ints.Add(num7); + } + return ints; + + case IntegerCollectionType.Consecutive: + for (int m = reader.ReadInt32(); m < capacity; m++) + { + ints.Add(m); + } + return ints; + } + throw new ArgumentException(); + } + + private void ReadPropertyWithExtension() + { + short identifier = reader.ReadInt16(); + short x = reader.ReadInt16(); + short valueIdentifier = reader.ReadInt16(); + bool isValueType = (x & 0x4000) == 0x4000; + bool isStaticType = (x & 0x2000) == 0x2000; + x = (short)(x & 0xfff); + + PropertyDeclaration pd = this.GetPropertyDeclaration(identifier); + short extensionIdentifier = (short)-(x & 0xfff); + string value = String.Empty; + + switch (x) + { + case 0x25a: + // StaticExtension + object resource = this.GetResourceName(valueIdentifier); + if (resource is ResourceName) + value = this.GetStaticExtension(((ResourceName)resource).Name); + else if (resource is PropertyDeclaration) + value = this.GetStaticExtension(FormatPropertyDeclaration(((PropertyDeclaration)resource), true, false, false)); + break; + case 0x25b: // StaticResource + case 0xbd: // DynamicResource + if (isValueType) + { + value = this.GetTypeExtension(valueIdentifier); + } + else if (isStaticType) + { + TypeDeclaration extensionDeclaration = this.GetTypeDeclaration(extensionIdentifier); + value = GetExtension(extensionDeclaration, GetStaticExtension(GetResourceName(valueIdentifier).ToString())); + } + else + { + TypeDeclaration extensionDeclaration = this.GetTypeDeclaration(extensionIdentifier); + value = GetExtension(extensionDeclaration, (string)this.stringTable[valueIdentifier]); + } + break; + + case 0x27a: + // TemplateBinding + PropertyDeclaration pdValue = this.GetPropertyDeclaration(valueIdentifier); + value = GetTemplateBindingExtension(pdValue); + break; + default: + throw new NotSupportedException("Unknown property with extension"); + } + + XmlBamlProperty property = new XmlBamlProperty(PropertyType.Value, pd); + property.Value = value; + + nodes.Enqueue(property); + } + + private void ReadProperty() + { + short identifier = reader.ReadInt16(); + string text = reader.ReadString(); + + PropertyDeclaration pd = this.GetPropertyDeclaration(identifier); + XmlBamlProperty property = new XmlBamlProperty(PropertyType.Value, pd); + property.Value = text; + + nodes.Enqueue(property); + } + + private void ReadPropertyWithConverter() + { + short identifier = reader.ReadInt16(); + string text = reader.ReadString(); + reader.ReadInt16(); + + PropertyDeclaration pd = this.GetPropertyDeclaration(identifier); + XmlBamlProperty property = new XmlBamlProperty(PropertyType.Value, pd); + property.Value = text; + + nodes.Enqueue(property); + } + + private 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); + } + + private 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)); + } + + private void ReadDefAttribute() + { + string text = reader.ReadString(); + short identifier = reader.ReadInt16(); + + PropertyDeclaration pd; + switch (identifier) + { + case -2: + pd = new PropertyDeclaration("Uid", XamlTypeDeclaration); + break; + case -1: + pd = new PropertyDeclaration("Name", XamlTypeDeclaration); + break; + default: + string recordName = (string)this.stringTable[identifier]; + if (recordName != "Key") throw new NotSupportedException(recordName); + pd = new PropertyDeclaration(recordName, XamlTypeDeclaration); + + AddDefKey(-1, text); + break; + } + + XmlBamlProperty property = new XmlBamlProperty(PropertyType.Key, pd); + property.Value = text; + + nodes.Enqueue(property); + } + + private void ReadDefAttributeKeyString() + { + short num = reader.ReadInt16(); + int position = reader.ReadInt32(); + //bool shared = reader.ReadBoolean(); + //bool sharedSet = reader.ReadBoolean(); + string text = (string)this.stringTable[num]; + if (text == null) + throw new NotSupportedException(); + + AddDefKey(position, text); + } + + 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() + { + string prefix = reader.ReadString(); + string @namespace = reader.ReadString(); + string[] textArray = new string[(uint)reader.ReadInt16()]; + for (int i = 0; i < textArray.Length; i++) + { + textArray[i] = (string)this.assemblyTable[reader.ReadInt16()]; + } + + XmlNamespaceCollection namespaces = elements.Peek().Namespaces; + // Mapping locale, ci aggiunto l'assembly + if (@namespace.StartsWith("clr-namespace:") && @namespace.IndexOf("assembly=") < 0) + { + XmlPIMapping mappingToChange = null; + foreach (XmlPIMapping mapping in this.Mappings) + { + if (String.CompareOrdinal(mapping.XmlNamespace, @namespace) == 0) + { + mappingToChange = mapping; + break; + } + } + if (mappingToChange == null) + throw new InvalidOperationException("Cannot find mapping"); + + @namespace = String.Format("{0};assembly={1}", @namespace, GetAssembly(mappingToChange.AssemblyId).Replace(" ", "")); + mappingToChange.XmlNamespace = @namespace; + } + namespaces.Add(new XmlNamespace(prefix, @namespace)); + } + + private 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); + } + + private void ReadPropertyComplexStart() + { + short identifier = reader.ReadInt16(); + + PropertyDeclaration pd = this.GetPropertyDeclaration(identifier); + XmlBamlElement element = FindXmlBamlElement(); + + XmlBamlPropertyElement property = new XmlBamlPropertyElement(element, PropertyType.Complex, pd); + elements.Push(property); + nodes.Enqueue(property); + complexPropertyOpened++; + } + + private XmlBamlElement FindXmlBamlElement() + { + return elements.Peek(); + + //XmlBamlElement element; + //int x = nodes.Count - 1; + //do + //{ + // element = nodes[x] as XmlBamlElement; + // x--; + //} while (element == null); + //return element; + } + + private void ReadPropertyListStart() + { + short identifier = reader.ReadInt16(); + + PropertyDeclaration pd = this.GetPropertyDeclaration(identifier); + XmlBamlElement element = FindXmlBamlElement(); + XmlBamlPropertyElement property = new XmlBamlPropertyElement(element, PropertyType.List, pd); + elements.Push(property); + nodes.Enqueue(property); + } + + private void ReadPropertyListEnd() + { + CloseElement(); + } + + private void ReadPropertyComplexEnd() + { + XmlBamlPropertyElement propertyElement = (XmlBamlPropertyElement) elements.Peek(); + + CloseElement(); + + complexPropertyOpened--; + // Valuto se contiene tutte extension + int start = nodes.IndexOf(propertyElement) + 1; + IEnumerator enumerator = nodes.GetEnumerator(); + + int c = 0; + while (c < start && enumerator.MoveNext()) + c++; + + if (IsExtension(enumerator)) + { + start--; + nodes.RemoveAt(start); + nodes.RemoveLast(); + + StringBuilder sb = new StringBuilder(); + FormatElementExtension((XmlBamlElement) nodes[start], sb); + + XmlBamlProperty property = + new XmlBamlProperty(PropertyType.Complex, propertyElement.PropertyDeclaration); + property.Value = sb.ToString(); + nodes.Add(property); + + return; + } + } + + private void FormatElementExtension(XmlBamlElement element, StringBuilder sb) + { + sb.Append("{"); + sb.Append(FormatTypeDeclaration(element.TypeDeclaration)); + + int start = nodes.IndexOf(element); + nodes.RemoveAt(start); + + string sep = " "; + while (nodes.Count > start) + { + XmlBamlNode node = nodes[start]; + + if (node is XmlBamlEndElement) + { + sb.Append("}"); + nodes.RemoveAt(start); + break; + } + else if (node is XmlBamlPropertyElement) + { + nodes.RemoveAt(start); + + sb.Append(sep); + XmlBamlPropertyElement property = (XmlBamlPropertyElement)node; + sb.Append(property.PropertyDeclaration.Name); + sb.Append("="); + + node = nodes[start]; + nodes.RemoveLast(); + FormatElementExtension((XmlBamlElement)node, sb); + } + else if (node is XmlBamlElement) + { + sb.Append(sep); + FormatElementExtension((XmlBamlElement)node, sb); + } + else if (node is XmlBamlProperty) + { + nodes.RemoveAt(start); + + sb.Append(sep); + XmlBamlProperty property = (XmlBamlProperty)node; + sb.Append(property.PropertyDeclaration.Name); + sb.Append("="); + sb.Append(property.Value); + } + else if (node is XmlBamlText) + { + nodes.RemoveAt(start); + + sb.Append(sep); + sb.Append(((XmlBamlText)node).Text); + } + sep = ","; + } + } + + private static bool IsExtension(IEnumerator enumerator) + { + bool r = true; + while (enumerator.MoveNext() && r) + { + object node = enumerator.Current; + if (node is XmlBamlElement && !(node is XmlBamlEndElement) && !((XmlBamlElement)node).TypeDeclaration.IsExtension) + { + r = false; + } + } + + return r; + } + + private void CloseElement() + { + nodes.Enqueue(new XmlBamlEndElement(elements.Pop())); + } + + private void ReadElementStart() + { + short identifier = reader.ReadInt16(); + reader.ReadByte(); + TypeDeclaration declaration = GetTypeDeclaration(identifier); + + XmlBamlElement element; + XmlBamlElement parentElement = null; + if (elements.Count > 0) + { + parentElement = elements.Peek(); + element = new XmlBamlElement(parentElement); + element.Position = this.reader.BaseStream.Position; + + // Porto l'inizio del padre all'inizio del primo figlio + if (parentElement.Position == 0 && complexPropertyOpened == 0) + parentElement.Position = element.Position; + } + else + element = new XmlBamlElement(); + + element.TypeDeclaration = declaration; + elements.Push(element); + nodes.Enqueue(element); + + 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); + + AddKeyToElement(key); + } + } + } + + private void AddKeyToElement(string key) + { + PropertyDeclaration pd = new PropertyDeclaration("Key", XamlTypeDeclaration); + XmlBamlProperty property = new XmlBamlProperty(PropertyType.Key, pd); + + property.Value = key; + + nodes.Enqueue(property); + } + + private XmlPIMapping FindByClrNamespaceAndAssemblyId(TypeDeclaration declaration) + { + return FindByClrNamespaceAndAssemblyId(declaration.Namespace, declaration.AssemblyId); + } + + private XmlPIMapping FindByClrNamespaceAndAssemblyId(string clrNamespace, int assemblyId) + { + if (clrNamespace == XamlTypeDeclaration.Namespace && assemblyId == XamlTypeDeclaration.AssemblyId) + return new XmlPIMapping(XmlPIMapping.XamlNamespace, 0, clrNamespace); + + for (int x = 0; x < Mappings.Count; x++) + { + XmlPIMapping xp = Mappings[x]; + if (xp.AssemblyId == assemblyId && String.CompareOrdinal(xp.ClrNamespace, clrNamespace) == 0) + return xp; + } + + return null; + } + + private void ReadPIMapping() + { + string xmlNamespace = reader.ReadString(); + string clrNamespace = reader.ReadString(); + short assemblyId = reader.ReadInt16(); + + Mappings.Add(new XmlPIMapping(xmlNamespace, assemblyId, clrNamespace)); + } + + private void ReadContentProperty() + { + reader.ReadInt16(); + + // Non serve aprire niente, è il default + } + + private static void ReadConstructorParametersStart() + { + //this.constructorParameterTable.Add(this.elements.Peek()); + //PromoteDataToComplexProperty(); + } + + private static void ReadConstructorParametersEnd() + { + //this.constructorParameterTable.Remove(this.elements.Peek()); + //properties.Pop(); + } + + private void ReadConstructorParameterType() + { + short identifier = reader.ReadInt16(); + + //TypeDeclaration declaration = GetTypeDeclaration(identifier); + nodes.Enqueue(new XmlBamlText(GetTypeExtension(identifier))); + } + + private void ReadText() + { + string text = reader.ReadString(); + + nodes.Enqueue(new XmlBamlText(text)); + } + + private void ReadKeyElementStart() + { + short typeIdentifier = reader.ReadInt16(); + byte valueIdentifier = reader.ReadByte(); + // TODO: handle shared + //bool shared = (valueIdentifier & 1) != 0; + //bool sharedSet = (valueIdentifier & 2) != 0; + int position = reader.ReadInt32(); + reader.ReadBoolean(); + reader.ReadBoolean(); + + TypeDeclaration declaration = this.GetTypeDeclaration(typeIdentifier); + + XmlBamlPropertyElement property = new XmlBamlPropertyElement(elements.Peek(), PropertyType.Key, new PropertyDeclaration("Key", declaration)); + property.Position = position; + elements.Push(property); + nodes.Enqueue(property); + complexPropertyOpened++; + } + + private void ReadKeyElementEnd() + { + XmlBamlPropertyElement propertyElement = (XmlBamlPropertyElement)elements.Peek(); + + CloseElement(); + complexPropertyOpened--; + if (complexPropertyOpened == 0) + { + + int start = nodes.IndexOf(propertyElement); + + StringBuilder sb = new StringBuilder(); + FormatElementExtension((XmlBamlElement)nodes[start], sb); + AddDefKey(propertyElement.Position, sb.ToString()); + } + } + + private static void ReadStaticResourceStart() + { + //short identifier = reader.ReadInt16(); + //byte n = reader.ReadByte(); + //TypeDeclaration declaration = this.GetTypeDeclaration(identifier); + //this.staticResourceTable.Add(declaration); + + throw new NotImplementedException("StaticResourceStart"); + } + + private static void ReadStaticResourceEnd() + { + throw new NotImplementedException("ReadStaticResourceEnd"); + } + + private static void ReadStaticResourceId() + { + //short identifier = reader.ReadInt16(); + //object staticResource = this.GetStaticResource(identifier); + //TypeDeclaration declaration = this.GetTypeDeclaration(-603); + + throw new NotImplementedException("StaticResourceId"); + } + + private 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); + property.Value = text; + } + + private void ReadPropertyTypeReference() + { + short identifier = reader.ReadInt16(); + short typeIdentifier = reader.ReadInt16(); + + PropertyDeclaration pd = this.GetPropertyDeclaration(identifier); + string value = this.GetTypeExtension(typeIdentifier); + + XmlBamlProperty property = new XmlBamlProperty(PropertyType.Value, pd); + property.Value = value; + + nodes.Enqueue(property); + } + + private void ReadOptimizedStaticResource() + { + byte num = reader.ReadByte(); + short typeIdentifier = reader.ReadInt16(); + bool isValueType = (num & 1) == 1; + bool isStaticType = (num & 2) == 2; + object resource; + + if (isValueType) + resource = this.GetTypeExtension(typeIdentifier); + else if (isStaticType) + { + ResourceName resourceName = (ResourceName)this.GetResourceName(typeIdentifier); + resource = GetStaticExtension(resourceName.Name); + } + else + { + resource = this.stringTable[typeIdentifier]; + } + + //this.staticResourceTable.Add(resource); + isPartialDefKeysClosed = true; + // Aggiungo la risorsa nell'ultimo gruppo + keysResources.Peek().Last.StaticResources.Add(resource); + } + + private string GetTemplateBindingExtension(PropertyDeclaration propertyDeclaration) + { + return String.Format("{{TemplateBinding {0}}}", FormatPropertyDeclaration(propertyDeclaration, true, false, false)); + } + + private string GetStaticExtension(string name) + { + string prefix = this.LookupPrefix(XmlPIMapping.XamlNamespace, false); + if (String.IsNullOrEmpty(prefix)) + return String.Format("{{Static {0}}}", name); + else + return String.Format("{{{0}:Static {1}}}", prefix, name); + } + + private string GetExtension(TypeDeclaration declaration, string value) + { + return String.Format("{{{0} {1}}}", FormatTypeDeclaration(declaration), value); + } + + private string GetTypeExtension(short typeIdentifier) + { + string prefix = this.LookupPrefix(XmlPIMapping.XamlNamespace, false); + if (String.IsNullOrEmpty(prefix)) + return String.Format("{{Type {0}}}", FormatTypeDeclaration(GetTypeDeclaration(typeIdentifier))); + else + return String.Format("{{{0}:Type {1}}}", prefix, FormatTypeDeclaration(GetTypeDeclaration(typeIdentifier))); + } + + private string FormatTypeDeclaration(TypeDeclaration typeDeclaration) + { + XmlPIMapping mapping = FindByClrNamespaceAndAssemblyId(typeDeclaration.Namespace, typeDeclaration.AssemblyId); + string prefix = (mapping != null) ? this.LookupPrefix(mapping.XmlNamespace, false) : null; + string name = typeDeclaration.Name; + if (name.EndsWith("Extension")) + name = name.Substring(0, name.Length - 9); + if (String.IsNullOrEmpty(prefix)) + return name; + else + return String.Format("{0}:{1}", prefix, name); + } + + + + private string FormatPropertyDeclaration(PropertyDeclaration propertyDeclaration, bool withPrefix, bool useReading, bool checkType) + { + StringBuilder sb = new StringBuilder(); + + TypeDeclaration elementDeclaration = (useReading) ? readingElements.Peek().TypeDeclaration : elements.Peek().TypeDeclaration; + + IDependencyPropertyDescriptor descriptor = null; + bool areValidTypes = elementDeclaration.Type != null && propertyDeclaration.DeclaringType.Type != null; + if (areValidTypes) + descriptor = this.Resolver.GetDependencyPropertyDescriptor(propertyDeclaration.Name, elementDeclaration.Type, propertyDeclaration.DeclaringType.Type); + + bool isDescendant = (areValidTypes && (propertyDeclaration.DeclaringType.Type.Equals(elementDeclaration.Type) || elementDeclaration.Type.IsSubclassOf(propertyDeclaration.DeclaringType.Type))); + bool isAttached = (descriptor != null && descriptor.IsAttached); + bool differentType = ((propertyDeclaration.DeclaringType != propertyDeclaration.DeclaringType || !isDescendant)); + + 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)) + { + sb.Append(prefix); + sb.Append(":"); + } + } + if ((differentType || isAttached || !checkType) && propertyDeclaration.DeclaringType.Name.Length > 0) + { + sb.Append(propertyDeclaration.DeclaringType.Name); + sb.Append("."); + } + sb.Append(propertyDeclaration.Name); + + return sb.ToString(); + } + + private void ReadPropertyWithStaticResourceIdentifier() + { + short identifier = reader.ReadInt16(); + short staticIdentifier = reader.ReadInt16(); + + PropertyDeclaration pd = this.GetPropertyDeclaration(identifier); + object staticResource = this.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); + property.Value = value; + + nodes.Enqueue(property); + } + + + private 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]; + } + } + + //return "???"; + throw new ArgumentException("Cannot find StaticResource", "identifier"); + } + + private void ReadTextWithConverter() + { + string text = reader.ReadString(); + reader.ReadInt16(); + + nodes.Enqueue(new XmlBamlText(text)); + } + + private void ReadTypeInfo() + { + short typeId = reader.ReadInt16(); + short assemblyId = reader.ReadInt16(); + string fullName = reader.ReadString(); + assemblyId = (short)(assemblyId & 0xfff); + TypeDeclaration declaration; + int length = fullName.LastIndexOf('.'); + if (length != -1) + { + string name = fullName.Substring(length + 1); + string namespaceName = fullName.Substring(0, length); + declaration = new TypeDeclaration(this, this.Resolver, name, namespaceName, assemblyId, false); + } + else + { + declaration = new TypeDeclaration(this, this.Resolver, fullName, string.Empty, assemblyId, false); + } + this.typeTable.Add(typeId, declaration); + } + + private void ReadAssemblyInfo() + { + short key = reader.ReadInt16(); + string text = reader.ReadString(); + this.assemblyTable.Add(key, text); + } + + private void ReadStringInfo() + { + short key = reader.ReadInt16(); + string text = reader.ReadString(); + this.stringTable.Add(key, text); + } + + private TypeDeclaration GetTypeDeclaration(short identifier) + { + TypeDeclaration declaration; + if (identifier >= 0) + declaration = (TypeDeclaration)this.typeTable[identifier]; + else + declaration = KnownInfo.KnownTypeTable[-identifier]; + + if (declaration == null) + throw new NotSupportedException(); + + return declaration; + } + + internal string GetAssembly(short identifier) + { + return this.assemblyTable[identifier].ToString(); + } + + private XmlBamlNode CurrentNode + { + get + { + return _currentNode; + } + } + + /// + ///When overridden in a derived class, gets the namespace URI (as defined in the W3C Namespace specification) of the node on which the reader is positioned. + /// + /// + /// + ///The namespace URI of the current node; otherwise an empty string. + /// + /// + public override string NamespaceURI + { + get + { + if (intoAttribute) return String.Empty; + + TypeDeclaration declaration; + XmlBamlNode node = this.CurrentNode; + 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 (String.CompareOrdinal(propertyMapping.XmlNamespace, elementMapping.XmlNamespace) == 0 + || (elementDeclaration.Type != null && declaration.Type != null && elementDeclaration.Type.IsSubclassOf(declaration.Type))) + return String.Empty; + } + else if (node is XmlBamlElement) + declaration = ((XmlBamlElement)node).TypeDeclaration; + else + return String.Empty; + + XmlPIMapping mapping = FindByClrNamespaceAndAssemblyId(declaration); + if (mapping == null) + mapping = XmlPIMapping.Presentation; + + return mapping.XmlNamespace; + } + } + + /// + ///When overridden in a derived class, gets the namespace prefix associated with the current node. + /// + /// + /// + ///The namespace prefix associated with the current node. + /// + /// + public override string Prefix + { + get + { + if (!intoAttribute) + return ((IXmlNamespaceResolver)this).LookupPrefix(this.NamespaceURI) ?? String.Empty; + return String.Empty; + } + } + + /// + ///When overridden in a derived class, gets a value indicating whether the current node can have a . + /// + /// + /// + ///true if the node on which the reader is currently positioned can have a Value; otherwise, false. If false, the node has a value of String.Empty. + /// + /// + public override bool HasValue + { + get { return this.Value != null; } + } + + /// + /// Returns object used to resolve types + /// + public ITypeResolver Resolver + { + get { return _resolver; } + } + + /// + ///When overridden in a derived class, gets the text value of the current node. + /// + /// + /// + ///The value returned depends on the of the node. The following table lists node types that have a value to return. All other node types return String.Empty.Node type Value AttributeThe value of the attribute. CDATAThe content of the CDATA section. CommentThe content of the comment. DocumentTypeThe internal subset. ProcessingInstructionThe entire content, excluding the target. SignificantWhitespaceThe white space between markup in a mixed content model. TextThe content of the text node. WhitespaceThe white space between markup. XmlDeclarationThe content of the declaration. + /// + /// + public override string Value + { + get + { + XmlBamlNode node = this.CurrentNode; + if (node is XmlBamlProperty) + return ((XmlBamlProperty)node).Value.ToString(); + else if (node is XmlBamlText) + return ((XmlBamlText)node).Text; + else if (node is XmlBamlElement) + return String.Empty; + + return String.Empty; + } + } + + /// + /// Return root namespaces + /// + public IDictionary RootNamespaces + { + get { return _rootNamespaces; } + } + + /// + ///When overridden in a derived class, gets the depth of the current node in the XML document. + /// + /// + /// + ///The depth of the current node in the XML document. + /// + /// + public override int Depth + { + get { return this.readingElements.Count; } + } + + /// + ///When overridden in a derived class, gets the base URI of the current node. + /// + /// + /// + ///The base URI of the current node. + /// + /// + public override string BaseURI + { + get { return String.Empty; } + } + + /// + ///When overridden in a derived class, gets a value indicating whether the current node is an empty element (for example, <MyElement/>). + /// + /// + /// + ///true if the current node is an element ( equals XmlNodeType.Element) that ends with />; otherwise, false. + /// + /// + public override bool IsEmptyElement + { + get { return false; } + } + + //public override bool IsDefault + //{ + // get + // { + // return this.NamespaceURI == null; + // } + //} + + /// + ///When overridden in a derived class, gets the number of attributes on the current node. + /// + /// + /// + ///The number of attributes on the current node. + /// + /// + public override int AttributeCount + { + get { throw new NotImplementedException(); } + } + + /// + ///When overridden in a derived class, gets a value indicating whether the reader is positioned at the end of the stream. + /// + /// + /// + ///true if the reader is positioned at the end of the stream; otherwise, false. + /// + /// + public override bool EOF + { + get { return _eof; } + } + + /// + ///When overridden in a derived class, gets the state of the reader. + /// + /// + /// + ///One of the values. + /// + /// + public override ReadState ReadState + { + get + { + if (!initialized) + return ReadState.Initial; + else if (reader == null) + return ReadState.Closed; + else if (this.EOF) + return ReadState.EndOfFile; + else + return ReadState.Interactive; + } + } + + public List Mappings + { + get { return _mappings; } + } + + /// + ///When overridden in a derived class, gets the associated with this implementation. + /// + /// + /// + ///The XmlNameTable enabling you to get the atomized version of a string within the node. + /// + /// + public override XmlNameTable NameTable + { + get { return _nameTable; } + } + + #region IXmlNamespaceResolver Members + + /// + ///Gets a collection of defined prefix-namespace Mappings that are currently in scope. + /// + /// + /// + ///An that contains the current in-scope namespaces. + /// + /// + ///An value that specifies the type of namespace nodes to return. + IDictionary IXmlNamespaceResolver.GetNamespacesInScope(XmlNamespaceScope scope) + { + XmlNamespaceCollection namespaces = readingElements.Peek().Namespaces; + Dictionary list = new Dictionary(); + foreach (XmlNamespace ns in namespaces) + { + list.Add(ns.Prefix, ns.Namespace); + } + + return list; + } + + /// + ///Gets the namespace URI mapped to the specified prefix. + /// + /// + /// + ///The namespace URI that is mapped to the prefix; null if the prefix is not mapped to a namespace URI. + /// + /// + ///The prefix whose namespace URI you wish to find. + string IXmlNamespaceResolver.LookupNamespace(string prefix) + { + return this.LookupNamespace(prefix); + } + + /// + ///Gets the prefix that is mapped to the specified namespace URI. + /// + /// + /// + ///The prefix that is mapped to the namespace URI; null if the namespace URI is not mapped to a prefix. + /// + /// + ///The namespace URI whose prefix you wish to find. + string IXmlNamespaceResolver.LookupPrefix(string namespaceName) + { + return this.LookupPrefix(namespaceName, true); + } + + private string LookupPrefix(string namespaceName, bool useReading) + { + Stack elements; + if (useReading) + elements = readingElements; + else + elements = this.elements; + + if (elements.Count == 0) return null; + XmlNamespaceCollection namespaces = elements.Peek().Namespaces; + + return LookupPrefix(namespaceName, namespaces); + } + + private static string LookupPrefix(string namespaceName, XmlNamespaceCollection namespaces) + { + for (int x = 0; x < namespaces.Count; x++) + { + if (String.CompareOrdinal(namespaces[x].Namespace, namespaceName) == 0) + return namespaces[x].Prefix; + } + + return null; + } + + #endregion + + #region IntegerCollectionType + + internal enum IntegerCollectionType : byte + { + Byte = 2, + Consecutive = 1, + Integer = 4, + Unknown = 0, + UShort = 3 + } + + #endregion + + #region NodesCollection + + internal class NodesCollection : List + { + public XmlBamlNode Last + { + get + { + if (this.Count > 0) + { + int i = this.Count - 1; + return this[i]; + } + return null; + } + } + + public void RemoveLast() + { + if (this.Count > 0) + this.Remove(this.Last); + } + + public XmlBamlNode Dequeue() + { + return DequeueInternal(true); + } + + public XmlBamlNode Peek() + { + return DequeueInternal(false); + } + + private XmlBamlNode DequeueInternal(bool remove) + { + if (this.Count > 0) + { + XmlBamlNode node = this[0]; + if (remove) + this.RemoveAt(0); + return node; + } + else + return null; + } + + + public void Enqueue(XmlBamlNode node) + { + this.Add(node); + } + } + + #endregion + } +} \ No newline at end of file diff --git a/ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/XmlBamlText.cs b/ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/XmlBamlText.cs new file mode 100644 index 000000000..56114cac3 --- /dev/null +++ b/ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/XmlBamlText.cs @@ -0,0 +1,33 @@ +// Copyright (c) Cristian Civera (cristian@aspitalia.com) +// This code is distributed under the MS-PL (for details please see \doc\MS-PL.txt) + +using System; +using System.Collections.Generic; +using System.Text; +using System.Xml; + +namespace Ricciolo.StylesExplorer.MarkupReflection +{ + internal class XmlBamlText : XmlBamlNode + { + private string _text; + + public XmlBamlText(string text) + { + _text = text; + } + + public string Text + { + get { return _text; } + } + + public override System.Xml.XmlNodeType NodeType + { + get + { + return XmlNodeType.Text; + } + } + } +} diff --git a/ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/XmlNamespace.cs b/ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/XmlNamespace.cs new file mode 100644 index 000000000..c064931b5 --- /dev/null +++ b/ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/XmlNamespace.cs @@ -0,0 +1,47 @@ +// Copyright (c) Cristian Civera (cristian@aspitalia.com) +// This code is distributed under the MS-PL (for details please see \doc\MS-PL.txt) + +using System.Collections.Generic; + +namespace Ricciolo.StylesExplorer.MarkupReflection +{ + internal class XmlNamespace + { + private string _prefix; + private string _namespace; + + public XmlNamespace(string prefix, string ns) + { + _prefix = prefix; + _namespace = ns; + } + + public string Prefix + { + get { return _prefix; } + } + + public string Namespace + { + get { return _namespace; } + } + + public override bool Equals(object obj) + { + if (obj is XmlNamespace) + { + XmlNamespace o = (XmlNamespace)obj; + return (o.Prefix.Equals(this.Prefix) && o.Namespace.Equals(this.Namespace)); + } + return base.Equals(obj); + } + + public override int GetHashCode() + { + return _prefix.GetHashCode() + _namespace.GetHashCode() >> 20; + } + } + + internal class XmlNamespaceCollection : List + {} +} \ No newline at end of file diff --git a/ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/XmlPIMapping.cs b/ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/XmlPIMapping.cs new file mode 100644 index 000000000..3c321c8f1 --- /dev/null +++ b/ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/XmlPIMapping.cs @@ -0,0 +1,63 @@ +// Copyright (c) Cristian Civera (cristian@aspitalia.com) +// This code is distributed under the MS-PL (for details please see \doc\MS-PL.txt) + +using System; + +namespace Ricciolo.StylesExplorer.MarkupReflection +{ + /// + /// Rappresenta la mappatura tra namespace XML e namespace CLR con relativo assembly + /// + public class XmlPIMapping + { + private string _xmlNamespace; + private short _assemblyId; + private string _clrNamespace; + private static XmlPIMapping _default = new XmlPIMapping(PresentationNamespace, 0, String.Empty); + + public const string XamlNamespace = "http://schemas.microsoft.com/winfx/2006/xaml"; + public const string PresentationNamespace = "http://schemas.microsoft.com/winfx/2006/xaml/presentation"; + public const string PresentationOptionsNamespace = "http://schemas.microsoft.com/winfx/2006/xaml/presentation/options"; + public const string McNamespace = "http://schemas.openxmlformats.org/markup-compatibility/2006"; + + public XmlPIMapping(string xmlNamespace, short assemblyId, string clrNamespace) + { + _xmlNamespace = xmlNamespace; + _assemblyId = assemblyId; + _clrNamespace = clrNamespace; + } + + /// + /// Restituisce o imposta il namespace XML + /// + public string XmlNamespace + { + get { return _xmlNamespace; } + set { _xmlNamespace = value;} + } + + /// + /// Restituisce l'id dell'assembly + /// + public short AssemblyId + { + get { return _assemblyId; } + } + + /// + /// Restituisce il namespace clr + /// + public string ClrNamespace + { + get { return _clrNamespace; } + } + + /// + /// Restituisce il mapping di default di WPF + /// + public static XmlPIMapping Presentation + { + get { return _default; } + } + } +} \ No newline at end of file diff --git a/ILSpy.sln b/ILSpy.sln index 78bafdde2..747fdd135 100644 --- a/ILSpy.sln +++ b/ILSpy.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 11.00 # Visual Studio 2010 -# SharpDevelop 4.1.0.7384-alpha +# SharpDevelop 4.1.0.7466-alpha Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "doc", "doc", "{F45DB999-7E72-4000-B5AD-3A7B485A0896}" ProjectSection(SolutionItems) = postProject doc\Command Line.txt = doc\Command Line.txt @@ -25,6 +25,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestPlugin", "TestPlugin\Te EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Mono.Cecil.Pdb", "Mono.Cecil\symbols\pdb\Mono.Cecil.Pdb.csproj", "{63E6915C-7EA4-4D76-AB28-0D7191EEA626}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ILSpy.BamlDecompiler", "ILSpy.BamlDecompiler\ILSpy.BamlDecompiler.csproj", "{A6BAD2BA-76BA-461C-8B6D-418607591247}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -105,6 +107,14 @@ Global {63E6915C-7EA4-4D76-AB28-0D7191EEA626}.Release|Any CPU.ActiveCfg = net_4_0_Release|Any CPU {63E6915C-7EA4-4D76-AB28-0D7191EEA626}.Release|x86.Build.0 = net_4_0_Debug|Any CPU {63E6915C-7EA4-4D76-AB28-0D7191EEA626}.Release|x86.ActiveCfg = net_4_0_Release|Any CPU + {A6BAD2BA-76BA-461C-8B6D-418607591247}.Debug|Any CPU.Build.0 = Debug|x86 + {A6BAD2BA-76BA-461C-8B6D-418607591247}.Debug|Any CPU.ActiveCfg = Debug|x86 + {A6BAD2BA-76BA-461C-8B6D-418607591247}.Debug|x86.Build.0 = Debug|x86 + {A6BAD2BA-76BA-461C-8B6D-418607591247}.Debug|x86.ActiveCfg = Debug|x86 + {A6BAD2BA-76BA-461C-8B6D-418607591247}.Release|Any CPU.Build.0 = Release|x86 + {A6BAD2BA-76BA-461C-8B6D-418607591247}.Release|Any CPU.ActiveCfg = Release|x86 + {A6BAD2BA-76BA-461C-8B6D-418607591247}.Release|x86.Build.0 = Release|x86 + {A6BAD2BA-76BA-461C-8B6D-418607591247}.Release|x86.ActiveCfg = Release|x86 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/ILSpy/AboutPage.cs b/ILSpy/AboutPage.cs index c88f832dc..fd4fb4891 100644 --- a/ILSpy/AboutPage.cs +++ b/ILSpy/AboutPage.cs @@ -93,7 +93,7 @@ namespace ICSharpCode.ILSpy output.AddVisualLineElementGenerator(new MyLinkElementGenerator("SharpDevelop", "http://www.icsharpcode.net/opensource/sd/")); output.AddVisualLineElementGenerator(new MyLinkElementGenerator("MIT License", "resource:license.txt")); output.AddVisualLineElementGenerator(new MyLinkElementGenerator("LGPL", "resource:LGPL.txt")); - textView.Show(output); + textView.ShowText(output); } sealed class MyLinkElementGenerator : LinkElementGenerator @@ -130,7 +130,7 @@ namespace ICSharpCode.ILSpy } catch (Exception ex) { AvalonEditTextOutput exceptionOutput = new AvalonEditTextOutput(); exceptionOutput.WriteLine(ex.ToString()); - textView.Show(exceptionOutput); + textView.ShowText(exceptionOutput); } }, TaskScheduler.FromCurrentSynchronizationContext()); }; diff --git a/ILSpy/App.xaml.cs b/ILSpy/App.xaml.cs index f0644d70a..0eab2937f 100644 --- a/ILSpy/App.xaml.cs +++ b/ILSpy/App.xaml.cs @@ -165,7 +165,7 @@ namespace ICSharpCode.ILSpy } } } - ILSpy.MainWindow.Instance.TextView.Show(output); + ILSpy.MainWindow.Instance.TextView.ShowText(output); } else { Process.Start(e.Uri.ToString()); } diff --git a/ILSpy/BamlDecompiler.cs b/ILSpy/BamlDecompiler.cs deleted file mode 100644 index c223dcb82..000000000 --- a/ILSpy/BamlDecompiler.cs +++ /dev/null @@ -1,445 +0,0 @@ -// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of this -// software and associated documentation files (the "Software"), to deal in the Software -// without restriction, including without limitation the rights to use, copy, modify, merge, -// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons -// to whom the Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all copies or -// substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, -// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE -// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. - -using System; -using System.ComponentModel.Composition; -using System.IO; -using System.Linq; -using System.Reflection; -using System.Threading.Tasks; -using System.Windows.Baml2006; -using System.Xaml; -using System.Xaml.Schema; -using System.Xml; -using System.Xml.Linq; -using ICSharpCode.AvalonEdit.Highlighting; -using ICSharpCode.ILSpy.TextView; -using ICSharpCode.ILSpy.TreeNodes; -using System.Diagnostics; -using System.Collections; -using System.Collections.Generic; - -namespace ICSharpCode.ILSpy.Baml -{ - /// Caution: use in separate AppDomain only! - sealed class BamlDecompiler : MarshalByRefObject - { - public BamlDecompiler() - { - } - - abstract class XamlNode - { - public readonly List Children = new List(); - - public abstract void WriteTo(XamlWriter writer); - } - - [Conditional("DEBUG")] - static void Log(string format, params object[] args) - { - Debug.WriteLine(format, args); - } - - sealed class XamlObjectNode : XamlNode - { - public readonly XamlType Type; - - public XamlObjectNode(XamlType type) - { - this.Type = type; - } - - public override void WriteTo(XamlWriter writer) - { - Log("StartObject {0}", this.Type); - writer.WriteStartObject(this.Type); - Debug.Indent(); - foreach (XamlNode node in this.Children) - node.WriteTo(writer); - Debug.Unindent(); - Log("EndObject"); - writer.WriteEndObject(); - } - } - - sealed class XamlGetObjectNode : XamlNode - { - public override void WriteTo(XamlWriter writer) - { - Log("GetObject"); - writer.WriteGetObject(); - Debug.Indent(); - foreach (XamlNode node in this.Children) - node.WriteTo(writer); - Debug.Unindent(); - Log("EndObject"); - writer.WriteEndObject(); - } - } - - sealed class XamlMemberNode : XamlNode - { - public XamlMember Member; - - public XamlMemberNode(XamlMember member) - { - this.Member = member; - } - - public override void WriteTo(XamlWriter writer) - { - Log("StartMember {0}", this.Member); - writer.WriteStartMember(this.Member); - Debug.Indent(); - foreach (XamlNode node in this.Children) - node.WriteTo(writer); - Debug.Unindent(); - Log("EndMember"); - writer.WriteEndMember(); - } - } - - sealed class XamlValueNode : XamlNode - { - public readonly object Value; - - public XamlValueNode(object value) - { - this.Value = value; - } - - public override void WriteTo(XamlWriter writer) - { - Log("Value {0}", this.Value); - Debug.Assert(this.Children.Count == 0); - // requires XamlReaderSettings.ValuesMustBeString = true to work properly - writer.WriteValue(this.Value); - } - } - - sealed class XamlNamespaceDeclarationNode : XamlNode - { - public readonly NamespaceDeclaration Namespace; - - public XamlNamespaceDeclarationNode(NamespaceDeclaration @namespace) - { - this.Namespace = @namespace; - } - - public override void WriteTo(XamlWriter writer) - { - Log("NamespaceDeclaration {0}", this.Namespace); - Debug.Assert(this.Children.Count == 0); - writer.WriteNamespace(this.Namespace); - } - } - - static List Parse(XamlReader reader) - { - List currentList = new List(); - Stack> stack = new Stack>(); - while (reader.Read()) { - switch (reader.NodeType) { - case XamlNodeType.None: - break; - case XamlNodeType.StartObject: - XamlObjectNode obj = new XamlObjectNode(reader.Type); - currentList.Add(obj); - stack.Push(currentList); - currentList = obj.Children; - break; - case XamlNodeType.GetObject: - XamlGetObjectNode getObject = new XamlGetObjectNode(); - currentList.Add(getObject); - stack.Push(currentList); - currentList = getObject.Children; - break; - case XamlNodeType.StartMember: - XamlMemberNode member = new XamlMemberNode(reader.Member); - currentList.Add(member); - stack.Push(currentList); - currentList = member.Children; - break; - case XamlNodeType.Value: - currentList.Add(new XamlValueNode(reader.Value)); - break; - case XamlNodeType.NamespaceDeclaration: - currentList.Add(new XamlNamespaceDeclarationNode(reader.Namespace)); - break; - case XamlNodeType.EndObject: - case XamlNodeType.EndMember: - currentList = stack.Pop(); - break; - default: - throw new InvalidOperationException("Invalid value for XamlNodeType"); - } - } - if (stack.Count != 0) - throw new InvalidOperationException("Imbalanced stack"); - return currentList; - } - - void AvoidContentProperties(XamlNode node) - { - foreach (XamlNode child in node.Children) - AvoidContentProperties(child); - - - XamlObjectNode obj = node as XamlObjectNode; - if (obj != null) { - // Visit all except for the last child: - for (int i = 0; i < obj.Children.Count - 1; i++) { - // Avoids using content property syntax for simple string values, if the content property is not the last member. - // Without this, we cannot decompile <GridViewColumn Header="Culture" DisplayMemberBinding="{Binding Culture}" />, - // because the Header property is the content property, but there is no way to represent the Binding as an element. - XamlMemberNode memberNode = obj.Children[i] as XamlMemberNode; - if (memberNode != null && memberNode.Member == obj.Type.ContentProperty) { - if (memberNode.Children.Count == 1 && memberNode.Children[0] is XamlValueNode) { - // By creating a clone of the XamlMember, we prevent WPF from knowing that it's the content property. - XamlMember member = memberNode.Member; - memberNode.Member = new XamlMember(member.Name, member.DeclaringType, member.IsAttachable); - } - } - } - // We also need to avoid using content properties that have a markup extension as value, as the XamlXmlWriter would always expand those: - for (int i = 0; i < obj.Children.Count; i++) { - XamlMemberNode memberNode = obj.Children[i] as XamlMemberNode; - if (memberNode != null && memberNode.Member == obj.Type.ContentProperty && memberNode.Children.Count == 1) { - XamlObjectNode me = memberNode.Children[0] as XamlObjectNode; - if (me != null && me.Type.IsMarkupExtension) { - // By creating a clone of the XamlMember, we prevent WPF from knowing that it's the content property. - XamlMember member = memberNode.Member; - memberNode.Member = new XamlMember(member.Name, member.DeclaringType, member.IsAttachable); - } - } - } - } - } - - /// - /// It seems like BamlReader will always output 'x:Key' as last property. However, it must be specified as attribute in valid .xaml, so we move it to the front - /// of the attribute list. - /// - void MoveXKeyToFront(XamlNode node) - { - foreach (XamlNode child in node.Children) - MoveXKeyToFront(child); - - XamlObjectNode obj = node as XamlObjectNode; - if (obj != null && obj.Children.Count > 0) { - XamlMemberNode memberNode = obj.Children[obj.Children.Count - 1] as XamlMemberNode; - if (memberNode != null && memberNode.Member == XamlLanguage.Key) { - // move memberNode in front of the first member node: - for (int i = 0; i < obj.Children.Count; i++) { - if (obj.Children[i] is XamlMemberNode) { - obj.Children.Insert(i, memberNode); - obj.Children.RemoveAt(obj.Children.Count - 1); - break; - } - } - } - } - } - - AssemblyResolver asmResolver; - - Assembly AssemblyResolve(object sender, ResolveEventArgs args) - { - string path = asmResolver.FindAssembly(args.Name); - - if (path == null) - return null; - - return Assembly.LoadFile(path); - } - - public string DecompileBaml(MemoryStream bamlCode, string containingAssemblyFile, ConnectMethodDecompiler connectMethodDecompiler, AssemblyResolver asmResolver) - { - this.asmResolver = asmResolver; - AppDomain.CurrentDomain.AssemblyResolve += AssemblyResolve; - - bamlCode.Position = 0; - TextWriter w = new StringWriter(); - - Assembly assembly = Assembly.LoadFile(containingAssemblyFile); - - Baml2006Reader reader = new Baml2006Reader(bamlCode, new XamlReaderSettings() { ValuesMustBeString = true, LocalAssembly = assembly }); - var xamlDocument = Parse(reader); - - string bamlTypeName = xamlDocument.OfType().First().Type.UnderlyingType.FullName; - - var eventMappings = connectMethodDecompiler.DecompileEventMappings(bamlTypeName); - - foreach (var xamlNode in xamlDocument) { - RemoveConnectionIds(xamlNode, eventMappings, reader.SchemaContext); - AvoidContentProperties(xamlNode); - MoveXKeyToFront(xamlNode); - } - - XDocument doc = new XDocument(); - XamlXmlWriter writer = new XamlXmlWriter(doc.CreateWriter(), reader.SchemaContext, new XamlXmlWriterSettings { AssumeValidInput = true }); - foreach (var xamlNode in xamlDocument) - xamlNode.WriteTo(writer); - writer.Close(); - - // Fix namespace references - string suffixToRemove = ";assembly=" + assembly.GetName().Name; - foreach (XAttribute attrib in doc.Root.Attributes()) { - if (attrib.Name.Namespace == XNamespace.Xmlns) { - if (attrib.Value.EndsWith(suffixToRemove, StringComparison.Ordinal)) { - string newNamespace = attrib.Value.Substring(0, attrib.Value.Length - suffixToRemove.Length); - ChangeXmlNamespace(doc, attrib.Value, newNamespace); - attrib.Value = newNamespace; - } - } - } - - return doc.ToString(); - } - - void RemoveConnectionIds(XamlNode node, Dictionary eventMappings, XamlSchemaContext context) - { - foreach (XamlNode child in node.Children) - RemoveConnectionIds(child, eventMappings, context); - - XamlObjectNode obj = node as XamlObjectNode; - if (obj != null && obj.Children.Count > 0) { - var removableNodes = new List(); - var addableNodes = new List(); - foreach (XamlMemberNode memberNode in obj.Children.OfType()) { - if (memberNode.Member == XamlLanguage.ConnectionId && memberNode.Children.Single() is XamlValueNode) { - var value = memberNode.Children.Single() as XamlValueNode; - int id; - if (value.Value is string && int.TryParse(value.Value as string, out id) && eventMappings.ContainsKey(id)) { - var map = eventMappings[id]; - foreach (var entry in map) { - if (entry.IsAttached) { - var type = context.GetXamlType(Type.GetType(entry.AttachSourceType)); - var member = new XamlMemberNode(new XamlMember(entry.EventName, type, true)); - member.Children.Add(new XamlValueNode(entry.MethodName)); - addableNodes.Add(member); - } else { - var member = new XamlMemberNode(obj.Type.GetMember(entry.EventName)); - member.Children.Add(new XamlValueNode(entry.MethodName)); - addableNodes.Add(member); - } - } - removableNodes.Add(memberNode); - } - } - } - foreach (var rnode in removableNodes) - node.Children.Remove(rnode); - node.Children.InsertRange(node.Children.Count > 1 ? node.Children.Count - 1 : 0, addableNodes); - } - } - - /// - /// Changes all references from oldNamespace to newNamespace in the document. - /// - void ChangeXmlNamespace(XDocument doc, XNamespace oldNamespace, XNamespace newNamespace) - { - foreach (XElement e in doc.Descendants()) { - if (e.Name.Namespace == oldNamespace) - e.Name = newNamespace + e.Name.LocalName; - } - } - } - - [Export(typeof(IResourceNodeFactory))] - sealed class BamlResourceNodeFactory : IResourceNodeFactory - { - public ILSpyTreeNode CreateNode(Mono.Cecil.Resource resource) - { - return null; - } - - public ILSpyTreeNode CreateNode(string key, Stream data) - { - if (key.EndsWith(".baml", StringComparison.OrdinalIgnoreCase)) - return new BamlResourceEntryNode(key, data); - else - return null; - } - } - - sealed class BamlResourceEntryNode : ResourceEntryNode - { - public BamlResourceEntryNode(string key, Stream data) : base(key, data) - { - } - - internal override bool View(DecompilerTextView textView) - { - AvalonEditTextOutput output = new AvalonEditTextOutput(); - IHighlightingDefinition highlighting = null; - - textView.RunWithCancellation( - token => Task.Factory.StartNew( - () => { - try { - if (LoadBaml(output)) - highlighting = HighlightingManager.Instance.GetDefinitionByExtension(".xml"); - } catch (Exception ex) { - output.Write(ex.ToString()); - } - return output; - }), - t => textView.Show(t.Result, highlighting) - ); - return true; - } - - bool LoadBaml(AvalonEditTextOutput output) - { - var asm = this.Ancestors().OfType().FirstOrDefault().LoadedAssembly; - - AppDomain bamlDecompilerAppDomain = null; - try { - BamlDecompiler decompiler = CreateBamlDecompilerInAppDomain(ref bamlDecompilerAppDomain, asm.FileName); - - MemoryStream bamlStream = new MemoryStream(); - Data.Position = 0; - Data.CopyTo(bamlStream); - - output.Write(decompiler.DecompileBaml(bamlStream, asm.FileName, new ConnectMethodDecompiler(asm), new AssemblyResolver(asm))); - return true; - } finally { - if (bamlDecompilerAppDomain != null) - AppDomain.Unload(bamlDecompilerAppDomain); - } - } - - public static BamlDecompiler CreateBamlDecompilerInAppDomain(ref AppDomain appDomain, string assemblyFileName) - { - if (appDomain == null) { - // Construct and initialize settings for a second AppDomain. - AppDomainSetup bamlDecompilerAppDomainSetup = new AppDomainSetup(); -// bamlDecompilerAppDomainSetup.ApplicationBase = "file:///" + Path.GetDirectoryName(assemblyFileName); - bamlDecompilerAppDomainSetup.DisallowBindingRedirects = false; - bamlDecompilerAppDomainSetup.DisallowCodeDownload = true; - bamlDecompilerAppDomainSetup.ConfigurationFile = AppDomain.CurrentDomain.SetupInformation.ConfigurationFile; - - // Create the second AppDomain. - appDomain = AppDomain.CreateDomain("BamlDecompiler AD", null, bamlDecompilerAppDomainSetup); - } - return (BamlDecompiler)appDomain.CreateInstanceAndUnwrap(typeof(BamlDecompiler).Assembly.FullName, typeof(BamlDecompiler).FullName); - } - } -} \ No newline at end of file diff --git a/ILSpy/CSharpLanguage.cs b/ILSpy/CSharpLanguage.cs index c0fee6954..67ab007d7 100644 --- a/ILSpy/CSharpLanguage.cs +++ b/ILSpy/CSharpLanguage.cs @@ -47,11 +47,11 @@ namespace ICSharpCode.ILSpy string name = "C#"; bool showAllMembers = false; Predicate transformAbortCondition = null; - + public CSharpLanguage() { } - + #if DEBUG internal static IEnumerable GetDebugLanguages() { @@ -72,28 +72,73 @@ namespace ICSharpCode.ILSpy }; } #endif - - public override string Name { + + public override string Name + { get { return name; } } - - public override string FileExtension { + + public override string FileExtension + { get { return ".cs"; } } - - public override string ProjectFileExtension { + + public override string ProjectFileExtension + { get { return ".csproj"; } } - + public override void DecompileMethod(MethodDefinition method, ITextOutput output, DecompilationOptions options) { WriteCommentLine(output, TypeToString(method.DeclaringType, includeNamespace: true)); AstBuilder codeDomBuilder = CreateAstBuilder(options, currentType: method.DeclaringType, isSingleMember: true); - codeDomBuilder.AddMethod(method); - RunTransformsAndGenerateCode(codeDomBuilder, output, options); + if (method.IsConstructor && !method.IsStatic && !method.DeclaringType.IsValueType) { + // also fields and other ctors so that the field initializers can be shown as such + AddFieldsAndCtors(codeDomBuilder, method.DeclaringType, method.IsStatic); + RunTransformsAndGenerateCode(codeDomBuilder, output, options, new SelectCtorTransform(method)); + } else { + codeDomBuilder.AddMethod(method); + RunTransformsAndGenerateCode(codeDomBuilder, output, options); + } NotifyDecompilationFinished(codeDomBuilder); } + class SelectCtorTransform : IAstTransform + { + readonly MethodDefinition ctorDef; + + public SelectCtorTransform(MethodDefinition ctorDef) + { + this.ctorDef = ctorDef; + } + + public void Run(AstNode compilationUnit) + { + ConstructorDeclaration ctorDecl = null; + foreach (var node in compilationUnit.Children) { + ConstructorDeclaration ctor = node as ConstructorDeclaration; + if (ctor != null) { + if (ctor.Annotation() == ctorDef) { + ctorDecl = ctor; + } else { + // remove other ctors + ctor.Remove(); + } + } + // Remove any fields without initializers + FieldDeclaration fd = node as FieldDeclaration; + if (fd != null && fd.Variables.All(v => v.Initializer.IsNull)) + fd.Remove(); + } + if (ctorDecl.Initializer.ConstructorInitializerType == ConstructorInitializerType.This) { + // remove all fields + foreach (var node in compilationUnit.Children) + if (node is FieldDeclaration) + node.Remove(); + } + } + } + public override void DecompileProperty(PropertyDefinition property, ITextOutput output, DecompilationOptions options) { WriteCommentLine(output, TypeToString(property.DeclaringType, includeNamespace: true)); @@ -102,16 +147,56 @@ namespace ICSharpCode.ILSpy RunTransformsAndGenerateCode(codeDomBuilder, output, options); NotifyDecompilationFinished(codeDomBuilder); } - + public override void DecompileField(FieldDefinition field, ITextOutput output, DecompilationOptions options) { WriteCommentLine(output, TypeToString(field.DeclaringType, includeNamespace: true)); AstBuilder codeDomBuilder = CreateAstBuilder(options, currentType: field.DeclaringType, isSingleMember: true); - codeDomBuilder.AddField(field); - RunTransformsAndGenerateCode(codeDomBuilder, output, options); + if (field.IsLiteral) { + codeDomBuilder.AddField(field); + } else { + // also decompile ctors so that the field initializer can be shown + AddFieldsAndCtors(codeDomBuilder, field.DeclaringType, field.IsStatic); + } + RunTransformsAndGenerateCode(codeDomBuilder, output, options, new SelectFieldTransform(field)); NotifyDecompilationFinished(codeDomBuilder); } + /// + /// Removes all top-level members except for the specified fields. + /// + sealed class SelectFieldTransform : IAstTransform + { + readonly FieldDefinition field; + + public SelectFieldTransform(FieldDefinition field) + { + this.field = field; + } + + public void Run(AstNode compilationUnit) + { + foreach (var child in compilationUnit.Children) { + if (child is AttributedNode) { + if (child.Annotation() != field) + child.Remove(); + } + } + } + } + + void AddFieldsAndCtors(AstBuilder codeDomBuilder, TypeDefinition declaringType, bool isStatic) + { + foreach (var field in declaringType.Fields) { + if (field.IsStatic == isStatic) + codeDomBuilder.AddField(field); + } + foreach (var ctor in declaringType.Methods) { + if (ctor.IsConstructor && ctor.IsStatic == isStatic) + codeDomBuilder.AddMethod(ctor); + } + } + public override void DecompileEvent(EventDefinition ev, ITextOutput output, DecompilationOptions options) { WriteCommentLine(output, TypeToString(ev.DeclaringType, includeNamespace: true)); @@ -120,7 +205,7 @@ namespace ICSharpCode.ILSpy RunTransformsAndGenerateCode(codeDomBuilder, output, options); NotifyDecompilationFinished(codeDomBuilder); } - + public override void DecompileType(TypeDefinition type, ITextOutput output, DecompilationOptions options) { AstBuilder codeDomBuilder = CreateAstBuilder(options, currentType: type); @@ -129,14 +214,18 @@ namespace ICSharpCode.ILSpy NotifyDecompilationFinished(codeDomBuilder); } - void RunTransformsAndGenerateCode(AstBuilder astBuilder, ITextOutput output, DecompilationOptions options) + void RunTransformsAndGenerateCode(AstBuilder astBuilder, ITextOutput output, DecompilationOptions options, IAstTransform additionalTransform = null) { astBuilder.RunTransformations(transformAbortCondition); - if (options.DecompilerSettings.ShowXmlDocumentation) + if (additionalTransform != null) { + additionalTransform.Run(astBuilder.CompilationUnit); + } + if (options.DecompilerSettings.ShowXmlDocumentation) { AddXmlDocTransform.Run(astBuilder.CompilationUnit); + } astBuilder.GenerateCode(output); } - + public override void DecompileAssembly(LoadedAssembly assembly, ITextOutput output, DecompilationOptions options) { if (options.FullDecompilation && options.SaveAsProjectDirectory != null) { @@ -156,7 +245,7 @@ namespace ICSharpCode.ILSpy } OnDecompilationFinished(null); } - + #region WriteProjectFile void WriteProjectFile(TextWriter writer, IEnumerable> files, ModuleDefinition module) { @@ -184,20 +273,20 @@ namespace ICSharpCode.ILSpy w.WriteStartElement("Project", ns); w.WriteAttributeString("ToolsVersion", "4.0"); w.WriteAttributeString("DefaultTargets", "Build"); - + w.WriteStartElement("PropertyGroup"); w.WriteElementString("ProjectGuid", Guid.NewGuid().ToString().ToUpperInvariant()); - + w.WriteStartElement("Configuration"); w.WriteAttributeString("Condition", " '$(Configuration)' == '' "); w.WriteValue("Debug"); w.WriteEndElement(); // - + w.WriteStartElement("Platform"); w.WriteAttributeString("Condition", " '$(Platform)' == '' "); w.WriteValue(platformName); w.WriteEndElement(); // - + switch (module.Kind) { case ModuleKind.Windows: w.WriteElementString("OutputType", "WinExe"); @@ -209,7 +298,7 @@ namespace ICSharpCode.ILSpy w.WriteElementString("OutputType", "Library"); break; } - + w.WriteElementString("AssemblyName", module.Assembly.Name.Name); switch (module.Runtime) { case TargetRuntime.Net_1_0: @@ -228,14 +317,14 @@ namespace ICSharpCode.ILSpy break; } w.WriteElementString("WarningLevel", "4"); - + w.WriteEndElement(); // - + w.WriteStartElement("PropertyGroup"); // platform-specific w.WriteAttributeString("Condition", " '$(Platform)' == '" + platformName + "' "); w.WriteElementString("PlatformTarget", platformName); w.WriteEndElement(); // (platform-specific) - + w.WriteStartElement("PropertyGroup"); // Debug w.WriteAttributeString("Condition", " '$(Configuration)' == 'Debug' "); w.WriteElementString("OutputPath", "bin\\Debug\\"); @@ -243,7 +332,7 @@ namespace ICSharpCode.ILSpy w.WriteElementString("DebugType", "full"); w.WriteElementString("Optimize", "false"); w.WriteEndElement(); // (Debug) - + w.WriteStartElement("PropertyGroup"); // Release w.WriteAttributeString("Condition", " '$(Configuration)' == 'Release' "); w.WriteElementString("OutputPath", "bin\\Release\\"); @@ -251,8 +340,8 @@ namespace ICSharpCode.ILSpy w.WriteElementString("DebugType", "pdbonly"); w.WriteElementString("Optimize", "true"); w.WriteEndElement(); // (Release) - - + + w.WriteStartElement("ItemGroup"); // References foreach (AssemblyNameReference r in module.AssemblyReferences) { if (r.Name != "mscorlib") { @@ -263,7 +352,7 @@ namespace ICSharpCode.ILSpy } } w.WriteEndElement(); // (References) - + foreach (IGrouping gr in (from f in files group f.Item2 by f.Item1 into g orderby g.Key select g)) { w.WriteStartElement("ItemGroup"); foreach (string file in gr.OrderBy(f => f, StringComparer.OrdinalIgnoreCase)) { @@ -273,16 +362,16 @@ namespace ICSharpCode.ILSpy } w.WriteEndElement(); } - + w.WriteStartElement("Import"); w.WriteAttributeString("Project", "$(MSBuildToolsPath)\\Microsoft.CSharp.targets"); w.WriteEndElement(); - + w.WriteEndDocument(); } } #endregion - + #region WriteCodeFilesInProject bool IncludeTypeWhenDecompilingProject(TypeDefinition type, DecompilationOptions options) { @@ -292,11 +381,11 @@ namespace ICSharpCode.ILSpy return false; return true; } - + IEnumerable> WriteCodeFilesInProject(AssemblyDefinition assembly, DecompilationOptions options, HashSet directories) { var files = assembly.MainModule.Types.Where(t => IncludeTypeWhenDecompilingProject(t, options)).GroupBy( - delegate (TypeDefinition type) { + delegate(TypeDefinition type) { string file = TextView.DecompilerTextView.CleanUpName(type.Name) + this.FileExtension; if (string.IsNullOrEmpty(type.Namespace)) { return file; @@ -311,7 +400,7 @@ namespace ICSharpCode.ILSpy Parallel.ForEach( files, new ParallelOptions { MaxDegreeOfParallelism = Environment.ProcessorCount }, - delegate (IGrouping file) { + delegate(IGrouping file) { using (StreamWriter w = new StreamWriter(Path.Combine(options.SaveAsProjectDirectory, file.Key))) { AstBuilder codeDomBuilder = CreateAstBuilder(options, currentModule: assembly.MainModule); foreach (TypeDefinition type in file) { @@ -325,7 +414,7 @@ namespace ICSharpCode.ILSpy return files.Select(f => Tuple.Create("Compile", f.Key)); } #endregion - + #region WriteResourceFilesInProject IEnumerable> WriteResourceFilesInProject(LoadedAssembly assembly, DecompilationOptions options, HashSet directories) { @@ -339,7 +428,8 @@ namespace ICSharpCode.ILSpy IEnumerable rs = null; try { rs = new ResourceSet(s).Cast(); - } catch (ArgumentException) { + } + catch (ArgumentException) { } if (rs != null && rs.All(e => e.Value is Stream)) { foreach (var pair in rs) { @@ -353,16 +443,18 @@ namespace ICSharpCode.ILSpy if (fileName.EndsWith(".baml", StringComparison.OrdinalIgnoreCase)) { MemoryStream ms = new MemoryStream(); entryStream.CopyTo(ms); - var decompiler = Baml.BamlResourceEntryNode.CreateBamlDecompilerInAppDomain(ref bamlDecompilerAppDomain, assembly.FileName); - string xaml = null; - try { - xaml = decompiler.DecompileBaml(ms, assembly.FileName, new ConnectMethodDecompiler(assembly), new AssemblyResolver(assembly)); - } catch (XamlXmlWriterException) {} // ignore XAML writer exceptions - if (xaml != null) { - File.WriteAllText(Path.Combine(options.SaveAsProjectDirectory, Path.ChangeExtension(fileName, ".xaml")), xaml); - yield return Tuple.Create("Page", Path.ChangeExtension(fileName, ".xaml")); - continue; - } + // TODO implement extension point +// var decompiler = Baml.BamlResourceEntryNode.CreateBamlDecompilerInAppDomain(ref bamlDecompilerAppDomain, assembly.FileName); +// string xaml = null; +// try { +// xaml = decompiler.DecompileBaml(ms, assembly.FileName, new ConnectMethodDecompiler(assembly), new AssemblyResolver(assembly)); +// } +// catch (XamlXmlWriterException) { } // ignore XAML writer exceptions +// if (xaml != null) { +// File.WriteAllText(Path.Combine(options.SaveAsProjectDirectory, Path.ChangeExtension(fileName, ".xaml")), xaml); +// yield return Tuple.Create("Page", Path.ChangeExtension(fileName, ".xaml")); +// continue; +// } } using (FileStream fs = new FileStream(Path.Combine(options.SaveAsProjectDirectory, fileName), FileMode.Create, FileAccess.Write)) { entryStream.CopyTo(fs); @@ -378,12 +470,13 @@ namespace ICSharpCode.ILSpy } yield return Tuple.Create("EmbeddedResource", fileName); } - } finally { + } + finally { if (bamlDecompilerAppDomain != null) AppDomain.Unload(bamlDecompilerAppDomain); } } - + string GetFileNameForResource(string fullName, HashSet directories) { string[] splitName = fullName.Split('.'); @@ -399,7 +492,7 @@ namespace ICSharpCode.ILSpy return fileName; } #endregion - + AstBuilder CreateAstBuilder(DecompilationOptions options, ModuleDefinition currentModule = null, TypeDefinition currentType = null, bool isSingleMember = false) { if (currentModule == null) @@ -422,8 +515,14 @@ namespace ICSharpCode.ILSpy ConvertTypeOptions options = ConvertTypeOptions.IncludeTypeParameterDefinitions; if (includeNamespace) options |= ConvertTypeOptions.IncludeNamespace; + + return TypeToString(options, type, typeAttributes); + } + + string TypeToString(ConvertTypeOptions options, TypeReference type, ICustomAttributeProvider typeAttributes = null) + { AstType astType = AstBuilder.ConvertType(type, typeAttributes, options); - + StringWriter w = new StringWriter(); if (type.IsByReference) { ParameterDefinition pd = typeAttributes as ParameterDefinition; @@ -431,11 +530,11 @@ namespace ICSharpCode.ILSpy w.Write("out "); else w.Write("ref "); - + if (astType is ComposedType && ((ComposedType)astType).PointerRank > 0) ((ComposedType)astType).PointerRank--; } - + astType.AcceptVisitor(new OutputVisitor(w, new CSharpFormattingOptions()), null); return w.ToString(); } @@ -471,11 +570,27 @@ namespace ICSharpCode.ILSpy return property.Name; } + public override string FormatTypeName(TypeDefinition type) + { + if (type == null) + throw new ArgumentNullException("type"); + + return TypeToString(ConvertTypeOptions.DoNotUsePrimitiveTypeNames | ConvertTypeOptions.IncludeTypeParameterDefinitions, type); + } + public override bool ShowMember(MemberReference member) { return showAllMembers || !AstBuilder.MemberIsHidden(member, new DecompilationOptions().DecompilerSettings); } - + + public override MemberReference GetOriginalCodeLocation(MemberReference member) + { + if (showAllMembers || !DecompilerSettingsPanel.CurrentDecompilerSettings.AnonymousMethods) + return member; + else + return ICSharpCode.ILSpy.TreeNodes.Analyzer.Helpers.GetOriginalCodeLocation(member); + } + public override string GetTooltip(MemberReference member) { MethodDefinition md = member as MethodDefinition; @@ -496,12 +611,12 @@ namespace ICSharpCode.ILSpy b.RunTransformations(); foreach (var attribute in b.CompilationUnit.Descendants.OfType()) attribute.Remove(); - + StringWriter w = new StringWriter(); b.GenerateCode(new PlainTextOutput(w)); return Regex.Replace(w.ToString(), @"\s+", " ").TrimEnd(); } - + return base.GetTooltip(member); } } diff --git a/ILSpy/Commands.cs b/ILSpy/Commands.cs index 67775f43d..8d89e9afc 100644 --- a/ILSpy/Commands.cs +++ b/ILSpy/Commands.cs @@ -122,7 +122,7 @@ namespace ICSharpCode.ILSpy return output; } ), - task => MainWindow.Instance.TextView.Show(task.Result)); + task => MainWindow.Instance.TextView.ShowText(task.Result)); } } #endif diff --git a/ILSpy/ConnectMethodDecompiler.cs b/ILSpy/ConnectMethodDecompiler.cs index b5487f06a..7cb2c1760 100644 --- a/ILSpy/ConnectMethodDecompiler.cs +++ b/ILSpy/ConnectMethodDecompiler.cs @@ -1,5 +1,20 @@ -// 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) +// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team +// +// Permission is hereby granted, free of charge, to any person obtaining a copy of this +// software and associated documentation files (the "Software"), to deal in the Software +// without restriction, including without limitation the rights to use, copy, modify, merge, +// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons +// to whom the Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all copies or +// substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE +// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. using System; using System.Collections.Generic; diff --git a/ILSpy/DisplaySettings.cs b/ILSpy/DisplaySettings.cs new file mode 100644 index 000000000..569bc0509 --- /dev/null +++ b/ILSpy/DisplaySettings.cs @@ -0,0 +1,93 @@ +// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team +// +// Permission is hereby granted, free of charge, to any person obtaining a copy of this +// software and associated documentation files (the "Software"), to deal in the Software +// without restriction, including without limitation the rights to use, copy, modify, merge, +// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons +// to whom the Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all copies or +// substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE +// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. + +using System; +using System.ComponentModel; +using System.Windows.Media; + +namespace ICSharpCode.ILSpy +{ + /// + /// Description of DisplaySettings. + /// + public class DisplaySettings : INotifyPropertyChanged + { + public DisplaySettings() + { + } + + #region INotifyPropertyChanged implementation + public event PropertyChangedEventHandler PropertyChanged; + + protected virtual void OnPropertyChanged(PropertyChangedEventArgs e) + { + if (PropertyChanged != null) { + PropertyChanged(this, e); + } + } + + protected void OnPropertyChanged(string propertyName) + { + OnPropertyChanged(new PropertyChangedEventArgs(propertyName)); + } + #endregion + + FontFamily selectedFont; + + public FontFamily SelectedFont { + get { return selectedFont; } + set { + if (selectedFont != value) { + selectedFont = value; + OnPropertyChanged("SelectedFont"); + } + } + } + + double selectedFontSize; + + public double SelectedFontSize { + get { return selectedFontSize; } + set { + if (selectedFontSize != value) { + selectedFontSize = value; + OnPropertyChanged("SelectedFontSize"); + } + } + } + + bool showLineNumbers; + + public bool ShowLineNumbers { + get { return showLineNumbers; } + set { + if (showLineNumbers != value) { + showLineNumbers = value; + OnPropertyChanged("ShowLineNumbers"); + } + } + } + + public void CopyValues(DisplaySettings s) + { + this.SelectedFont = s.selectedFont; + this.SelectedFontSize = s.selectedFontSize; + this.ShowLineNumbers = s.showLineNumbers; + } + } +} diff --git a/ILSpy/DisplaySettingsPanel.xaml b/ILSpy/DisplaySettingsPanel.xaml new file mode 100644 index 000000000..97131eca3 --- /dev/null +++ b/ILSpy/DisplaySettingsPanel.xaml @@ -0,0 +1,64 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + 15 + 16 + 17 + 18 + 19 + 20 + 21 + 22 + 23 + 24 + + + + + + + + Show line numbers + + + \ No newline at end of file diff --git a/ILSpy/DisplaySettingsPanel.xaml.cs b/ILSpy/DisplaySettingsPanel.xaml.cs new file mode 100644 index 000000000..b66bb316d --- /dev/null +++ b/ILSpy/DisplaySettingsPanel.xaml.cs @@ -0,0 +1,154 @@ +// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team +// +// Permission is hereby granted, free of charge, to any person obtaining a copy of this +// software and associated documentation files (the "Software"), to deal in the Software +// without restriction, including without limitation the rights to use, copy, modify, merge, +// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons +// to whom the Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all copies or +// substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE +// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Threading; +using System.Xml.Linq; +using ICSharpCode.Decompiler; + +namespace ICSharpCode.ILSpy +{ + /// + /// Interaction logic for DisplaySettingsPanel.xaml + /// + [ExportOptionPage("Display")] + public partial class DisplaySettingsPanel : UserControl, IOptionPage + { + public DisplaySettingsPanel() + { + InitializeComponent(); + + Task task = new Task(FontLoader); + task.Start(); + task.ContinueWith( + delegate(Task continuation) { + App.Current.Dispatcher.Invoke( + DispatcherPriority.Normal, + (Action)( + () => { + fontSelector.ItemsSource = task.Result; + if (continuation.Exception != null) { + foreach (var ex in continuation.Exception.InnerExceptions) { + MessageBox.Show(ex.ToString()); + } + } + }) + ); + } + ); + } + + public void Load(ILSpySettings settings) + { + this.DataContext = LoadDisplaySettings(settings); + } + + static DisplaySettings currentDisplaySettings; + + public static DisplaySettings CurrentDisplaySettings { + get { + return currentDisplaySettings ?? (currentDisplaySettings = LoadDisplaySettings(ILSpySettings.Load())); + } + } + + static bool IsSymbolFont(FontFamily fontFamily) + { + foreach (var tf in fontFamily.GetTypefaces()) { + GlyphTypeface glyph; + try { + if (tf.TryGetGlyphTypeface(out glyph)) + return glyph.Symbol; + } catch (Exception) { + return true; + } + } + return false; + } + + static FontFamily[] FontLoader() + { + return Fonts.SystemFontFamilies + .Where(ff => !IsSymbolFont(ff)) + .OrderBy(ff => ff.Source) + .ToArray(); + } + + public static DisplaySettings LoadDisplaySettings(ILSpySettings settings) + { + XElement e = settings["DisplaySettings"]; + DisplaySettings s = new DisplaySettings(); + s.SelectedFont = new FontFamily((string)e.Attribute("Font") ?? "Consolas"); + s.SelectedFontSize = (double?)e.Attribute("FontSize") ?? 10.0 * 4 / 3; + s.ShowLineNumbers = (bool?)e.Attribute("ShowLineNumbers") ?? false; + + return s; + } + + public void Save(XElement root) + { + DisplaySettings s = (DisplaySettings)this.DataContext; + + currentDisplaySettings.CopyValues(s); + + XElement section = new XElement("DisplaySettings"); + section.SetAttributeValue("Font", s.SelectedFont.Source); + section.SetAttributeValue("FontSize", s.SelectedFontSize); + section.SetAttributeValue("ShowLineNumbers", s.ShowLineNumbers); + + XElement existingElement = root.Element("DisplaySettings"); + if (existingElement != null) + existingElement.ReplaceWith(section); + else + root.Add(section); + } + } + + public class FontSizeConverter : IValueConverter + { + public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) + { + if (value is double) { + return Math.Round((double)value / 4 * 3); + } + + throw new NotImplementedException(); + } + + public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) + { + if (value is string) { + double d; + if (double.TryParse((string)value, out d)) + return d * 4 / 3; + return 11 * 4 / 3; + } + + throw new NotImplementedException(); + } + } +} \ No newline at end of file diff --git a/ILSpy/ILAstLanguage.cs b/ILSpy/ILAstLanguage.cs index 84348a4de..a462c2f21 100644 --- a/ILSpy/ILAstLanguage.cs +++ b/ILSpy/ILAstLanguage.cs @@ -68,7 +68,7 @@ namespace ICSharpCode.ILSpy output.Write(" : "); if (v.IsPinned) output.Write("pinned "); - v.Type.WriteTo(output, true, true); + v.Type.WriteTo(output, ILNameSyntax.ShortTypeName); } output.WriteLine(); } @@ -100,7 +100,7 @@ namespace ICSharpCode.ILSpy public override string TypeToString(TypeReference t, bool includeNamespace, ICustomAttributeProvider attributeProvider) { PlainTextOutput output = new PlainTextOutput(); - t.WriteTo(output, true, shortName: !includeNamespace); + t.WriteTo(output, includeNamespace ? ILNameSyntax.TypeName : ILNameSyntax.ShortTypeName); return output.ToString(); } } diff --git a/ILSpy/ILLanguage.cs b/ILSpy/ILLanguage.cs index 5033635ff..cf497476f 100644 --- a/ILSpy/ILLanguage.cs +++ b/ILSpy/ILLanguage.cs @@ -64,16 +64,40 @@ namespace ICSharpCode.ILSpy public override void DecompileProperty(PropertyDefinition property, ITextOutput output, DecompilationOptions options) { - var dis = new ReflectionDisassembler(output, detectControlStructure, options.CancellationToken); - dis.DisassembleProperty(property); - NotifyDecompilationFinished(dis); + ReflectionDisassembler rd = new ReflectionDisassembler(output, detectControlStructure, options.CancellationToken); + rd.DisassembleProperty(property); + if (property.GetMethod != null) { + output.WriteLine(); + rd.DisassembleMethod(property.GetMethod); + } + if (property.SetMethod != null) { + output.WriteLine(); + rd.DisassembleMethod(property.SetMethod); + } + foreach (var m in property.OtherMethods) { + output.WriteLine(); + rd.DisassembleMethod(m); + } + NotifyDecompilationFinished(rd); } public override void DecompileEvent(EventDefinition ev, ITextOutput output, DecompilationOptions options) { - var dis = new ReflectionDisassembler(output, detectControlStructure, options.CancellationToken); - dis.DisassembleEvent(ev); - NotifyDecompilationFinished(dis); + ReflectionDisassembler rd = new ReflectionDisassembler(output, detectControlStructure, options.CancellationToken); + rd.DisassembleEvent(ev); + if (ev.AddMethod != null) { + output.WriteLine(); + rd.DisassembleMethod(ev.AddMethod); + } + if (ev.RemoveMethod != null) { + output.WriteLine(); + rd.DisassembleMethod(ev.RemoveMethod); + } + foreach (var m in ev.OtherMethods) { + output.WriteLine(); + rd.DisassembleMethod(m); + } + NotifyDecompilationFinished(rd); } public override void DecompileType(TypeDefinition type, ITextOutput output, DecompilationOptions options) @@ -94,14 +118,24 @@ namespace ICSharpCode.ILSpy output.WriteLine("// " + assembly.FileName); output.WriteLine(); - new ReflectionDisassembler(output, detectControlStructure, options.CancellationToken).WriteAssemblyHeader(assembly.AssemblyDefinition); + ReflectionDisassembler rd = new ReflectionDisassembler(output, detectControlStructure, options.CancellationToken); + if (options.FullDecompilation) + rd.WriteAssemblyReferences(assembly.AssemblyDefinition.MainModule); + rd.WriteAssemblyHeader(assembly.AssemblyDefinition); + output.WriteLine(); + rd.WriteModuleHeader(assembly.AssemblyDefinition.MainModule); + if (options.FullDecompilation) { + output.WriteLine(); + output.WriteLine(); + rd.WriteModuleContents(assembly.AssemblyDefinition.MainModule); + } OnDecompilationFinished(null); } public override string TypeToString(TypeReference t, bool includeNamespace, ICustomAttributeProvider attributeProvider) { PlainTextOutput output = new PlainTextOutput(); - t.WriteTo(output, true, shortName: !includeNamespace); + t.WriteTo(output, includeNamespace ? ILNameSyntax.TypeName : ILNameSyntax.ShortTypeName); return output.ToString(); } } diff --git a/ILSpy/ILSpy.csproj b/ILSpy/ILSpy.csproj index 460ca4c90..8c43c0a4b 100644 --- a/ILSpy/ILSpy.csproj +++ b/ILSpy/ILSpy.csproj @@ -99,7 +99,6 @@ - @@ -115,6 +114,7 @@ DecompilerSettingsPanel.xaml Code + @@ -151,22 +151,27 @@ Code + + DisplaySettingsPanel.xaml + Code + - + + + - @@ -243,6 +248,7 @@ SearchPane.cs + DecompilerTextView.cs @@ -250,6 +256,7 @@ + diff --git a/ILSpy/ILSpySettings.cs b/ILSpy/ILSpySettings.cs index 7d0fd19cb..053bee7ce 100644 --- a/ILSpy/ILSpySettings.cs +++ b/ILSpy/ILSpySettings.cs @@ -19,6 +19,7 @@ using System; using System.IO; using System.Linq; +using System.Text; using System.Threading; using System.Xml; using System.Xml.Linq; @@ -58,7 +59,7 @@ namespace ICSharpCode.ILSpy { using (new MutexProtector(ConfigFileMutex)) { try { - XDocument doc = XDocument.Load(GetConfigFile()); + XDocument doc = LoadWithoutCheckingCharacters(GetConfigFile()); return new ILSpySettings(doc.Root); } catch (IOException) { return new ILSpySettings(); @@ -68,6 +69,15 @@ namespace ICSharpCode.ILSpy } } + static XDocument LoadWithoutCheckingCharacters(string fileName) + { + // XDocument.Load(fileName) validates that no invalid characters appear (not even in escaped form), + // but we need those characters for some obfuscated assemblies. + using (XmlTextReader r = new XmlTextReader(fileName)) { + return XDocument.Load(r); + } + } + /// /// Saves a setting section. /// @@ -94,7 +104,7 @@ namespace ICSharpCode.ILSpy string config = GetConfigFile(); XDocument doc; try { - doc = XDocument.Load(config); + doc = LoadWithoutCheckingCharacters(config); } catch (IOException) { // ensure the directory exists Directory.CreateDirectory(Path.GetDirectoryName(config)); @@ -104,7 +114,12 @@ namespace ICSharpCode.ILSpy } doc.Root.SetAttributeValue("version", RevisionClass.Major + "." + RevisionClass.Minor + "." + RevisionClass.Build + "." + RevisionClass.Revision); action(doc.Root); - doc.Save(config); + // We can't use XDocument.Save(filename) because that checks for invalid characters, but those can appear + // in obfuscated assemblies. + using (XmlTextWriter writer = new XmlTextWriter(config, Encoding.UTF8)) { + writer.Formatting = Formatting.Indented; + doc.Save(writer); + } } } diff --git a/ILSpy/Images/Images.cs b/ILSpy/Images/Images.cs index 361f6a5a8..8755e772e 100644 --- a/ILSpy/Images/Images.cs +++ b/ILSpy/Images/Images.cs @@ -65,6 +65,7 @@ namespace ICSharpCode.ILSpy public static readonly BitmapImage Interface = LoadBitmap("Interface"); public static readonly BitmapImage Delegate = LoadBitmap("Delegate"); public static readonly BitmapImage Enum = LoadBitmap("Enum"); + public static readonly BitmapImage StaticClass = LoadBitmap("StaticClass"); public static readonly BitmapImage Field = LoadBitmap("Field"); @@ -133,6 +134,7 @@ namespace ICSharpCode.ILSpy PreloadPublicIconToCache(TypeIcon.Struct, Images.Struct); PreloadPublicIconToCache(TypeIcon.Interface, Images.Interface); PreloadPublicIconToCache(TypeIcon.Delegate, Images.Delegate); + PreloadPublicIconToCache(TypeIcon.StaticClass, Images.StaticClass); } protected override ImageSource GetBaseImage(TypeIcon icon) @@ -154,6 +156,9 @@ namespace ICSharpCode.ILSpy case TypeIcon.Delegate: baseImage = Images.Delegate; break; + case TypeIcon.StaticClass: + baseImage = Images.StaticClass; + break; default: throw new NotSupportedException(); } diff --git a/ILSpy/Images/StaticClass.png b/ILSpy/Images/StaticClass.png new file mode 100644 index 000000000..af9ebd06a Binary files /dev/null and b/ILSpy/Images/StaticClass.png differ diff --git a/ILSpy/Images/TypeIcon.cs b/ILSpy/Images/TypeIcon.cs index 2e5f3f498..7bbb0d08a 100644 --- a/ILSpy/Images/TypeIcon.cs +++ b/ILSpy/Images/TypeIcon.cs @@ -26,6 +26,7 @@ namespace ICSharpCode.ILSpy Enum, Struct, Interface, - Delegate + Delegate, + StaticClass } } diff --git a/ILSpy/Language.cs b/ILSpy/Language.cs index 4cb85722f..d957560b7 100644 --- a/ILSpy/Language.cs +++ b/ILSpy/Language.cs @@ -73,67 +73,70 @@ namespace ICSharpCode.ILSpy /// Gets the name of the language (as shown in the UI) /// public abstract string Name { get; } - + /// /// Gets the file extension used by source code files in this language. /// public abstract string FileExtension { get; } - - public virtual string ProjectFileExtension { + + public virtual string ProjectFileExtension + { get { return null; } } - + /// /// Gets the syntax highlighting used for this language. /// - public virtual ICSharpCode.AvalonEdit.Highlighting.IHighlightingDefinition SyntaxHighlighting { - get { + public virtual ICSharpCode.AvalonEdit.Highlighting.IHighlightingDefinition SyntaxHighlighting + { + get + { return ICSharpCode.AvalonEdit.Highlighting.HighlightingManager.Instance.GetDefinitionByExtension(this.FileExtension); } } - + public virtual void DecompileMethod(MethodDefinition method, ITextOutput output, DecompilationOptions options) { WriteCommentLine(output, TypeToString(method.DeclaringType, true) + "." + method.Name); } - + public virtual void DecompileProperty(PropertyDefinition property, ITextOutput output, DecompilationOptions options) { WriteCommentLine(output, TypeToString(property.DeclaringType, true) + "." + property.Name); } - + public virtual void DecompileField(FieldDefinition field, ITextOutput output, DecompilationOptions options) { WriteCommentLine(output, TypeToString(field.DeclaringType, true) + "." + field.Name); } - + public virtual void DecompileEvent(EventDefinition ev, ITextOutput output, DecompilationOptions options) { WriteCommentLine(output, TypeToString(ev.DeclaringType, true) + "." + ev.Name); } - + public virtual void DecompileType(TypeDefinition type, ITextOutput output, DecompilationOptions options) { WriteCommentLine(output, TypeToString(type, true)); } - + public virtual void DecompileNamespace(string nameSpace, IEnumerable types, ITextOutput output, DecompilationOptions options) { WriteCommentLine(output, nameSpace); OnDecompilationFinished(null); } - + public virtual void DecompileAssembly(LoadedAssembly assembly, ITextOutput output, DecompilationOptions options) { WriteCommentLine(output, assembly.FileName); WriteCommentLine(output, assembly.AssemblyDefinition.FullName); } - + public virtual void WriteCommentLine(ITextOutput output, string comment) { output.WriteLine("// " + comment); } - + /// /// Converts a type reference into a string. This method is used by the member tree node for parameter and return types. /// @@ -144,7 +147,7 @@ namespace ICSharpCode.ILSpy else return type.Name; } - + /// /// Converts a member signature to a string. /// This is used for displaying the tooltip on a member reference. @@ -156,7 +159,7 @@ namespace ICSharpCode.ILSpy else return member.ToString(); } - + public virtual string FormatPropertyName(PropertyDefinition property, bool? isIndexer = null) { if (property == null) @@ -164,6 +167,13 @@ namespace ICSharpCode.ILSpy return property.Name; } + public virtual string FormatTypeName(TypeDefinition type) + { + if (type == null) + throw new ArgumentNullException("type"); + return type.Name; + } + /// /// Used for WPF keyboard navigation. /// @@ -171,11 +181,19 @@ namespace ICSharpCode.ILSpy { return Name; } - + public virtual bool ShowMember(MemberReference member) { return true; } + + /// + /// Used by the analyzer to map compiler generated code back to the original code's location + /// + public virtual MemberReference GetOriginalCodeLocation(MemberReference member) + { + return member; + } protected virtual void OnDecompilationFinished(DecompileEventArgs e) { @@ -211,33 +229,35 @@ namespace ICSharpCode.ILSpy } } } - + public static class Languages { static ReadOnlyCollection allLanguages; - + /// /// A list of all languages. /// - public static ReadOnlyCollection AllLanguages { - get { + public static ReadOnlyCollection AllLanguages + { + get + { return allLanguages; } } - - + + internal static void Initialize(CompositionContainer composition) { List languages = new List(); languages.AddRange(composition.GetExportedValues()); languages.Add(new ILLanguage(true)); - #if DEBUG +#if DEBUG languages.AddRange(ILAstLanguage.GetDebugLanguages()); languages.AddRange(CSharpLanguage.GetDebugLanguages()); - #endif +#endif allLanguages = languages.AsReadOnly(); } - + /// /// Gets a language using its name. /// If the language is not found, C# is returned instead. @@ -247,4 +267,4 @@ namespace ICSharpCode.ILSpy return AllLanguages.FirstOrDefault(l => l.Name == name) ?? AllLanguages.First(); } } -} \ No newline at end of file +} diff --git a/ILSpy/MainWindow.xaml.cs b/ILSpy/MainWindow.xaml.cs index 262365ed0..4425555af 100644 --- a/ILSpy/MainWindow.xaml.cs +++ b/ILSpy/MainWindow.xaml.cs @@ -242,7 +242,7 @@ namespace ICSharpCode.ILSpy if (!found) { AvalonEditTextOutput output = new AvalonEditTextOutput(); output.Write("Cannot find " + args.NavigateTo); - decompilerTextView.Show(output); + decompilerTextView.ShowText(output); } } commandLineLoadedAssemblies.Clear(); // clear references once we don't need them anymore @@ -511,8 +511,12 @@ namespace ICSharpCode.ILSpy if (ignoreDecompilationRequests) return; - if (recordHistory) - history.Record(new NavigationState(treeView.SelectedItems.OfType(), decompilerTextView.GetState())); + if (recordHistory) { + var dtState = decompilerTextView.GetState(); + if(dtState != null) + history.UpdateCurrent(new NavigationState(dtState)); + history.Record(new NavigationState(treeView.SelectedItems.OfType())); + } if (treeView.SelectedItems.Count == 1) { ILSpyTreeNode node = treeView.SelectedItem as ILSpyTreeNode; @@ -586,8 +590,9 @@ namespace ICSharpCode.ILSpy void NavigateHistory(bool forward) { - var combinedState = new NavigationState(treeView.SelectedItems.OfType(), decompilerTextView.GetState()); - history.Record(combinedState, replace: true, clearForward: false); + var dtState = decompilerTextView.GetState(); + if(dtState != null) + history.UpdateCurrent(new NavigationState(dtState)); var newState = forward ? history.GoForward() : history.GoBack(); ignoreDecompilationRequests = true; diff --git a/ILSpy/NavigationHistory.cs b/ILSpy/NavigationHistory.cs index 0fb1bed05..c5983a96d 100644 --- a/ILSpy/NavigationHistory.cs +++ b/ILSpy/NavigationHistory.cs @@ -71,13 +71,18 @@ namespace ICSharpCode.ILSpy back.Clear(); forward.Clear(); } + + public void UpdateCurrent(T node) + { + current = node; + } - public void Record(T node, bool replace = false, bool clearForward = true) + public void Record(T node) { var navigationTime = DateTime.Now; var period = navigationTime - lastNavigationTime; - if (period.TotalSeconds < NavigationSecondsBeforeNewEntry || replace) { + if (period.TotalSeconds < NavigationSecondsBeforeNewEntry) { current = node; } else { if (current != null) @@ -88,8 +93,7 @@ namespace ICSharpCode.ILSpy current = node; } - if (clearForward) - forward.Clear(); + forward.Clear(); lastNavigationTime = navigationTime; } diff --git a/ILSpy/NavigationState.cs b/ILSpy/NavigationState.cs index 7a86ebec5..123c0b642 100644 --- a/ILSpy/NavigationState.cs +++ b/ILSpy/NavigationState.cs @@ -32,12 +32,18 @@ namespace ICSharpCode.ILSpy public IEnumerable TreeNodes { get { return treeNodes; } } public DecompilerTextViewState ViewState { get; private set; } - public NavigationState(IEnumerable treeNodes, DecompilerTextViewState viewState) + public NavigationState(DecompilerTextViewState viewState) { - this.treeNodes = new HashSet(treeNodes); + this.treeNodes = new HashSet(viewState.DecompiledNodes); ViewState = viewState; } + public NavigationState(IEnumerable treeNodes) + { + this.treeNodes = new HashSet(treeNodes); + } + + public bool Equals(NavigationState other) { // TODO: should this care about the view state as well? diff --git a/ILSpy/TextView/DecompilerTextView.cs b/ILSpy/TextView/DecompilerTextView.cs index 3e00b99be..3ade72e99 100644 --- a/ILSpy/TextView/DecompilerTextView.cs +++ b/ILSpy/TextView/DecompilerTextView.cs @@ -29,6 +29,7 @@ using System.Threading; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; +using System.Windows.Data; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Animation; @@ -63,6 +64,7 @@ namespace ICSharpCode.ILSpy.TextView readonly UIElementGenerator uiElementGenerator; List activeCustomElementGenerators = new List(); FoldingManager foldingManager; + ILSpyTreeNode[] decompiledNodes; DefinitionLookup definitionLookup; CancellationTokenSource currentCancellationTokenSource; @@ -92,6 +94,9 @@ namespace ICSharpCode.ILSpy.TextView textEditor.Options.RequireControlModifierForHyperlinkClick = false; textEditor.TextArea.TextView.MouseHover += TextViewMouseHover; textEditor.TextArea.TextView.MouseHoverStopped += TextViewMouseHoverStopped; + textEditor.SetBinding(TextEditor.FontFamilyProperty, new Binding { Source = DisplaySettingsPanel.CurrentDisplaySettings, Path = new PropertyPath("SelectedFont") }); + textEditor.SetBinding(TextEditor.FontSizeProperty, new Binding { Source = DisplaySettingsPanel.CurrentDisplaySettings, Path = new PropertyPath("SelectedFontSize") }); + textEditor.SetBinding(TextEditor.ShowLineNumbersProperty, new Binding { Source = DisplaySettingsPanel.CurrentDisplaySettings, Path = new PropertyPath("ShowLineNumbers") }); // add marker service & margin iconMargin = new IconBarMargin((manager = new IconBarManager())); @@ -227,11 +232,21 @@ namespace ICSharpCode.ILSpy.TextView #endregion #region ShowOutput + public void ShowText(AvalonEditTextOutput textOutput) + { + ShowNodes(textOutput, null); + } + + public void ShowNode(AvalonEditTextOutput textOutput, ILSpyTreeNode node, IHighlightingDefinition highlighting = null) + { + ShowNodes(textOutput, new[] { node }, highlighting); + } + /// /// Shows the given output in the text view. /// Cancels any currently running decompilation tasks. /// - public void Show(AvalonEditTextOutput textOutput, IHighlightingDefinition highlighting = null) + public void ShowNodes(AvalonEditTextOutput textOutput, ILSpyTreeNode[] nodes, IHighlightingDefinition highlighting = null) { // Cancel the decompilation task: if (currentCancellationTokenSource != null) { @@ -240,6 +255,7 @@ namespace ICSharpCode.ILSpy.TextView } this.nextDecompilationRun = null; // remove scheduled decompilation run ShowOutput(textOutput, highlighting); + decompiledNodes = nodes; } /// @@ -362,6 +378,7 @@ namespace ICSharpCode.ILSpy.TextView } finally { iconMargin.InvalidateVisual(); } + decompiledNodes = context.TreeNodes; }); } @@ -550,6 +567,7 @@ namespace ICSharpCode.ILSpy.TextView output.WriteLine(ex.ToString()); ShowOutput(output); } + decompiledNodes = context.TreeNodes; }); } @@ -612,11 +630,15 @@ namespace ICSharpCode.ILSpy.TextView public DecompilerTextViewState GetState() { + if (decompiledNodes == null) + return null; + var state = new DecompilerTextViewState(); if (foldingManager != null) state.SaveFoldingsState(foldingManager.AllFoldings); state.VerticalOffset = textEditor.VerticalOffset; state.HorizontalOffset = textEditor.HorizontalOffset; + state.DecompiledNodes = decompiledNodes; return state; } } @@ -627,16 +649,17 @@ namespace ICSharpCode.ILSpy.TextView private int FoldingsChecksum; public double VerticalOffset; public double HorizontalOffset; + public ILSpyTreeNode[] DecompiledNodes; public void SaveFoldingsState(IEnumerable foldings) { ExpandedFoldings = foldings.Where(f => !f.IsFolded).Select(f => Tuple.Create(f.StartOffset, f.EndOffset)).ToList(); - FoldingsChecksum = foldings.Select(f => f.StartOffset * 3 - f.EndOffset).Aggregate((a, b) => a + b); + FoldingsChecksum = unchecked(foldings.Select(f => f.StartOffset * 3 - f.EndOffset).Aggregate((a, b) => a + b)); } internal void RestoreFoldings(List list) { - var checksum = list.Select(f => f.StartOffset * 3 - f.EndOffset).Aggregate((a, b) => a + b); + var checksum = unchecked(list.Select(f => f.StartOffset * 3 - f.EndOffset).Aggregate((a, b) => a + b)); if (FoldingsChecksum == checksum) foreach (var folding in list) folding.DefaultClosed = !ExpandedFoldings.Any(f => f.Item1 == folding.StartOffset && f.Item2 == folding.EndOffset); diff --git a/ILSpy/TextView/ILAsm-Mode.xshd b/ILSpy/TextView/ILAsm-Mode.xshd index 5f582d37c..76fbc1afa 100644 --- a/ILSpy/TextView/ILAsm-Mode.xshd +++ b/ILSpy/TextView/ILAsm-Mode.xshd @@ -348,6 +348,7 @@ tls true false + strict .class diff --git a/ILSpy/TreeNodes/Analyzer/AnalyzedEventAccessorsTreeNode.cs b/ILSpy/TreeNodes/Analyzer/AnalyzedEventAccessorTreeNode.cs similarity index 50% rename from ILSpy/TreeNodes/Analyzer/AnalyzedEventAccessorsTreeNode.cs rename to ILSpy/TreeNodes/Analyzer/AnalyzedEventAccessorTreeNode.cs index d350147f1..041e4ef86 100644 --- a/ILSpy/TreeNodes/Analyzer/AnalyzedEventAccessorsTreeNode.cs +++ b/ILSpy/TreeNodes/Analyzer/AnalyzedEventAccessorTreeNode.cs @@ -21,50 +21,19 @@ using Mono.Cecil; namespace ICSharpCode.ILSpy.TreeNodes.Analyzer { - internal sealed class AnalyzedEventAccessorsTreeNode : AnalyzerTreeNode + internal class AnalyzedEventAccessorTreeNode : AnalyzedMethodTreeNode { - public AnalyzedEventAccessorsTreeNode(EventDefinition analyzedEvent) - { - if (analyzedEvent == null) - throw new ArgumentNullException("analyzedEvent"); - - if (analyzedEvent.AddMethod != null) - this.Children.Add(new AnalyzedEventAccessorTreeNode(analyzedEvent.AddMethod, "add")); - if (analyzedEvent.RemoveMethod != null) - this.Children.Add(new AnalyzedEventAccessorTreeNode(analyzedEvent.RemoveMethod, "remove")); - foreach (var accessor in analyzedEvent.OtherMethods) - this.Children.Add(new AnalyzedEventAccessorTreeNode(accessor, null)); - } + private string name; - public override object Icon + public AnalyzedEventAccessorTreeNode(MethodDefinition analyzedMethod, string name) + : base(analyzedMethod) { - get { return Images.Search; } + this.name = name; } public override object Text { - get { return "Accessors"; } - } - - public static bool CanShow(EventDefinition property) - { - return !MainWindow.Instance.CurrentLanguage.ShowMember(property.AddMethod ?? property.RemoveMethod); - } - - internal class AnalyzedEventAccessorTreeNode : AnalyzedMethodTreeNode - { - private string name; - - public AnalyzedEventAccessorTreeNode(MethodDefinition analyzedMethod, string name) - : base(analyzedMethod) - { - this.name = name; - } - - public override object Text - { - get { return name ?? base.Text; } - } + get { return name ?? base.Text; } } } } diff --git a/ILSpy/TreeNodes/Analyzer/AnalyzedEventOverridesTreeNode.cs b/ILSpy/TreeNodes/Analyzer/AnalyzedEventOverridesTreeNode.cs index 113ffd029..549152bb7 100644 --- a/ILSpy/TreeNodes/Analyzer/AnalyzedEventOverridesTreeNode.cs +++ b/ILSpy/TreeNodes/Analyzer/AnalyzedEventOverridesTreeNode.cs @@ -68,36 +68,25 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer private IEnumerable FetchChildren(CancellationToken ct) { - return FindReferences(MainWindow.Instance.CurrentAssemblyList.GetAssemblies(), ct); - } - - private IEnumerable FindReferences(IEnumerable assemblies, CancellationToken ct) - { - assemblies = assemblies.Where(asm => asm.AssemblyDefinition != null); + ScopedWhereUsedAnalyzer analyzer; - // use parallelism only on the assembly level (avoid locks within Cecil) - return assemblies.AsParallel().WithCancellation(ct).SelectMany((LoadedAssembly asm) => FindReferences(asm, ct)); + analyzer = new ScopedWhereUsedAnalyzer(analyzedEvent, FindReferencesInType); + return analyzer.PerformAnalysis(ct); } - private IEnumerable FindReferences(LoadedAssembly asm, CancellationToken ct) + private IEnumerable FindReferencesInType(TypeDefinition type) { - string asmName = asm.AssemblyDefinition.Name.Name; string name = analyzedEvent.Name; string declTypeName = analyzedEvent.DeclaringType.FullName; - foreach (TypeDefinition type in TreeTraversal.PreOrder(asm.AssemblyDefinition.MainModule.Types, t => t.NestedTypes)) { - ct.ThrowIfCancellationRequested(); - - if (!TypesHierarchyHelpers.IsBaseType(analyzedEvent.DeclaringType, type, resolveTypeArguments: false)) - continue; - foreach (EventDefinition eventDef in type.Events) { - ct.ThrowIfCancellationRequested(); + if (!TypesHierarchyHelpers.IsBaseType(analyzedEvent.DeclaringType, type, resolveTypeArguments: false)) + yield break; - if (TypesHierarchyHelpers.IsBaseEvent(analyzedEvent, eventDef)) { - MethodDefinition anyAccessor = eventDef.AddMethod ?? eventDef.RemoveMethod; - bool hidesParent = !anyAccessor.IsVirtual ^ anyAccessor.IsNewSlot; - yield return new AnalyzedEventTreeNode(eventDef, hidesParent ? "(hides) " : ""); - } + foreach (EventDefinition eventDef in type.Events) { + if (TypesHierarchyHelpers.IsBaseEvent(analyzedEvent, eventDef)) { + MethodDefinition anyAccessor = eventDef.AddMethod ?? eventDef.RemoveMethod; + bool hidesParent = !anyAccessor.IsVirtual ^ anyAccessor.IsNewSlot; + yield return new AnalyzedEventTreeNode(eventDef, hidesParent ? "(hides) " : ""); } } } diff --git a/ILSpy/TreeNodes/Analyzer/AnalyzedEventTreeNode.cs b/ILSpy/TreeNodes/Analyzer/AnalyzedEventTreeNode.cs index 3ebf2d23b..89903abd4 100644 --- a/ILSpy/TreeNodes/Analyzer/AnalyzedEventTreeNode.cs +++ b/ILSpy/TreeNodes/Analyzer/AnalyzedEventTreeNode.cs @@ -57,8 +57,13 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer protected override void LoadChildren() { - if (AnalyzedEventAccessorsTreeNode.CanShow(analyzedEvent)) - this.Children.Add(new AnalyzedEventAccessorsTreeNode(analyzedEvent)); + if (analyzedEvent.AddMethod != null) + this.Children.Add(new AnalyzedEventAccessorTreeNode(analyzedEvent.AddMethod, "add")); + if (analyzedEvent.RemoveMethod != null) + this.Children.Add(new AnalyzedEventAccessorTreeNode(analyzedEvent.RemoveMethod, "remove")); + foreach (var accessor in analyzedEvent.OtherMethods) + this.Children.Add(new AnalyzedEventAccessorTreeNode(accessor, null)); + if (AnalyzedEventOverridesTreeNode.CanShow(analyzedEvent)) this.Children.Add(new AnalyzedEventOverridesTreeNode(analyzedEvent)); if (AnalyzedInterfaceEventImplementedByTreeNode.CanShow(analyzedEvent)) @@ -75,12 +80,12 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer public static bool CanShow(MemberReference member) { - var property = member as EventDefinition; - if (property == null) + var eventDef = member as EventDefinition; + if (eventDef == null) return false; - return AnalyzedEventAccessorsTreeNode.CanShow(property) - || AnalyzedEventOverridesTreeNode.CanShow(property); + return !MainWindow.Instance.CurrentLanguage.ShowMember(eventDef.AddMethod ?? eventDef.RemoveMethod) + || AnalyzedEventOverridesTreeNode.CanShow(eventDef); } } } diff --git a/ILSpy/TreeNodes/Analyzer/AnalyzedFieldAccessTreeNode.cs b/ILSpy/TreeNodes/Analyzer/AnalyzedFieldAccessTreeNode.cs index c18b62d0f..850ab3141 100644 --- a/ILSpy/TreeNodes/Analyzer/AnalyzedFieldAccessTreeNode.cs +++ b/ILSpy/TreeNodes/Analyzer/AnalyzedFieldAccessTreeNode.cs @@ -22,6 +22,7 @@ using System.Threading; using ICSharpCode.TreeView; using Mono.Cecil; using Mono.Cecil.Cil; +using System.Collections; namespace ICSharpCode.ILSpy.TreeNodes.Analyzer { @@ -30,6 +31,8 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer private readonly bool showWrites; // true: show writes; false: show read access private readonly FieldDefinition analyzedField; private readonly ThreadingSupport threading; + private Lazy foundMethods; + private object hashLock = new object(); public AnalyzedFieldAccessTreeNode(FieldDefinition analyzedField, bool showWrites) { @@ -68,8 +71,14 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer private IEnumerable FetchChildren(CancellationToken ct) { - var analyzer = new ScopedWhereUsedScopeAnalyzer(analyzedField, FindReferencesInType); - return analyzer.PerformAnalysis(ct); + foundMethods = new Lazy(LazyThreadSafetyMode.ExecutionAndPublication); + + var analyzer = new ScopedWhereUsedAnalyzer(analyzedField, FindReferencesInType); + foreach (var child in analyzer.PerformAnalysis(ct)) { + yield return child; + } + + foundMethods = null; } private IEnumerable FindReferencesInType(TypeDefinition type) @@ -95,8 +104,12 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer method.Body = null; - if (found) - yield return new AnalyzedMethodTreeNode(method); + if (found) { + MethodDefinition codeLocation = this.Language.GetOriginalCodeLocation(method) as MethodDefinition; + if (codeLocation != null && !HasAlreadyBeenFound(codeLocation)) { + yield return new AnalyzedMethodTreeNode(codeLocation); + } + } } } @@ -116,5 +129,18 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer return false; } } + + private bool HasAlreadyBeenFound(MethodDefinition method) + { + Hashtable hashtable = foundMethods.Value; + lock (hashLock) { + if (hashtable.Contains(method)) { + return true; + } else { + hashtable.Add(method, null); + return false; + } + } + } } } diff --git a/ILSpy/TreeNodes/Analyzer/AnalyzedInterfaceEventImplementedByTreeNode.cs b/ILSpy/TreeNodes/Analyzer/AnalyzedInterfaceEventImplementedByTreeNode.cs index c17f3ec36..09cab0bf3 100644 --- a/ILSpy/TreeNodes/Analyzer/AnalyzedInterfaceEventImplementedByTreeNode.cs +++ b/ILSpy/TreeNodes/Analyzer/AnalyzedInterfaceEventImplementedByTreeNode.cs @@ -69,8 +69,8 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer private IEnumerable FetchChildren(CancellationToken ct) { - ScopedWhereUsedScopeAnalyzer analyzer; - analyzer = new ScopedWhereUsedScopeAnalyzer(analyzedMethod, FindReferencesInType); + ScopedWhereUsedAnalyzer analyzer; + analyzer = new ScopedWhereUsedAnalyzer(analyzedMethod, FindReferencesInType); return analyzer.PerformAnalysis(ct); } diff --git a/ILSpy/TreeNodes/Analyzer/AnalyzedInterfaceMethodImplementedByTreeNode.cs b/ILSpy/TreeNodes/Analyzer/AnalyzedInterfaceMethodImplementedByTreeNode.cs index 6ce86fc8b..960f48f89 100644 --- a/ILSpy/TreeNodes/Analyzer/AnalyzedInterfaceMethodImplementedByTreeNode.cs +++ b/ILSpy/TreeNodes/Analyzer/AnalyzedInterfaceMethodImplementedByTreeNode.cs @@ -67,8 +67,8 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer private IEnumerable FetchChildren(CancellationToken ct) { - ScopedWhereUsedScopeAnalyzer analyzer; - analyzer = new ScopedWhereUsedScopeAnalyzer(analyzedMethod, FindReferencesInType); + ScopedWhereUsedAnalyzer analyzer; + analyzer = new ScopedWhereUsedAnalyzer(analyzedMethod, FindReferencesInType); return analyzer.PerformAnalysis(ct); } diff --git a/ILSpy/TreeNodes/Analyzer/AnalyzedInterfacePropertyImplementedByTreeNode.cs b/ILSpy/TreeNodes/Analyzer/AnalyzedInterfacePropertyImplementedByTreeNode.cs index 06a4fb961..35d9bc3d0 100644 --- a/ILSpy/TreeNodes/Analyzer/AnalyzedInterfacePropertyImplementedByTreeNode.cs +++ b/ILSpy/TreeNodes/Analyzer/AnalyzedInterfacePropertyImplementedByTreeNode.cs @@ -69,8 +69,8 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer private IEnumerable FetchChildren(CancellationToken ct) { - ScopedWhereUsedScopeAnalyzer analyzer; - analyzer = new ScopedWhereUsedScopeAnalyzer(analyzedMethod, FindReferencesInType); + ScopedWhereUsedAnalyzer analyzer; + analyzer = new ScopedWhereUsedAnalyzer(analyzedMethod, FindReferencesInType); return analyzer.PerformAnalysis(ct); } diff --git a/ILSpy/TreeNodes/Analyzer/AnalyzedMethodOverridesTreeNode.cs b/ILSpy/TreeNodes/Analyzer/AnalyzedMethodOverridesTreeNode.cs index f8f891d2d..05a3f5d6a 100644 --- a/ILSpy/TreeNodes/Analyzer/AnalyzedMethodOverridesTreeNode.cs +++ b/ILSpy/TreeNodes/Analyzer/AnalyzedMethodOverridesTreeNode.cs @@ -73,45 +73,32 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer private IEnumerable FetchChildren(CancellationToken ct) { - return FindReferences(MainWindow.Instance.CurrentAssemblyList.GetAssemblies(), ct); - } - - private IEnumerable FindReferences(IEnumerable assemblies, CancellationToken ct) - { - assemblies = assemblies.Where(asm => asm.AssemblyDefinition != null); + ScopedWhereUsedAnalyzer analyzer; - // use parallelism only on the assembly level (avoid locks within Cecil) - return assemblies.AsParallel().WithCancellation(ct).SelectMany((LoadedAssembly asm) => FindReferences(asm, ct)); + analyzer = new ScopedWhereUsedAnalyzer(analyzedMethod, FindReferencesInType); + return analyzer.PerformAnalysis(ct); } - private IEnumerable FindReferences(LoadedAssembly asm, CancellationToken ct) + private IEnumerable FindReferencesInType(TypeDefinition type) { - string asmName = asm.AssemblyDefinition.Name.Name; - string name = analyzedMethod.Name; - string declTypeName = analyzedMethod.DeclaringType.FullName; - foreach (TypeDefinition type in TreeTraversal.PreOrder(asm.AssemblyDefinition.MainModule.Types, t => t.NestedTypes)) { - ct.ThrowIfCancellationRequested(); - SharpTreeNode newNode = null; - try { - if (!TypesHierarchyHelpers.IsBaseType(analyzedMethod.DeclaringType, type, resolveTypeArguments: false)) - continue; - - foreach (MethodDefinition method in type.Methods) { - ct.ThrowIfCancellationRequested(); - - if (TypesHierarchyHelpers.IsBaseMethod(analyzedMethod, method)) { - bool hidesParent = !method.IsVirtual ^ method.IsNewSlot; - newNode = new AnalyzedMethodTreeNode(method, hidesParent ? "(hides) " : ""); - } + SharpTreeNode newNode = null; + try { + if (!TypesHierarchyHelpers.IsBaseType(analyzedMethod.DeclaringType, type, resolveTypeArguments: false)) + yield break; + + foreach (MethodDefinition method in type.Methods) { + if (TypesHierarchyHelpers.IsBaseMethod(analyzedMethod, method)) { + bool hidesParent = !method.IsVirtual ^ method.IsNewSlot; + newNode = new AnalyzedMethodTreeNode(method, hidesParent ? "(hides) " : ""); } } - catch (ReferenceResolvingException) { - // ignore this type definition. maybe add a notification about such cases. - } - - if (newNode != null) - yield return newNode; } + catch (ReferenceResolvingException) { + // ignore this type definition. maybe add a notification about such cases. + } + + if (newNode != null) + yield return newNode; } public static bool CanShow(MethodDefinition method) diff --git a/ILSpy/TreeNodes/Analyzer/AnalyzedMethodTreeNode.cs b/ILSpy/TreeNodes/Analyzer/AnalyzedMethodTreeNode.cs index 2ecc053f8..ad7654eae 100644 --- a/ILSpy/TreeNodes/Analyzer/AnalyzedMethodTreeNode.cs +++ b/ILSpy/TreeNodes/Analyzer/AnalyzedMethodTreeNode.cs @@ -58,9 +58,15 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer { if (analyzedMethod.HasBody) this.Children.Add(new AnalyzedMethodUsesTreeNode(analyzedMethod)); - this.Children.Add(new AnalyzedMethodUsedByTreeNode(analyzedMethod)); + + if (analyzedMethod.IsVirtual && !(analyzedMethod.IsNewSlot && analyzedMethod.IsFinal)) + this.Children.Add(new AnalyzedVirtualMethodUsedByTreeNode(analyzedMethod)); + else + this.Children.Add(new AnalyzedMethodUsedByTreeNode(analyzedMethod)); + if (AnalyzedMethodOverridesTreeNode.CanShow(analyzedMethod)) this.Children.Add(new AnalyzedMethodOverridesTreeNode(analyzedMethod)); + if (AnalyzedInterfaceMethodImplementedByTreeNode.CanShow(analyzedMethod)) this.Children.Add(new AnalyzedInterfaceMethodImplementedByTreeNode(analyzedMethod)); } diff --git a/ILSpy/TreeNodes/Analyzer/AnalyzedMethodUsedByTreeNode.cs b/ILSpy/TreeNodes/Analyzer/AnalyzedMethodUsedByTreeNode.cs index 2a7cf784f..f3f9504e6 100644 --- a/ILSpy/TreeNodes/Analyzer/AnalyzedMethodUsedByTreeNode.cs +++ b/ILSpy/TreeNodes/Analyzer/AnalyzedMethodUsedByTreeNode.cs @@ -17,6 +17,7 @@ // DEALINGS IN THE SOFTWARE. using System; +using System.Collections.Concurrent; using System.Collections.Generic; using System.Threading; using ICSharpCode.TreeView; @@ -29,6 +30,7 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer { private readonly MethodDefinition analyzedMethod; private readonly ThreadingSupport threading; + private ConcurrentDictionary foundMethods; public AnalyzedMethodUsedByTreeNode(MethodDefinition analyzedMethod) { @@ -66,10 +68,14 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer private IEnumerable FetchChildren(CancellationToken ct) { - ScopedWhereUsedScopeAnalyzer analyzer; + foundMethods = new ConcurrentDictionary(); - analyzer = new ScopedWhereUsedScopeAnalyzer(analyzedMethod, FindReferencesInType); - return analyzer.PerformAnalysis(ct); + var analyzer = new ScopedWhereUsedAnalyzer(analyzedMethod, FindReferencesInType); + foreach (var child in analyzer.PerformAnalysis(ct)) { + yield return child; + } + + foundMethods = null; } private IEnumerable FindReferencesInType(TypeDefinition type) @@ -81,8 +87,7 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer continue; foreach (Instruction instr in method.Body.Instructions) { MethodReference mr = instr.Operand as MethodReference; - if (mr != null && - mr.Name == name && + if (mr != null && mr.Name == name && Helpers.IsReferencedBy(analyzedMethod.DeclaringType, mr.DeclaringType) && mr.Resolve() == analyzedMethod) { found = true; @@ -92,9 +97,18 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer method.Body = null; - if (found) - yield return new AnalyzedMethodTreeNode(method); + if (found) { + MethodDefinition codeLocation = this.Language.GetOriginalCodeLocation(method) as MethodDefinition; + if (codeLocation != null && !HasAlreadyBeenFound(codeLocation)) { + yield return new AnalyzedMethodTreeNode(codeLocation); + } + } } } + + private bool HasAlreadyBeenFound(MethodDefinition method) + { + return !foundMethods.TryAdd(method, 0); + } } } diff --git a/ILSpy/TreeNodes/Analyzer/AnalyzedPropertyAccessorsTreeNode.cs b/ILSpy/TreeNodes/Analyzer/AnalyzedPropertyAccessorTreeNode.cs similarity index 50% rename from ILSpy/TreeNodes/Analyzer/AnalyzedPropertyAccessorsTreeNode.cs rename to ILSpy/TreeNodes/Analyzer/AnalyzedPropertyAccessorTreeNode.cs index 621417d2b..e9b898cba 100644 --- a/ILSpy/TreeNodes/Analyzer/AnalyzedPropertyAccessorsTreeNode.cs +++ b/ILSpy/TreeNodes/Analyzer/AnalyzedPropertyAccessorTreeNode.cs @@ -21,50 +21,19 @@ using Mono.Cecil; namespace ICSharpCode.ILSpy.TreeNodes.Analyzer { - internal sealed class AnalyzedPropertyAccessorsTreeNode : AnalyzerTreeNode + internal class AnalyzedPropertyAccessorTreeNode : AnalyzedMethodTreeNode { - public AnalyzedPropertyAccessorsTreeNode(PropertyDefinition analyzedProperty) - { - if (analyzedProperty == null) - throw new ArgumentNullException("analyzedProperty"); - - if (analyzedProperty.GetMethod != null) - this.Children.Add(new AnalyzedPropertyAccessorTreeNode(analyzedProperty.GetMethod, "get")); - if (analyzedProperty.SetMethod != null) - this.Children.Add(new AnalyzedPropertyAccessorTreeNode(analyzedProperty.SetMethod, "set")); - foreach (var accessor in analyzedProperty.OtherMethods) - this.Children.Add(new AnalyzedPropertyAccessorTreeNode(accessor, null)); - } + private readonly string name; - public override object Icon + public AnalyzedPropertyAccessorTreeNode(MethodDefinition analyzedMethod, string name) + : base(analyzedMethod) { - get { return Images.Search; } + this.name = name; } public override object Text { - get { return "Accessors"; } - } - - public static bool CanShow(PropertyDefinition property) - { - return !MainWindow.Instance.CurrentLanguage.ShowMember(property.GetMethod ?? property.SetMethod); - } - - private class AnalyzedPropertyAccessorTreeNode : AnalyzedMethodTreeNode - { - private readonly string name; - - public AnalyzedPropertyAccessorTreeNode(MethodDefinition analyzedMethod, string name) - : base(analyzedMethod) - { - this.name = name; - } - - public override object Text - { - get { return name ?? base.Text; } - } + get { return name ?? base.Text; } } } } diff --git a/ILSpy/TreeNodes/Analyzer/AnalyzedPropertyOverridesTreeNode.cs b/ILSpy/TreeNodes/Analyzer/AnalyzedPropertyOverridesTreeNode.cs index 440a54f6e..6a6ea0f32 100644 --- a/ILSpy/TreeNodes/Analyzer/AnalyzedPropertyOverridesTreeNode.cs +++ b/ILSpy/TreeNodes/Analyzer/AnalyzedPropertyOverridesTreeNode.cs @@ -69,45 +69,27 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer private IEnumerable FetchChildren(CancellationToken ct) { - return FindReferences(MainWindow.Instance.CurrentAssemblyList.GetAssemblies(), ct); - } - - private IEnumerable FindReferences(IEnumerable assemblies, CancellationToken ct) - { - assemblies = assemblies.Where(asm => asm.AssemblyDefinition != null); + ScopedWhereUsedAnalyzer analyzer; - // use parallelism only on the assembly level (avoid locks within Cecil) - return assemblies.AsParallel().WithCancellation(ct).SelectMany((LoadedAssembly asm) => FindReferences(asm, ct)); + analyzer = new ScopedWhereUsedAnalyzer(analyzedProperty, FindReferencesInType); + return analyzer.PerformAnalysis(ct); } - private IEnumerable FindReferences(LoadedAssembly asm, CancellationToken ct) + private IEnumerable FindReferencesInType(TypeDefinition type) { - string asmName = asm.AssemblyDefinition.Name.Name; string name = analyzedProperty.Name; string declTypeName = analyzedProperty.DeclaringType.FullName; - foreach (TypeDefinition type in TreeTraversal.PreOrder(asm.AssemblyDefinition.MainModule.Types, t => t.NestedTypes)) { - ct.ThrowIfCancellationRequested(); - SharpTreeNode newNode = null; - try { - if (!TypesHierarchyHelpers.IsBaseType(analyzedProperty.DeclaringType, type, resolveTypeArguments: false)) - continue; + if (!TypesHierarchyHelpers.IsBaseType(analyzedProperty.DeclaringType, type, resolveTypeArguments: false)) + yield break; - foreach (PropertyDefinition property in type.Properties) { - ct.ThrowIfCancellationRequested(); + foreach (PropertyDefinition property in type.Properties) { - if (TypesHierarchyHelpers.IsBaseProperty(analyzedProperty, property)) { - MethodDefinition anyAccessor = property.GetMethod ?? property.SetMethod; - bool hidesParent = !anyAccessor.IsVirtual ^ anyAccessor.IsNewSlot; - newNode = new AnalyzedPropertyTreeNode(property, hidesParent ? "(hides) " : ""); - } - } - } - catch (ReferenceResolvingException) { - // ignore this type definition. + if (TypesHierarchyHelpers.IsBaseProperty(analyzedProperty, property)) { + MethodDefinition anyAccessor = property.GetMethod ?? property.SetMethod; + bool hidesParent = !anyAccessor.IsVirtual ^ anyAccessor.IsNewSlot; + yield return new AnalyzedPropertyTreeNode(property, hidesParent ? "(hides) " : ""); } - if (newNode != null) - yield return newNode; } } diff --git a/ILSpy/TreeNodes/Analyzer/AnalyzedPropertyTreeNode.cs b/ILSpy/TreeNodes/Analyzer/AnalyzedPropertyTreeNode.cs index bba0b3362..b08127b52 100644 --- a/ILSpy/TreeNodes/Analyzer/AnalyzedPropertyTreeNode.cs +++ b/ILSpy/TreeNodes/Analyzer/AnalyzedPropertyTreeNode.cs @@ -60,8 +60,13 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer protected override void LoadChildren() { - if (AnalyzedPropertyAccessorsTreeNode.CanShow(analyzedProperty)) - this.Children.Add(new AnalyzedPropertyAccessorsTreeNode(analyzedProperty)); + if (analyzedProperty.GetMethod != null) + this.Children.Add(new AnalyzedPropertyAccessorTreeNode(analyzedProperty.GetMethod, "get")); + if (analyzedProperty.SetMethod != null) + this.Children.Add(new AnalyzedPropertyAccessorTreeNode(analyzedProperty.SetMethod, "set")); + foreach (var accessor in analyzedProperty.OtherMethods) + this.Children.Add(new AnalyzedPropertyAccessorTreeNode(accessor, null)); + if (AnalyzedPropertyOverridesTreeNode.CanShow(analyzedProperty)) this.Children.Add(new AnalyzedPropertyOverridesTreeNode(analyzedProperty)); if (AnalyzedInterfacePropertyImplementedByTreeNode.CanShow(analyzedProperty)) @@ -82,8 +87,8 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer if (property == null) return false; - return AnalyzedPropertyAccessorsTreeNode.CanShow(property) - || AnalyzedPropertyOverridesTreeNode.CanShow(property); + return !MainWindow.Instance.CurrentLanguage.ShowMember(property.GetMethod ?? property.SetMethod) + || AnalyzedPropertyOverridesTreeNode.CanShow(property); } } } diff --git a/ILSpy/TreeNodes/Analyzer/AnalyzedTypeExposedByTreeNode.cs b/ILSpy/TreeNodes/Analyzer/AnalyzedTypeExposedByTreeNode.cs index 00e09e37d..cd14c0575 100644 --- a/ILSpy/TreeNodes/Analyzer/AnalyzedTypeExposedByTreeNode.cs +++ b/ILSpy/TreeNodes/Analyzer/AnalyzedTypeExposedByTreeNode.cs @@ -65,9 +65,9 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer private IEnumerable FetchChildren(CancellationToken ct) { - ScopedWhereUsedScopeAnalyzer analyzer; + ScopedWhereUsedAnalyzer analyzer; - analyzer = new ScopedWhereUsedScopeAnalyzer(analyzedType, FindReferencesInType); + analyzer = new ScopedWhereUsedAnalyzer(analyzedType, FindReferencesInType); return analyzer.PerformAnalysis(ct); } diff --git a/ILSpy/TreeNodes/Analyzer/AnalyzedTypeExtensionMethodsTreeNode.cs b/ILSpy/TreeNodes/Analyzer/AnalyzedTypeExtensionMethodsTreeNode.cs index c88ece234..3bd42506c 100644 --- a/ILSpy/TreeNodes/Analyzer/AnalyzedTypeExtensionMethodsTreeNode.cs +++ b/ILSpy/TreeNodes/Analyzer/AnalyzedTypeExtensionMethodsTreeNode.cs @@ -66,9 +66,9 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer private IEnumerable FetchChildren(CancellationToken ct) { - ScopedWhereUsedScopeAnalyzer analyzer; + ScopedWhereUsedAnalyzer analyzer; - analyzer = new ScopedWhereUsedScopeAnalyzer(analyzedType, FindReferencesInType); + analyzer = new ScopedWhereUsedAnalyzer(analyzedType, FindReferencesInType); return analyzer.PerformAnalysis(ct); } diff --git a/ILSpy/TreeNodes/Analyzer/AnalyzedTypeInstantiationsTreeNode.cs b/ILSpy/TreeNodes/Analyzer/AnalyzedTypeInstantiationsTreeNode.cs index f11fca495..0c2d9465a 100644 --- a/ILSpy/TreeNodes/Analyzer/AnalyzedTypeInstantiationsTreeNode.cs +++ b/ILSpy/TreeNodes/Analyzer/AnalyzedTypeInstantiationsTreeNode.cs @@ -71,9 +71,9 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer private IEnumerable FetchChildren(CancellationToken ct) { - ScopedWhereUsedScopeAnalyzer analyzer; + ScopedWhereUsedAnalyzer analyzer; - analyzer = new ScopedWhereUsedScopeAnalyzer(analyzedType, FindReferencesInType); + analyzer = new ScopedWhereUsedAnalyzer(analyzedType, FindReferencesInType); return analyzer.PerformAnalysis(ct); } diff --git a/ILSpy/TreeNodes/Analyzer/AnalyzedVirtualMethodUsedByTreeNode.cs b/ILSpy/TreeNodes/Analyzer/AnalyzedVirtualMethodUsedByTreeNode.cs new file mode 100644 index 000000000..993ef36d7 --- /dev/null +++ b/ILSpy/TreeNodes/Analyzer/AnalyzedVirtualMethodUsedByTreeNode.cs @@ -0,0 +1,151 @@ +// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team +// +// Permission is hereby granted, free of charge, to any person obtaining a copy of this +// software and associated documentation files (the "Software"), to deal in the Software +// without restriction, including without limitation the rights to use, copy, modify, merge, +// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons +// to whom the Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all copies or +// substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE +// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. + +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Linq; +using System.Threading; +using ICSharpCode.TreeView; +using Mono.Cecil; +using Mono.Cecil.Cil; +using ICSharpCode.Decompiler.Ast; + +namespace ICSharpCode.ILSpy.TreeNodes.Analyzer +{ + internal sealed class AnalyzedVirtualMethodUsedByTreeNode : AnalyzerTreeNode + { + private readonly MethodDefinition analyzedMethod; + private readonly ThreadingSupport threading; + private ConcurrentDictionary foundMethods; + private MethodDefinition baseMethod; + private List possibleTypes; + + public AnalyzedVirtualMethodUsedByTreeNode(MethodDefinition analyzedMethod) + { + if (analyzedMethod == null) + throw new ArgumentNullException("analyzedMethod"); + + this.analyzedMethod = analyzedMethod; + this.threading = new ThreadingSupport(); + this.LazyLoading = true; + } + + public override object Text + { + get { return "Used By"; } + } + + public override object Icon + { + get { return Images.Search; } + } + + protected override void LoadChildren() + { + threading.LoadChildren(this, FetchChildren); + } + + protected override void OnCollapsing() + { + if (threading.IsRunning) { + this.LazyLoading = true; + threading.Cancel(); + this.Children.Clear(); + } + } + + private IEnumerable FetchChildren(CancellationToken ct) + { + InitializeAnalyzer(); + + var analyzer = new ScopedWhereUsedAnalyzer(analyzedMethod, FindReferencesInType); + foreach (var child in analyzer.PerformAnalysis(ct)) { + yield return child; + } + + ReleaseAnalyzer(); + } + + private void InitializeAnalyzer() + { + foundMethods = new ConcurrentDictionary(); + + var BaseMethods = TypesHierarchyHelpers.FindBaseMethods(analyzedMethod).ToArray(); + if (BaseMethods.Length > 0) { + baseMethod = BaseMethods[BaseMethods.Length - 1]; + } + + possibleTypes = new List(); + + TypeReference type = analyzedMethod.DeclaringType.BaseType; + while (type !=null) + { + possibleTypes.Add(type); + type = type.Resolve().BaseType; + } + } + + private void ReleaseAnalyzer() + { + foundMethods = null; + baseMethod = null; + } + + private IEnumerable FindReferencesInType(TypeDefinition type) + { + string name = analyzedMethod.Name; + foreach (MethodDefinition method in type.Methods) { + bool found = false; + string prefix = string.Empty; + if (!method.HasBody) + continue; + foreach (Instruction instr in method.Body.Instructions) { + MethodReference mr = instr.Operand as MethodReference; + if (mr != null && mr.Name == name) { + // explicit call to the requested method + if (Helpers.IsReferencedBy(analyzedMethod.DeclaringType, mr.DeclaringType) && mr.Resolve() == analyzedMethod) { + found = true; + prefix = "(as base) "; + break; + } + // virtual call to base method + if (instr.OpCode.Code == Code.Callvirt && Helpers.IsReferencedBy(baseMethod.DeclaringType, mr.DeclaringType) && mr.Resolve() == baseMethod) { + found = true; + break; + } + } + } + + method.Body = null; + + if (found) { + MethodDefinition codeLocation = this.Language.GetOriginalCodeLocation(method) as MethodDefinition; + if (codeLocation != null && !HasAlreadyBeenFound(codeLocation)) { + yield return new AnalyzedMethodTreeNode(codeLocation, prefix); + } + } + } + } + + private bool HasAlreadyBeenFound(MethodDefinition method) + { + return !foundMethods.TryAdd(method, 0); + } + } +} diff --git a/ILSpy/TreeNodes/Analyzer/Helpers.cs b/ILSpy/TreeNodes/Analyzer/Helpers.cs index 778996a72..bef4e486a 100644 --- a/ILSpy/TreeNodes/Analyzer/Helpers.cs +++ b/ILSpy/TreeNodes/Analyzer/Helpers.cs @@ -20,7 +20,10 @@ using System; using System.Collections.Generic; using System.Linq; using System.Text; +using ICSharpCode.Decompiler; using Mono.Cecil; +using ICSharpCode.Decompiler.ILAst; +using Mono.Cecil.Cil; namespace ICSharpCode.ILSpy.TreeNodes.Analyzer { @@ -50,5 +53,65 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer return true; } + + public static MemberReference GetOriginalCodeLocation(MemberReference member) + { + if (member is MethodDefinition) + return GetOriginalCodeLocation((MethodDefinition)member); + return member; + } + + public static MethodDefinition GetOriginalCodeLocation(MethodDefinition method) + { + if (method.IsCompilerGenerated()) { + return FindMethodUsageInType(method.DeclaringType, method) ?? method; + } + + var typeUsage = GetOriginalCodeLocation(method.DeclaringType, method); + + return typeUsage ?? method; + } + public static MethodDefinition GetOriginalCodeLocation(TypeDefinition type, MethodDefinition method) + { + if (type != null && type.DeclaringType != null && type.IsCompilerGenerated()) { + MethodDefinition constructor = GetTypeConstructor(type); + return FindMethodUsageInType(type.DeclaringType, constructor); + } + return null; + } + + private static MethodDefinition GetTypeConstructor(TypeDefinition type) + { + foreach (MethodDefinition method in type.Methods) { + if (method.Name == ".ctor") + return method; + } + return null; + } + + private static MethodDefinition FindMethodUsageInType(TypeDefinition type, MethodDefinition analyzedMethod) + { + string name = analyzedMethod.Name; + foreach (MethodDefinition method in type.Methods) { + bool found = false; + if (!method.HasBody) + continue; + foreach (Instruction instr in method.Body.Instructions) { + MethodReference mr = instr.Operand as MethodReference; + if (mr != null && mr.Name == name && + Helpers.IsReferencedBy(analyzedMethod.DeclaringType, mr.DeclaringType) && + mr.Resolve() == analyzedMethod) { + found = true; + break; + } + } + + method.Body = null; + + if (found) + return method; + } + return null; + } } } diff --git a/ILSpy/TreeNodes/Analyzer/ScopedWhereUsedAnalyzer.cs b/ILSpy/TreeNodes/Analyzer/ScopedWhereUsedAnalyzer.cs index 48eb21bc5..2840901a9 100644 --- a/ILSpy/TreeNodes/Analyzer/ScopedWhereUsedAnalyzer.cs +++ b/ILSpy/TreeNodes/Analyzer/ScopedWhereUsedAnalyzer.cs @@ -28,7 +28,7 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer /// /// Determines the accessibility domain of a member for where-used analysis. /// - internal class ScopedWhereUsedScopeAnalyzer + internal class ScopedWhereUsedAnalyzer { private AssemblyDefinition assemblyScope; private TypeDefinition typeScope; @@ -37,40 +37,36 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer private Accessibility typeAccessibility = Accessibility.Public; private Func> typeAnalysisFunction; - public ScopedWhereUsedScopeAnalyzer(TypeDefinition type, Func> typeAnalysisFunction) + public ScopedWhereUsedAnalyzer(TypeDefinition type, Func> typeAnalysisFunction) { this.typeScope = type; this.assemblyScope = type.Module.Assembly; this.typeAnalysisFunction = typeAnalysisFunction; } - public ScopedWhereUsedScopeAnalyzer(MethodDefinition method, Func> typeAnalysisFunction) + public ScopedWhereUsedAnalyzer(MethodDefinition method, Func> typeAnalysisFunction) : this(method.DeclaringType, typeAnalysisFunction) { - switch (method.Attributes & MethodAttributes.MemberAccessMask) { - case MethodAttributes.Private: - default: - memberAccessibility = Accessibility.Private; - break; - case MethodAttributes.FamANDAssem: - memberAccessibility = Accessibility.FamilyAndInternal; - break; - case MethodAttributes.Family: - memberAccessibility = Accessibility.Family; - break; - case MethodAttributes.Assembly: - memberAccessibility = Accessibility.Internal; - break; - case MethodAttributes.FamORAssem: - memberAccessibility = Accessibility.FamilyOrInternal; - break; - case MethodAttributes.Public: - memberAccessibility = Accessibility.Public; - break; - } + this.memberAccessibility = GetMethodAccessibility(method); + } + + public ScopedWhereUsedAnalyzer(PropertyDefinition property, Func> typeAnalysisFunction) + : this(property.DeclaringType, typeAnalysisFunction) + { + Accessibility getterAccessibility = (property.GetMethod == null) ? Accessibility.Private : GetMethodAccessibility(property.GetMethod); + Accessibility setterAccessibility = (property.SetMethod == null) ? Accessibility.Private : GetMethodAccessibility(property.SetMethod); + this.memberAccessibility = (Accessibility)Math.Max((int)getterAccessibility, (int)setterAccessibility); } - public ScopedWhereUsedScopeAnalyzer(FieldDefinition field, Func> typeAnalysisFunction) + public ScopedWhereUsedAnalyzer(EventDefinition eventDef, Func> typeAnalysisFunction) + : this(eventDef.DeclaringType, typeAnalysisFunction) + { + // we only have to check the accessibility of the the get method + // [CLS Rule 30: The accessibility of an event and of its accessors shall be identical.] + this.memberAccessibility = GetMethodAccessibility(eventDef.AddMethod); + } + + public ScopedWhereUsedAnalyzer(FieldDefinition field, Func> typeAnalysisFunction) : this(field.DeclaringType, typeAnalysisFunction) { switch (field.Attributes & FieldAttributes.FieldAccessMask) { @@ -96,6 +92,33 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer } } + private Accessibility GetMethodAccessibility(MethodDefinition method) + { + Accessibility accessibility; + switch (method.Attributes & MethodAttributes.MemberAccessMask) { + case MethodAttributes.Private: + default: + accessibility = Accessibility.Private; + break; + case MethodAttributes.FamANDAssem: + accessibility = Accessibility.FamilyAndInternal; + break; + case MethodAttributes.Family: + accessibility = Accessibility.Family; + break; + case MethodAttributes.Assembly: + accessibility = Accessibility.Internal; + break; + case MethodAttributes.FamORAssem: + accessibility = Accessibility.FamilyOrInternal; + break; + case MethodAttributes.Public: + accessibility = Accessibility.Public; + break; + } + return accessibility; + } + public IEnumerable PerformAnalysis(CancellationToken ct) { if (memberAccessibility == Accessibility.Private) { @@ -231,7 +254,7 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer break; } } - if (found) + if (found && AssemblyReferencesScopeType(assembly.AssemblyDefinition)) yield return assembly.AssemblyDefinition; } } @@ -255,12 +278,24 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer foreach (var assembly in assemblies) { ct.ThrowIfCancellationRequested(); - if (friendAssemblies.Contains(assembly.ShortName)) { + if (friendAssemblies.Contains(assembly.ShortName) && AssemblyReferencesScopeType(assembly.AssemblyDefinition)) { yield return assembly.AssemblyDefinition; } } } } } + + private bool AssemblyReferencesScopeType(AssemblyDefinition asm) + { + bool hasRef = false; + foreach (var typeref in asm.MainModule.GetTypeReferences()) { + if (typeref.Name == typeScope.Name && typeref.Namespace == typeScope.Namespace) { + hasRef = true; + break; + } + } + return hasRef; + } } } diff --git a/ILSpy/TreeNodes/AssemblyTreeNode.cs b/ILSpy/TreeNodes/AssemblyTreeNode.cs index 73dbb38da..864759152 100644 --- a/ILSpy/TreeNodes/AssemblyTreeNode.cs +++ b/ILSpy/TreeNodes/AssemblyTreeNode.cs @@ -134,6 +134,10 @@ namespace ICSharpCode.ILSpy.TreeNodes this.Children.Add(ns); } } + + public override bool CanExpandRecursively { + get { return true; } + } public TypeTreeNode FindTypeNode(TypeDefinition def) { diff --git a/ILSpy/TreeNodes/ILSpyTreeNode.cs b/ILSpy/TreeNodes/ILSpyTreeNode.cs index 0ead7be94..ea92d8f22 100644 --- a/ILSpy/TreeNodes/ILSpyTreeNode.cs +++ b/ILSpy/TreeNodes/ILSpyTreeNode.cs @@ -69,7 +69,7 @@ namespace ICSharpCode.ILSpy.TreeNodes /// This method is called on the main thread when only a single item is selected. /// If it returns false, normal decompilation is used to view the item. /// - internal virtual bool View(TextView.DecompilerTextView textView) + public virtual bool View(TextView.DecompilerTextView textView) { return false; } diff --git a/ILSpy/TreeNodes/ResourceEntryNode.cs b/ILSpy/TreeNodes/ResourceEntryNode.cs index 787c82dc3..cddab8326 100644 --- a/ILSpy/TreeNodes/ResourceEntryNode.cs +++ b/ILSpy/TreeNodes/ResourceEntryNode.cs @@ -132,7 +132,7 @@ namespace ICSharpCode.ILSpy.TreeNodes get { return Images.ResourceImage; } } - internal override bool View(DecompilerTextView textView) + public override bool View(DecompilerTextView textView) { try { AvalonEditTextOutput output = new AvalonEditTextOutput(); @@ -144,7 +144,7 @@ namespace ICSharpCode.ILSpy.TreeNodes output.AddUIElement(() => new Image { Source = image }); output.WriteLine(); output.AddButton(Images.Save, "Save", delegate { Save(null); }); - textView.Show(output, null); + textView.ShowNode(output, this, null); return true; } catch (Exception) { diff --git a/ILSpy/TreeNodes/ResourceTreeNode.cs b/ILSpy/TreeNodes/ResourceTreeNode.cs index 3b277a983..1c1a1f08a 100644 --- a/ILSpy/TreeNodes/ResourceTreeNode.cs +++ b/ILSpy/TreeNodes/ResourceTreeNode.cs @@ -78,7 +78,7 @@ namespace ICSharpCode.ILSpy.TreeNodes } } - internal override bool View(DecompilerTextView textView) + public override bool View(DecompilerTextView textView) { EmbeddedResource er = r as EmbeddedResource; if (er != null) { @@ -95,7 +95,7 @@ namespace ICSharpCode.ILSpy.TreeNodes ext = ".xml"; else ext = Path.GetExtension(DecompilerTextView.CleanUpName(er.Name)); - textView.Show(output, HighlightingManager.Instance.GetDefinitionByExtension(ext)); + textView.ShowNode(output, this, HighlightingManager.Instance.GetDefinitionByExtension(ext)); return true; } } diff --git a/ILSpy/TreeNodes/TypeTreeNode.cs b/ILSpy/TreeNodes/TypeTreeNode.cs index 23bce5df7..653def410 100644 --- a/ILSpy/TreeNodes/TypeTreeNode.cs +++ b/ILSpy/TreeNodes/TypeTreeNode.cs @@ -59,7 +59,7 @@ namespace ICSharpCode.ILSpy.TreeNodes } public override object Text { - get { return HighlightSearchMatch(this.Language.TypeToString(type, includeNamespace: false)); } + get { return HighlightSearchMatch(this.Language.FormatTypeName(type)); } } public bool IsPublicAPI { @@ -117,6 +117,10 @@ namespace ICSharpCode.ILSpy.TreeNodes } } + public override bool CanExpandRecursively { + get { return true; } + } + public override void Decompile(Language language, ITextOutput output, DecompilationOptions options) { language.DecompileType(type, output, options); @@ -146,8 +150,10 @@ namespace ICSharpCode.ILSpy.TreeNodes } else { if (type.IsInterface) return TypeIcon.Interface; - else if (type.BaseType != null && type.BaseType.FullName == typeof(MulticastDelegate).FullName) + else if (IsDelegate(type)) return TypeIcon.Delegate; + else if (IsStaticClass(type)) + return TypeIcon.StaticClass; else return TypeIcon.Class; } @@ -178,6 +184,17 @@ namespace ICSharpCode.ILSpy.TreeNodes } return overlay; } + + private static bool IsDelegate(TypeDefinition type) + { + return type.BaseType != null && type.BaseType.FullName == typeof(MulticastDelegate).FullName; + } + + private static bool IsStaticClass(TypeDefinition type) + { + return type.IsSealed && type.IsAbstract; + } + #endregion MemberReference IMemberTreeNode.Member { diff --git a/ILSpy/TreeNodes/XamlResourceNode.cs b/ILSpy/TreeNodes/XamlResourceNode.cs index 9e42fb431..13912e348 100644 --- a/ILSpy/TreeNodes/XamlResourceNode.cs +++ b/ILSpy/TreeNodes/XamlResourceNode.cs @@ -52,7 +52,7 @@ namespace ICSharpCode.ILSpy.Xaml { } - internal override bool View(DecompilerTextView textView) + public override bool View(DecompilerTextView textView) { AvalonEditTextOutput output = new AvalonEditTextOutput(); IHighlightingDefinition highlighting = null; @@ -74,7 +74,7 @@ namespace ICSharpCode.ILSpy.Xaml } return output; }), - t => textView.Show(t.Result, highlighting) + t => textView.ShowNode(t.Result, this, highlighting) ); return true; } diff --git a/ILSpy/XmlDoc/XmlDocKeyProvider.cs b/ILSpy/XmlDoc/XmlDocKeyProvider.cs index 7e9960067..fc503c115 100644 --- a/ILSpy/XmlDoc/XmlDocKeyProvider.cs +++ b/ILSpy/XmlDoc/XmlDocKeyProvider.cs @@ -79,6 +79,10 @@ namespace ICSharpCode.ILSpy.XmlDoc static void AppendTypeName(StringBuilder b, TypeReference type) { + if (type == null) { + // could happen when a TypeSpecification has no ElementType; e.g. function pointers in C++/CLI assemblies + return; + } if (type is GenericInstanceType) { GenericInstanceType giType = (GenericInstanceType)type; if (type.DeclaringType != null) { diff --git a/NRefactory/ICSharpCode.NRefactory/CSharp/Analysis/DefiniteAssignmentAnalysis.cs b/NRefactory/ICSharpCode.NRefactory/CSharp/Analysis/DefiniteAssignmentAnalysis.cs index d4cc6e1c5..452ca686a 100644 --- a/NRefactory/ICSharpCode.NRefactory/CSharp/Analysis/DefiniteAssignmentAnalysis.cs +++ b/NRefactory/ICSharpCode.NRefactory/CSharp/Analysis/DefiniteAssignmentAnalysis.cs @@ -167,12 +167,14 @@ namespace ICSharpCode.NRefactory.CSharp.Analysis /// This method can be used to restrict the analysis to only a part of the method. /// Only the control flow paths that are fully contained within the selected part will be analyzed. /// - /// Both 'start' and 'end' are inclusive. - public void SetAnalyzedRange(Statement start, Statement end) + /// By default, both 'start' and 'end' are inclusive. + public void SetAnalyzedRange(Statement start, Statement end, bool startInclusive = true, bool endInclusive = true) { - Debug.Assert(beginNodeDict.ContainsKey(start) && endNodeDict.ContainsKey(end)); - int startIndex = beginNodeDict[start].Index; - int endIndex = endNodeDict[end].Index; + var dictForStart = startInclusive ? beginNodeDict : endNodeDict; + var dictForEnd = endInclusive ? endNodeDict : beginNodeDict; + Debug.Assert(dictForStart.ContainsKey(start) && dictForEnd.ContainsKey(end)); + int startIndex = dictForStart[start].Index; + int endIndex = dictForEnd[end].Index; if (startIndex > endIndex) throw new ArgumentException("The start statement must be lexically preceding the end statement"); this.analyzedRangeStart = startIndex; diff --git a/NRefactory/ICSharpCode.NRefactory/CSharp/Ast/ComposedType.cs b/NRefactory/ICSharpCode.NRefactory/CSharp/Ast/ComposedType.cs index b888cdea2..813f47213 100644 --- a/NRefactory/ICSharpCode.NRefactory/CSharp/Ast/ComposedType.cs +++ b/NRefactory/ICSharpCode.NRefactory/CSharp/Ast/ComposedType.cs @@ -52,7 +52,7 @@ namespace ICSharpCode.NRefactory.CSharp public int PointerRank { get { - return GetChildrenByRole(PointerRole).Count(); + return GetChildrenByRole(PointerRole).Count; } set { if (value < 0) @@ -141,7 +141,7 @@ namespace ICSharpCode.NRefactory.CSharp } public int Dimensions { - get { return 1 + GetChildrenByRole(Roles.Comma).Count(); } + get { return 1 + GetChildrenByRole(Roles.Comma).Count; } set { int d = this.Dimensions; while (d > value) { diff --git a/NRefactory/ICSharpCode.NRefactory/CSharp/Ast/Identifier.cs b/NRefactory/ICSharpCode.NRefactory/CSharp/Ast/Identifier.cs index 70f1ddca4..6db26e523 100644 --- a/NRefactory/ICSharpCode.NRefactory/CSharp/Ast/Identifier.cs +++ b/NRefactory/ICSharpCode.NRefactory/CSharp/Ast/Identifier.cs @@ -96,7 +96,7 @@ namespace ICSharpCode.NRefactory.CSharp { if (name == null) throw new ArgumentNullException("name"); - IsVerbatim = name.StartsWith ("@"); + IsVerbatim = name.Length > 0 && name[0] == '@'; this.Name = IsVerbatim ? name.Substring (1) : name; this.startLocation = location; } diff --git a/NRefactory/ICSharpCode.NRefactory/CSharp/OutputVisitor/OutputVisitor.cs b/NRefactory/ICSharpCode.NRefactory/CSharp/OutputVisitor/OutputVisitor.cs index 1c770b634..da524257d 100644 --- a/NRefactory/ICSharpCode.NRefactory/CSharp/OutputVisitor/OutputVisitor.cs +++ b/NRefactory/ICSharpCode.NRefactory/CSharp/OutputVisitor/OutputVisitor.cs @@ -941,7 +941,11 @@ namespace ICSharpCode.NRefactory.CSharp return ConvertChar(ch); } - static string ConvertChar(char ch) + /// + /// Gets the escape sequence for the specified character. + /// + /// This method does not convert ' or ". + public static string ConvertChar(char ch) { switch (ch) { case '\\': @@ -963,7 +967,9 @@ namespace ICSharpCode.NRefactory.CSharp case '\v': return "\\v"; default: - if (char.IsControl(ch) || char.IsSurrogate(ch)) { + if (char.IsControl(ch) || char.IsSurrogate(ch) || + // print all uncommon white spaces as numbers + (char.IsWhiteSpace(ch) && ch != ' ')) { return "\\u" + ((int)ch).ToString("x4"); } else { return ch.ToString(); @@ -971,7 +977,10 @@ namespace ICSharpCode.NRefactory.CSharp } } - static string ConvertString(string str) + /// + /// Converts special characters to escape sequences within the given string. + /// + public static string ConvertString(string str) { StringBuilder sb = new StringBuilder(); foreach (char ch in str) { @@ -2145,7 +2154,9 @@ namespace ICSharpCode.NRefactory.CSharp // "1.0 / /*comment*/a", then we need to insert a space in front of the comment. formatter.Space(); } + formatter.StartNode(comment); formatter.WriteComment(comment.CommentType, comment.Content); + formatter.EndNode(comment); lastWritten = LastWritten.Whitespace; return null; } diff --git a/NRefactory/ICSharpCode.NRefactory/CSharp/Parser/TypeSystemConvertVisitor.cs b/NRefactory/ICSharpCode.NRefactory/CSharp/Parser/TypeSystemConvertVisitor.cs index 66865d53c..756adce40 100644 --- a/NRefactory/ICSharpCode.NRefactory/CSharp/Parser/TypeSystemConvertVisitor.cs +++ b/NRefactory/ICSharpCode.NRefactory/CSharp/Parser/TypeSystemConvertVisitor.cs @@ -263,7 +263,7 @@ namespace ICSharpCode.NRefactory.CSharp #region Fields public override IEntity VisitFieldDeclaration(FieldDeclaration fieldDeclaration, object data) { - bool isSingleField = fieldDeclaration.Variables.Count() == 1; + bool isSingleField = fieldDeclaration.Variables.Count == 1; Modifiers modifiers = fieldDeclaration.Modifiers; DefaultField field = null; foreach (VariableInitializer vi in fieldDeclaration.Variables) { @@ -476,7 +476,7 @@ namespace ICSharpCode.NRefactory.CSharp #region Events public override IEntity VisitEventDeclaration(EventDeclaration eventDeclaration, object data) { - bool isSingleEvent = eventDeclaration.Variables.Count() == 1; + bool isSingleEvent = eventDeclaration.Variables.Count == 1; Modifiers modifiers = eventDeclaration.Modifiers; DefaultEvent ev = null; foreach (VariableInitializer vi in eventDeclaration.Variables) { diff --git a/NRefactory/ICSharpCode.NRefactory/CSharp/Resolver/ResolveVisitor.cs b/NRefactory/ICSharpCode.NRefactory/CSharp/Resolver/ResolveVisitor.cs index 3bcea943b..162f5c2bf 100644 --- a/NRefactory/ICSharpCode.NRefactory/CSharp/Resolver/ResolveVisitor.cs +++ b/NRefactory/ICSharpCode.NRefactory/CSharp/Resolver/ResolveVisitor.cs @@ -241,7 +241,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver ResolveResult VisitFieldOrEventDeclaration(AttributedNode fieldOrEventDeclaration) { - int initializerCount = fieldOrEventDeclaration.GetChildrenByRole(FieldDeclaration.Roles.Variable).Count(); + int initializerCount = fieldOrEventDeclaration.GetChildrenByRole(FieldDeclaration.Roles.Variable).Count; ResolveResult result = null; for (AstNode node = fieldOrEventDeclaration.FirstChild; node != null; node = node.NextSibling) { if (node.Role == FieldDeclaration.Roles.Variable) { @@ -939,7 +939,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver firstInitializer != null ? firstInitializer.Initializer : null, false); - int initializerCount = variableDeclarationStatement.Variables.Count(); + int initializerCount = variableDeclarationStatement.Variables.Count; ResolveResult result = null; for (AstNode node = variableDeclarationStatement.FirstChild; node != null; node = node.NextSibling) { if (node.Role == FieldDeclaration.Roles.Variable) { diff --git a/NRefactory/ICSharpCode.NRefactory/Documentation/XmlDocumentationProvider.cs b/NRefactory/ICSharpCode.NRefactory/Documentation/XmlDocumentationProvider.cs index 315f212eb..70d88aa16 100644 --- a/NRefactory/ICSharpCode.NRefactory/Documentation/XmlDocumentationProvider.cs +++ b/NRefactory/ICSharpCode.NRefactory/Documentation/XmlDocumentationProvider.cs @@ -120,7 +120,7 @@ namespace ICSharpCode.NRefactory.Documentation static string GetRedirectionTarget(string target) { - string programFilesDir = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles); + string programFilesDir = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86); programFilesDir = AppendDirectorySeparator(programFilesDir); string corSysDir = System.Runtime.InteropServices.RuntimeEnvironment.GetRuntimeDirectory(); diff --git a/SharpTreeView/SharpTreeNode.cs b/SharpTreeView/SharpTreeNode.cs index 3de3c9f9f..ae0a0e646 100644 --- a/SharpTreeView/SharpTreeNode.cs +++ b/SharpTreeView/SharpTreeNode.cs @@ -267,12 +267,26 @@ namespace ICSharpCode.TreeView lazyLoading = value; if (lazyLoading) { IsExpanded = false; + if (canExpandRecursively) { + canExpandRecursively = false; + RaisePropertyChanged("CanExpandRecursively"); + } } RaisePropertyChanged("LazyLoading"); RaisePropertyChanged("ShowExpander"); } } + bool canExpandRecursively = true; + + /// + /// Gets whether this node can be expanded recursively. + /// If not overridden, this property returns false if the node is using lazy-loading, and true otherwise. + /// + public virtual bool CanExpandRecursively { + get { return canExpandRecursively; } + } + public virtual bool ShowIcon { get { return Icon != null; } diff --git a/SharpTreeView/SharpTreeView.cs b/SharpTreeView/SharpTreeView.cs index d9409b79b..f2a66c797 100644 --- a/SharpTreeView/SharpTreeView.cs +++ b/SharpTreeView/SharpTreeView.cs @@ -227,11 +227,28 @@ namespace ICSharpCode.TreeView e.Handled = true; } break; + case Key.Multiply: + if (container != null && ItemsControl.ItemsControlFromItemContainer(container) == this) { + container.Node.IsExpanded = true; + ExpandRecursively(container.Node); + e.Handled = true; + } + break; } if (!e.Handled) base.OnKeyDown(e); } + void ExpandRecursively(SharpTreeNode node) + { + if (node.CanExpandRecursively) { + node.IsExpanded = true; + foreach (SharpTreeNode child in node.Children) { + ExpandRecursively(child); + } + } + } + /// /// Scrolls the specified node in view and sets keyboard focus on it. /// diff --git a/doc/MS-PL.txt b/doc/MS-PL.txt new file mode 100644 index 000000000..622a544b7 --- /dev/null +++ b/doc/MS-PL.txt @@ -0,0 +1,31 @@ +Microsoft Public License (Ms-PL) + +This license governs use of the accompanying software. If you use the software, you accept this license. If you do not accept the license, do not use the software. + +1. Definitions + +The terms "reproduce," "reproduction," "derivative works," and "distribution" have the same meaning here as under U.S. copyright law. + +A "contribution" is the original software, or any additions or changes to the software. + +A "contributor" is any person that distributes its contribution under this license. + +"Licensed patents" are a contributor's patent claims that read directly on its contribution. + +2. Grant of Rights + +(A) Copyright Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free copyright license to reproduce its contribution, prepare derivative works of its contribution, and distribute its contribution or any derivative works that you create. + +(B) Patent Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free license under its licensed patents to make, have made, use, sell, offer for sale, import, and/or otherwise dispose of its contribution in the software or derivative works of the contribution in the software. + +3. Conditions and Limitations + +(A) No Trademark License- This license does not grant you rights to use any contributors' name, logo, or trademarks. + +(B) If you bring a patent claim against any contributor over patents that you claim are infringed by the software, your patent license from such contributor to the software ends automatically. + +(C) If you distribute any portion of the software, you must retain all copyright, patent, trademark, and attribution notices that are present in the software. + +(D) If you distribute any portion of the software in source code form, you may do so only under this license by including a complete copy of this license with your distribution. If you distribute any portion of the software in compiled or object code form, you may only do so under a license that complies with this license. + +(E) The software is licensed "as-is." You bear the risk of using it. The contributors give no express warranties, guarantees or conditions. You may have additional consumer rights under your local laws which this license cannot change. To the extent permitted under your local laws, the contributors exclude the implied warranties of merchantability, fitness for a particular purpose and non-infringement. \ No newline at end of file