From 38b404a709ebc8b76f2092ead8e664354c1e2f77 Mon Sep 17 00:00:00 2001 From: Eusebiu Marcu Date: Fri, 7 Oct 2011 23:40:48 +0300 Subject: [PATCH] fix icon margin. --- .../Ast/TextOutputFormatter.cs | 37 +++-- .../Disassembler/ReflectionDisassembler.cs | 8 +- ICSharpCode.Decompiler/ITextOutput.cs | 2 +- ICSharpCode.Decompiler/PlainTextOutput.cs | 4 +- ILSpy/Bookmarks/MemberBookmark.cs | 145 +++++++++++++----- ILSpy/Images/Images.cs | 4 +- ILSpy/TextView/AvalonEditTextOutput.cs | 31 ++-- ILSpy/TextView/DecompilerTextView.cs | 9 +- ILSpy/VB/VBTextOutputFormatter.cs | 38 +++-- 9 files changed, 198 insertions(+), 80 deletions(-) diff --git a/ICSharpCode.Decompiler/Ast/TextOutputFormatter.cs b/ICSharpCode.Decompiler/Ast/TextOutputFormatter.cs index 0b03385bc..c02decd3b 100644 --- a/ICSharpCode.Decompiler/Ast/TextOutputFormatter.cs +++ b/ICSharpCode.Decompiler/Ast/TextOutputFormatter.cs @@ -45,14 +45,20 @@ namespace ICSharpCode.Decompiler.Ast public void WriteIdentifier(string identifier) { + var definition = GetCurrentDefinition(); + if (definition != null) { + output.WriteDefinition(identifier, definition); + return; + } + object memberRef = GetCurrentMemberReference(); if (memberRef != null) { - output.WriteReference(identifier, memberRef, isIconMapping: IsIconMapping()); + output.WriteReference(identifier, memberRef); return; } - var definition = GetCurrentLocalDefinition(); + definition = GetCurrentLocalDefinition(); if (definition != null) { output.WriteDefinition(identifier, definition); return; @@ -136,6 +142,22 @@ namespace ICSharpCode.Decompiler.Ast return null; } + object GetCurrentDefinition() + { + if (nodeStack == null || nodeStack.Count == 0) + return null; + + var node = nodeStack.Peek(); + if (IsDefinition(node)) + return node.Annotation(); + + var fieldDef = node.Parent.Annotation(); + if (fieldDef != null) + return node.Parent.Annotation(); + + return null; + } + public void WriteKeyword(string keyword) { output.Write(keyword); @@ -147,7 +169,7 @@ namespace ICSharpCode.Decompiler.Ast MemberReference memberRef = GetCurrentMemberReference(); var node = nodeStack.Peek(); if (memberRef != null && node.GetChildByRole(AstNode.Roles.Identifier).IsNull) - output.WriteReference(token, memberRef, isIconMapping: IsIconMapping()); + output.WriteReference(token, memberRef); else output.Write(token); } @@ -288,18 +310,13 @@ namespace ICSharpCode.Decompiler.Ast } } - private bool IsIconMapping() + private static bool IsDefinition(AstNode node) { - if (nodeStack == null || nodeStack.Count == 0) - return false; - - var node = nodeStack.Peek(); - return node is FieldDeclaration || node is ConstructorDeclaration || + node is DestructorDeclaration || node is EventDeclaration || - node is DestructorDeclaration || node is DelegateDeclaration || node is OperatorDeclaration|| node is MemberDeclaration || diff --git a/ICSharpCode.Decompiler/Disassembler/ReflectionDisassembler.cs b/ICSharpCode.Decompiler/Disassembler/ReflectionDisassembler.cs index 8ffb68b16..413234e77 100644 --- a/ICSharpCode.Decompiler/Disassembler/ReflectionDisassembler.cs +++ b/ICSharpCode.Decompiler/Disassembler/ReflectionDisassembler.cs @@ -160,7 +160,7 @@ namespace ICSharpCode.Decompiler.Disassembler output.WriteLine(); output.Indent(); if (method.ExplicitThis) { - output.Write("instance explicit "); + output.Write("instance explicit "); } else if (method.HasThis) { output.Write("instance "); } @@ -179,7 +179,6 @@ namespace ICSharpCode.Decompiler.Disassembler output.Write(DisassemblerHelpers.Escape(method.Name + "$PST" + method.MetadataToken.ToInt32().ToString("X8"))); } else { output.Write(DisassemblerHelpers.Escape(method.Name)); - output.WriteReference(DisassemblerHelpers.Escape(method.Name), method, isIconMapping: true); } WriteTypeParameters(output, method); @@ -675,7 +674,6 @@ namespace ICSharpCode.Decompiler.Disassembler public void DisassembleField(FieldDefinition field) { output.WriteDefinition(".field ", field); - output.WriteReference(DisassemblerHelpers.Escape(field.Name), field, isIconMapping: true); WriteEnum(field.Attributes & FieldAttributes.FieldAccessMask, fieldVisibility); const FieldAttributes hasXAttributes = FieldAttributes.HasDefault | FieldAttributes.HasFieldMarshal | FieldAttributes.HasFieldRVA; WriteFlags(field.Attributes & ~(FieldAttributes.FieldAccessMask | hasXAttributes), fieldAttributes); @@ -714,7 +712,6 @@ namespace ICSharpCode.Decompiler.Disassembler currentMember = property; output.WriteDefinition(".property ", property); - output.WriteReference(DisassemblerHelpers.Escape(property.Name), property, isIconMapping: true); WriteFlags(property.Attributes, propertyAttributes); if (property.HasThis) output.Write("instance "); @@ -747,7 +744,6 @@ namespace ICSharpCode.Decompiler.Disassembler if (method == null) return; - output.WriteReference(DisassemblerHelpers.Escape(method.Name), method, isIconMapping: true); output.Write(keyword); output.Write(' '); method.WriteTo(output); @@ -767,7 +763,6 @@ namespace ICSharpCode.Decompiler.Disassembler currentMember = ev; output.WriteDefinition(".event ", ev); - output.WriteReference(DisassemblerHelpers.Escape(ev.Name), ev, isIconMapping: true); WriteFlags(ev.Attributes, eventAttributes); ev.EventType.WriteTo(output, ILNameSyntax.TypeName); output.Write(' '); @@ -822,7 +817,6 @@ namespace ICSharpCode.Decompiler.Disassembler { // start writing IL output.WriteDefinition(".class ", type); - output.WriteReference(DisassemblerHelpers.Escape(type.Name), type, isIconMapping: true); if ((type.Attributes & TypeAttributes.ClassSemanticMask) == TypeAttributes.Interface) output.Write("interface "); diff --git a/ICSharpCode.Decompiler/ITextOutput.cs b/ICSharpCode.Decompiler/ITextOutput.cs index b98ad6960..cd58d63bb 100644 --- a/ICSharpCode.Decompiler/ITextOutput.cs +++ b/ICSharpCode.Decompiler/ITextOutput.cs @@ -33,7 +33,7 @@ namespace ICSharpCode.Decompiler void Write(string text); void WriteLine(); void WriteDefinition(string text, object definition); - void WriteReference(string text, object reference, bool isLocal = false, bool isIconMapping = false); + void WriteReference(string text, object reference, bool isLocal = false); void AddDebuggerMemberMapping(MemberMapping memberMapping); diff --git a/ICSharpCode.Decompiler/PlainTextOutput.cs b/ICSharpCode.Decompiler/PlainTextOutput.cs index e7610d8a2..848fc80fb 100644 --- a/ICSharpCode.Decompiler/PlainTextOutput.cs +++ b/ICSharpCode.Decompiler/PlainTextOutput.cs @@ -57,7 +57,7 @@ namespace ICSharpCode.Decompiler public abstract void Write(string text); public abstract void WriteLine(); public abstract void WriteDefinition(string text, object definition); - public abstract void WriteReference(string text, object reference, bool isLocal, bool isIconMapping); + public abstract void WriteReference(string text, object reference, bool isLocal); public abstract void MarkFoldStart(string collapsedText, bool defaultCollapsed); public abstract void MarkFoldEnd(); #endregion @@ -147,7 +147,7 @@ namespace ICSharpCode.Decompiler Write(text); } - public override void WriteReference(string text, object reference, bool isLocal, bool isIconMapping) + public override void WriteReference(string text, object reference, bool isLocal) { Write(text); } diff --git a/ILSpy/Bookmarks/MemberBookmark.cs b/ILSpy/Bookmarks/MemberBookmark.cs index c228ba35e..be51e4f5b 100644 --- a/ILSpy/Bookmarks/MemberBookmark.cs +++ b/ILSpy/Bookmarks/MemberBookmark.cs @@ -52,32 +52,24 @@ namespace ICSharpCode.ILSpy.Bookmarks public virtual ImageSource Image { get { if (member is FieldDefinition) - return GetMemberOverlayedImage(member, MemberIcon.Field); + return GetOverlayedImage(member as FieldDefinition, MemberIcon.Field); if (member is PropertyDefinition) - return GetMemberOverlayedImage(member, MemberIcon.Property); + return GetOverlayedImage(member as PropertyDefinition, MemberIcon.Property); if (member is EventDefinition) - return GetMemberOverlayedImage(member, MemberIcon.Event); + return GetOverlayedImage(member as EventDefinition, MemberIcon.Event); - return GetMemberOverlayedImage(member, MemberIcon.Method); + if (member is MethodDefinition) + return GetOverlayedImage(member as MethodDefinition, MemberIcon.Method); + + if (member is TypeDefinition) + return GetOverlayedImage(member as TypeDefinition); + + return null; } } - ImageSource GetMemberOverlayedImage(MemberReference member, MemberIcon icon) - { - if (member is FieldDefinition) - return Images.GetIcon(icon, ((FieldDefinition)member).IsPublic ? AccessOverlayIcon.Public : AccessOverlayIcon.Private, false); - - if (member is PropertyDefinition) - return Images.GetIcon(icon, AccessOverlayIcon.Public, false); - - if (member is EventDefinition) - return Images.GetIcon(icon, AccessOverlayIcon.Public, false); - - return Images.GetIcon(icon, ((MethodDefinition)member).IsPublic ? AccessOverlayIcon.Public : AccessOverlayIcon.Private, false); - } - public int LineNumber { get; private set; } @@ -102,6 +94,105 @@ namespace ICSharpCode.ILSpy.Bookmarks { throw new NotSupportedException(); } + + #region Overlayed images + + internal ImageSource GetOverlayedImage(TypeDefinition typeDef) + { + TypeIcon icon = TypeIcon.Class; + if (typeDef.IsEnum) + icon = TypeIcon.Enum; + if (typeDef.IsValueType) + icon = TypeIcon.Struct; + if (typeDef.IsInterface) + icon = TypeIcon.Interface; + if (typeDef.BaseType.FullName == "System.MulticastDelegate" || typeDef.BaseType.FullName == "System.Delegate") + icon = TypeIcon.Delegate; + + bool isStatic = false; + AccessOverlayIcon overlayIcon = AccessOverlayIcon.Private; + + if (typeDef.IsNestedPrivate) + overlayIcon = AccessOverlayIcon.Public; + else if (typeDef.IsNestedAssembly || typeDef.IsNestedFamilyAndAssembly || typeDef.IsNotPublic) + overlayIcon = AccessOverlayIcon.Internal; + else if (typeDef.IsNestedFamily) + overlayIcon = AccessOverlayIcon.Protected; + else if (typeDef.IsNestedFamilyOrAssembly) + overlayIcon = AccessOverlayIcon.ProtectedInternal; + else if (typeDef.IsPublic || typeDef.IsNestedPublic) + overlayIcon = AccessOverlayIcon.Public; + + if (typeDef.IsAbstract && typeDef.IsSealed) + isStatic = true; + + return Images.GetIcon(icon, overlayIcon, isStatic); + } + + ImageSource GetOverlayedImage(FieldDefinition fieldDef, MemberIcon icon) + { + bool isStatic = false; + AccessOverlayIcon overlayIcon = AccessOverlayIcon.Public; + + if (fieldDef.IsPrivate) + overlayIcon = AccessOverlayIcon.Private; + else if (fieldDef.IsAssembly || fieldDef.IsFamilyAndAssembly) + overlayIcon = AccessOverlayIcon.Internal; + else if (fieldDef.IsFamily) + overlayIcon = AccessOverlayIcon.Protected; + else if (fieldDef.IsFamilyOrAssembly) + overlayIcon = AccessOverlayIcon.ProtectedInternal; + else if (fieldDef.IsPublic) + overlayIcon = AccessOverlayIcon.Public; + + if (fieldDef.IsStatic) + isStatic = true; + + return Images.GetIcon(icon, overlayIcon, isStatic); + } + + ImageSource GetOverlayedImage(MethodDefinition methodDef, MemberIcon icon) + { + bool isStatic = false; + AccessOverlayIcon overlayIcon = AccessOverlayIcon.Public; + + if (methodDef == null) + return Images.GetIcon(icon, overlayIcon, isStatic);; + + if (methodDef.IsPrivate) + overlayIcon = AccessOverlayIcon.Private; + else if (methodDef.IsAssembly || methodDef.IsFamilyAndAssembly) + overlayIcon = AccessOverlayIcon.Internal; + else if (methodDef.IsFamily) + overlayIcon = AccessOverlayIcon.Protected; + else if (methodDef.IsFamilyOrAssembly) + overlayIcon = AccessOverlayIcon.ProtectedInternal; + else if (methodDef.IsPublic) + overlayIcon = AccessOverlayIcon.Public; + + if (methodDef.IsStatic) + isStatic = true; + + return Images.GetIcon(icon, overlayIcon, isStatic); + } + + ImageSource GetOverlayedImage(PropertyDefinition propDef, MemberIcon icon) + { + bool isStatic = false; + AccessOverlayIcon overlayIcon = AccessOverlayIcon.Public; + + return Images.GetIcon(propDef.IsIndexer() ? MemberIcon.Indexer : icon, overlayIcon, isStatic); + } + + ImageSource GetOverlayedImage(EventDefinition eventDef, MemberIcon icon) + { + bool isStatic = false; + AccessOverlayIcon overlayIcon = AccessOverlayIcon.Public; + + return Images.GetIcon(icon, overlayIcon, isStatic); + } + + #endregion } public class TypeBookmark : MemberBookmark @@ -113,27 +204,11 @@ namespace ICSharpCode.ILSpy.Bookmarks public override ImageSource Image { get { if (Member is TypeDefinition) { - var type = Member as TypeDefinition; - if (type.IsEnum) - return GetTypeOverlayedImage(type, TypeIcon.Enum); - if (type.IsValueType) - return GetTypeOverlayedImage(type, TypeIcon.Struct); - if (type.IsInterface) - return GetTypeOverlayedImage(type, TypeIcon.Interface); - - return GetTypeOverlayedImage(type, TypeIcon.Class); + return GetOverlayedImage(Member as TypeDefinition); } return null; } } - - ImageSource GetTypeOverlayedImage(TypeDefinition type, TypeIcon icon) - { - if (type.IsNotPublic) - return Images.GetIcon(icon, AccessOverlayIcon.Private); - - return Images.GetIcon(icon, AccessOverlayIcon.Public); - } } } diff --git a/ILSpy/Images/Images.cs b/ILSpy/Images/Images.cs index e7a1c9fd1..6654a809a 100644 --- a/ILSpy/Images/Images.cs +++ b/ILSpy/Images/Images.cs @@ -117,10 +117,10 @@ namespace ICSharpCode.ILSpy private static TypeIconCache typeIconCache = new TypeIconCache(); private static MemberIconCache memberIconCache = new MemberIconCache(); - public static ImageSource GetIcon(TypeIcon icon, AccessOverlayIcon overlay) + public static ImageSource GetIcon(TypeIcon icon, AccessOverlayIcon overlay, bool isStatic = false) { lock (typeIconCache) - return typeIconCache.GetIcon(icon, overlay, false); + return typeIconCache.GetIcon(icon, overlay, isStatic); } public static ImageSource GetIcon(MemberIcon icon, AccessOverlayIcon overlay, bool isStatic) diff --git a/ILSpy/TextView/AvalonEditTextOutput.cs b/ILSpy/TextView/AvalonEditTextOutput.cs index a5d71edea..0875ab753 100644 --- a/ILSpy/TextView/AvalonEditTextOutput.cs +++ b/ILSpy/TextView/AvalonEditTextOutput.cs @@ -47,7 +47,7 @@ namespace ICSharpCode.ILSpy.TextView /// sealed class DefinitionLookup { - Dictionary definitions = new Dictionary(); + internal Dictionary definitions = new Dictionary(); public int GetDefinitionPosition(object definition) { @@ -94,9 +94,6 @@ namespace ICSharpCode.ILSpy.TextView /// Embedded UIElements, see . internal readonly List>> UIElements = new List>>(); - /// Icon mappings. - internal readonly Dictionary IconMappings = new Dictionary(); - public AvalonEditTextOutput() { } @@ -217,17 +214,13 @@ namespace ICSharpCode.ILSpy.TextView references.Add(new ReferenceSegment { StartOffset = start, EndOffset = end, Reference = definition, IsLocal = true, IsLocalTarget = true }); } - public override void WriteReference(string text, object reference, bool isLocal, bool isIconMapping) + public override void WriteReference(string text, object reference, bool isLocal) { WriteIndent(); int start = this.TextLength; b.Append(text); int end = this.TextLength; references.Add(new ReferenceSegment { StartOffset = start, EndOffset = end, Reference = reference, IsLocal = isLocal }); - - if (isIconMapping && reference is MemberReference && !this.IconMappings.ContainsKey((MemberReference)reference)) { - this.IconMappings.Add((MemberReference)reference, this.Location.Line); - } } public override void MarkFoldStart(string collapsedText, bool defaultCollapsed) @@ -257,4 +250,24 @@ namespace ICSharpCode.ILSpy.TextView } } } + + internal static class Extentions + { + public static Dictionary ToDictionary(this DefinitionLookup definitions, Func lineNumber) + { + if (definitions == null) + throw new ArgumentNullException("definitions"); + + var result = new Dictionary(); + + foreach (var element in definitions.definitions) { + if (!(element.Key is MemberReference)) + continue; + + result.Add((MemberReference)element.Key, lineNumber(element.Value)); + } + + return result; + } + } } diff --git a/ILSpy/TextView/DecompilerTextView.cs b/ILSpy/TextView/DecompilerTextView.cs index a29cda32b..ba6697784 100644 --- a/ILSpy/TextView/DecompilerTextView.cs +++ b/ILSpy/TextView/DecompilerTextView.cs @@ -357,6 +357,12 @@ namespace ICSharpCode.ILSpy.TextView foldingManager.UpdateFoldings(textOutput.Foldings.OrderBy(f => f.StartOffset), -1); Debug.WriteLine(" Updating folding: {0}", w.Elapsed); w.Restart(); } + + // update class bookmarks + var document = textEditor.Document; + manager.UpdateClassMemberBookmarks(textOutput.DefinitionLookup.ToDictionary(line => document.GetLineByOffset(line).LineNumber), + typeof(TypeBookmark), + typeof(MemberBookmark)); } #endregion @@ -551,9 +557,6 @@ namespace ICSharpCode.ILSpy.TextView var output = textOutput as AvalonEditTextOutput; - // update class bookmarks - manager.UpdateClassMemberBookmarks(output.IconMappings, typeof(TypeBookmark), typeof(MemberBookmark)); - // update debug inforomation DebugInformation.CodeMappings = output.CodeMappings; } diff --git a/ILSpy/VB/VBTextOutputFormatter.cs b/ILSpy/VB/VBTextOutputFormatter.cs index d4fbce3ed..b00d20dfa 100644 --- a/ILSpy/VB/VBTextOutputFormatter.cs +++ b/ILSpy/VB/VBTextOutputFormatter.cs @@ -78,14 +78,19 @@ namespace ICSharpCode.ILSpy.VB public void WriteIdentifier(string identifier) { + var definition = GetCurrentDefinition(); + if (definition != null) { + output.WriteDefinition(identifier, definition); + return; + } + object memberRef = GetCurrentMemberReference(); - if (memberRef != null) { - output.WriteReference(identifier, memberRef, isIconMapping: IsIconMapping()); + output.WriteReference(identifier, memberRef); return; } - var definition = GetCurrentLocalDefinition(); + definition = GetCurrentLocalDefinition(); if (definition != null) { output.WriteDefinition(identifier, definition); return; @@ -147,6 +152,22 @@ namespace ICSharpCode.ILSpy.VB return null; } + object GetCurrentDefinition() + { + if (nodeStack == null || nodeStack.Count == 0) + return null; + + var node = nodeStack.Peek(); + if (IsDefinition(node)) + return node.Annotation(); + + node = node.Parent; + if (IsDefinition(node)) + return node.Annotation(); + + return null; + } + public void WriteKeyword(string keyword) { output.Write(keyword); @@ -157,7 +178,7 @@ namespace ICSharpCode.ILSpy.VB // Attach member reference to token only if there's no identifier in the current node. MemberReference memberRef = GetCurrentMemberReference(); if (memberRef != null && nodeStack.Peek().GetChildByRole(AstNode.Roles.Identifier).IsNull) - output.WriteReference(token, memberRef, isIconMapping: IsIconMapping()); + output.WriteReference(token, memberRef); else output.Write(token); } @@ -201,14 +222,9 @@ namespace ICSharpCode.ILSpy.VB output.MarkFoldEnd(); } - private bool IsIconMapping() + private static bool IsDefinition(AstNode node) { - if (nodeStack == null || nodeStack.Count == 0) - return false; - - var node = nodeStack.Peek(); - - return + return node is FieldDeclaration || node is ConstructorDeclaration || node is EventDeclaration ||