22 changed files with 178 additions and 758 deletions
@ -1,204 +0,0 @@
@@ -1,204 +0,0 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
||||
using System; |
||||
using System.Collections.Concurrent; |
||||
using System.Collections.Generic; |
||||
using System.IO; |
||||
|
||||
using ICSharpCode.Decompiler; |
||||
using ICSharpCode.Decompiler.Ast; |
||||
using ICSharpCode.Decompiler.ILAst; |
||||
using ICSharpCode.ILSpyAddIn.LaunchILSpy; |
||||
using ICSharpCode.SharpDevelop.Debugging; |
||||
using ICSharpCode.SharpDevelop.Project; |
||||
using Mono.Cecil; |
||||
|
||||
namespace ICSharpCode.ILSpyAddIn |
||||
{ |
||||
/* |
||||
// Dummy class to avoid the build errors after updating the ICSharpCode.Decompiler version.
|
||||
// TODO: get rid of this & fix debugging decompiled files
|
||||
public class DecompileInformation { |
||||
public dynamic LocalVariables; |
||||
public dynamic CodeMappings; |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Stores the decompilation information.
|
||||
/// </summary>
|
||||
public class DebuggerDecompilerService : IDebuggerDecompilerService |
||||
{ |
||||
ILSpyAssemblyResolver resolver; |
||||
|
||||
static DebuggerDecompilerService() |
||||
{ |
||||
DebugInformation = new ConcurrentDictionary<int, DecompileInformation>(); |
||||
ProjectService.SolutionClosed += delegate { |
||||
DebugInformation.Clear(); |
||||
GC.Collect(); |
||||
}; |
||||
} |
||||
|
||||
internal static IDebuggerDecompilerService Instance { get; private set; } |
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the external debug information.
|
||||
/// <summary>This constains the code mappings and local variables.</summary>
|
||||
/// </summary>
|
||||
internal static ConcurrentDictionary<int, DecompileInformation> DebugInformation { get; private set; } |
||||
|
||||
public DebuggerDecompilerService() |
||||
{ |
||||
Instance = this; |
||||
} |
||||
|
||||
public Tuple<int, int> DebugStepInformation { get; set; } |
||||
|
||||
public bool CheckMappings(int typeToken) |
||||
{ |
||||
DecompileInformation data = null; |
||||
DebugInformation.TryGetValue(typeToken, out data); |
||||
DecompileInformation information = data as DecompileInformation; |
||||
|
||||
if (information == null) |
||||
return false; |
||||
|
||||
if (information.CodeMappings == null) |
||||
return false; |
||||
|
||||
return true; |
||||
} |
||||
|
||||
public void DecompileOnDemand(TypeDefinition type) |
||||
{ |
||||
if (type == null) |
||||
return; |
||||
|
||||
if (CheckMappings(type.MetadataToken.ToInt32())) |
||||
return; |
||||
|
||||
try { |
||||
DecompilerContext context = new DecompilerContext(type.Module); |
||||
AstBuilder astBuilder = new AstBuilder(context); |
||||
astBuilder.AddType(type); |
||||
DebuggerTextOutput output = new DebuggerTextOutput(new PlainTextOutput()); |
||||
astBuilder.GenerateCode(output); |
||||
|
||||
// int token = type.MetadataToken.ToInt32();
|
||||
// var info = new DecompileInformation {
|
||||
// CodeMappings = astBuilder.CodeMappings,
|
||||
// LocalVariables = astBuilder.LocalVariables,
|
||||
// DecompiledMemberReferences = astBuilder.DecompiledMemberReferences
|
||||
// };
|
||||
//
|
||||
// // save the data
|
||||
// DebugInformation.AddOrUpdate(token, info, (k, v) => info);
|
||||
} catch { |
||||
return; |
||||
} |
||||
} |
||||
|
||||
public bool GetILAndTokenByLineNumber(int typeToken, int lineNumber, out int[] ilRanges, out int memberToken) |
||||
{ |
||||
ilRanges = null; |
||||
memberToken = -1; |
||||
if (!CheckMappings(typeToken)) |
||||
return false; |
||||
|
||||
var data = (DecompileInformation)DebugInformation[typeToken]; |
||||
var mappings = data.CodeMappings; |
||||
foreach (var key in mappings.Keys) { |
||||
var list = mappings[key]; |
||||
var instruction = list.GetInstructionByLineNumber(lineNumber, out memberToken); |
||||
if (instruction == null) |
||||
continue; |
||||
|
||||
ilRanges = new int[] { instruction.ILInstructionOffset.From, instruction.ILInstructionOffset.To }; |
||||
memberToken = instruction.MemberMapping.MetadataToken; |
||||
return true; |
||||
} |
||||
|
||||
return false; |
||||
} |
||||
|
||||
public bool GetILAndLineNumber(int typeToken, int memberToken, int ilOffset, out int[] ilRange, out int line, out bool isMatch) |
||||
{ |
||||
ilRange = null; |
||||
line = -1; |
||||
isMatch = false; |
||||
|
||||
if (!CheckMappings(typeToken)) |
||||
return false; |
||||
|
||||
var data = (DecompileInformation)DebugInformation[typeToken]; |
||||
var mappings = data.CodeMappings; |
||||
|
||||
if (!mappings.ContainsKey(memberToken)) |
||||
return false; |
||||
|
||||
var map = mappings[memberToken].GetInstructionByTokenAndOffset(memberToken, ilOffset, out isMatch); |
||||
if (map != null) { |
||||
ilRange = map.ToArray(isMatch); |
||||
line = map.SourceCodeLine; |
||||
return true; |
||||
} |
||||
|
||||
return false; |
||||
} |
||||
|
||||
public IEnumerable<string> GetLocalVariables(int typeToken, int memberToken) |
||||
{ |
||||
if (DebugInformation == null || !DebugInformation.ContainsKey(typeToken)) |
||||
yield break; |
||||
|
||||
var externalData = DebugInformation[typeToken]; |
||||
IEnumerable<ILVariable> list; |
||||
|
||||
if (externalData.LocalVariables.TryGetValue(memberToken, out list)) { |
||||
foreach (var local in list) { |
||||
if (local.IsParameter) |
||||
continue; |
||||
if (string.IsNullOrEmpty(local.Name)) |
||||
continue; |
||||
yield return local.Name; |
||||
} |
||||
} |
||||
} |
||||
|
||||
public object GetLocalVariableIndex(int typeToken, int memberToken, string name) |
||||
{ |
||||
if (DebugInformation == null || !DebugInformation.ContainsKey(typeToken)) |
||||
return null; |
||||
|
||||
var externalData = DebugInformation[typeToken]; |
||||
IEnumerable<ILVariable> list; |
||||
|
||||
if (externalData.LocalVariables.TryGetValue(memberToken, out list)) { |
||||
foreach (var local in list) { |
||||
if (local.IsParameter) |
||||
continue; |
||||
if (local.Name == name) |
||||
return new[] { local.OriginalVariable.Index }; |
||||
} |
||||
} |
||||
|
||||
return null; |
||||
} |
||||
|
||||
public IAssemblyResolver GetAssemblyResolver(string assemblyFile) |
||||
{ |
||||
if (string.IsNullOrEmpty(assemblyFile)) |
||||
throw new ArgumentException("assemblyFile is null or empty"); |
||||
|
||||
string folderPath = Path.GetDirectoryName(assemblyFile); |
||||
if (resolver == null) |
||||
return (resolver = new ILSpyAssemblyResolver(folderPath)); |
||||
|
||||
if (string.Compare(folderPath, resolver.FolderPath, StringComparison.OrdinalIgnoreCase) != 0) |
||||
return (resolver = new ILSpyAssemblyResolver(folderPath)); |
||||
|
||||
return resolver; |
||||
} |
||||
} |
||||
*/ |
||||
} |
@ -1,84 +0,0 @@
@@ -1,84 +0,0 @@
|
||||
// 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; |
||||
using System.ComponentModel.Design; |
||||
using System.Windows.Controls; |
||||
|
||||
using ICSharpCode.AvalonEdit.AddIn; |
||||
using ICSharpCode.AvalonEdit.Document; |
||||
using ICSharpCode.AvalonEdit.Highlighting; |
||||
using ICSharpCode.AvalonEdit.Search; |
||||
using ICSharpCode.SharpDevelop; |
||||
using ICSharpCode.SharpDevelop.Editor; |
||||
using ICSharpCode.SharpDevelop.Editor.Bookmarks; |
||||
using ICSharpCode.SharpDevelop.Gui; |
||||
|
||||
namespace ICSharpCode.ILSpyAddIn.ViewContent |
||||
{ |
||||
/// <summary>
|
||||
/// Equivalent to AE.AddIn CodeEditor, but without editing capabilities.
|
||||
/// </summary>
|
||||
class CodeView : Grid, IDisposable, IPositionable |
||||
{ |
||||
readonly SharpDevelopTextEditor textEditor; |
||||
readonly IconBarManager iconBarManager; |
||||
readonly IconBarMargin iconMargin; |
||||
readonly TextMarkerService textMarkerService; |
||||
readonly AvalonEditTextEditorAdapter adapter; |
||||
|
||||
public CodeView() |
||||
{ |
||||
textEditor = new SharpDevelopTextEditor(); |
||||
textEditor.IsReadOnly = true; |
||||
this.Children.Add(textEditor); |
||||
adapter = new AvalonEditTextEditorAdapter(textEditor); |
||||
|
||||
textEditor.SyntaxHighlighting = HighlightingManager.Instance.GetDefinition("C#"); |
||||
|
||||
// add margin
|
||||
this.iconMargin = new IconBarMargin(iconBarManager = new IconBarManager()); |
||||
textEditor.TextArea.LeftMargins.Insert(0, iconMargin); |
||||
textEditor.TextArea.TextView.VisualLinesChanged += delegate { iconMargin.InvalidateVisual(); }; |
||||
|
||||
// add marker service
|
||||
this.textMarkerService = new TextMarkerService(textEditor.Document); |
||||
textEditor.TextArea.TextView.BackgroundRenderers.Add(textMarkerService); |
||||
textEditor.TextArea.TextView.LineTransformers.Add(textMarkerService); |
||||
var documentServiceContainer = textEditor.Document.GetRequiredService<ServiceContainer>(); |
||||
documentServiceContainer.AddService(typeof(ITextMarkerService), textMarkerService); |
||||
documentServiceContainer.AddService(typeof(IBookmarkMargin), iconBarManager); |
||||
|
||||
textEditor.TextArea.DefaultInputHandler.NestedInputHandlers.Add(new SearchInputHandler(textEditor.TextArea)); |
||||
} |
||||
|
||||
public TextDocument Document { |
||||
get { return textEditor.Document; } |
||||
} |
||||
|
||||
public IconBarManager IconBarManager { |
||||
get { return iconBarManager; } |
||||
} |
||||
|
||||
public void Dispose() |
||||
{ |
||||
} |
||||
|
||||
public int Line { |
||||
get { |
||||
return textEditor.TextArea.Caret.Line; |
||||
} |
||||
} |
||||
|
||||
public int Column { |
||||
get { |
||||
return textEditor.TextArea.Caret.Column; |
||||
} |
||||
} |
||||
|
||||
public void JumpTo(int line, int column) |
||||
{ |
||||
adapter.JumpTo(line, column); |
||||
} |
||||
} |
||||
} |
@ -1,73 +0,0 @@
@@ -1,73 +0,0 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
||||
using System; |
||||
using ICSharpCode.Core; |
||||
using ICSharpCode.NRefactory; |
||||
using ICSharpCode.SharpDevelop.Debugging; |
||||
|
||||
namespace ICSharpCode.SharpDevelop.Editor.Bookmarks |
||||
{ |
||||
/* |
||||
public class DecompiledBreakpointBookmark : BreakpointBookmark |
||||
{ |
||||
public const string SEPARATOR = ","; // don't use '.'
|
||||
|
||||
MemberReference memberReference; |
||||
string assemblyFile; |
||||
|
||||
public DecompiledBreakpointBookmark(FileName fileName, TextLocation location) |
||||
: base(fileName, location) |
||||
{ |
||||
|
||||
} |
||||
|
||||
public MemberReference MemberReference { |
||||
get { return memberReference; } |
||||
} |
||||
|
||||
public MemberReference GetMemberReference(IAssemblyResolver resolver) |
||||
{ |
||||
if (resolver == null) |
||||
throw new ArgumentNullException("resolver"); |
||||
|
||||
if (memberReference != null) |
||||
return memberReference; |
||||
|
||||
// reload from filename
|
||||
ReaderParameters readerParameters = new ReaderParameters(); |
||||
// Use new assembly resolver instance so that the AssemblyDefinitions can be garbage-collected
|
||||
// once the code is decompiled.
|
||||
readerParameters.AssemblyResolver = resolver; |
||||
|
||||
string typeName; |
||||
if (GetAssemblyAndType(FileName.ToString(), out assemblyFile, out typeName)) { |
||||
ModuleDefinition module = ModuleDefinition.ReadModule(assemblyFile, readerParameters); |
||||
TypeDefinition typeDefinition = module.GetType(typeName); |
||||
if (typeDefinition == null) |
||||
throw new InvalidOperationException("Could not find type"); |
||||
memberReference = typeDefinition; |
||||
} |
||||
|
||||
return memberReference; |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets the assembly file and the type from the file name.
|
||||
/// </summary>
|
||||
/// <returns><c>true</c>, if the operation succeded; <c>false</c>, otherwise.</returns>
|
||||
public static bool GetAssemblyAndType(string fileName, out string assemblyFile, out string typeName) |
||||
{ |
||||
if (string.IsNullOrEmpty(fileName) || !fileName.Contains(",")) { |
||||
assemblyFile = null; |
||||
typeName = null; |
||||
return false; |
||||
} |
||||
|
||||
int index = fileName.IndexOf(SEPARATOR); |
||||
assemblyFile = fileName.Substring(0, index); |
||||
typeName = fileName.Substring(index + 1, fileName.Length - index - 4); |
||||
return true; |
||||
} |
||||
} |
||||
*/ |
||||
} |
Loading…
Reference in new issue