Browse Source

Merge remote branch 'eusebiu/master' (re-enable debugger and IconBarMargin)

pull/285/head
Daniel Grunwald 14 years ago
parent
commit
cb02344e52
  1. 7
      Debugger/ILSpy.Debugger/Commands/BreakpointCommand.cs
  2. 7
      Debugger/ILSpy.Debugger/Models/TreeModel/ExpressionNode.cs
  3. 6
      Debugger/ILSpy.Debugger/Services/Debugger/WindowsDebugger.cs
  4. 2
      ICSharpCode.Decompiler/Ast/AstMethodBodyBuilder.cs
  5. 40
      ICSharpCode.Decompiler/Ast/TextOutputFormatter.cs
  6. 96
      ICSharpCode.Decompiler/CodeMappings.cs
  7. 1
      ICSharpCode.Decompiler/Disassembler/ReflectionDisassembler.cs
  8. 3
      ICSharpCode.Decompiler/ITextOutput.cs
  9. 71
      ICSharpCode.Decompiler/PlainTextOutput.cs
  10. 23
      ILSpy.SharpDevelop.LGPL/AvalonEdit/IconBarManager.cs
  11. 31
      ILSpy.SharpDevelop.LGPL/AvalonEdit/IconBarMargin.cs
  12. 7
      ILSpy.SharpDevelop.LGPL/Bookmarks/BreakpointBookmark.cs
  13. 4
      ILSpy.SharpDevelop.LGPL/Bookmarks/CurrentLineBookmark.cs
  14. 54
      ILSpy.SharpDevelop.LGPL/DebugInformation.cs
  15. 4
      ILSpy.SharpDevelop.LGPL/Services/DebuggerService.cs
  16. 2
      ILSpy/Bookmarks/Commands.cs
  17. 189
      ILSpy/Bookmarks/MemberBookmark.cs
  18. 4
      ILSpy/Images/Images.cs
  19. 6
      ILSpy/Languages/Language.cs
  20. 53
      ILSpy/TextView/AvalonEditTextOutput.cs
  21. 46
      ILSpy/TextView/DecompilerTextView.cs
  22. 37
      ILSpy/VB/VBTextOutputFormatter.cs

7
Debugger/ILSpy.Debugger/Commands/BreakpointCommand.cs

@ -28,8 +28,8 @@ namespace ICSharpCode.ILSpy.Debugger.Commands @@ -28,8 +28,8 @@ namespace ICSharpCode.ILSpy.Debugger.Commands
// check if the codemappings exists for this line
var storage = DebugInformation.CodeMappings;
int token = 0;
foreach (var storageEntry in storage) {
var instruction = storageEntry.Value.GetInstructionByLineNumber(line, out token);
foreach (var storageEntry in storage.Values) {
var instruction = storageEntry.GetInstructionByLineNumber(line, out token);
if (instruction == null) {
continue;
@ -40,8 +40,7 @@ namespace ICSharpCode.ILSpy.Debugger.Commands @@ -40,8 +40,7 @@ namespace ICSharpCode.ILSpy.Debugger.Commands
instruction.MemberMapping.MemberReference,
line,
token,
instruction.ILInstructionOffset,
DebugInformation.Language);
instruction.ILInstructionOffset);
break;
}

7
Debugger/ILSpy.Debugger/Models/TreeModel/ExpressionNode.cs

@ -11,6 +11,7 @@ using System.Windows.Media; @@ -11,6 +11,7 @@ using System.Windows.Media;
using Debugger;
using Debugger.MetaData;
using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.Ast;
using ICSharpCode.Decompiler.ILAst;
using ICSharpCode.ILSpy.Debugger.Services;
@ -161,9 +162,9 @@ namespace ICSharpCode.ILSpy.Debugger.Models.TreeModel @@ -161,9 +162,9 @@ namespace ICSharpCode.ILSpy.Debugger.Models.TreeModel
}
// get local variable index
IEnumerable<ILVariable> list;
if (DebugInformation.LocalVariables.TryGetValue(token, out list)) {
var variable = list.FirstOrDefault(v => v.Name == targetName);
MemberMapping mapping;
if (DebugInformation.CodeMappings != null && DebugInformation.CodeMappings.TryGetValue(token, out mapping)) {
var variable = mapping.LocalVariables.FirstOrDefault(v => v.Name == targetName);
if (variable != null && variable.OriginalVariable != null) {
if (expression is MemberReferenceExpression) {
var memberExpression = (MemberReferenceExpression)expression;

6
Debugger/ILSpy.Debugger/Services/Debugger/WindowsDebugger.cs

@ -288,7 +288,7 @@ namespace ICSharpCode.ILSpy.Debugger.Services @@ -288,7 +288,7 @@ namespace ICSharpCode.ILSpy.Debugger.Services
if (DebugInformation.CodeMappings == null || !DebugInformation.CodeMappings.ContainsKey(key))
return null;
return DebugInformation.CodeMappings[key].GetInstructionByTokenAndOffset(key, frame.IP, out isMatch);
return DebugInformation.CodeMappings[key].GetInstructionByTokenAndOffset(frame.IP, out isMatch);
}
StackFrame GetStackFrame()
@ -301,7 +301,7 @@ namespace ICSharpCode.ILSpy.Debugger.Services @@ -301,7 +301,7 @@ namespace ICSharpCode.ILSpy.Debugger.Services
frame.ILRanges = new [] { 0, 1 };
} else {
//var frame = debuggedProcess.SelectedThread.MostRecentStackFrame;
frame.SourceCodeLine = map.SourceCodeLine;
frame.SourceCodeLine = map.StartLocation.Line;
frame.ILRanges = map.ToArray(isMatch);
}
@ -800,7 +800,7 @@ namespace ICSharpCode.ILSpy.Debugger.Services @@ -800,7 +800,7 @@ namespace ICSharpCode.ILSpy.Debugger.Services
if (DebugInformation.CodeMappings != null &&
DebugInformation.CodeMappings.ContainsKey(token) &&
DebugInformation.CodeMappings[token].GetInstructionByTokenAndOffset(token, ilOffset, out memberReference, out line)) {
DebugInformation.CodeMappings[token].GetInstructionByTokenAndOffset(ilOffset, out memberReference, out line)) {
DebugInformation.DebugStepInformation = null; // we do not need to step into/out
DebuggerService.RemoveCurrentLineMarker();
DebuggerService.JumpToCurrentLine(memberReference, line, 0, line, 0, ilOffset);

2
ICSharpCode.Decompiler/Ast/AstMethodBodyBuilder.cs

@ -125,7 +125,7 @@ namespace ICSharpCode.Decompiler.Ast @@ -125,7 +125,7 @@ namespace ICSharpCode.Decompiler.Ast
astBlock.Statements.InsertBefore(insertionPoint, newVarDecl);
}
astBlock.AddAnnotation(new MemberMapping(methodDef));
astBlock.AddAnnotation(new MemberMapping(methodDef) { LocalVariables = localVariables });
return astBlock;
}

40
ICSharpCode.Decompiler/Ast/TextOutputFormatter.cs

@ -45,6 +45,12 @@ namespace ICSharpCode.Decompiler.Ast @@ -45,6 +45,12 @@ namespace ICSharpCode.Decompiler.Ast
public void WriteIdentifier(string identifier)
{
var definition = GetCurrentDefinition();
if (definition != null) {
output.WriteDefinition(identifier, definition, false);
return;
}
object memberRef = GetCurrentMemberReference();
if (memberRef != null) {
@ -52,7 +58,7 @@ namespace ICSharpCode.Decompiler.Ast @@ -52,7 +58,7 @@ namespace ICSharpCode.Decompiler.Ast
return;
}
var definition = GetCurrentLocalDefinition();
definition = GetCurrentLocalDefinition();
if (definition != null) {
output.WriteDefinition(identifier, definition);
return;
@ -136,6 +142,22 @@ namespace ICSharpCode.Decompiler.Ast @@ -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<MemberReference>();
var fieldDef = node.Parent.Annotation<FieldDefinition>();
if (fieldDef != null)
return node.Parent.Annotation<MemberReference>();
return null;
}
public void WriteKeyword(string keyword)
{
output.Write(keyword);
@ -145,7 +167,8 @@ namespace ICSharpCode.Decompiler.Ast @@ -145,7 +167,8 @@ namespace ICSharpCode.Decompiler.Ast
{
// 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)
var node = nodeStack.Peek();
if (memberRef != null && node.GetChildByRole(AstNode.Roles.Identifier).IsNull)
output.WriteReference(token, memberRef);
else
output.Write(token);
@ -286,5 +309,18 @@ namespace ICSharpCode.Decompiler.Ast @@ -286,5 +309,18 @@ namespace ICSharpCode.Decompiler.Ast
currentMemberMapping = parentMemberMappings.Pop();
}
}
private static bool IsDefinition(AstNode node)
{
return
node is FieldDeclaration ||
node is ConstructorDeclaration ||
node is DestructorDeclaration ||
node is EventDeclaration ||
node is DelegateDeclaration ||
node is OperatorDeclaration||
node is MemberDeclaration ||
node is TypeDeclaration;
}
}
}

96
ICSharpCode.Decompiler/CodeMappings.cs

@ -29,25 +29,11 @@ using Mono.Cecil; @@ -29,25 +29,11 @@ using Mono.Cecil;
namespace ICSharpCode.Decompiler
{
[Obsolete]
public enum DecompiledLanguages
{
IL,
CSharp
}
/// <summary>
/// Maps the source code to IL.
/// </summary>
public sealed class SourceCodeMapping
{
[Obsolete("Use StartLocation instead - there might be multiple statements per line (e.g. for loops)")]
public int SourceCodeLine {
get {
return this.StartLocation.Line;
}
}
/// <summary>
/// Gets or sets the start location of the instruction.
/// </summary>
@ -78,7 +64,7 @@ namespace ICSharpCode.Decompiler @@ -78,7 +64,7 @@ namespace ICSharpCode.Decompiler
// add list for the current source code line
currentList.AddRange(ILRange.OrderAndJoint(MemberMapping.MemberCodeMappings
.FindAll(m => m.SourceCodeLine == this.SourceCodeLine)
.FindAll(m => m.StartLocation.Line == this.StartLocation.Line)
.ConvertAll<ILRange>(m => m.ILInstructionOffset)));
if (!isMatch) {
@ -103,7 +89,7 @@ namespace ICSharpCode.Decompiler @@ -103,7 +89,7 @@ namespace ICSharpCode.Decompiler
}
/// <summary>
/// Stores the method information and its source code mappings.
/// Stores the member information and its source code mappings.
/// </summary>
public sealed class MemberMapping
{
@ -141,6 +127,11 @@ namespace ICSharpCode.Decompiler @@ -141,6 +127,11 @@ namespace ICSharpCode.Decompiler
/// </summary>
public List<SourceCodeMapping> MemberCodeMappings { get; internal set; }
/// <summary>
/// Gets or sets the local variables.
/// </summary>
public IEnumerable<ILVariable> LocalVariables { get; internal set; }
/// <summary>
/// Gets the inverted IL Ranges.<br/>
/// E.g.: for (0-9, 11-14, 14-18, 21-25) => (9-11,18-21).
@ -164,40 +155,6 @@ namespace ICSharpCode.Decompiler @@ -164,40 +155,6 @@ namespace ICSharpCode.Decompiler
/// </summary>
public static class CodeMappings
{
/// <summary>
/// Create code mapping for a method.
/// </summary>
/// <param name="method">Method to create the mapping for.</param>
/// <param name="codeMappings">Source code mapping storage.</param>
/// <param name="actualMemberReference">The actual member reference.</param>
internal static MemberMapping CreateCodeMapping(
this MethodDefinition member,
List<MemberMapping> codeMappings,
MemberReference actualMemberReference = null)
{
if (member == null || !member.HasBody)
return null;
if (codeMappings == null)
return null;
// create IL/CSharp code mappings - used in debugger
MemberMapping currentMemberMapping = null;
if (codeMappings.Find(map => map.MetadataToken == member.MetadataToken.ToInt32()) == null) {
currentMemberMapping = new MemberMapping() {
MetadataToken = member.MetadataToken.ToInt32(),
MemberCodeMappings = new List<SourceCodeMapping>(),
MemberReference = actualMemberReference ?? member,
CodeSize = member.Body.CodeSize
};
codeMappings.Add(currentMemberMapping);
}
return currentMemberMapping;
}
/// <summary>
/// Gets source code mapping and metadata token based on type name and line number.
/// </summary>
@ -207,20 +164,18 @@ namespace ICSharpCode.Decompiler @@ -207,20 +164,18 @@ namespace ICSharpCode.Decompiler
/// <param name="metadataToken">Metadata token.</param>
/// <returns></returns>
public static SourceCodeMapping GetInstructionByLineNumber(
this List<MemberMapping> codeMappings,
this MemberMapping codeMapping,
int lineNumber,
out int metadataToken)
{
if (codeMappings == null)
if (codeMapping == null)
throw new ArgumentException("CodeMappings storage must be valid!");
foreach (var maping in codeMappings) {
var map = maping.MemberCodeMappings.Find(m => m.SourceCodeLine == lineNumber);
var map = codeMapping.MemberCodeMappings.Find(m => m.StartLocation.Line == lineNumber);
if (map != null) {
metadataToken = maping.MetadataToken;
metadataToken = codeMapping.MetadataToken;
return map;
}
}
metadataToken = 0;
return null;
@ -235,30 +190,24 @@ namespace ICSharpCode.Decompiler @@ -235,30 +190,24 @@ namespace ICSharpCode.Decompiler
/// <param name="isMatch">True, if perfect match.</param>
/// <returns>A code mapping.</returns>
public static SourceCodeMapping GetInstructionByTokenAndOffset(
this List<MemberMapping> codeMappings,
int token,
this MemberMapping codeMapping,
int ilOffset,
out bool isMatch)
{
isMatch = false;
if (codeMappings == null)
if (codeMapping == null)
throw new ArgumentNullException("CodeMappings storage must be valid!");
var maping = codeMappings.Find(m => m.MetadataToken == token);
if (maping == null)
return null;
// try find an exact match
var map = maping.MemberCodeMappings.Find(m => m.ILInstructionOffset.From <= ilOffset && ilOffset < m.ILInstructionOffset.To);
var map = codeMapping.MemberCodeMappings.Find(m => m.ILInstructionOffset.From <= ilOffset && ilOffset < m.ILInstructionOffset.To);
if (map == null) {
// get the immediate next one
map = maping.MemberCodeMappings.Find(m => m.ILInstructionOffset.From > ilOffset);
map = codeMapping.MemberCodeMappings.Find(m => m.ILInstructionOffset.From > ilOffset);
isMatch = false;
if (map == null)
map = maping.MemberCodeMappings.LastOrDefault(); // get the last
map = codeMapping.MemberCodeMappings.LastOrDefault(); // get the last
return map;
}
@ -270,15 +219,14 @@ namespace ICSharpCode.Decompiler @@ -270,15 +219,14 @@ namespace ICSharpCode.Decompiler
/// <summary>
/// Gets the source code and type name from metadata token and offset.
/// </summary>
/// <param name="codeMappings">Code mappings storage.</param>
/// <param name="codeMappings">Code mapping storage.</param>
/// <param name="token">Metadata token.</param>
/// <param name="ilOffset">IL offset.</param>
/// <param name="typeName">Type definition.</param>
/// <param name="line">Line number.</param>
/// <remarks>It is possible to exist to different types from different assemblies with the same metadata token.</remarks>
public static bool GetInstructionByTokenAndOffset(
this List<MemberMapping> codeMappings,
int token,
this MemberMapping mapping,
int ilOffset,
out MemberReference member,
out int line)
@ -286,12 +234,8 @@ namespace ICSharpCode.Decompiler @@ -286,12 +234,8 @@ namespace ICSharpCode.Decompiler
member = null;
line = 0;
if (codeMappings == null)
throw new ArgumentException("CodeMappings storage must be valid!");
var mapping = codeMappings.Find(m => m.MetadataToken == token);
if (mapping == null)
return false;
throw new ArgumentException("CodeMappings storage must be valid!");
var codeMapping = mapping.MemberCodeMappings.Find(
cm => cm.ILInstructionOffset.From <= ilOffset && ilOffset <= cm.ILInstructionOffset.To - 1);
@ -305,7 +249,7 @@ namespace ICSharpCode.Decompiler @@ -305,7 +249,7 @@ namespace ICSharpCode.Decompiler
}
member = mapping.MemberReference;
line = codeMapping.SourceCodeLine;
line = codeMapping.StartLocation.Line;
return true;
}
}

1
ICSharpCode.Decompiler/Disassembler/ReflectionDisassembler.cs

@ -743,6 +743,7 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -743,6 +743,7 @@ namespace ICSharpCode.Decompiler.Disassembler
{
if (method == null)
return;
output.Write(keyword);
output.Write(' ');
method.WriteTo(output);

3
ICSharpCode.Decompiler/ITextOutput.cs

@ -19,6 +19,7 @@ @@ -19,6 +19,7 @@
using System;
using System.IO;
using ICSharpCode.NRefactory;
using Mono.Cecil;
namespace ICSharpCode.Decompiler
{
@ -31,7 +32,7 @@ namespace ICSharpCode.Decompiler @@ -31,7 +32,7 @@ namespace ICSharpCode.Decompiler
void Write(char ch);
void Write(string text);
void WriteLine();
void WriteDefinition(string text, object definition);
void WriteDefinition(string text, object definition, bool isLocal = true);
void WriteReference(string text, object reference, bool isLocal = false);
void AddDebuggerMemberMapping(MemberMapping memberMapping);

71
ICSharpCode.Decompiler/PlainTextOutput.cs

@ -17,12 +17,57 @@ @@ -17,12 +17,57 @@
// DEALINGS IN THE SOFTWARE.
using System;
using System.Collections.Generic;
using System.IO;
using ICSharpCode.NRefactory;
using Mono.Cecil;
namespace ICSharpCode.Decompiler
{
public sealed class PlainTextOutput : ITextOutput
/// <summary>
/// Base text output.
/// <remarks>Provides access to code mappings.</remarks>
/// </summary>
public abstract class BaseTextOutput : ITextOutput
{
#region Code mappings
Dictionary<int, MemberMapping> codeMappings = new Dictionary<int, MemberMapping>();
public Dictionary<int, MemberMapping> CodeMappings {
get { return codeMappings; }
}
public virtual void AddDebuggerMemberMapping(MemberMapping memberMapping)
{
if (memberMapping == null)
throw new ArgumentNullException("memberMapping");
int token = memberMapping.MetadataToken;
codeMappings.Add(token, memberMapping);
}
#endregion
#region ITextOutput members
public abstract TextLocation Location { get; }
public abstract void Indent();
public abstract void Unindent();
public abstract void Write(char ch);
public abstract void Write(string text);
public abstract void WriteLine();
public abstract void WriteDefinition(string text, object definition, bool isLocal);
public abstract void WriteReference(string text, object reference, bool isLocal);
public abstract void MarkFoldStart(string collapsedText, bool defaultCollapsed);
public abstract void MarkFoldEnd();
#endregion
}
/// <summary>
/// Plain text output.
/// <remarks>Can be used when there's no UI.</remarks>
/// </summary>
public sealed class PlainTextOutput : BaseTextOutput
{
readonly TextWriter writer;
int indent;
@ -43,7 +88,7 @@ namespace ICSharpCode.Decompiler @@ -43,7 +88,7 @@ namespace ICSharpCode.Decompiler
this.writer = new StringWriter();
}
public TextLocation Location {
public override TextLocation Location {
get {
return new TextLocation(line, column + (needsIndent ? indent : 0));
}
@ -54,12 +99,12 @@ namespace ICSharpCode.Decompiler @@ -54,12 +99,12 @@ namespace ICSharpCode.Decompiler
return writer.ToString();
}
public void Indent()
public override void Indent()
{
indent++;
}
public void Unindent()
public override void Unindent()
{
indent--;
}
@ -75,21 +120,21 @@ namespace ICSharpCode.Decompiler @@ -75,21 +120,21 @@ namespace ICSharpCode.Decompiler
}
}
public void Write(char ch)
public override void Write(char ch)
{
WriteIndent();
writer.Write(ch);
column++;
}
public void Write(string text)
public override void Write(string text)
{
WriteIndent();
writer.Write(text);
column += text.Length;
}
public void WriteLine()
public override void WriteLine()
{
writer.WriteLine();
needsIndent = true;
@ -97,25 +142,21 @@ namespace ICSharpCode.Decompiler @@ -97,25 +142,21 @@ namespace ICSharpCode.Decompiler
column = 1;
}
public void WriteDefinition(string text, object definition)
public override void WriteDefinition(string text, object definition, bool isLocal)
{
Write(text);
}
public void WriteReference(string text, object reference, bool isLocal)
public override void WriteReference(string text, object reference, bool isLocal)
{
Write(text);
}
void ITextOutput.MarkFoldStart(string collapsedText, bool defaultCollapsed)
{
}
void ITextOutput.MarkFoldEnd()
public override void MarkFoldStart(string collapsedText, bool defaultCollapsed)
{
}
void ITextOutput.AddDebuggerMemberMapping(MemberMapping memberMapping)
public override void MarkFoldEnd()
{
}
}

23
ILSpy.SharpDevelop.LGPL/AvalonEdit/IconBarManager.cs

@ -8,7 +8,9 @@ using System.Collections.Specialized; @@ -8,7 +8,9 @@ using System.Collections.Specialized;
using System.Linq;
using ICSharpCode.ILSpy.Bookmarks;
using ICSharpCode.ILSpy.Debugger;
using ICSharpCode.NRefactory.CSharp;
using Mono.Cecil;
namespace ICSharpCode.ILSpy.AvalonEdit
{
@ -42,25 +44,18 @@ namespace ICSharpCode.ILSpy.AvalonEdit @@ -42,25 +44,18 @@ namespace ICSharpCode.ILSpy.AvalonEdit
public event EventHandler RedrawRequested;
public void UpdateClassMemberBookmarks(IEnumerable<AstNode> nodes, Type bookmarkType, Type memberType)
public void UpdateClassMemberBookmarks(Dictionary<MemberReference, int> iconMappings, Type bookmarkType, Type memberType)
{
this.bookmarks.Clear();
if (nodes == null || nodes.Count() == 0)
if (iconMappings == null || iconMappings.Count == 0)
return;
foreach (var n in nodes) {
switch (n.NodeType) {
case NodeType.TypeDeclaration:
case NodeType.TypeReference:
this.bookmarks.Add(Activator.CreateInstance(bookmarkType, n) as IBookmark);
break;
case NodeType.Member:
this.bookmarks.Add(Activator.CreateInstance(memberType, n) as IBookmark);
break;
default:
// do nothing
break;
foreach (var n in iconMappings) {
if (n.Key is TypeDefinition) {
this.bookmarks.Add(Activator.CreateInstance(bookmarkType, n.Key, n.Value) as IBookmark);
} else {
this.bookmarks.Add(Activator.CreateInstance(memberType, n.Key, n.Value) as IBookmark);
}
}
}

31
ILSpy.SharpDevelop.LGPL/AvalonEdit/IconBarMargin.cs

@ -7,6 +7,7 @@ using System.Linq; @@ -7,6 +7,7 @@ using System.Linq;
using System.Windows;
using System.Windows.Input;
using System.Windows.Media;
using ICSharpCode.AvalonEdit.Editing;
using ICSharpCode.AvalonEdit.Rendering;
using ICSharpCode.AvalonEdit.Utils;
@ -16,7 +17,6 @@ using ICSharpCode.ILSpy.Debugger; @@ -16,7 +17,6 @@ using ICSharpCode.ILSpy.Debugger;
using ICSharpCode.ILSpy.Debugger.Bookmarks;
using ICSharpCode.ILSpy.Debugger.Services;
using ICSharpCode.NRefactory;
using ICSharpCode.NRefactory.CSharp;
using Mono.Cecil;
namespace ICSharpCode.ILSpy.AvalonEdit
@ -37,8 +37,6 @@ namespace ICSharpCode.ILSpy.AvalonEdit @@ -37,8 +37,6 @@ namespace ICSharpCode.ILSpy.AvalonEdit
get { return manager; }
}
public IList<MemberReference> DecompiledMembers { get; set; }
public virtual void Dispose()
{
this.TextView = null; // detach from TextView (will also detach from manager)
@ -75,10 +73,6 @@ namespace ICSharpCode.ILSpy.AvalonEdit @@ -75,10 +73,6 @@ namespace ICSharpCode.ILSpy.AvalonEdit
if (DebugInformation.CodeMappings == null || DebugInformation.CodeMappings.Count == 0 ||
!DebugInformation.CodeMappings.ContainsKey(((BreakpointBookmark)bm).FunctionToken))
continue;
} else {
if (DebugInformation.DecompiledMemberReferences == null || DebugInformation.DecompiledMemberReferences.Count == 0 ||
!DebugInformation.DecompiledMemberReferences.ContainsKey(((MarkerBookmark)bm).MemberReference.MetadataToken.ToInt32()))
continue;
}
int line = bm.LineNumber;
IBookmark existingBookmark;
@ -143,12 +137,15 @@ namespace ICSharpCode.ILSpy.AvalonEdit @@ -143,12 +137,15 @@ namespace ICSharpCode.ILSpy.AvalonEdit
{
BookmarkBase result = null;
foreach (BookmarkBase bm in BookmarkManager.Bookmarks) {
if (bm.LineNumber == line &&
this.DecompiledMembers != null && this.DecompiledMembers.Contains(bm.MemberReference)) {
if (bm.LineNumber != line)
continue;
if (DebugInformation.CodeMappings == null || DebugInformation.CodeMappings.Count == 0 ||
!DebugInformation.CodeMappings.ContainsKey(((BreakpointBookmark)bm).FunctionToken))
continue;
if (result == null || bm.ZOrder > result.ZOrder)
return result;
}
}
return manager.Bookmarks.FirstOrDefault(b => b.LineNumber == line);
}
@ -299,17 +296,17 @@ namespace ICSharpCode.ILSpy.AvalonEdit @@ -299,17 +296,17 @@ namespace ICSharpCode.ILSpy.AvalonEdit
var key = breakpoint.FunctionToken;
if (!storage.ContainsKey(key))
{
continue;
}
bool isMatch;
SourceCodeMapping map = storage[key].GetInstructionByTokenAndOffset(key, breakpoint.ILRange.From, out isMatch);
SourceCodeMapping map = storage[key].GetInstructionByTokenAndOffset(breakpoint.ILRange.From, out isMatch);
if (map != null) {
BreakpointBookmark newBookmark = new BreakpointBookmark(
breakpoint.MemberReference, new TextLocation(map.SourceCodeLine, 0), breakpoint.FunctionToken,
map.ILInstructionOffset, BreakpointAction.Break, DebugInformation.Language);
BreakpointBookmark newBookmark = new BreakpointBookmark(breakpoint.MemberReference,
new TextLocation(map.StartLocation.Line, 0),
breakpoint.FunctionToken,
map.ILInstructionOffset,
BreakpointAction.Break);
newBookmark.IsEnabled = breakpoint.IsEnabled;
newBookmarks.Add(newBookmark);
@ -343,7 +340,7 @@ namespace ICSharpCode.ILSpy.AvalonEdit @@ -343,7 +340,7 @@ namespace ICSharpCode.ILSpy.AvalonEdit
// 2. map the marker line
MemberReference memberReference;
int newline;
if (codeMappings[token].GetInstructionByTokenAndOffset(token, offset, out memberReference, out newline)) {
if (codeMappings[token].GetInstructionByTokenAndOffset(offset, out memberReference, out newline)) {
// 3. create breakpoint for new languages
DebuggerService.JumpToCurrentLine(memberReference, newline, 0, newline, 0, offset);
}

7
ILSpy.SharpDevelop.LGPL/Bookmarks/BreakpointBookmark.cs

@ -27,8 +27,6 @@ namespace ICSharpCode.ILSpy.Debugger.Bookmarks @@ -27,8 +27,6 @@ namespace ICSharpCode.ILSpy.Debugger.Bookmarks
bool isEnabled = true;
BreakpointAction action = BreakpointAction.Break;
public DecompiledLanguages Language { get; private set; }
public BreakpointAction Action {
get {
return action;
@ -84,14 +82,13 @@ namespace ICSharpCode.ILSpy.Debugger.Bookmarks @@ -84,14 +82,13 @@ namespace ICSharpCode.ILSpy.Debugger.Bookmarks
public string Tooltip { get; private set; }
public BreakpointBookmark(MemberReference member, TextLocation location, int functionToken, ILRange range, BreakpointAction action, DecompiledLanguages language)
public BreakpointBookmark(MemberReference member, TextLocation location, int functionToken, ILRange range, BreakpointAction action)
: base(member, location)
{
this.action = action;
this.FunctionToken = functionToken;
this.ILRange = range;
this.Tooltip = string.Format("Language:{0}, Line:{1}, IL range:{2}-{3}", language.ToString(), location.Line, range.From, range.To);
this.Language = language;
this.Tooltip = string.Format("Line:{0}, IL range:{1}-{2}", location.Line, range.From, range.To);
}
public override ImageSource Image {

4
ILSpy.SharpDevelop.LGPL/Bookmarks/CurrentLineBookmark.cs

@ -84,8 +84,8 @@ namespace ICSharpCode.ILSpy.Debugger.Bookmarks @@ -84,8 +84,8 @@ namespace ICSharpCode.ILSpy.Debugger.Bookmarks
ITextMarker marker = markerService.Create(offset + startColumn - 1, length + 1);
marker.BackgroundColor = Colors.Yellow;
marker.ForegroundColor = Colors.Blue;
marker.IsVisible = b => b is MarkerBookmark && DebugInformation.DecompiledMemberReferences != null &&
DebugInformation.DecompiledMemberReferences.ContainsKey(((MarkerBookmark)b).MemberReference.MetadataToken.ToInt32());
marker.IsVisible = b => b is MarkerBookmark && DebugInformation.CodeMappings != null &&
DebugInformation.CodeMappings.ContainsKey(((MarkerBookmark)b).MemberReference.MetadataToken.ToInt32());
marker.Bookmark = this;
this.Marker = marker;
return marker;

54
ILSpy.SharpDevelop.LGPL/DebugInformation.cs

@ -16,22 +16,6 @@ namespace ICSharpCode.ILSpy.Debugger @@ -16,22 +16,6 @@ namespace ICSharpCode.ILSpy.Debugger
/// </summary>
public static class DebugInformation
{
static DecompiledLanguages language;
/// <summary>
/// Gets or sets the decompiled language.
/// </summary>
public static DecompiledLanguages Language {
get { return language; }
set {
var oldLanguage = language;
if (value != language) {
language = value;
OnLanguageChanged(new LanguageEventArgs(oldLanguage, language));
}
}
}
/// <summary>
/// List of loaded assemblies.
/// </summary>
@ -40,17 +24,7 @@ namespace ICSharpCode.ILSpy.Debugger @@ -40,17 +24,7 @@ namespace ICSharpCode.ILSpy.Debugger
/// <summary>
/// Gets or sets the current code mappings.
/// </summary>
public static Dictionary<int, List<MemberMapping>> CodeMappings { get; set; }
/// <summary>
/// Gets or sets the local variables of the current decompiled type, method, etc.
/// </summary>
public static ConcurrentDictionary<int, IEnumerable<ILVariable>> LocalVariables { get; set; }
/// <summary>
/// Gets or sets the MembeReference that was decompiled (a TypeDefinition, MethodDefinition, etc)
/// </summary>
public static Dictionary<int, MemberReference> DecompiledMemberReferences { get; set; }
public static Dictionary<int, MemberMapping> CodeMappings { get; set; }
/// <summary>
/// Gets or sets the current token, IL offset and member reference. Used for step in/out.
@ -61,31 +35,5 @@ namespace ICSharpCode.ILSpy.Debugger @@ -61,31 +35,5 @@ namespace ICSharpCode.ILSpy.Debugger
/// Gets or sets whether the debugger is loaded.
/// </summary>
public static bool IsDebuggerLoaded { get; set; }
/// <summary>
/// Occures when the language is changed.
/// </summary>
public static event EventHandler<LanguageEventArgs> LanguageChanged;
private static void OnLanguageChanged(LanguageEventArgs e)
{
var handler = LanguageChanged;
if (handler != null) {
handler(null, e);
}
}
}
public class LanguageEventArgs : EventArgs
{
public DecompiledLanguages OldLanguage { get; private set; }
public DecompiledLanguages NewLanguage { get; private set; }
public LanguageEventArgs(DecompiledLanguages oldLanguage, DecompiledLanguages newLanguage)
{
this.OldLanguage = oldLanguage;
this.NewLanguage = newLanguage;
}
}
}

4
ILSpy.SharpDevelop.LGPL/Services/DebuggerService.cs

@ -169,12 +169,12 @@ namespace ICSharpCode.ILSpy.Debugger.Services @@ -169,12 +169,12 @@ namespace ICSharpCode.ILSpy.Debugger.Services
}
}
public static void ToggleBreakpointAt(MemberReference member, int lineNumber, int functionToken, ILRange range, DecompiledLanguages language)
public static void ToggleBreakpointAt(MemberReference member, int lineNumber, int functionToken, ILRange range)
{
BookmarkManager.ToggleBookmark(
member.FullName, lineNumber,
b => b.CanToggle && b is BreakpointBookmark,
location => new BreakpointBookmark(member, location, functionToken, range, BreakpointAction.Break, language));
location => new BreakpointBookmark(member, location, functionToken, range, BreakpointAction.Break));
}
/* TODO: reimplement this stuff

2
ILSpy/Bookmarks/Commands.cs

@ -42,7 +42,7 @@ namespace ICSharpCode.ILSpy.Bookmarks @@ -42,7 +42,7 @@ namespace ICSharpCode.ILSpy.Bookmarks
if (!(mark is MemberBookmark))
continue;
var member = (mark as MemberBookmark).Node.Annotation<MemberReference>();
var member = (mark as MemberBookmark).Member;
AnalyzeContextMenuEntry.Analyze(member);
}
}

189
ILSpy/Bookmarks/MemberBookmark.cs

@ -35,68 +35,43 @@ namespace ICSharpCode.ILSpy.Bookmarks @@ -35,68 +35,43 @@ namespace ICSharpCode.ILSpy.Bookmarks
/// </summary>
public class MemberBookmark : IBookmark
{
AstNode node;
MemberReference member;
public AstNode Node {
public MemberReference Member {
get {
return node;
return member;
}
}
public MemberBookmark(AstNode node)
public MemberBookmark(MemberReference member, int line)
{
this.node = node;
this.member = member;
LineNumber = line;
}
public virtual ImageSource Image {
get {
var attrNode = (AttributedNode)node;
if (node is EnumMemberDeclaration)
return GetMemberOverlayedImage(attrNode, MemberIcon.EnumValue);
if (member is FieldDefinition)
return GetOverlayedImage(member as FieldDefinition, MemberIcon.Field);
if (node is FieldDeclaration)
return GetMemberOverlayedImage(attrNode, MemberIcon.Field);
if (member is PropertyDefinition)
return GetOverlayedImage(member as PropertyDefinition, MemberIcon.Property);
if (node is PropertyDeclaration)
return GetMemberOverlayedImage(attrNode, MemberIcon.Property);
if (member is EventDefinition)
return GetOverlayedImage(member as EventDefinition, MemberIcon.Event);
if (node is EventDeclaration || node is CustomEventDeclaration)
return GetMemberOverlayedImage(attrNode, MemberIcon.Event);
if (member is MethodDefinition)
return GetOverlayedImage(member as MethodDefinition, MemberIcon.Method);
if (node is IndexerDeclaration)
return GetMemberOverlayedImage(attrNode, MemberIcon.Indexer);
if (member is TypeDefinition)
return GetOverlayedImage(member as TypeDefinition);
if (node is OperatorDeclaration)
return GetMemberOverlayedImage(attrNode, MemberIcon.Operator);
if (node is ConstructorDeclaration || node is DestructorDeclaration)
return GetMemberOverlayedImage(attrNode, MemberIcon.Constructor);
return GetMemberOverlayedImage(attrNode, MemberIcon.Method);
}
return null;
}
ImageSource GetMemberOverlayedImage(AttributedNode attrNode, MemberIcon icon)
{
switch (attrNode.Modifiers & Modifiers.VisibilityMask) {
case Modifiers.Protected:
return Images.GetIcon(icon, AccessOverlayIcon.Protected, (attrNode.Modifiers & Modifiers.Static) == Modifiers.Static);
case Modifiers.Private:
return Images.GetIcon(icon, AccessOverlayIcon.Private, (attrNode.Modifiers & Modifiers.Static) == Modifiers.Static);
case Modifiers.Internal:
return Images.GetIcon(icon, AccessOverlayIcon.Internal, (attrNode.Modifiers & Modifiers.Static) == Modifiers.Static);
}
return Images.GetIcon(icon, AccessOverlayIcon.Public, (attrNode.Modifiers & Modifiers.Static) == Modifiers.Static);
}
public int LineNumber {
get {
//var t = node.Annotation<TextOutputLocation>();
//if (t != null)
// return t.Line;
return 0;
}
get; private set;
}
public virtual void MouseDown(MouseButtonEventArgs e)
@ -119,53 +94,121 @@ namespace ICSharpCode.ILSpy.Bookmarks @@ -119,53 +94,121 @@ namespace ICSharpCode.ILSpy.Bookmarks
{
throw new NotSupportedException();
}
}
public class TypeBookmark : MemberBookmark
#region Overlayed images
internal ImageSource GetOverlayedImage(TypeDefinition typeDef)
{
public TypeBookmark(AstNode node) : base (node)
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;
public override ImageSource Image {
get {
var attrNode = (AttributedNode)Node;
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 (Node is DelegateDeclaration)
return GetTypeOverlayedImage(attrNode, TypeIcon.Delegate);
if (fieldDef.IsStatic)
isStatic = true;
return Images.GetIcon(icon, overlayIcon, isStatic);
}
if (Node is TypeDeclaration) {
var n = Node as TypeDeclaration;
switch (n.ClassType)
ImageSource GetOverlayedImage(MethodDefinition methodDef, MemberIcon icon)
{
case ClassType.Enum:
return GetTypeOverlayedImage(attrNode, TypeIcon.Enum);
case ClassType.Struct:
return GetTypeOverlayedImage(attrNode, TypeIcon.Struct);
case ClassType.Interface:
return GetTypeOverlayedImage(attrNode, TypeIcon.Interface);
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);
}
if ((attrNode.Modifiers & Modifiers.Static) == Modifiers.Static)
return GetTypeOverlayedImage(attrNode, TypeIcon.StaticClass);
ImageSource GetOverlayedImage(EventDefinition eventDef, MemberIcon icon)
{
bool isStatic = false;
AccessOverlayIcon overlayIcon = AccessOverlayIcon.Public;
return GetTypeOverlayedImage(attrNode, TypeIcon.Class);
return Images.GetIcon(icon, overlayIcon, isStatic);
}
#endregion
}
ImageSource GetTypeOverlayedImage(AttributedNode attrNode, TypeIcon icon)
public class TypeBookmark : MemberBookmark
{
switch (attrNode.Modifiers & Modifiers.VisibilityMask) {
case Modifiers.Protected:
return Images.GetIcon(icon, AccessOverlayIcon.Protected);
case Modifiers.Private:
return Images.GetIcon(icon, AccessOverlayIcon.Private);
case Modifiers.Internal:
return Images.GetIcon(icon, AccessOverlayIcon.Internal);
public TypeBookmark(MemberReference member, int line) : base (member, line)
{
}
public override ImageSource Image {
get {
if (Member is TypeDefinition) {
return GetOverlayedImage(Member as TypeDefinition);
}
return Images.GetIcon(icon, AccessOverlayIcon.Public);
return null;
}
}
}
}

4
ILSpy/Images/Images.cs

@ -117,10 +117,10 @@ namespace ICSharpCode.ILSpy @@ -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)

6
ILSpy/Languages/Language.cs

@ -59,12 +59,6 @@ namespace ICSharpCode.ILSpy @@ -59,12 +59,6 @@ namespace ICSharpCode.ILSpy
/// </summary>
public abstract class Language
{
/// <summary>
/// Decompile finished event.
/// </summary>
[Obsolete]
public event EventHandler<DecompileEventArgs> DecompileFinished { add {} remove {} }
/// <summary>
/// Gets the name of the language (as shown in the UI)
/// </summary>

53
ILSpy/TextView/AvalonEditTextOutput.cs

@ -22,11 +22,13 @@ using System.Diagnostics; @@ -22,11 +22,13 @@ using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Windows;
using ICSharpCode.AvalonEdit.Document;
using ICSharpCode.AvalonEdit.Folding;
using ICSharpCode.AvalonEdit.Rendering;
using ICSharpCode.AvalonEdit.Utils;
using ICSharpCode.Decompiler;
using Mono.Cecil;
namespace ICSharpCode.ILSpy.TextView
{
@ -45,7 +47,7 @@ namespace ICSharpCode.ILSpy.TextView @@ -45,7 +47,7 @@ namespace ICSharpCode.ILSpy.TextView
/// </summary>
sealed class DefinitionLookup
{
Dictionary<object, int> definitions = new Dictionary<object, int>();
internal Dictionary<object, int> definitions = new Dictionary<object, int>();
public int GetDefinitionPosition(object definition)
{
@ -65,7 +67,7 @@ namespace ICSharpCode.ILSpy.TextView @@ -65,7 +67,7 @@ namespace ICSharpCode.ILSpy.TextView
/// <summary>
/// Text output implementation for AvalonEdit.
/// </summary>
public sealed class AvalonEditTextOutput : ISmartTextOutput
public sealed class AvalonEditTextOutput : BaseTextOutput, ISmartTextOutput
{
int lastLineStart = 0;
int lineNumber = 1;
@ -92,8 +94,6 @@ namespace ICSharpCode.ILSpy.TextView @@ -92,8 +94,6 @@ namespace ICSharpCode.ILSpy.TextView
/// <summary>Embedded UIElements, see <see cref="UIElementGenerator"/>.</summary>
internal readonly List<KeyValuePair<int, Lazy<UIElement>>> UIElements = new List<KeyValuePair<int, Lazy<UIElement>>>();
List<MemberMapping> memberMappings = new List<MemberMapping>();
public AvalonEditTextOutput()
{
}
@ -121,16 +121,12 @@ namespace ICSharpCode.ILSpy.TextView @@ -121,16 +121,12 @@ namespace ICSharpCode.ILSpy.TextView
get { return b.Length; }
}
public ICSharpCode.NRefactory.TextLocation Location {
public override ICSharpCode.NRefactory.TextLocation Location {
get {
return new ICSharpCode.NRefactory.TextLocation(lineNumber, b.Length - lastLineStart + 1 + (needsIndent ? indent : 0));
}
}
public IList<MemberMapping> MemberMappings {
get { return memberMappings; }
}
#region Text Document
TextDocument textDocument;
@ -163,12 +159,12 @@ namespace ICSharpCode.ILSpy.TextView @@ -163,12 +159,12 @@ namespace ICSharpCode.ILSpy.TextView
}
#endregion
public void Indent()
public override void Indent()
{
indent++;
}
public void Unindent()
public override void Unindent()
{
indent--;
}
@ -184,19 +180,19 @@ namespace ICSharpCode.ILSpy.TextView @@ -184,19 +180,19 @@ namespace ICSharpCode.ILSpy.TextView
}
}
public void Write(char ch)
public override void Write(char ch)
{
WriteIndent();
b.Append(ch);
}
public void Write(string text)
public override void Write(string text)
{
WriteIndent();
b.Append(text);
}
public void WriteLine()
public override void WriteLine()
{
Debug.Assert(textDocument == null);
b.AppendLine();
@ -208,17 +204,17 @@ namespace ICSharpCode.ILSpy.TextView @@ -208,17 +204,17 @@ namespace ICSharpCode.ILSpy.TextView
}
}
public void WriteDefinition(string text, object definition)
public override void WriteDefinition(string text, object definition, bool isLocal)
{
WriteIndent();
int start = this.TextLength;
b.Append(text);
int end = this.TextLength;
this.DefinitionLookup.AddDefinition(definition, this.TextLength);
references.Add(new ReferenceSegment { StartOffset = start, EndOffset = end, Reference = definition, IsLocal = true, IsLocalTarget = true });
references.Add(new ReferenceSegment { StartOffset = start, EndOffset = end, Reference = definition, IsLocal = isLocal, IsLocalTarget = true });
}
public void WriteReference(string text, object reference, bool isLocal)
public override void WriteReference(string text, object reference, bool isLocal)
{
WriteIndent();
int start = this.TextLength;
@ -227,7 +223,7 @@ namespace ICSharpCode.ILSpy.TextView @@ -227,7 +223,7 @@ namespace ICSharpCode.ILSpy.TextView
references.Add(new ReferenceSegment { StartOffset = start, EndOffset = end, Reference = reference, IsLocal = isLocal });
}
public void MarkFoldStart(string collapsedText, bool defaultCollapsed)
public override void MarkFoldStart(string collapsedText, bool defaultCollapsed)
{
WriteIndent();
openFoldings.Push(
@ -238,7 +234,7 @@ namespace ICSharpCode.ILSpy.TextView @@ -238,7 +234,7 @@ namespace ICSharpCode.ILSpy.TextView
});
}
public void MarkFoldEnd()
public override void MarkFoldEnd()
{
NewFolding f = openFoldings.Pop();
f.EndOffset = this.TextLength;
@ -253,10 +249,25 @@ namespace ICSharpCode.ILSpy.TextView @@ -253,10 +249,25 @@ namespace ICSharpCode.ILSpy.TextView
this.UIElements.Add(new KeyValuePair<int, Lazy<UIElement>>(this.TextLength, new Lazy<UIElement>(element)));
}
}
}
public void AddDebuggerMemberMapping(MemberMapping memberMapping)
internal static class Extentions
{
public static Dictionary<MemberReference, int> ToDictionary(this DefinitionLookup definitions, Func<int, int> lineNumber)
{
memberMappings.Add(memberMapping);
if (definitions == null)
throw new ArgumentNullException("definitions");
var result = new Dictionary<MemberReference, int>();
foreach (var element in definitions.definitions) {
if (!(element.Key is MemberReference))
continue;
result.Add((MemberReference)element.Key, lineNumber(element.Value));
}
return result;
}
}
}

46
ILSpy/TextView/DecompilerTextView.cs

@ -357,6 +357,12 @@ namespace ICSharpCode.ILSpy.TextView @@ -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
@ -465,7 +471,7 @@ namespace ICSharpCode.ILSpy.TextView @@ -465,7 +471,7 @@ namespace ICSharpCode.ILSpy.TextView
if (DebugInformation.CodeMappings == null || !DebugInformation.CodeMappings.ContainsKey(token))
return;
DebugInformation.CodeMappings[token].GetInstructionByTokenAndOffset(token, ilOffset, out member, out line);
DebugInformation.CodeMappings[token].GetInstructionByTokenAndOffset(ilOffset, out member, out line);
// update marker
DebuggerService.JumpToCurrentLine(member, line, 0, line, 0, ilOffset);
@ -529,15 +535,10 @@ namespace ICSharpCode.ILSpy.TextView @@ -529,15 +535,10 @@ namespace ICSharpCode.ILSpy.TextView
void DecompileNodes(DecompilationContext context, ITextOutput textOutput)
{
// reset data
// reset debug information
DebugInformation.CodeMappings = null;
DebugInformation.LocalVariables = null;
DebugInformation.DecompiledMemberReferences = null;
// set the language
DebugInformation.Language = MainWindow.Instance.sessionSettings.FilterSettings.Language.Name.StartsWith("IL") ? DecompiledLanguages.IL : DecompiledLanguages.CSharp;
var nodes = context.TreeNodes;
context.Language.DecompileFinished += Language_DecompileFinished;
for (int i = 0; i < nodes.Length; i++) {
if (i > 0)
textOutput.WriteLine();
@ -545,32 +546,19 @@ namespace ICSharpCode.ILSpy.TextView @@ -545,32 +546,19 @@ namespace ICSharpCode.ILSpy.TextView
context.Options.CancellationToken.ThrowIfCancellationRequested();
nodes[i].Decompile(context.Language, textOutput, context.Options);
}
context.Language.DecompileFinished -= Language_DecompileFinished;
OnDecompilationFinished(textOutput);
}
void Language_DecompileFinished(object sender, DecompileEventArgs e)
void OnDecompilationFinished(ITextOutput textOutput)
{
if (e != null) {
manager.UpdateClassMemberBookmarks(e.AstNodes, typeof(TypeBookmark), typeof(MemberBookmark));
if (iconMargin.DecompiledMembers == null) {
iconMargin.DecompiledMembers = new List<MemberReference>();
}
iconMargin.DecompiledMembers.AddRange(e.DecompiledMemberReferences.Values.AsEnumerable());
if (!(textOutput is AvalonEditTextOutput))
return;
// debugger info
if (DebugInformation.CodeMappings == null) {
DebugInformation.CodeMappings = e.CodeMappings;
DebugInformation.LocalVariables = e.LocalVariables;
DebugInformation.DecompiledMemberReferences = e.DecompiledMemberReferences;
} else {
DebugInformation.CodeMappings.AddRange(e.CodeMappings);
DebugInformation.DecompiledMemberReferences.AddRange(e.DecompiledMemberReferences);
if (e.LocalVariables != null)
DebugInformation.LocalVariables.AddRange(e.LocalVariables);
}
} else {
manager.UpdateClassMemberBookmarks(null, typeof(TypeBookmark), typeof(MemberBookmark));
}
var output = textOutput as AvalonEditTextOutput;
// update debug inforomation
DebugInformation.CodeMappings = output.CodeMappings;
}
#endregion

37
ILSpy/VB/VBTextOutputFormatter.cs

@ -78,14 +78,19 @@ namespace ICSharpCode.ILSpy.VB @@ -78,14 +78,19 @@ namespace ICSharpCode.ILSpy.VB
public void WriteIdentifier(string identifier)
{
object memberRef = GetCurrentMemberReference();
var definition = GetCurrentDefinition();
if (definition != null) {
output.WriteDefinition(identifier, definition);
return;
}
object memberRef = GetCurrentMemberReference();
if (memberRef != null) {
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 @@ -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<MemberReference>();
node = node.Parent;
if (IsDefinition(node))
return node.Annotation<MemberReference>();
return null;
}
public void WriteKeyword(string keyword)
{
output.Write(keyword);
@ -200,5 +221,17 @@ namespace ICSharpCode.ILSpy.VB @@ -200,5 +221,17 @@ namespace ICSharpCode.ILSpy.VB
{
output.MarkFoldEnd();
}
private static bool IsDefinition(AstNode node)
{
return
node is FieldDeclaration ||
node is ConstructorDeclaration ||
node is EventDeclaration ||
node is DelegateDeclaration ||
node is OperatorDeclaration||
node is MemberDeclaration ||
node is TypeDeclaration;
}
}
}

Loading…
Cancel
Save